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.context;
021
022import ca.uhn.fhir.i18n.Msg;
023import org.hl7.fhir.instance.model.api.IBase;
024import org.hl7.fhir.instance.model.api.IBaseReference;
025
026import java.util.List;
027import java.util.Map;
028import java.util.Map.Entry;
029import java.util.Optional;
030import java.util.Set;
031
032public abstract class BaseRuntimeChildDefinition {
033
034        private BaseRuntimeChildDefinition myReplacedParentDefinition;
035
036        public abstract IAccessor getAccessor();
037
038        public abstract BaseRuntimeElementDefinition<?> getChildByName(String theName);
039
040        public abstract BaseRuntimeElementDefinition<?> getChildElementDefinitionByDatatype(Class<? extends IBase> theType);
041
042        public abstract String getChildNameByDatatype(Class<? extends IBase> theDatatype);
043
044        public abstract String getElementName();
045
046        public String getExtensionUrl() {
047                return null;
048        }
049
050        public Object getInstanceConstructorArguments() {
051                return null;
052        }
053
054        public abstract int getMax();
055
056        public abstract int getMin();
057
058        public abstract IMutator getMutator();
059
060        public abstract Set<String> getValidChildNames();
061
062        public abstract boolean isSummary();
063
064        abstract void sealAndInitialize(FhirContext theContext, Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> theClassToElementDefinitions);
065
066        @Override
067        public String toString() {
068                return getClass().getSimpleName() + "[" + getElementName() + "]";
069        }
070
071        public BaseRuntimeChildDefinition getReplacedParentDefinition() {
072                return myReplacedParentDefinition;
073        }
074
075        public void setReplacedParentDefinition(BaseRuntimeChildDefinition myReplacedParentDefinition) {
076                this.myReplacedParentDefinition = myReplacedParentDefinition;
077        }
078
079        public interface IAccessor {
080                List<IBase> getValues(IBase theTarget);
081
082                default <T extends IBase> Optional<T> getFirstValueOrNull(IBase theTarget) {
083                        return (Optional<T>) getValues(theTarget).stream().findFirst();
084                }
085        }
086
087        public interface IMutator {
088                void addValue(IBase theTarget, IBase theValue);
089
090                void setValue(IBase theTarget, IBase theValue);
091
092                /**
093                 * Remove an item from a list of values
094                 * @param theTarget field to remove the item from (e.g. patient.name)
095                 * @param theIndex the index of the item to be removed (e.g. 1 for patient.name[1])
096                 */
097                default void remove(IBase theTarget, int theIndex) {
098                        // implemented in subclasses
099                }
100        }
101
102        BaseRuntimeElementDefinition<?> findResourceReferenceDefinition(Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> theClassToElementDefinitions) {
103                for (Entry<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> next : theClassToElementDefinitions.entrySet()) {
104                        if (IBaseReference.class.isAssignableFrom(next.getKey())) {
105                                return next.getValue();
106                        }
107                }
108                
109                // Shouldn't happen
110                throw new IllegalStateException(Msg.code(1692) + "Unable to find reference type");
111        }
112
113        // public String getExtensionUrl() {
114        // return null;
115        // }
116}