001package org.hl7.fhir.r5.model;
002
003
004/*
005  Copyright (c) 2011+, HL7, Inc.
006  All rights reserved.
007  
008  Redistribution and use in source and binary forms, with or without modification, \
009  are permitted provided that the following conditions are met:
010  
011   * Redistributions of source code must retain the above copyright notice, this \
012     list of conditions and the following disclaimer.
013   * Redistributions in binary form must reproduce the above copyright notice, \
014     this list of conditions and the following disclaimer in the documentation \
015     and/or other materials provided with the distribution.
016   * Neither the name of HL7 nor the names of its contributors may be used to 
017     endorse or promote products derived from this software without specific 
018     prior written permission.
019  
020  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND \
021  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED \
022  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \
023  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, \
024  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT \
025  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR \
026  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, \
027  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) \
028  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE \
029  POSSIBILITY OF SUCH DAMAGE.
030  */
031
032// Generated on Thu, Mar 23, 2023 19:59+1100 for FHIR v5.0.0
033
034import java.util.ArrayList;
035import java.util.Date;
036import java.util.List;
037import org.hl7.fhir.utilities.Utilities;
038import org.hl7.fhir.r5.model.Enumerations.*;
039import org.hl7.fhir.instance.model.api.IBaseDatatypeElement;
040import org.hl7.fhir.exceptions.FHIRException;
041import org.hl7.fhir.instance.model.api.ICompositeType;
042import ca.uhn.fhir.model.api.annotation.Child;
043import ca.uhn.fhir.model.api.annotation.ChildOrder;
044import ca.uhn.fhir.model.api.annotation.DatatypeDef;
045import ca.uhn.fhir.model.api.annotation.Description;
046import ca.uhn.fhir.model.api.annotation.Block;
047
048/**
049 * CodeableConcept Type: A concept that may be defined by a formal reference to a terminology or ontology or may be provided by text.
050 */
051@DatatypeDef(name="CodeableConcept")
052public class CodeableConcept extends DataType implements ICompositeType {
053
054    /**
055     * A reference to a code defined by a terminology system.
056     */
057    @Child(name = "coding", type = {Coding.class}, order=0, min=0, max=Child.MAX_UNLIMITED, modifier=false, summary=true)
058    @Description(shortDefinition="Code defined by a terminology system", formalDefinition="A reference to a code defined by a terminology system." )
059    protected List<Coding> coding;
060
061    /**
062     * A human language representation of the concept as seen/selected/uttered by the user who entered the data and/or which represents the intended meaning of the user.
063     */
064    @Child(name = "text", type = {StringType.class}, order=1, min=0, max=1, modifier=false, summary=true)
065    @Description(shortDefinition="Plain text representation of the concept", formalDefinition="A human language representation of the concept as seen/selected/uttered by the user who entered the data and/or which represents the intended meaning of the user." )
066    protected StringType text;
067
068    private static final long serialVersionUID = 760353246L;
069
070  /**
071   * Constructor
072   */
073    public CodeableConcept() {
074      super();
075    }
076
077    /**
078     * @return {@link #coding} (A reference to a code defined by a terminology system.)
079     */
080    public List<Coding> getCoding() { 
081      if (this.coding == null)
082        this.coding = new ArrayList<Coding>();
083      return this.coding;
084    }
085
086    /**
087     * @return Returns a reference to <code>this</code> for easy method chaining
088     */
089    public CodeableConcept setCoding(List<Coding> theCoding) { 
090      this.coding = theCoding;
091      return this;
092    }
093
094    public boolean hasCoding() { 
095      if (this.coding == null)
096        return false;
097      for (Coding item : this.coding)
098        if (!item.isEmpty())
099          return true;
100      return false;
101    }
102
103    public Coding addCoding() { //3
104      Coding t = new Coding();
105      if (this.coding == null)
106        this.coding = new ArrayList<Coding>();
107      this.coding.add(t);
108      return t;
109    }
110
111    public CodeableConcept addCoding(Coding t) { //3
112      if (t == null)
113        return this;
114      if (this.coding == null)
115        this.coding = new ArrayList<Coding>();
116      this.coding.add(t);
117      return this;
118    }
119
120    /**
121     * @return The first repetition of repeating field {@link #coding}, creating it if it does not already exist {3}
122     */
123    public Coding getCodingFirstRep() { 
124      if (getCoding().isEmpty()) {
125        addCoding();
126      }
127      return getCoding().get(0);
128    }
129
130    /**
131     * @return {@link #text} (A human language representation of the concept as seen/selected/uttered by the user who entered the data and/or which represents the intended meaning of the user.). This is the underlying object with id, value and extensions. The accessor "getText" gives direct access to the value
132     */
133    public StringType getTextElement() { 
134      if (this.text == null)
135        if (Configuration.errorOnAutoCreate())
136          throw new Error("Attempt to auto-create CodeableConcept.text");
137        else if (Configuration.doAutoCreate())
138          this.text = new StringType(); // bb
139      return this.text;
140    }
141
142    public boolean hasTextElement() { 
143      return this.text != null && !this.text.isEmpty();
144    }
145
146    public boolean hasText() { 
147      return this.text != null && !this.text.isEmpty();
148    }
149
150    /**
151     * @param value {@link #text} (A human language representation of the concept as seen/selected/uttered by the user who entered the data and/or which represents the intended meaning of the user.). This is the underlying object with id, value and extensions. The accessor "getText" gives direct access to the value
152     */
153    public CodeableConcept setTextElement(StringType value) { 
154      this.text = value;
155      return this;
156    }
157
158    /**
159     * @return A human language representation of the concept as seen/selected/uttered by the user who entered the data and/or which represents the intended meaning of the user.
160     */
161    public String getText() { 
162      return this.text == null ? null : this.text.getValue();
163    }
164
165    /**
166     * @param value A human language representation of the concept as seen/selected/uttered by the user who entered the data and/or which represents the intended meaning of the user.
167     */
168    public CodeableConcept setText(String value) { 
169      if (Utilities.noString(value))
170        this.text = null;
171      else {
172        if (this.text == null)
173          this.text = new StringType();
174        this.text.setValue(value);
175      }
176      return this;
177    }
178
179      protected void listChildren(List<Property> children) {
180        super.listChildren(children);
181        children.add(new Property("coding", "Coding", "A reference to a code defined by a terminology system.", 0, java.lang.Integer.MAX_VALUE, coding));
182        children.add(new Property("text", "string", "A human language representation of the concept as seen/selected/uttered by the user who entered the data and/or which represents the intended meaning of the user.", 0, 1, text));
183      }
184
185      @Override
186      public Property getNamedProperty(int _hash, String _name, boolean _checkValid) throws FHIRException {
187        switch (_hash) {
188        case -1355086998: /*coding*/  return new Property("coding", "Coding", "A reference to a code defined by a terminology system.", 0, java.lang.Integer.MAX_VALUE, coding);
189        case 3556653: /*text*/  return new Property("text", "string", "A human language representation of the concept as seen/selected/uttered by the user who entered the data and/or which represents the intended meaning of the user.", 0, 1, text);
190        default: return super.getNamedProperty(_hash, _name, _checkValid);
191        }
192
193      }
194
195      @Override
196      public Base[] getProperty(int hash, String name, boolean checkValid) throws FHIRException {
197        switch (hash) {
198        case -1355086998: /*coding*/ return this.coding == null ? new Base[0] : this.coding.toArray(new Base[this.coding.size()]); // Coding
199        case 3556653: /*text*/ return this.text == null ? new Base[0] : new Base[] {this.text}; // StringType
200        default: return super.getProperty(hash, name, checkValid);
201        }
202
203      }
204
205      @Override
206      public Base setProperty(int hash, String name, Base value) throws FHIRException {
207        switch (hash) {
208        case -1355086998: // coding
209          this.getCoding().add(TypeConvertor.castToCoding(value)); // Coding
210          return value;
211        case 3556653: // text
212          this.text = TypeConvertor.castToString(value); // StringType
213          return value;
214        default: return super.setProperty(hash, name, value);
215        }
216
217      }
218
219      @Override
220      public Base setProperty(String name, Base value) throws FHIRException {
221        if (name.equals("coding")) {
222          this.getCoding().add(TypeConvertor.castToCoding(value));
223        } else if (name.equals("text")) {
224          this.text = TypeConvertor.castToString(value); // StringType
225        } else
226          return super.setProperty(name, value);
227        return value;
228      }
229
230      @Override
231      public Base makeProperty(int hash, String name) throws FHIRException {
232        switch (hash) {
233        case -1355086998:  return addCoding(); 
234        case 3556653:  return getTextElement();
235        default: return super.makeProperty(hash, name);
236        }
237
238      }
239
240      @Override
241      public String[] getTypesForProperty(int hash, String name) throws FHIRException {
242        switch (hash) {
243        case -1355086998: /*coding*/ return new String[] {"Coding"};
244        case 3556653: /*text*/ return new String[] {"string"};
245        default: return super.getTypesForProperty(hash, name);
246        }
247
248      }
249
250      @Override
251      public Base addChild(String name) throws FHIRException {
252        if (name.equals("coding")) {
253          return addCoding();
254        }
255        else if (name.equals("text")) {
256          throw new FHIRException("Cannot call addChild on a singleton property CodeableConcept.text");
257        }
258        else
259          return super.addChild(name);
260      }
261
262  public String fhirType() {
263    return "CodeableConcept";
264
265  }
266
267      public CodeableConcept copy() {
268        CodeableConcept dst = new CodeableConcept();
269        copyValues(dst);
270        return dst;
271      }
272
273      public void copyValues(CodeableConcept dst) {
274        super.copyValues(dst);
275        if (coding != null) {
276          dst.coding = new ArrayList<Coding>();
277          for (Coding i : coding)
278            dst.coding.add(i.copy());
279        };
280        dst.text = text == null ? null : text.copy();
281      }
282
283      protected CodeableConcept typedCopy() {
284        return copy();
285      }
286
287      @Override
288      public boolean equalsDeep(Base other_) {
289        if (!super.equalsDeep(other_))
290          return false;
291        if (!(other_ instanceof CodeableConcept))
292          return false;
293        CodeableConcept o = (CodeableConcept) other_;
294        return compareDeep(coding, o.coding, true) && compareDeep(text, o.text, true);
295      }
296
297      @Override
298      public boolean equalsShallow(Base other_) {
299        if (!super.equalsShallow(other_))
300          return false;
301        if (!(other_ instanceof CodeableConcept))
302          return false;
303        CodeableConcept o = (CodeableConcept) other_;
304        return compareValues(text, o.text, true);
305      }
306
307      public boolean isEmpty() {
308        return super.isEmpty() && ca.uhn.fhir.util.ElementUtil.isEmpty(coding, text);
309      }
310
311// Manual code (from Configuration.txt):
312public boolean hasCoding(String system, String code) {
313    for (Coding c : getCoding()) {
314      if (system.equals(c.getSystem()) && code.equals(c.getCode()))
315        return true;
316    }
317    return false;
318  } 
319
320  public CodeableConcept(Coding code) {
321    super();
322    addCoding(code);
323  }
324  
325  
326  public boolean matches(CodeableConcept other) {
327    for (Coding c : other.getCoding()) {
328      if (hasCoding(c.getSystem(), c.getCode())) {
329        return true;
330      }
331    }
332    return false;
333  }
334
335  public boolean hasCoding(Coding coding) {
336    return hasCoding(coding.getSystem(), coding.getCode());
337  }
338  
339 public boolean hasCoding(String system) {
340    for (Coding c : getCoding()) {
341      if (system.equals(c.getSystem())) {
342        return true;
343      }
344    }
345    return false;
346  }
347
348  public String getCode(String system) {
349    for (Coding c : getCoding()) {
350      if (system.equals(c.getSystem())) {
351        return c.getCode();
352      }
353    }
354    return null;
355  }
356
357  public static CodeableConcept merge(CodeableConcept l, CodeableConcept r) {
358    CodeableConcept res = new CodeableConcept();
359    List<Coding> handled = new ArrayList<>();
360    for (Coding c : l.getCoding()) {
361      boolean done = false;
362      for (Coding t : r.getCoding()) {
363        if (t.matches(c)) {
364          handled.add(t);
365          res.getCoding().add(Coding.merge(c, t));
366          done = true;
367          break;
368        }
369      }
370      if (!done) {
371       res.getCoding().add(c.copy());
372      }
373    }
374    for (Coding c : r.getCoding()) {
375      if (!handled.contains(c)) {
376        res.getCoding().add(c);
377      }
378    }
379    if (l.hasText()) {
380      res.setText(l.getText());
381    } else {
382      res.setText(r.getText());
383    }
384    return res;
385  }
386
387  public static CodeableConcept intersect(CodeableConcept l, CodeableConcept r) {
388    CodeableConcept res = new CodeableConcept();
389    for (Coding c : l.getCoding()) {
390      for (Coding t : r.getCoding()) {
391        if (t.matches(c)) {
392          res.getCoding().add(Coding.intersect(c, t));
393          break;
394        }
395      }
396    }
397    if (l.hasText() && r.hasText() && l.getText().equals(r.getText())) {
398      res.setText(l.getText());
399    }
400    return res;
401  }  
402  
403    
404  public void addCoding(String system, String code, String display) {
405    getCoding().add(new Coding(system, code, display));
406  }
407  
408  @Override 
409  public String toString() { 
410    return hasCoding() ? getCoding().toString() : "["+getText()+"]"; 
411  }
412
413  public void removeCoding(String system, String version, String code) {
414    getCoding().removeIf(c -> 
415    (system == null || system.equals(c.getSystem())) &&
416    (version == null || version.equals(c.getVersion())) &&
417    (code == null || code.equals(c.getCode())));
418  } 
419   
420// end addition
421
422}
423