001/*
002 * #%L
003 * HAPI FHIR - Core Library
004 * %%
005 * Copyright (C) 2014 - 2024 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 ca.uhn.fhir.context.FhirContext;
023import ca.uhn.fhir.context.RuntimeResourceDefinition;
024import ca.uhn.fhir.context.RuntimeSearchParam;
025import ca.uhn.fhir.model.api.Include;
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 java.util.Iterator;
032import java.util.List;
033import java.util.Set;
034
035/**
036 * Created by Bill de Beaubien on 2/26/2015.
037 */
038public class ResourceReferenceInfo {
039        private String myOwningResource;
040        private String myName;
041        private IBaseReference myResource;
042        private FhirContext myContext;
043
044        public ResourceReferenceInfo(
045                        FhirContext theContext,
046                        IBaseResource theOwningResource,
047                        List<String> thePathToElement,
048                        IBaseReference theElement) {
049                myContext = theContext;
050                myOwningResource = theContext.getResourceType(theOwningResource);
051
052                myResource = theElement;
053                if (thePathToElement != null && !thePathToElement.isEmpty()) {
054                        StringBuilder sb = new StringBuilder();
055                        for (Iterator<String> iterator = thePathToElement.iterator(); iterator.hasNext(); ) {
056                                sb.append(iterator.next());
057                                if (iterator.hasNext()) sb.append(".");
058                        }
059                        myName = sb.toString();
060                } else {
061                        myName = null;
062                }
063        }
064
065        @Override
066        public String toString() {
067                ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
068                b.append("name", myName);
069                b.append("resource", myResource.getReferenceElement());
070                return b.build();
071        }
072
073        public String getName() {
074                return myName;
075        }
076
077        public IBaseReference getResourceReference() {
078                return myResource;
079        }
080
081        public boolean matchesIncludeSet(Set<Include> theIncludes) {
082                if (theIncludes == null) return false;
083                for (Include include : theIncludes) {
084                        if (matchesInclude(include)) 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) || s.startsWith(completeName + ".")) {
106                                                        matched = true;
107                                                        break;
108                                                }
109                                        }
110                                        return matched;
111                                }
112                        }
113                        return false;
114                }
115                // DSTU1 style
116                return (theInclude.getValue().equals(myOwningResource + '.' + myName));
117        }
118}