001/*
002 * #%L
003 * HAPI FHIR - Core Library
004 * %%
005 * Copyright (C) 2014 - 2023 Smile CDR, Inc.
006 * %%
007 * Licensed under the Apache License, Version 2.0 (the "License");
008 * you may not use this file except in compliance with the License.
009 * You may obtain a copy of the License at
010 *
011 *      http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing, software
014 * distributed under the License is distributed on an "AS IS" BASIS,
015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016 * See the License for the specific language governing permissions and
017 * limitations under the License.
018 * #L%
019 */
020package ca.uhn.fhir.util;
021
022import java.util.Iterator;
023import java.util.List;
024import java.util.Set;
025
026import org.apache.commons.lang3.builder.ToStringBuilder;
027import org.apache.commons.lang3.builder.ToStringStyle;
028import org.hl7.fhir.instance.model.api.IBaseReference;
029import org.hl7.fhir.instance.model.api.IBaseResource;
030
031import ca.uhn.fhir.context.FhirContext;
032import ca.uhn.fhir.context.RuntimeResourceDefinition;
033import ca.uhn.fhir.context.RuntimeSearchParam;
034import ca.uhn.fhir.model.api.Include;
035
036/**
037 * Created by Bill de Beaubien on 2/26/2015.
038 */
039public class ResourceReferenceInfo {
040        private String myOwningResource;
041        private String myName;
042        private IBaseReference myResource;
043        private FhirContext myContext;
044
045        public ResourceReferenceInfo(FhirContext theContext, IBaseResource theOwningResource, List<String> thePathToElement, IBaseReference theElement) {
046                myContext = theContext;
047                myOwningResource = theContext.getResourceType(theOwningResource);
048
049                myResource = theElement;
050                if (thePathToElement != null && !thePathToElement.isEmpty()) {
051                        StringBuilder sb = new StringBuilder();
052                        for (Iterator<String> iterator = thePathToElement.iterator(); iterator.hasNext();) {
053                                sb.append(iterator.next());
054                                if (iterator.hasNext())
055                                        sb.append(".");
056                        }
057                        myName = sb.toString();
058                } else {
059                        myName = null;
060                }
061        }
062
063        @Override
064        public String toString() {
065                ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
066                b.append("name", myName);
067                b.append("resource", myResource.getReferenceElement());
068                return b.build();
069        }
070
071        public String getName() {
072                return myName;
073        }
074
075        public IBaseReference getResourceReference() {
076                return myResource;
077        }
078
079        public boolean matchesIncludeSet(Set<Include> theIncludes) {
080                if (theIncludes == null)
081                        return false;
082                for (Include include : theIncludes) {
083                        if (matchesInclude(include))
084                                return true;
085                }
086                return false;
087        }
088
089        public boolean matchesInclude(Include theInclude) {
090                if (theInclude.getValue().equals("*")) {
091                        return true;
092                }
093                int colonIndex = theInclude.getValue().indexOf(':');
094                if (colonIndex != -1) {
095                        // DSTU2+ style
096                        String resourceName = theInclude.getValue().substring(0, colonIndex);
097                        String paramName = theInclude.getValue().substring(colonIndex + 1);
098                        RuntimeResourceDefinition resourceDef = myContext.getResourceDefinition(resourceName);
099                        if (resourceDef != null) {
100                                RuntimeSearchParam searchParamDef = resourceDef.getSearchParam(paramName);
101                                if (searchParamDef!=null) {
102                                        final String completeName = myOwningResource + "." + myName;
103                                        boolean matched = false;
104                                        for (String s : searchParamDef.getPathsSplit()) {
105                                                if (s.equals(completeName) ||
106                                                                       s.startsWith(completeName + ".")) {
107                                                        matched = true; break;
108                                                }
109                                        }
110                                        return matched;
111                                }
112                        }
113                        return false;
114                }
115                // DSTU1 style
116                return (theInclude.getValue().equals(myOwningResource + '.' + myName));
117        }
118}