001package org.hl7.fhir.dstu2016may.metamodel; 002 003import java.util.ArrayList; 004import java.util.List; 005 006import org.hl7.fhir.dstu2016may.model.Base; 007import org.hl7.fhir.exceptions.FHIRException; 008import org.hl7.fhir.utilities.Utilities; 009import org.hl7.fhir.utilities.xhtml.XhtmlNode; 010 011/** 012 * This class represents the reference model of FHIR 013 * 014 * A resource is nothing but a set of elements, where every element has a 015 * name, maybe a stated type, maybe an id, and either a value or child elements 016 * (one or the other, or both (but not neither if it's null) 017 * 018 * @author Grahame Grieve 019 * 020 */ 021public class Element extends Base { 022 023 public enum SpecialElement { 024 CONTAINED, BUNDLE_ENTRY; 025 } 026 027 private List<String> comments;// not relevant for production, but useful in documentation 028 private String name; 029 private String type; 030 private String value; 031 private int index = -1; 032 private List<Element> children; 033 private Property property; 034 private int line; 035 private int col; 036 private SpecialElement special; 037 private XhtmlNode xhtml; // if this is populated, then value will also hold the string representation 038 039 public Element(String name) { 040 super(); 041 this.name = name; 042 } 043 044 public Element(String name, Property property) { 045 super(); 046 this.name = name; 047 this.property = property; 048 } 049 050 public Element(String name, Property property, String type, String value) { 051 super(); 052 this.name = name; 053 this.property = property; 054 this.type = type; 055 this.value = value; 056 } 057 058 public void updateProperty(Property property, SpecialElement special) { 059 this.property = property; 060 this.special = special; 061 } 062 063 public SpecialElement getSpecial() { 064 return special; 065 } 066 067 public String getName() { 068 return name; 069 } 070 071 public String getType() { 072 if (type == null) 073 return property.getType(name); 074 else 075 return type; 076 } 077 078 public String getValue() { 079 return value; 080 } 081 082 public boolean hasChildren() { 083 return !(children == null || children.isEmpty()); 084 } 085 086 public List<Element> getChildren() { 087 if (children == null) 088 children = new ArrayList<Element>(); 089 return children; 090 } 091 092 public boolean hasComments() { 093 return !(comments == null || comments.isEmpty()); 094 } 095 096 public List<String> getComments() { 097 if (comments == null) 098 comments = new ArrayList<String>(); 099 return comments; 100 } 101 102 public Property getProperty() { 103 return property; 104 } 105 106 public void setValue(String value) { 107 this.value = value; 108 } 109 110 public void setType(String type) { 111 this.type = type; 112 113 } 114 115 public boolean hasValue() { 116 return value != null; 117 } 118 119 public List<Element> getChildrenByName(String name) { 120 List<Element> res = new ArrayList<Element>(); 121 if (hasChildren()) { 122 for (Element child : children) 123 if (name.equals(child.getName())) 124 res.add(child); 125 } 126 return res; 127 } 128 129 public void numberChildren() { 130 if (children == null) 131 return; 132 133 String last = ""; 134 int index = 0; 135 for (Element child : children) { 136 if (child.getProperty().isList()) { 137 if (last.equals(child.getName())) { 138 index++; 139 } else { 140 last = child.getName(); 141 index = 0; 142 } 143 child.index = index; 144 } else { 145 child.index = -1; 146 } 147 child.numberChildren(); 148 } 149 } 150 151 public int getIndex() { 152 return index; 153 } 154 155 public boolean hasIndex() { 156 return index > -1; 157 } 158 159 public void setIndex(int index) { 160 this.index = index; 161 } 162 163 public String getChildValue(String name) { 164 if (children == null) 165 return null; 166 for (Element child : children) { 167 if (name.equals(child.getName())) 168 return child.getValue(); 169 } 170 return null; 171 } 172 173 public List<Element> getChildren(String name) { 174 List<Element> res = new ArrayList<Element>(); 175 for (Element child : children) { 176 if (name.equals(child.getName())) 177 res.add(child); 178 } 179 return res; 180 } 181 182 public boolean hasType() { 183 if (type == null) 184 return property.hasType(name); 185 else 186 return true; 187 } 188 189 @Override 190 public String fhirType() { 191 return getType(); 192 } 193 194 @Override 195 public Base[] getProperty(int hash, String name, boolean checkValid) throws FHIRException { 196 if (isPrimitive() && (hash == "value".hashCode()) && !Utilities.noString(value)) { 197 String tn = getType(); 198 throw new Error("not done yet"); 199 } 200 201 List<Base> result = new ArrayList<Base>(); 202 for (Element child : children) { 203 if (child.getName().equals(name)) 204 result.add(child); 205 if (child.getName().startsWith(name) && child.getProperty().isChoice() && child.getProperty().getName().equals(name+"[x]")) 206 result.add(child); 207 } 208 if (result.isEmpty() && checkValid) { 209// throw new FHIRException("not determined yet"); 210 } 211 return result.toArray(new Base[result.size()]); 212 } 213 214 @Override 215 protected void listChildren( 216 List<org.hl7.fhir.dstu2016may.model.Property> result) { 217 // TODO Auto-generated method stub 218 219 } 220 221 @Override 222 public boolean isPrimitive() { 223 return type != null ? ParserBase.isPrimitive(type) : property.isPrimitive(name); 224 } 225 226 @Override 227 public boolean hasPrimitiveValue() { 228 return property.isPrimitive(name) || property.IsLogicalAndHasPrimitiveValue(name); 229 } 230 231 232 @Override 233 public String primitiveValue() { 234 if (isPrimitive()) 235 return value; 236 else { 237 if (hasPrimitiveValue()) { 238 for (Element c : children) { 239 if (c.getName().equals("value")) 240 return c.primitiveValue(); 241 } 242 } 243 return null; 244 } 245 } 246 247 // for the validator 248 public int line() { 249 return line; 250 } 251 252 public int col() { 253 return col; 254 } 255 256 public Element markLocation(int line, int col) { 257 this.line = line; 258 this.col = col; 259 return this; 260 } 261 262 public Element getNamedChild(String name) { 263 if (children == null) 264 return null; 265 Element result = null; 266 for (Element child : children) { 267 if (child.getName().equals(name)) { 268 if (result == null) 269 result = child; 270 else 271 throw new Error("Attempt to read a single element when there is more than one present ("+name+")"); 272 } 273 } 274 return result; 275 } 276 277 public void getNamedChildren(String name, List<Element> list) { 278 if (children != null) 279 for (Element child : children) 280 if (child.getName().equals(name)) 281 list.add(child); 282 } 283 284 public String getNamedChildValue(String name) { 285 Element child = getNamedChild(name); 286 return child == null ? null : child.value; 287 } 288 289 public void getNamedChildrenWithWildcard(String string, List<Element> values) { 290 throw new Error("not done yet"); 291 } 292 293 294 public XhtmlNode getXhtml() { 295 return xhtml; 296 } 297 298 public Element setXhtml(XhtmlNode xhtml) { 299 this.xhtml = xhtml; 300 return this; 301 } 302 303 304}