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}