001package org.hl7.fhir.r4.model;
002
003import org.hl7.fhir.exceptions.FHIRException;
004
005/**
006 * in a language with helper classes, this would be a helper class (at least, the base exgtension helpers would be)
007 * @author Grahame
008 *
009 */
010public class ExtensionHelper {
011
012  
013  /**
014   * @param name the identity of the extension of interest
015   * @return true if the named extension is on this element. Will check modifier extensions too if appropriate
016   */
017  public static boolean hasExtension(Element element, String name) {
018        if (element != null && element instanceof BackboneElement) 
019                return hasExtension((BackboneElement) element, name);
020        
021    if (name == null || element == null || !element.hasExtension())
022      return false;
023    for (Extension e : element.getExtension()) {
024      if (name.equals(e.getUrl()))
025        return true;
026    }
027    return false;
028  }
029  
030  /**
031   * @param name the identity of the extension of interest
032   * @return true if the named extension is on this element. Will check modifier extensions
033   */
034  public static boolean hasExtension(BackboneElement element, String name) {
035    if (name == null || element == null || !(element.hasExtension() || element.hasModifierExtension()))
036      return false;
037    for (Extension e : element.getModifierExtension()) {
038      if (name.equals(e.getUrl()))
039        return true;
040    }
041    for (Extension e : element.getExtension()) {
042      if (name.equals(e.getUrl()))
043        return true;
044    }
045    return false;
046  }
047  
048  
049  /**
050   * @param name the identity of the extension of interest
051   * @return The extension, if on this element, else null. will check modifier extensions too, if appropriate
052   */
053  public static Extension getExtension(Element element, String name) {
054        if (element != null && element instanceof BackboneElement) 
055                return getExtension((BackboneElement) element, name);
056        
057    if (name == null || element == null || !element.hasExtension())
058      return null;
059    for (Extension e : element.getExtension()) {
060      if (name.equals(e.getUrl()))
061        return e;
062    }
063    return null;
064  }
065  
066  /**
067   * @param name the identity of the extension of interest
068   * @return The extension, if on this element, else null. will check modifier extensions too, if appropriate
069   */
070  public static Extension getExtension(DomainResource resource, String name) {
071    
072    if (name == null || resource == null || !resource.hasExtension())
073      return null;
074    for (Extension e : resource.getExtension()) {
075      if (name.equals(e.getUrl()))
076        return e;
077    }
078    return null;
079  }
080  
081  /**
082   * @param name the identity of the extension of interest
083   * @return The extension, if on this element, else null. will check modifier extensions too
084   */
085  public static Extension getExtension(BackboneElement element, String name) {
086    if (name == null || element == null || !element.hasExtension())
087      return null;
088    for (Extension e : element.getModifierExtension()) {
089      if (name.equals(e.getUrl()))
090        return e;
091    }
092    for (Extension e : element.getExtension()) {
093      if (name.equals(e.getUrl()))
094        return e;
095    }
096    return null;
097  }
098
099  /**
100   * set the value of an extension on the element. if value == null, make sure it doesn't exist
101   * 
102   * @param element - the element to act on. Can also be a backbone element 
103   * @param modifier - whether this is a modifier. Note that this is a definitional property of the extension; don't alternate
104   * @param uri - the identifier for the extension
105   * @param value - the value of the extension. Delete if this is null
106   * @throws Exception - if the modifier logic is incorrect
107   */
108  public static void setExtension(Element element, boolean modifier, String uri, Type value) throws FHIRException {
109        if (value == null) {
110        // deleting the extension
111                if (element instanceof BackboneElement)
112                        for (Extension e : ((BackboneElement) element).getModifierExtension()) {
113                                if (uri.equals(e.getUrl()))
114                                        ((BackboneElement) element).getModifierExtension().remove(e);
115                        }
116                for (Extension e : element.getExtension()) {
117                        if (uri.equals(e.getUrl()))
118                                element.getExtension().remove(e);
119                }
120        } else {
121                // it would probably be easier to delete and then create, but this would re-order the extensions
122                // not that order matters, but we'll preserve it anyway
123                boolean found = false;
124                if (element instanceof BackboneElement)
125                        for (Extension e : ((BackboneElement) element).getModifierExtension()) {
126                                if (uri.equals(e.getUrl())) {
127                                        if (!modifier)
128                                                throw new FHIRException("Error adding extension \""+uri+"\": found an existing modifier extension, and the extension is not marked as a modifier");
129                                        e.setValue(value);
130                                        found = true;
131                                }
132                        }
133                for (Extension e : element.getExtension()) {
134                        if (uri.equals(e.getUrl())) {
135                                        if (modifier)
136                                                throw new FHIRException("Error adding extension \""+uri+"\": found an existing extension, and the extension is marked as a modifier");
137                                        e.setValue(value);
138                                        found = true;
139                        }
140                }
141                if (!found) {
142                        Extension ex = new Extension().setUrl(uri).setValue(value);
143                        if (modifier) {
144                        if (!(element instanceof BackboneElement))
145                                                throw new FHIRException("Error adding extension \""+uri+"\": extension is marked as a modifier, but element is not a backbone element");
146                                ((BackboneElement) element).getModifierExtension().add(ex);
147                                
148                        } else {
149                                element.getExtension().add(ex);
150                        }
151                }
152        }
153  }
154
155  public static boolean hasExtensions(Element element) {
156        if (element instanceof BackboneElement)
157                return element.hasExtension() || ((BackboneElement) element).hasModifierExtension();
158        else
159                return element.hasExtension();
160  }
161
162
163}