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.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.ArrayList; 028import java.util.Collections; 029import java.util.HashMap; 030import java.util.List; 031import java.util.Map; 032 033public abstract class BaseElement implements /*IElement, */ ISupportsUndeclaredExtensions { 034 035 private static final long serialVersionUID = -3092659584634499332L; 036 private List<String> myFormatCommentsPost; 037 private List<String> myFormatCommentsPre; 038 private Map<String, Object> userData; 039 040 @Child( 041 name = "extension", 042 type = {ExtensionDt.class}, 043 order = 0, 044 min = 0, 045 max = Child.MAX_UNLIMITED, 046 modifier = false, 047 summary = false) 048 @Description( 049 shortDefinition = "Additional Content defined by implementations", 050 formalDefinition = 051 "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.") 052 private List<ExtensionDt> myUndeclaredExtensions; 053 054 /** 055 * 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. 056 */ 057 @Child( 058 name = "modifierExtension", 059 type = {ExtensionDt.class}, 060 order = 1, 061 min = 0, 062 max = Child.MAX_UNLIMITED, 063 modifier = true, 064 summary = false) 065 @Description( 066 shortDefinition = "Extensions that cannot be ignored", 067 formalDefinition = 068 "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.") 069 private List<ExtensionDt> myUndeclaredModifierExtensions; 070 071 @Override 072 public ExtensionDt addUndeclaredExtension(boolean theIsModifier, String theUrl) { 073 Validate.notEmpty(theUrl, "URL must be populated"); 074 075 ExtensionDt retVal = new ExtensionDt(theIsModifier, theUrl); 076 if (theIsModifier) { 077 getUndeclaredModifierExtensions(); 078 myUndeclaredModifierExtensions.add(retVal); 079 } else { 080 getUndeclaredExtensions(); 081 myUndeclaredExtensions.add(retVal); 082 } 083 return retVal; 084 } 085 086 @Override 087 public ExtensionDt addUndeclaredExtension(boolean theIsModifier, String theUrl, IBaseDatatype theValue) { 088 Validate.notEmpty(theUrl, "URL must be populated"); 089 Validate.notNull(theValue, "Value must not be null"); 090 ExtensionDt retVal = new ExtensionDt(theIsModifier, theUrl, theValue); 091 if (theIsModifier) { 092 getUndeclaredModifierExtensions(); 093 myUndeclaredModifierExtensions.add(retVal); 094 } else { 095 getUndeclaredExtensions(); 096 myUndeclaredExtensions.add(retVal); 097 } 098 return retVal; 099 } 100 101 @Override 102 public void addUndeclaredExtension(ExtensionDt theExtension) { 103 Validate.notNull(theExtension, "Extension can not be null"); 104 if (theExtension.isModifier()) { 105 getUndeclaredModifierExtensions(); 106 myUndeclaredModifierExtensions.add(theExtension); 107 } else { 108 getUndeclaredExtensions(); 109 myUndeclaredExtensions.add(theExtension); 110 } 111 } 112 113 @Override 114 public List<ExtensionDt> getAllUndeclaredExtensions() { 115 ArrayList<ExtensionDt> retVal = new ArrayList<ExtensionDt>(); 116 if (myUndeclaredExtensions != null) { 117 retVal.addAll(myUndeclaredExtensions); 118 } 119 if (myUndeclaredModifierExtensions != null) { 120 retVal.addAll(myUndeclaredModifierExtensions); 121 } 122 return Collections.unmodifiableList(retVal); 123 } 124 125 @Override 126 public List<String> getFormatCommentsPost() { 127 if (myFormatCommentsPost == null) myFormatCommentsPost = new ArrayList<String>(); 128 return myFormatCommentsPost; 129 } 130 131 @Override 132 public List<String> getFormatCommentsPre() { 133 if (myFormatCommentsPre == null) myFormatCommentsPre = new ArrayList<String>(); 134 return myFormatCommentsPre; 135 } 136 137 @Override 138 public List<ExtensionDt> getUndeclaredExtensions() { 139 if (myUndeclaredExtensions == null) { 140 myUndeclaredExtensions = new ArrayList<ExtensionDt>(); 141 } 142 return (myUndeclaredExtensions); 143 } 144 145 @Override 146 public List<ExtensionDt> getUndeclaredExtensionsByUrl(String theUrl) { 147 org.apache.commons.lang3.Validate.notNull(theUrl, "URL can not be null"); 148 ArrayList<ExtensionDt> retVal = new ArrayList<ExtensionDt>(); 149 for (ExtensionDt next : getAllUndeclaredExtensions()) { 150 if (theUrl.equals(next.getUrlAsString())) { 151 retVal.add(next); 152 } 153 } 154 return Collections.unmodifiableList(retVal); 155 } 156 157 @Override 158 public List<ExtensionDt> getUndeclaredModifierExtensions() { 159 if (myUndeclaredModifierExtensions == null) { 160 myUndeclaredModifierExtensions = new ArrayList<ExtensionDt>(); 161 } 162 return (myUndeclaredModifierExtensions); 163 } 164 165 @Override 166 public boolean hasFormatComment() { 167 return (myFormatCommentsPre != null && !myFormatCommentsPre.isEmpty()) 168 || (myFormatCommentsPost != null && !myFormatCommentsPost.isEmpty()); 169 } 170 171 @Override 172 public Object getUserData(String name) { 173 if (userData == null) return null; 174 return userData.get(name); 175 } 176 177 @Override 178 public void setUserData(String name, Object value) { 179 if (userData == null) { 180 userData = new HashMap<>(); 181 } 182 userData.put(name, value); 183 } 184 185 /** 186 * Intended to be called by extending classes {@link #isEmpty()} implementations, returns <code>true</code> if all 187 * content in this superclass instance is empty per the semantics of {@link #isEmpty()}. 188 */ 189 protected boolean isBaseEmpty() { 190 if (myUndeclaredExtensions != null) { 191 for (ExtensionDt next : myUndeclaredExtensions) { 192 if (next == null) { 193 continue; 194 } 195 if (!next.isEmpty()) { 196 return false; 197 } 198 } 199 } 200 if (myUndeclaredModifierExtensions != null) { 201 for (ExtensionDt next : myUndeclaredModifierExtensions) { 202 if (next == null) { 203 continue; 204 } 205 if (!next.isEmpty()) { 206 return false; 207 } 208 } 209 } 210 return true; 211 } 212}