001package org.hl7.fhir.dstu2016may.metamodel; 002 003import org.hl7.fhir.dstu2016may.formats.FormatUtilities; 004import org.hl7.fhir.dstu2016may.model.ElementDefinition; 005import org.hl7.fhir.dstu2016may.model.ElementDefinition.TypeRefComponent; 006import org.hl7.fhir.dstu2016may.model.StructureDefinition; 007import org.hl7.fhir.dstu2016may.model.StructureDefinition.StructureDefinitionKind; 008import org.hl7.fhir.dstu2016may.utils.IWorkerContext; 009import org.hl7.fhir.dstu2016may.utils.ToolingExtensions; 010 011public class Property { 012 013 private IWorkerContext context; 014 private ElementDefinition definition; 015 private StructureDefinition structure; 016 private Boolean canBePrimitive; 017 018 public Property(IWorkerContext context, ElementDefinition definition, StructureDefinition structure) { 019 this.context = context; 020 this.definition = definition; 021 this.structure = structure; 022 } 023 024 public String getName() { 025 return definition.getPath().substring(definition.getPath().lastIndexOf(".")+1); 026 } 027 028 public ElementDefinition getDefinition() { 029 return definition; 030 } 031 032 public String getType() { 033 if (definition.getType().size() == 0) 034 return null; 035 else if (definition.getType().size() > 1) { 036 String tn = definition.getType().get(0).getCode(); 037 for (int i = 1; i < definition.getType().size(); i++) { 038 if (!tn.equals(definition.getType().get(i).getCode())) 039 throw new Error("logic error, gettype when types > 1"); 040 } 041 return tn; 042 } else 043 return definition.getType().get(0).getCode(); 044 } 045 046 public String getType(String elementName) { 047 if (definition.getType().size() == 0) 048 return null; 049 else if (definition.getType().size() > 1) { 050 String t = definition.getType().get(0).getCode(); 051 boolean all = true; 052 for (TypeRefComponent tr : definition.getType()) { 053 if (!t.equals(tr.getCode())) 054 all = false; 055 } 056 if (all) 057 return t; 058 String tail = definition.getPath().substring(definition.getPath().lastIndexOf(".")+1); 059 if (tail.endsWith("[x]") && elementName != null && elementName.startsWith(tail.substring(0, tail.length()-3))) { 060 String name = elementName.substring(tail.length()-3); 061 return ParserBase.isPrimitive(lowFirst(name)) ? lowFirst(name) : name; 062 } else 063 throw new Error("logic error, gettype when types > 1, name mismatch for "+elementName+" on at "+definition.getPath()); 064 } else if (definition.getType().get(0).getCode() == null) { 065 return structure.getId(); 066 } else 067 return definition.getType().get(0).getCode(); 068 } 069 070 public boolean hasType(String elementName) { 071 if (definition.getType().size() == 0) 072 return false; 073 else if (definition.getType().size() > 1) { 074 String t = definition.getType().get(0).getCode(); 075 boolean all = true; 076 for (TypeRefComponent tr : definition.getType()) { 077 if (!t.equals(tr.getCode())) 078 all = false; 079 } 080 if (all) 081 return true; 082 String tail = definition.getPath().substring(definition.getPath().lastIndexOf(".")+1); 083 if (tail.endsWith("[x]") && elementName.startsWith(tail.substring(0, tail.length()-3))) { 084 String name = elementName.substring(tail.length()-3); 085 return true; 086 } else 087 return false; 088 } else 089 return true; 090 } 091 092 public StructureDefinition getStructure() { 093 return structure; 094 } 095 096 public boolean isPrimitive(String name) { 097 return ParserBase.isPrimitive(getType(name)); 098 } 099 100 private String lowFirst(String t) { 101 return t.substring(0, 1).toLowerCase()+t.substring(1); 102 } 103 104 public boolean isResource() { 105 return definition.getType().size() == 1 && ("Resource".equals(definition.getType().get(0).getCode()) || "DomainResource".equals(definition.getType().get(0).getCode())); 106 } 107 108 public boolean isList() { 109 return !definition.getMax().equals("1"); 110 } 111 112 public String getScopedPropertyName() { 113 return definition.getBase().getPath(); 114 } 115 116 public String getNamespace() { 117 if (ToolingExtensions.hasExtension(definition, "http://hl7.org/fhir/StructureDefinition/elementdefinition-namespace")) 118 return ToolingExtensions.readStringExtension(definition, "http://hl7.org/fhir/StructureDefinition/elementdefinition-namespace"); 119 if (ToolingExtensions.hasExtension(structure, "http://hl7.org/fhir/StructureDefinition/elementdefinition-namespace")) 120 return ToolingExtensions.readStringExtension(structure, "http://hl7.org/fhir/StructureDefinition/elementdefinition-namespace"); 121 return FormatUtilities.FHIR_NS; 122 } 123 124 public boolean IsLogicalAndHasPrimitiveValue(String name) { 125 if (canBePrimitive!= null) 126 return canBePrimitive; 127 128 canBePrimitive = false; 129 if (structure.getKind() != StructureDefinitionKind.LOGICAL) 130 return false; 131 if (!hasType(name)) 132 return false; 133 StructureDefinition sd = context.fetchResource(StructureDefinition.class, structure.getUrl().substring(0, structure.getUrl().lastIndexOf("/")+1)+getType(name)); 134 if (sd == null || sd.getKind() != StructureDefinitionKind.LOGICAL) 135 return false; 136 for (ElementDefinition ed : sd.getSnapshot().getElement()) { 137 if (ed.getPath().equals(sd.getId()+".value") && ed.getType().size() == 1 && ParserBase.isPrimitive(ed.getType().get(0).getCode())) { 138 canBePrimitive = true; 139 return true; 140 } 141 } 142 return false; 143 } 144 145 public boolean isChoice() { 146 if (definition.getType().size() <= 1) 147 return false; 148 String tn = definition.getType().get(0).getCode(); 149 for (int i = 1; i < definition.getType().size(); i++) 150 if (!definition.getType().get(i).getCode().equals(tn)) 151 return true; 152 return false; 153 } 154 155 156 157}