001package org.hl7.fhir.dstu3.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
069   */
070  public static Extension getExtension(BackboneElement element, String name) {
071    if (name == null || element == null || !element.hasExtension())
072      return null;
073    for (Extension e : element.getModifierExtension()) {
074      if (name.equals(e.getUrl()))
075        return e;
076    }
077    for (Extension e : element.getExtension()) {
078      if (name.equals(e.getUrl()))
079        return e;
080    }
081    return null;
082  }
083
084  /**
085   * set the value of an extension on the element. if value == null, make sure it doesn't exist
086   * 
087   * @param element - the element to act on. Can also be a backbone element 
088   * @param modifier - whether this is a modifier. Note that this is a definitional property of the extension; don't alternate
089   * @param uri - the identifier for the extension
090   * @param value - the value of the extension. Delete if this is null
091   * @throws Exception - if the modifier logic is incorrect
092   */
093  public static void setExtension(Element element, boolean modifier, String uri, Type value) throws FHIRException {
094        if (value == null) {
095        // deleting the extension
096                if (element instanceof BackboneElement)
097                        for (Extension e : ((BackboneElement) element).getModifierExtension()) {
098                                if (uri.equals(e.getUrl()))
099                                        ((BackboneElement) element).getModifierExtension().remove(e);
100                        }
101                for (Extension e : element.getExtension()) {
102                        if (uri.equals(e.getUrl()))
103                                element.getExtension().remove(e);
104                }
105        } else {
106                // it would probably be easier to delete and then create, but this would re-order the extensions
107                // not that order matters, but we'll preserve it anyway
108                boolean found = false;
109                if (element instanceof BackboneElement)
110                        for (Extension e : ((BackboneElement) element).getModifierExtension()) {
111                                if (uri.equals(e.getUrl())) {
112                                        if (!modifier)
113                                                throw new FHIRException("Error adding extension \""+uri+"\": found an existing modifier extension, and the extension is not marked as a modifier");
114                                        e.setValue(value);
115                                        found = true;
116                                }
117                        }
118                for (Extension e : element.getExtension()) {
119                        if (uri.equals(e.getUrl())) {
120                                        if (modifier)
121                                                throw new FHIRException("Error adding extension \""+uri+"\": found an existing extension, and the extension is marked as a modifier");
122                                        e.setValue(value);
123                                        found = true;
124                        }
125                }
126                if (!found) {
127                        Extension ex = new Extension().setUrl(uri).setValue(value);
128                        if (modifier) {
129                        if (!(element instanceof BackboneElement))
130                                                throw new FHIRException("Error adding extension \""+uri+"\": extension is marked as a modifier, but element is not a backbone element");
131                                ((BackboneElement) element).getModifierExtension().add(ex);
132                                
133                        } else {
134                                element.getExtension().add(ex);
135                        }
136                }
137        }
138  }
139
140  public static boolean hasExtensions(Element element) {
141        if (element instanceof BackboneElement)
142                return element.hasExtension() || ((BackboneElement) element).hasModifierExtension();
143        else
144                return element.hasExtension();
145  }
146
147
148}