001package ca.uhn.fhir.context;
002
003/*
004 * #%L
005 * HAPI FHIR - Core Library
006 * %%
007 * Copyright (C) 2014 - 2023 Smile CDR, Inc.
008 * %%
009 * Licensed under the Apache License, Version 2.0 (the "License");
010 * you may not use this file except in compliance with the License.
011 * You may obtain a copy of the License at
012 *
013 *      http://www.apache.org/licenses/LICENSE-2.0
014 *
015 * Unless required by applicable law or agreed to in writing, software
016 * distributed under the License is distributed on an "AS IS" BASIS,
017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
018 * See the License for the specific language governing permissions and
019 * limitations under the License.
020 * #L%
021 */
022
023import ca.uhn.fhir.i18n.Msg;
024import org.hl7.fhir.instance.model.api.IBase;
025import org.hl7.fhir.instance.model.api.IBaseReference;
026
027import java.util.List;
028import java.util.Map;
029import java.util.Map.Entry;
030import java.util.Optional;
031import java.util.Set;
032
033public abstract class BaseRuntimeChildDefinition {
034
035        private BaseRuntimeChildDefinition myReplacedParentDefinition;
036
037        public abstract IAccessor getAccessor();
038
039        public abstract BaseRuntimeElementDefinition<?> getChildByName(String theName);
040
041        public abstract BaseRuntimeElementDefinition<?> getChildElementDefinitionByDatatype(Class<? extends IBase> theType);
042
043        public abstract String getChildNameByDatatype(Class<? extends IBase> theDatatype);
044
045        public abstract String getElementName();
046
047        public String getExtensionUrl() {
048                return null;
049        }
050
051        public Object getInstanceConstructorArguments() {
052                return null;
053        }
054
055        public abstract int getMax();
056
057        public abstract int getMin();
058
059        public abstract IMutator getMutator();
060
061        public abstract Set<String> getValidChildNames();
062
063        public abstract boolean isSummary();
064
065        abstract void sealAndInitialize(FhirContext theContext, Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> theClassToElementDefinitions);
066
067        @Override
068        public String toString() {
069                return getClass().getSimpleName() + "[" + getElementName() + "]";
070        }
071
072        public BaseRuntimeChildDefinition getReplacedParentDefinition() {
073                return myReplacedParentDefinition;
074        }
075
076        public void setReplacedParentDefinition(BaseRuntimeChildDefinition myReplacedParentDefinition) {
077                this.myReplacedParentDefinition = myReplacedParentDefinition;
078        }
079
080        public interface IAccessor {
081                List<IBase> getValues(IBase theTarget);
082
083                default <T extends IBase> Optional<T> getFirstValueOrNull(IBase theTarget) {
084                        return (Optional<T>) getValues(theTarget).stream().findFirst();
085                }
086        }
087
088        public interface IMutator {
089                void addValue(IBase theTarget, IBase theValue);
090
091                void setValue(IBase theTarget, IBase theValue);
092
093                /**
094                 * Remove an item from a list of values
095                 * @param theTarget field to remove the item from (e.g. patient.name)
096                 * @param theIndex the index of the item to be removed (e.g. 1 for patient.name[1])
097                 */
098                default void remove(IBase theTarget, int theIndex) {
099                        // implemented in subclasses
100                }
101        }
102
103        BaseRuntimeElementDefinition<?> findResourceReferenceDefinition(Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> theClassToElementDefinitions) {
104                for (Entry<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> next : theClassToElementDefinitions.entrySet()) {
105                        if (IBaseReference.class.isAssignableFrom(next.getKey())) {
106                                return next.getValue();
107                        }
108                }
109                
110                // Shouldn't happen
111                throw new IllegalStateException(Msg.code(1692) + "Unable to find reference type");
112        }
113
114        // public String getExtensionUrl() {
115        // return null;
116        // }
117}