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.model.api;
021
022import ca.uhn.fhir.model.api.annotation.Child;
023import ca.uhn.fhir.model.api.annotation.Description;
024import org.apache.commons.lang3.Validate;
025import org.hl7.fhir.instance.model.api.IBaseDatatype;
026
027import java.util.*;
028
029public abstract class BaseElement implements /*IElement, */ISupportsUndeclaredExtensions {
030
031        private static final long serialVersionUID = -3092659584634499332L;
032        private List<String> myFormatCommentsPost;
033        private List<String> myFormatCommentsPre;
034        private Map<String, Object> userData;
035
036        @Child(name = "extension", type = {ExtensionDt.class}, order = 0, min = 0, max = Child.MAX_UNLIMITED, modifier = false, summary = false)
037        @Description(shortDefinition = "Additional Content defined by implementations", formalDefinition = "May be used to represent additional information that is not part of the basic definition of the resource. In order to make the use of extensions safe and manageable, there is a strict set of governance  applied to the definition and use of extensions. Though any implementer is allowed to define an extension, there is a set of requirements that SHALL be met as part of the definition of the extension.")
038        private List<ExtensionDt> myUndeclaredExtensions;
039
040        /**
041         * May be used to represent additional information that is not part of the basic definition of the resource, and that modifies the understanding of the element that contains it. Usually modifier elements provide negation or qualification. In order to make the use of extensions safe and manageable, there is a strict set of governance applied to the definition and use of extensions. Though any implementer is allowed to define an extension, there is a set of requirements that SHALL be met as part of the definition of the extension. Applications processing a resource are required to check for modifier extensions.
042         */
043        @Child(name = "modifierExtension", type = {ExtensionDt.class}, order = 1, min = 0, max = Child.MAX_UNLIMITED, modifier = true, summary = false)
044        @Description(shortDefinition = "Extensions that cannot be ignored", formalDefinition = "May be used to represent additional information that is not part of the basic definition of the resource, and that modifies the understanding of the element that contains it. Usually modifier elements provide negation or qualification. In order to make the use of extensions safe and manageable, there is a strict set of governance applied to the definition and use of extensions. Though any implementer is allowed to define an extension, there is a set of requirements that SHALL be met as part of the definition of the extension. Applications processing a resource are required to check for modifier extensions.")
045        private List<ExtensionDt> myUndeclaredModifierExtensions;
046
047        @Override
048        public ExtensionDt addUndeclaredExtension(boolean theIsModifier, String theUrl) {
049                Validate.notEmpty(theUrl, "URL must be populated");
050
051                ExtensionDt retVal = new ExtensionDt(theIsModifier, theUrl);
052                if (theIsModifier) {
053                        getUndeclaredModifierExtensions();
054                        myUndeclaredModifierExtensions.add(retVal);
055                } else {
056                        getUndeclaredExtensions();
057                        myUndeclaredExtensions.add(retVal);
058                }
059                return retVal;
060        }
061
062        @Override
063        public ExtensionDt addUndeclaredExtension(boolean theIsModifier, String theUrl, IBaseDatatype theValue) {
064                Validate.notEmpty(theUrl, "URL must be populated");
065                Validate.notNull(theValue, "Value must not be null");
066                ExtensionDt retVal = new ExtensionDt(theIsModifier, theUrl, theValue);
067                if (theIsModifier) {
068                        getUndeclaredModifierExtensions();
069                        myUndeclaredModifierExtensions.add(retVal);
070                } else {
071                        getUndeclaredExtensions();
072                        myUndeclaredExtensions.add(retVal);
073                }
074                return retVal;
075        }
076
077        @Override
078        public void addUndeclaredExtension(ExtensionDt theExtension) {
079                Validate.notNull(theExtension, "Extension can not be null");
080                if (theExtension.isModifier()) {
081                        getUndeclaredModifierExtensions();
082                        myUndeclaredModifierExtensions.add(theExtension);
083                } else {
084                        getUndeclaredExtensions();
085                        myUndeclaredExtensions.add(theExtension);
086                }
087        }
088
089        @Override
090        public List<ExtensionDt> getAllUndeclaredExtensions() {
091                ArrayList<ExtensionDt> retVal = new ArrayList<ExtensionDt>();
092                if (myUndeclaredExtensions != null) {
093                        retVal.addAll(myUndeclaredExtensions);
094                }
095                if (myUndeclaredModifierExtensions != null) {
096                        retVal.addAll(myUndeclaredModifierExtensions);
097                }
098                return Collections.unmodifiableList(retVal);
099        }
100
101        @Override
102        public List<String> getFormatCommentsPost() {
103                if (myFormatCommentsPost == null)
104                        myFormatCommentsPost = new ArrayList<String>();
105                return myFormatCommentsPost;
106        }
107
108        @Override
109        public List<String> getFormatCommentsPre() {
110                if (myFormatCommentsPre == null)
111                        myFormatCommentsPre = new ArrayList<String>();
112                return myFormatCommentsPre;
113        }
114
115        @Override
116        public List<ExtensionDt> getUndeclaredExtensions() {
117                if (myUndeclaredExtensions == null) {
118                        myUndeclaredExtensions = new ArrayList<ExtensionDt>();
119                }
120                return (myUndeclaredExtensions);
121        }
122
123        @Override
124        public List<ExtensionDt> getUndeclaredExtensionsByUrl(String theUrl) {
125                org.apache.commons.lang3.Validate.notNull(theUrl, "URL can not be null");
126                ArrayList<ExtensionDt> retVal = new ArrayList<ExtensionDt>();
127                for (ExtensionDt next : getAllUndeclaredExtensions()) {
128                        if (theUrl.equals(next.getUrlAsString())) {
129                                retVal.add(next);
130                        }
131                }
132                return Collections.unmodifiableList(retVal);
133        }
134
135        @Override
136        public List<ExtensionDt> getUndeclaredModifierExtensions() {
137                if (myUndeclaredModifierExtensions == null) {
138                        myUndeclaredModifierExtensions = new ArrayList<ExtensionDt>();
139                }
140                return (myUndeclaredModifierExtensions);
141        }
142
143        @Override
144        public boolean hasFormatComment() {
145                return (myFormatCommentsPre != null && !myFormatCommentsPre.isEmpty()) || (myFormatCommentsPost != null && !myFormatCommentsPost.isEmpty());
146        }
147
148        @Override
149        public Object getUserData(String name) {
150                if (userData == null)
151                        return null;
152                return userData.get(name);
153        }
154
155        @Override
156        public void setUserData(String name, Object value) {
157                if (userData == null) {
158                        userData = new HashMap<>();
159                }
160                userData.put(name, value);
161        }
162
163        /**
164         * Intended to be called by extending classes {@link #isEmpty()} implementations, returns <code>true</code> if all
165         * content in this superclass instance is empty per the semantics of {@link #isEmpty()}.
166         */
167        protected boolean isBaseEmpty() {
168                if (myUndeclaredExtensions != null) {
169                        for (ExtensionDt next : myUndeclaredExtensions) {
170                                if (next == null) {
171                                        continue;
172                                }
173                                if (!next.isEmpty()) {
174                                        return false;
175                                }
176                        }
177                }
178                if (myUndeclaredModifierExtensions != null) {
179                        for (ExtensionDt next : myUndeclaredModifierExtensions) {
180                                if (next == null) {
181                                        continue;
182                                }
183                                if (!next.isEmpty()) {
184                                        return false;
185                                }
186                        }
187                }
188                return true;
189        }
190
191}