001package org.hl7.fhir.r4.model;
002
003/*-
004 * #%L
005 * org.hl7.fhir.r4
006 * %%
007 * Copyright (C) 2014 - 2019 Health Level 7
008 * %%
009 * Licensed under the Apache License, Version 2.0 (the "License");
010 * you may not use this file except in compliance with the License.
011 * You may obtain a copy of the License at
012 * 
013 *      http://www.apache.org/licenses/LICENSE-2.0
014 * 
015 * Unless required by applicable law or agreed to in writing, software
016 * distributed under the License is distributed on an "AS IS" BASIS,
017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
018 * See the License for the specific language governing permissions and
019 * limitations under the License.
020 * #L%
021 */
022
023
024import org.hl7.fhir.exceptions.FHIRException;
025
026/**
027 * in a language with helper classes, this would be a helper class (at least, the base exgtension helpers would be)
028 * @author Grahame
029 *
030 */
031public class ExtensionHelper {
032
033  
034  /**
035   * @param name the identity of the extension of interest
036   * @return true if the named extension is on this element. Will check modifier extensions too if appropriate
037   */
038  public static boolean hasExtension(Element element, String name) {
039        if (element != null && element instanceof BackboneElement) 
040                return hasExtension((BackboneElement) element, name);
041        
042    if (name == null || element == null || !element.hasExtension())
043      return false;
044    for (Extension e : element.getExtension()) {
045      if (name.equals(e.getUrl()))
046        return true;
047    }
048    return false;
049  }
050  
051  /**
052   * @param name the identity of the extension of interest
053   * @return true if the named extension is on this element. Will check modifier extensions
054   */
055  public static boolean hasExtension(BackboneElement element, String name) {
056    if (name == null || element == null || !(element.hasExtension() || element.hasModifierExtension()))
057      return false;
058    for (Extension e : element.getModifierExtension()) {
059      if (name.equals(e.getUrl()))
060        return true;
061    }
062    for (Extension e : element.getExtension()) {
063      if (name.equals(e.getUrl()))
064        return true;
065    }
066    return false;
067  }
068  
069  
070  /**
071   * @param name the identity of the extension of interest
072   * @return The extension, if on this element, else null. will check modifier extensions too, if appropriate
073   */
074  public static Extension getExtension(Element element, String name) {
075        if (element != null && element instanceof BackboneElement) 
076                return getExtension((BackboneElement) element, name);
077        
078    if (name == null || element == null || !element.hasExtension())
079      return null;
080    for (Extension e : element.getExtension()) {
081      if (name.equals(e.getUrl()))
082        return e;
083    }
084    return null;
085  }
086  
087  /**
088   * @param name the identity of the extension of interest
089   * @return The extension, if on this element, else null. will check modifier extensions too, if appropriate
090   */
091  public static Extension getExtension(DomainResource resource, String name) {
092    
093    if (name == null || resource == null || !resource.hasExtension())
094      return null;
095    for (Extension e : resource.getExtension()) {
096      if (name.equals(e.getUrl()))
097        return e;
098    }
099    return null;
100  }
101  
102  /**
103   * @param name the identity of the extension of interest
104   * @return The extension, if on this element, else null. will check modifier extensions too
105   */
106  public static Extension getExtension(BackboneElement element, String name) {
107    if (name == null || element == null || !element.hasExtension())
108      return null;
109    for (Extension e : element.getModifierExtension()) {
110      if (name.equals(e.getUrl()))
111        return e;
112    }
113    for (Extension e : element.getExtension()) {
114      if (name.equals(e.getUrl()))
115        return e;
116    }
117    return null;
118  }
119
120  /**
121   * set the value of an extension on the element. if value == null, make sure it doesn't exist
122   * 
123   * @param element - the element to act on. Can also be a backbone element 
124   * @param modifier - whether this is a modifier. Note that this is a definitional property of the extension; don't alternate
125   * @param uri - the identifier for the extension
126   * @param value - the value of the extension. Delete if this is null
127   * @throws Exception - if the modifier logic is incorrect
128   */
129  public static void setExtension(Element element, boolean modifier, String uri, Type value) throws FHIRException {
130        if (value == null) {
131        // deleting the extension
132                if (element instanceof BackboneElement)
133                        for (Extension e : ((BackboneElement) element).getModifierExtension()) {
134                                if (uri.equals(e.getUrl()))
135                                        ((BackboneElement) element).getModifierExtension().remove(e);
136                        }
137                for (Extension e : element.getExtension()) {
138                        if (uri.equals(e.getUrl()))
139                                element.getExtension().remove(e);
140                }
141        } else {
142                // it would probably be easier to delete and then create, but this would re-order the extensions
143                // not that order matters, but we'll preserve it anyway
144                boolean found = false;
145                if (element instanceof BackboneElement)
146                        for (Extension e : ((BackboneElement) element).getModifierExtension()) {
147                                if (uri.equals(e.getUrl())) {
148                                        if (!modifier)
149                                                throw new FHIRException("Error adding extension \""+uri+"\": found an existing modifier extension, and the extension is not marked as a modifier");
150                                        e.setValue(value);
151                                        found = true;
152                                }
153                        }
154                for (Extension e : element.getExtension()) {
155                        if (uri.equals(e.getUrl())) {
156                                        if (modifier)
157                                                throw new FHIRException("Error adding extension \""+uri+"\": found an existing extension, and the extension is marked as a modifier");
158                                        e.setValue(value);
159                                        found = true;
160                        }
161                }
162                if (!found) {
163                        Extension ex = new Extension().setUrl(uri).setValue(value);
164                        if (modifier) {
165                        if (!(element instanceof BackboneElement))
166                                                throw new FHIRException("Error adding extension \""+uri+"\": extension is marked as a modifier, but element is not a backbone element");
167                                ((BackboneElement) element).getModifierExtension().add(ex);
168                                
169                        } else {
170                                element.getExtension().add(ex);
171                        }
172                }
173        }
174  }
175
176  public static boolean hasExtensions(Element element) {
177        if (element instanceof BackboneElement)
178                return element.hasExtension() || ((BackboneElement) element).hasModifierExtension();
179        else
180                return element.hasExtension();
181  }
182
183
184}