001package org.hl7.fhir.r5.model;
002
003/*
004  Copyright (c) 2011+, HL7, Inc.
005  All rights reserved.
006  
007  Redistribution and use in source and binary forms, with or without modification, 
008  are permitted provided that the following conditions are met:
009    
010   * Redistributions of source code must retain the above copyright notice, this 
011     list of conditions and the following disclaimer.
012   * Redistributions in binary form must reproduce the above copyright notice, 
013     this list of conditions and the following disclaimer in the documentation 
014     and/or other materials provided with the distribution.
015   * Neither the name of HL7 nor the names of its contributors may be used to 
016     endorse or promote products derived from this software without specific 
017     prior written permission.
018  
019  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
020  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
021  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
022  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
023  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
024  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
025  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
026  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
027  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
028  POSSIBILITY OF SUCH DAMAGE.
029  
030 */
031
032
033
034import java.util.ArrayList;
035import java.util.List;
036
037import org.hl7.fhir.r5.context.IWorkerContext;
038import org.hl7.fhir.utilities.MergedList.IMatcher;
039
040/**
041 * A child element or property defined by the FHIR specification
042 * This class is defined as a helper class when iterating the 
043 * children of an element in a generic fashion
044 * 
045 * At present, iteration is only based on the specification, but 
046 * this may be changed to allow profile based expression at a
047 * later date
048 * 
049 * note: there's no point in creating one of these classes outside this package
050 */
051public class Property {
052
053        public static class PropertyMatcher implements IMatcher<Property> {
054
055    @Override
056    public boolean match(Property l, Property r) {
057      return l.getName().equals(r.getName());
058    }
059
060  }
061
062
063  /**
064         * The name of the property as found in the FHIR specification
065         */
066        private String name;
067        
068        /**
069         * The type of the property as specified in the FHIR specification (e.g. type|type|Reference(Name|Name)
070         */
071        private String typeCode;
072        
073        /**
074         * The formal definition of the element given in the FHIR specification
075         */
076        private String definition;
077        
078        /**
079         * The minimum allowed cardinality - 0 or 1 when based on the specification
080         */
081        private int minCardinality;
082        
083        /** 
084         * The maximum allowed cardinality - 1 or MAX_INT when based on the specification
085         */
086        private int maxCardinality;
087        
088        /**
089         * The actual elements that exist on this instance
090         */
091        private List<Base> values = new ArrayList<Base>();
092
093        /**
094         * For run time, if/once a property is hooked up to it's definition
095         */
096        private StructureDefinition structure; 
097
098        /**
099         * Internal constructor
100         */
101        public Property(String name, String typeCode, String definition, int minCardinality, int maxCardinality, Base value) {
102          super();
103          this.name = name;
104          this.typeCode = typeCode;
105          this.definition = definition;
106          this.minCardinality = minCardinality;
107          this.maxCardinality = maxCardinality;
108          if (value != null)
109            this.values.add(value);
110  }
111
112        /**
113         * Internal constructor
114         */
115        public Property(String name, String typeCode, String definition, int minCardinality, int maxCardinality, List<? extends Base> values) {
116          super();
117          this.name = name;
118          this.typeCode = typeCode;
119          this.definition = definition;
120          this.minCardinality = minCardinality;
121          this.maxCardinality = maxCardinality;
122          if (values != null)
123            this.values.addAll(values);
124  }
125
126        /**
127         * @return The name of this property in the FHIR Specification
128         */
129        public String getName() {
130                return name;
131        }
132
133        /**
134         * @return The stated type in the FHIR specification
135         */
136        public String getTypeCode() {
137                return typeCode;
138        }
139
140        /** 
141         * @return The definition of this element in the FHIR spec
142         */
143        public String getDefinition() {
144                return definition;
145        }
146
147        /**
148         * @return the minimum cardinality for this element 
149         */
150        public int getMinCardinality() {
151                return minCardinality;
152        }
153
154        /**
155         * @return the maximum cardinality for this element 
156         */
157        public int getMaxCardinality() {
158                return maxCardinality;
159        }
160
161        /**
162         * @return the actual values - will only be 1 unless maximum cardinality == MAX_INT
163         */
164        public List<Base> getValues() {
165                return values;
166        }
167
168  public boolean hasValues() {
169    for (Base e : getValues())
170      if (e != null)
171        return true;
172    return false;
173  }
174
175  public StructureDefinition getStructure() {
176    return structure;
177  }
178
179  public void setStructure(StructureDefinition structure) {
180    this.structure = structure;
181  }
182
183  public boolean isList() {
184    return maxCardinality > 1;
185  }
186
187
188  public String toString() {
189    return name; 
190  }
191
192}