Merge branch 'master' of https://github.com/hapifhir/org.hl7.fhir.core
This commit is contained in:
commit
fff0d5a36d
|
@ -0,0 +1,46 @@
|
|||
package org.hl7.fhir.core.generator.codegen;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hl7.fhir.utilities.IniFile;
|
||||
import org.hl7.fhir.utilities.TextFile;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
|
||||
public class Configuration {
|
||||
|
||||
private String license;
|
||||
private IniFile ini;
|
||||
private Map<String, String> adornments = new HashMap<>();
|
||||
|
||||
public Configuration(String path) throws FileNotFoundException, IOException {
|
||||
license = TextFile.fileToString(Utilities.path(path, "license.txt"));
|
||||
ini = new IniFile(Utilities.path(path, "configuration.ini"));
|
||||
for (File jfn : new File(path).listFiles()) {
|
||||
if (jfn.getName().endsWith(".java")) {
|
||||
adornments.put(Utilities.changeFileExt(jfn.getName(), ""), TextFile.fileToString(jfn));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public String getLicense() {
|
||||
return license;
|
||||
}
|
||||
|
||||
public Map<String, String> getAdornments() {
|
||||
return adornments;
|
||||
}
|
||||
|
||||
|
||||
public IniFile getIni() {
|
||||
return ini;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,286 @@
|
|||
package org.hl7.fhir.core.generator.codegen;
|
||||
import java.io.IOException;
|
||||
/*
|
||||
Copyright (c) 2011+, HL7, Inc
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of HL7 nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.core.generator.engine.Definitions;
|
||||
import org.hl7.fhir.r5.model.CodeSystem;
|
||||
import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionBindingComponent;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent;
|
||||
import org.hl7.fhir.r5.model.Enumerations.BindingStrength;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionKind;
|
||||
import org.hl7.fhir.r5.model.ValueSet;
|
||||
import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
|
||||
|
||||
public class JavaBaseGenerator extends OutputStreamWriter {
|
||||
|
||||
protected Definitions definitions;
|
||||
protected Configuration config;
|
||||
protected String version;
|
||||
protected Date genDate;
|
||||
|
||||
public JavaBaseGenerator(OutputStream arg0, Definitions definitions, Configuration config, String version, Date genDate) throws UnsupportedEncodingException {
|
||||
super(arg0, "UTF-8");
|
||||
this.definitions = definitions;
|
||||
this.config = config;
|
||||
this.version = version;
|
||||
this.genDate = genDate;
|
||||
}
|
||||
|
||||
public void startMark(String version, Date genDate) throws IOException {
|
||||
write(startLicenseValue());
|
||||
write(startVMarkValue());
|
||||
}
|
||||
|
||||
public String startLicenseValue() {
|
||||
return "\r\n/*-\r\n"+config.getLicense()+"*/\r\n\r\n";
|
||||
}
|
||||
|
||||
public String startVMarkValue() {
|
||||
// return "// Generated on "+Config.DATE_FORMAT().format(genDate)+" for FHIR v"+version+"\r\n\r\n";
|
||||
return "// Generated on Thu, Dec 13, 2018 14:07+1100 for FHIR v4.0.0\r\n\r\n";
|
||||
}
|
||||
|
||||
|
||||
public static boolean isJavaReservedWord(String word) {
|
||||
if (word.equals("abstract")) return true;
|
||||
if (word.equals("assert")) return true;
|
||||
if (word.equals("boolean")) return true;
|
||||
if (word.equals("break")) return true;
|
||||
if (word.equals("byte")) return true;
|
||||
if (word.equals("case")) return true;
|
||||
if (word.equals("catch")) return true;
|
||||
if (word.equals("char")) return true;
|
||||
if (word.equals("class")) return true;
|
||||
if (word.equals("const")) return true;
|
||||
if (word.equals("continue")) return true;
|
||||
if (word.equals("default")) return true;
|
||||
if (word.equals("double")) return true;
|
||||
if (word.equals("do")) return true;
|
||||
if (word.equals("else")) return true;
|
||||
if (word.equals("enum")) return true;
|
||||
if (word.equals("extends")) return true;
|
||||
if (word.equals("false")) return true;
|
||||
if (word.equals("final")) return true;
|
||||
if (word.equals("finally")) return true;
|
||||
if (word.equals("float")) return true;
|
||||
if (word.equals("for")) return true;
|
||||
if (word.equals("goto")) return true;
|
||||
if (word.equals("if")) return true;
|
||||
if (word.equals("implements")) return true;
|
||||
if (word.equals("import")) return true;
|
||||
if (word.equals("instanceof")) return true;
|
||||
if (word.equals("int")) return true;
|
||||
if (word.equals("interface")) return true;
|
||||
if (word.equals("long")) return true;
|
||||
if (word.equals("native")) return true;
|
||||
if (word.equals("new")) return true;
|
||||
if (word.equals("null")) return true;
|
||||
if (word.equals("package")) return true;
|
||||
if (word.equals("private")) return true;
|
||||
if (word.equals("protected")) return true;
|
||||
if (word.equals("public")) return true;
|
||||
if (word.equals("return")) return true;
|
||||
if (word.equals("short")) return true;
|
||||
if (word.equals("static")) return true;
|
||||
if (word.equals("strictfp")) return true;
|
||||
if (word.equals("super")) return true;
|
||||
if (word.equals("switch")) return true;
|
||||
if (word.equals("synchronized")) return true;
|
||||
if (word.equals("this")) return true;
|
||||
if (word.equals("throw")) return true;
|
||||
if (word.equals("throws")) return true;
|
||||
if (word.equals("transient")) return true;
|
||||
if (word.equals("true")) return true;
|
||||
if (word.equals("try")) return true;
|
||||
if (word.equals("void")) return true;
|
||||
if (word.equals("volatile")) return true;
|
||||
if (word.equals("while")) return true;
|
||||
if (word.equals("Exception")) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean isJavaPrimitive(ElementDefinition e) {
|
||||
return e.getType().size() == 1 && (isPrimitive(e.getType().get(0).getWorkingCode()));
|
||||
}
|
||||
|
||||
protected boolean isPrimitive(String name) {
|
||||
return definitions.getStructures().has(typeNs(name)) && definitions.getStructures().get(typeNs(name)).getKind() == StructureDefinitionKind.PRIMITIVETYPE;
|
||||
}
|
||||
|
||||
private String typeNs(String name) {
|
||||
return "http://hl7.org/fhir/StructureDefinition/"+name;
|
||||
}
|
||||
|
||||
protected String getElementName(String name, boolean alone) {
|
||||
if (name.equals("[type]"))
|
||||
return "value";
|
||||
else if ((alone && isJavaReservedWord(name)) || (!alone && name.equals("class")))
|
||||
return name+"_";
|
||||
else if (name.equals("[x]"))
|
||||
return "value";
|
||||
else
|
||||
return name.replace("[x]", "");
|
||||
}
|
||||
|
||||
protected String getTypeName(ElementDefinition e) throws Exception {
|
||||
if (e.getType().size() > 1) {
|
||||
return "DataType";
|
||||
} else if (e.getType().size() == 0) {
|
||||
throw new Exception("not supported");
|
||||
} else {
|
||||
return getTypename(e.getType().get(0));
|
||||
}
|
||||
}
|
||||
|
||||
protected String getTypename(TypeRefComponent type) throws Exception {
|
||||
if (type.hasExtension("http://hl7.org/fhir/StructureDefinition/structuredefinition-fhir-type")) {
|
||||
return type.getExtensionString("http://hl7.org/fhir/StructureDefinition/structuredefinition-fhir-type");
|
||||
} else {
|
||||
return getTypeName(type.getCode());
|
||||
}
|
||||
}
|
||||
|
||||
protected String getTypeName(String tn) {
|
||||
if (tn.equals("string")) {
|
||||
return "StringType";
|
||||
} else if (tn.equals("Any")) {
|
||||
return "Reference";
|
||||
} else if (tn.equals("SimpleQuantity")) {
|
||||
return "Quantity";
|
||||
} else if (isPrimitive(tn)) {
|
||||
return getTitle(tn)+"Type";
|
||||
} else {
|
||||
return getTitle(tn);
|
||||
}
|
||||
}
|
||||
|
||||
protected String getTitle(String name) {
|
||||
return Utilities.noString(name) ? "Value" : name.substring(0, 1).toUpperCase()+ name.substring(1);
|
||||
}
|
||||
|
||||
|
||||
protected List<ConceptDefinitionComponent> listAllCodes(CodeSystem cs) {
|
||||
List<ConceptDefinitionComponent> result = new ArrayList<ConceptDefinitionComponent>();
|
||||
addAllCodes(result, cs.getConcept());
|
||||
return result;
|
||||
}
|
||||
|
||||
private void addAllCodes(List<ConceptDefinitionComponent> result, List<ConceptDefinitionComponent> concept) {
|
||||
for (ConceptDefinitionComponent c : concept) {
|
||||
result.add(c);
|
||||
addAllCodes(result, c.getConcept());
|
||||
}
|
||||
}
|
||||
|
||||
protected String makeConst(String cc) {
|
||||
if (cc.equals("*"))
|
||||
cc = "ASTERISK";
|
||||
if (Utilities.isOid(cc))
|
||||
cc = "OID_"+cc;
|
||||
if (cc.equals("%"))
|
||||
cc = "pct";
|
||||
else if (cc.equals("<"))
|
||||
cc = "less_Than";
|
||||
else if (cc.equals("<="))
|
||||
cc = "less_Or_Equal";
|
||||
else if (cc.equals(">"))
|
||||
cc = "greater_Than";
|
||||
else if (cc.equals(">="))
|
||||
cc = "greater_Or_Equal";
|
||||
else if (cc.equals("="))
|
||||
cc = "equal";
|
||||
else if (cc.equals("!="))
|
||||
cc = "not_equal";
|
||||
else if (allPlusMinus(cc))
|
||||
cc = cc.replace("-", "Minus").replace("+", "Plus");
|
||||
else
|
||||
cc = cc.replace("-", "").replace("+", "");
|
||||
cc = cc.replace("(", "_").replace(")", "_");
|
||||
cc = cc.replace("{", "_").replace("}", "_");
|
||||
cc = cc.replace("<", "_").replace(">", "_");
|
||||
cc = cc.replace(".", "_").replace("/", "_");
|
||||
cc = cc.replace(":", "_");
|
||||
cc = cc.replace("%", "pct");
|
||||
if (Utilities.isInteger(cc.substring(0, 1)))
|
||||
cc = "_"+cc;
|
||||
cc = cc.toUpperCase();
|
||||
if (isJavaReservedWord(cc))
|
||||
cc = cc + "_";
|
||||
return cc;
|
||||
}
|
||||
|
||||
private boolean allPlusMinus(String cc) {
|
||||
for (char c : cc.toCharArray())
|
||||
if (!(c == '-' || c == '+'))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
protected boolean isEnum(ElementDefinitionBindingComponent cd) {
|
||||
boolean ok = cd != null && cd.getStrength() == BindingStrength.REQUIRED;
|
||||
if (ok) {
|
||||
if (cd.getValueSet() != null) {
|
||||
ValueSet vs = definitions.getValuesets().get(cd.getValueSet());
|
||||
if (vs != null && vs.hasCompose() && vs.getCompose().getInclude().size() == 1) {
|
||||
ConceptSetComponent inc = vs.getCompose().getIncludeFirstRep();
|
||||
if (inc.hasSystem() && !inc.hasFilter() && !inc.hasConcept() && !(inc.getSystem().startsWith("http://hl7.org/fhir") || inc.getSystem().startsWith("http://terminology.hl7.org")))
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
protected String getCodeListType(String binding) {
|
||||
StringBuilder b = new StringBuilder();
|
||||
boolean up = true;
|
||||
for (char ch: binding.toCharArray()) {
|
||||
if (ch == '-' || ch == ' ' || ch == '.')
|
||||
up = true;
|
||||
else if (up) {
|
||||
b.append(Character.toUpperCase(ch));
|
||||
up = false;
|
||||
}
|
||||
else
|
||||
b.append(ch);
|
||||
}
|
||||
return "ResourceType".equals(b.toString()) ? "ResourceTypeEnum" : b.toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,256 @@
|
|||
package org.hl7.fhir.core.generator.codegen;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hl7.fhir.core.generator.engine.Definitions;
|
||||
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
import org.hl7.fhir.r5.model.ValueSet;
|
||||
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionKind;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition.TypeDerivationRule;
|
||||
|
||||
/*
|
||||
Copyright (c) 2011+, HL7, Inc
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of HL7 nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
changes for James
|
||||
- lazy construction of lists
|
||||
- getX will construct if null
|
||||
- add hasX
|
||||
|
||||
*/
|
||||
public class JavaEnumerationsGenerator extends JavaBaseGenerator {
|
||||
|
||||
public JavaEnumerationsGenerator(OutputStream out, Definitions definitions, Configuration configuration, Date genDate, String version) throws UnsupportedEncodingException {
|
||||
super(out, definitions, configuration, version, genDate);
|
||||
}
|
||||
|
||||
public void generate() throws Exception {
|
||||
write("package org.hl7.fhir.r5.model;\r\n");
|
||||
startMark(version, genDate);
|
||||
write("\r\n");
|
||||
write("import org.hl7.fhir.instance.model.api.*;\r\n");
|
||||
write("import org.hl7.fhir.exceptions.FHIRException;\r\n");
|
||||
write("\r\n");
|
||||
|
||||
write("public class Enumerations {\r\n");
|
||||
write("\r\n");
|
||||
write("// In here: \r\n");
|
||||
|
||||
Map<String, ValueSet> enums = scanForEnums();
|
||||
List<String> names = new ArrayList<String>();
|
||||
names.addAll(enums.keySet());
|
||||
Collections.sort(names);
|
||||
for (String n : names) {
|
||||
ValueSet vs = enums.get(n);
|
||||
write("// "+n+": "+vs.getDescription());
|
||||
ValueSet vsd = definitions.getValuesets().get(vs.getUrl());
|
||||
write(vsd.getUserData("usages").toString());
|
||||
write("\r\n");
|
||||
}
|
||||
write("\r\n");
|
||||
write("\r\n");
|
||||
for (String n : names) {
|
||||
ValueSet vs = enums.get(n);
|
||||
generateEnum(n, vs);
|
||||
}
|
||||
write("\r\n");
|
||||
write("}\r\n");
|
||||
write("\r\n");
|
||||
flush();
|
||||
}
|
||||
|
||||
private Map<String, ValueSet> scanForEnums() {
|
||||
Map<String, ValueSet> res = new HashMap<>();
|
||||
for (StructureDefinition sd : definitions.getStructures().getList()) {
|
||||
if (sd.getDerivation() == TypeDerivationRule.SPECIALIZATION && sd.getKind() != StructureDefinitionKind.PRIMITIVETYPE) {
|
||||
for (ElementDefinition ed : sd.getSnapshot().getElement()) {
|
||||
if (ed.hasBinding() && ed.getBinding().hasValueSet() && ed.getBinding().hasUserData("shared")) {
|
||||
ValueSet vs = (ValueSet) ed.getBinding().getUserData("expansion");
|
||||
if (vs != null) {
|
||||
res.put(getCodeListType(vs.getName()), vs);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void generateEnum(String name, ValueSet vs) throws Exception {
|
||||
String url = vs.getUrl();
|
||||
CommaSeparatedStringBuilder el = new CommaSeparatedStringBuilder();
|
||||
|
||||
write(" public enum "+name+" {\r\n");
|
||||
int l = vs.getExpansion().getContains().size();
|
||||
int i = 0;
|
||||
for (ValueSetExpansionContainsComponent c : vs.getExpansion().getContains()) {
|
||||
i++;
|
||||
String cc = Utilities.camelCase(c.getCode());
|
||||
cc = makeConst(cc);
|
||||
el.append(cc);
|
||||
|
||||
write(" /**\r\n");
|
||||
write(" * "+definitions.getCodeDefinition(c.getSystem(), c.getCode())+"\r\n");
|
||||
write(" */\r\n");
|
||||
write(" "+cc.toUpperCase()+", \r\n");
|
||||
}
|
||||
write(" /**\r\n");
|
||||
write(" * added to help the parsers\r\n");
|
||||
write(" */\r\n");
|
||||
write(" NULL;\r\n");
|
||||
el.append("NULL");
|
||||
|
||||
|
||||
write(" public static "+name+" fromCode(String codeString) throws FHIRException {\r\n");
|
||||
write(" if (codeString == null || \"\".equals(codeString))\r\n");
|
||||
write(" return null;\r\n");
|
||||
for (ValueSetExpansionContainsComponent c : vs.getExpansion().getContains()) {
|
||||
String cc = Utilities.camelCase(c.getCode());
|
||||
cc = makeConst(cc);
|
||||
write(" if (\""+c.getCode()+"\".equals(codeString))\r\n");
|
||||
write(" return "+cc+";\r\n");
|
||||
}
|
||||
write(" throw new FHIRException(\"Unknown "+name+" code '\"+codeString+\"'\");\r\n");
|
||||
write(" }\r\n");
|
||||
|
||||
write(" public String toCode() {\r\n");
|
||||
write(" switch (this) {\r\n");
|
||||
for (ValueSetExpansionContainsComponent c : vs.getExpansion().getContains()) {
|
||||
String cc = Utilities.camelCase(c.getCode());
|
||||
cc = makeConst(cc);
|
||||
write(" case "+cc+": return \""+c.getCode()+"\";\r\n");
|
||||
}
|
||||
write(" default: return \"?\";\r\n");
|
||||
write(" }\r\n");
|
||||
write(" }\r\n");
|
||||
|
||||
write(" public String getSystem() {\r\n");
|
||||
write(" switch (this) {\r\n");
|
||||
for (ValueSetExpansionContainsComponent c : vs.getExpansion().getContains()) {
|
||||
String cc = Utilities.camelCase(c.getCode());
|
||||
cc = makeConst(cc);
|
||||
write(" case "+cc+": return \""+c.getSystem()+"\";\r\n");
|
||||
}
|
||||
write(" default: return \"?\";\r\n");
|
||||
write(" }\r\n");
|
||||
write(" }\r\n");
|
||||
|
||||
write(" public String getDefinition() {\r\n");
|
||||
write(" switch (this) {\r\n");
|
||||
for (ValueSetExpansionContainsComponent c : vs.getExpansion().getContains()) {
|
||||
String cc = Utilities.camelCase(c.getCode());
|
||||
cc = makeConst(cc);
|
||||
write(" case "+cc+": return \""+Utilities.escapeJava(definitions.getCodeDefinition(c.getSystem(), c.getCode()))+"\";\r\n");
|
||||
}
|
||||
write(" default: return \"?\";\r\n");
|
||||
write(" }\r\n");
|
||||
write(" }\r\n");
|
||||
|
||||
write(" public String getDisplay() {\r\n");
|
||||
write(" switch (this) {\r\n");
|
||||
for (ValueSetExpansionContainsComponent c : vs.getExpansion().getContains()) {
|
||||
String cc = Utilities.camelCase(c.getCode());
|
||||
cc = makeConst(cc);
|
||||
write(" case "+cc+": return \""+Utilities.escapeJava(Utilities.noString(c.getDisplay()) ? c.getCode() : c.getDisplay())+"\";\r\n");
|
||||
}
|
||||
write(" default: return \"?\";\r\n");
|
||||
write(" }\r\n");
|
||||
write(" }\r\n");
|
||||
|
||||
if (config.getAdornments().containsKey(name)) {
|
||||
write("// manual code from configuration.txt:\r\n");
|
||||
write(config.getAdornments().get(name)+"\r\n");
|
||||
write("// end addition\r\n");
|
||||
}
|
||||
|
||||
write(" }\r\n");
|
||||
write("\r\n");
|
||||
|
||||
|
||||
write(" public static class "+name+"EnumFactory implements EnumFactory<"+name+"> {\r\n");
|
||||
write(" public "+name+" fromCode(String codeString) throws IllegalArgumentException {\r\n");
|
||||
|
||||
write(" if (codeString == null || \"\".equals(codeString))\r\n");
|
||||
write(" if (codeString == null || \"\".equals(codeString))\r\n");
|
||||
write(" return null;\r\n");
|
||||
for (ValueSetExpansionContainsComponent c : vs.getExpansion().getContains()) {
|
||||
String cc = Utilities.camelCase(c.getCode());
|
||||
cc = makeConst(cc);
|
||||
write(" if (\""+c.getCode()+"\".equals(codeString))\r\n");
|
||||
write(" return "+name+"."+cc+";\r\n");
|
||||
}
|
||||
write(" throw new IllegalArgumentException(\"Unknown "+name+" code '\"+codeString+\"'\");\r\n");
|
||||
write(" }\r\n");
|
||||
write(" public Enumeration<"+name+"> fromType(Base code) throws FHIRException {\r\n");
|
||||
write(" if (code == null)\r\n");
|
||||
write(" return null;\r\n");
|
||||
write(" if (code.isEmpty())\r\n");
|
||||
write(" return new Enumeration<"+name+">(this);\r\n");
|
||||
write(" String codeString = ((PrimitiveType) code).asStringValue();\r\n");
|
||||
write(" if (codeString == null || \"\".equals(codeString))\r\n");
|
||||
write(" return null;\r\n");
|
||||
for (ValueSetExpansionContainsComponent c : vs.getExpansion().getContains()) {
|
||||
String cc = Utilities.camelCase(c.getCode());
|
||||
cc = makeConst(cc);
|
||||
write(" if (\""+c.getCode()+"\".equals(codeString))\r\n");
|
||||
write(" return new Enumeration<"+name+">(this, "+name+"."+cc+");\r\n");
|
||||
}
|
||||
write(" throw new FHIRException(\"Unknown "+name+" code '\"+codeString+\"'\");\r\n");
|
||||
write(" }\r\n");
|
||||
write(" public String toCode("+name+" code) {\r\n");
|
||||
for (ValueSetExpansionContainsComponent c : vs.getExpansion().getContains()) {
|
||||
String cc = Utilities.camelCase(c.getCode());
|
||||
cc = makeConst(cc);
|
||||
write(" if (code == "+name+"."+cc+")\r\n return \""+c.getCode()+"\";\r\n");
|
||||
}
|
||||
write(" return \"?\";\r\n");
|
||||
write(" }\r\n");
|
||||
|
||||
write(" public String toSystem("+name+" code) {\r\n");
|
||||
write(" return code.getSystem();\r\n");
|
||||
write(" }\r\n");
|
||||
|
||||
write(" }\r\n");
|
||||
write("\r\n");
|
||||
}
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,79 @@
|
|||
package org.hl7.fhir.core.generator.engine;
|
||||
|
||||
import org.hl7.fhir.r5.context.CanonicalResourceManager;
|
||||
import org.hl7.fhir.r5.model.CapabilityStatement;
|
||||
import org.hl7.fhir.r5.model.CodeSystem;
|
||||
import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent;
|
||||
import org.hl7.fhir.r5.model.CompartmentDefinition;
|
||||
import org.hl7.fhir.r5.model.ConceptMap;
|
||||
import org.hl7.fhir.r5.model.OperationDefinition;
|
||||
import org.hl7.fhir.r5.model.SearchParameter;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionKind;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition.TypeDerivationRule;
|
||||
import org.hl7.fhir.r5.model.ValueSet;
|
||||
|
||||
public class Definitions {
|
||||
|
||||
private CanonicalResourceManager<CodeSystem> codeSystems = new CanonicalResourceManager<>(true);
|
||||
private CanonicalResourceManager<ValueSet> valuesets = new CanonicalResourceManager<>(true);
|
||||
private CanonicalResourceManager<ConceptMap> conceptMaps = new CanonicalResourceManager<>(true);
|
||||
|
||||
private CanonicalResourceManager<CapabilityStatement> statements = new CanonicalResourceManager<>(true);
|
||||
private CanonicalResourceManager<StructureDefinition> structures = new CanonicalResourceManager<>(true);
|
||||
private CanonicalResourceManager<OperationDefinition> operations = new CanonicalResourceManager<>(true);
|
||||
private CanonicalResourceManager<SearchParameter> searchParams = new CanonicalResourceManager<>(true);
|
||||
private CanonicalResourceManager<CompartmentDefinition> compartments = new CanonicalResourceManager<>(true);
|
||||
|
||||
public CanonicalResourceManager<CodeSystem> getCodeSystems() {
|
||||
return codeSystems;
|
||||
}
|
||||
public CanonicalResourceManager<ValueSet> getValuesets() {
|
||||
return valuesets;
|
||||
}
|
||||
public CanonicalResourceManager<ConceptMap> getConceptMaps() {
|
||||
return conceptMaps;
|
||||
}
|
||||
public CanonicalResourceManager<CapabilityStatement> getStatements() {
|
||||
return statements;
|
||||
}
|
||||
public CanonicalResourceManager<StructureDefinition> getStructures() {
|
||||
return structures;
|
||||
}
|
||||
public CanonicalResourceManager<OperationDefinition> getOperations() {
|
||||
return operations;
|
||||
}
|
||||
public CanonicalResourceManager<SearchParameter> getSearchParams() {
|
||||
return searchParams;
|
||||
}
|
||||
public CanonicalResourceManager<CompartmentDefinition> getCompartments() {
|
||||
return compartments;
|
||||
}
|
||||
|
||||
public String getCodeDefinition(String system, String code) {
|
||||
CodeSystem cs = codeSystems.get(system);
|
||||
if (cs == null) {
|
||||
return null;
|
||||
} else {
|
||||
ConceptDefinitionComponent cc = cs.getDefinitionByCode(code);
|
||||
return cc == null ? null : cc.getDefinition();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasPrimitiveType(String tn) {
|
||||
StructureDefinition sd = structures.get("http://hl7.org/fhir/StructureDefinition/"+tn);
|
||||
return sd != null && sd.getKind() == StructureDefinitionKind.PRIMITIVETYPE && sd.getDerivation() == TypeDerivationRule.SPECIALIZATION;
|
||||
}
|
||||
|
||||
public boolean hasResource(String tn) {
|
||||
StructureDefinition sd = structures.get("http://hl7.org/fhir/StructureDefinition/"+tn);
|
||||
return sd != null && sd.getKind() == StructureDefinitionKind.RESOURCE && sd.getDerivation() == TypeDerivationRule.SPECIALIZATION;
|
||||
|
||||
}
|
||||
public StructureDefinition getType(String tn) {
|
||||
StructureDefinition sd = structures.get("http://hl7.org/fhir/StructureDefinition/"+tn);
|
||||
return sd;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,197 @@
|
|||
package org.hl7.fhir.core.generator.engine;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hl7.fhir.core.generator.codegen.Configuration;
|
||||
import org.hl7.fhir.core.generator.codegen.JavaEnumerationsGenerator;
|
||||
import org.hl7.fhir.core.generator.codegen.JavaResourceGenerator;
|
||||
import org.hl7.fhir.core.generator.loader.DefinitionsLoader;
|
||||
import org.hl7.fhir.r5.model.ValueSet;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionKind;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition.TypeDerivationRule;
|
||||
import org.hl7.fhir.r5.model.CodeType;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition;
|
||||
import org.hl7.fhir.r5.model.Enumerations.BindingStrength;
|
||||
import org.hl7.fhir.r5.model.SearchParameter;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
import org.hl7.fhir.utilities.TextFile;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.cache.NpmPackage;
|
||||
import org.hl7.fhir.utilities.cache.PackageCacheManager;
|
||||
import org.hl7.fhir.utilities.cache.ToolsVersion;
|
||||
|
||||
public class JavaCoreGenerator {
|
||||
|
||||
// C:\work\org.hl7.fhir\org.hl7.fhir.core\org.hl7.fhir.r5
|
||||
// C:\work\org.hl7.fhir\org.hl7.fhir.core\org.hl7.fhir.r5.new
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
System.out.println("HAPI CORE Code Generator");
|
||||
if (args.length != 3) {
|
||||
System.out.println("Usage: invoke with 3 command line parameters to generate HAPI R5 code");
|
||||
System.out.println("1: fhir version to generate from (e.g. 4.1.0 or 'current'");
|
||||
System.out.println("2: project directory to read java-adorment from - e.g. C:\\work\\org.hl7.fhir\\org.hl7.fhir.core\\org.hl7.fhir.r5");
|
||||
System.out.println("3: project directory to generate code into - e.g. C:\\work\\org.hl7.fhir\\org.hl7.fhir.core\\org.hl7.fhir.r5.new");
|
||||
} else {
|
||||
String version = args[0];
|
||||
String src = args[1];
|
||||
String dest = args[2];
|
||||
new JavaCoreGenerator().generate(version, src, dest);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void generate(String version, String src, String dest) throws Exception {
|
||||
Date date = new Date();
|
||||
|
||||
String ap = Utilities.path(src, "src", "main", "resources");
|
||||
System.out.println("Load Configuration from "+ap);
|
||||
Configuration config = new Configuration(ap);
|
||||
|
||||
|
||||
PackageCacheManager pcm = new PackageCacheManager(true, ToolsVersion.TOOLS_VERSION);
|
||||
System.out.println("Cache: "+pcm.userDir());
|
||||
System.out.println("Load hl7.fhir.r5.core");
|
||||
NpmPackage npm = pcm.loadPackage("hl7.fhir.r5.core", version);
|
||||
Definitions master = DefinitionsLoader.load(npm);
|
||||
|
||||
markValueSets(master, config);
|
||||
|
||||
System.out.println("Load hl7.fhir.r5.expansions");
|
||||
Definitions expansions = DefinitionsLoader.load(pcm.loadPackage("hl7.fhir.r5.expansions", version));
|
||||
|
||||
System.out.println("Process Expansions");
|
||||
updateExpansions(master, expansions);
|
||||
|
||||
System.out.println("Generate Model");
|
||||
System.out.println(" .. Enumerations");
|
||||
JavaEnumerationsGenerator egen = new JavaEnumerationsGenerator(new FileOutputStream(Utilities.path(dest, "src", "org", "hl7", "fhir", "r5", "model", "Enumerations.java")), master, config, date, npm.version());
|
||||
egen.generate();
|
||||
|
||||
for (StructureDefinition sd : master.getStructures().getList()) {
|
||||
if (sd.getDerivation() == TypeDerivationRule.SPECIALIZATION && sd.getKind() != StructureDefinitionKind.PRIMITIVETYPE) {
|
||||
if (!Utilities.existsInList(sd.getName(), "Base", "PrimitiveType") && !sd.getName().contains(".") && sd.getAbstract()) {
|
||||
String name = javaName(sd.getName());
|
||||
|
||||
System.out.println(" .. "+name);
|
||||
String fn = Utilities.path(dest, "src", "org", "hl7", "fhir", "r5", "model", name+".java");
|
||||
JavaResourceGenerator gen = new JavaResourceGenerator(new FileOutputStream(fn), master, config, date, npm.version());
|
||||
gen.generate(sd, name, getSearchParams(master, sd.getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
for (StructureDefinition sd : master.getStructures().getList()) {
|
||||
if (sd.getDerivation() == TypeDerivationRule.SPECIALIZATION && sd.getKind() != StructureDefinitionKind.PRIMITIVETYPE) {
|
||||
if (!Utilities.existsInList(sd.getName(), "Base", "PrimitiveType") && !sd.getName().contains(".") && !sd.getAbstract()) {
|
||||
String name = javaName(sd.getName());
|
||||
|
||||
System.out.println(" .. "+name);
|
||||
String fn = Utilities.path(dest, "src", "org", "hl7", "fhir", "r5", "model", name+".java");
|
||||
JavaResourceGenerator gen = new JavaResourceGenerator(new FileOutputStream(fn), master, config, date, npm.version());
|
||||
gen.generate(sd, name, getSearchParams(master, sd.getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.println("Done");
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void markValueSets(Definitions defns, Configuration config) {
|
||||
for (StructureDefinition sd : defns.getStructures().getList()) {
|
||||
if (sd.getDerivation() == TypeDerivationRule.SPECIALIZATION && sd.getKind() != StructureDefinitionKind.PRIMITIVETYPE && !sd.getName().contains(".")) {
|
||||
for (ElementDefinition ed : sd.getSnapshot().getElement()) {
|
||||
if (ed.hasBinding() && ed.getBinding().hasValueSet() && ed.getBinding().getStrength() == BindingStrength.REQUIRED) {
|
||||
ValueSet vs = defns.getValuesets().get(ed.getBinding().getValueSet());
|
||||
if (vs != null) {
|
||||
if (!vs.hasUserData("usages")) {
|
||||
vs.setUserData("usages", new ArrayList<>());
|
||||
}
|
||||
List<String> list = (List<String>) vs.getUserData("usages");
|
||||
if (!list.contains(sd.getName())) {
|
||||
list.add(sd.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (StructureDefinition sd : defns.getStructures().getList()) {
|
||||
if (sd.getDerivation() == TypeDerivationRule.SPECIALIZATION && sd.getKind() != StructureDefinitionKind.PRIMITIVETYPE) {
|
||||
for (ElementDefinition ed : sd.getSnapshot().getElement()) {
|
||||
if (ed.hasBinding() && ed.getBinding().hasValueSet()) {
|
||||
ValueSet vs = defns.getValuesets().get(ed.getBinding().getValueSet());
|
||||
boolean shared = false;
|
||||
if (vs != null) {
|
||||
List<String> list = (List<String>) vs.getUserData("usages");
|
||||
if (list != null && list.size() > 1) {
|
||||
shared = true;
|
||||
}
|
||||
}
|
||||
if (config.getIni().hasProperty("shared", ed.getPath())) {
|
||||
shared = config.getIni().getBooleanProperty("shared", ed.getPath());
|
||||
}
|
||||
if (shared) {
|
||||
ed.getBinding().setUserData("shared", true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private List<SearchParameter> getSearchParams(Definitions defns, String name) {
|
||||
List<SearchParameter> res = new ArrayList<>();
|
||||
if (!Utilities.existsInList(name, "Resource")) {
|
||||
for (SearchParameter sp : defns.getSearchParams().getList()) {
|
||||
boolean relevant = false;
|
||||
for (CodeType c : sp.getBase()) {
|
||||
if (c.getValue().equals(name)) {
|
||||
relevant = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (relevant) {
|
||||
res.add(sp);
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
private String javaName(String name) {
|
||||
return "List".equals(name) ? "ListResource" : name;
|
||||
}
|
||||
|
||||
private void updateExpansions(Definitions master, Definitions expansions) {
|
||||
for (StructureDefinition sd : master.getStructures().getList()) {
|
||||
for (ElementDefinition ed : sd.getSnapshot().getElement()) {
|
||||
if (ed.hasBinding() && ed.getBinding().hasValueSet()) {
|
||||
String ref = ed.getBinding().getValueSet();
|
||||
if (ref.contains("|")) {
|
||||
ref = ref.substring(0, ref.indexOf("|"));
|
||||
}
|
||||
ValueSet exp = expansions.getValuesets().get(ref);
|
||||
if (exp != null) {
|
||||
ed.getBinding().setUserData("expansion", exp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package org.hl7.fhir.core.generator.loader;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.hl7.fhir.core.generator.engine.Definitions;
|
||||
import org.hl7.fhir.r5.formats.JsonParser;
|
||||
import org.hl7.fhir.r5.model.CapabilityStatement;
|
||||
import org.hl7.fhir.r5.model.CodeSystem;
|
||||
import org.hl7.fhir.r5.model.CompartmentDefinition;
|
||||
import org.hl7.fhir.r5.model.ConceptMap;
|
||||
import org.hl7.fhir.r5.model.OperationDefinition;
|
||||
import org.hl7.fhir.r5.model.SearchParameter;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
import org.hl7.fhir.r5.model.ValueSet;
|
||||
import org.hl7.fhir.utilities.cache.NpmPackage;
|
||||
import org.hl7.fhir.utilities.cache.PackageCacheManager;
|
||||
import org.hl7.fhir.utilities.cache.ToolsVersion;
|
||||
|
||||
public class DefinitionsLoader {
|
||||
|
||||
public static Definitions load(NpmPackage npm) throws IOException {
|
||||
Definitions res = new Definitions();
|
||||
|
||||
for (String t : npm.listResources("CodeSystem")) {
|
||||
res.getCodeSystems().see((CodeSystem) new JsonParser().parse(npm.loadResource(t)));
|
||||
}
|
||||
for (String t : npm.listResources("ValueSet")) {
|
||||
res.getValuesets().see((ValueSet) new JsonParser().parse(npm.loadResource(t)));
|
||||
}
|
||||
for (String t : npm.listResources("ConceptMap")) {
|
||||
res.getConceptMaps().see((ConceptMap) new JsonParser().parse(npm.loadResource(t)));
|
||||
}
|
||||
for (String t : npm.listResources("CapabilityStatement")) {
|
||||
res.getStatements().see((CapabilityStatement) new JsonParser().parse(npm.loadResource(t)));
|
||||
}
|
||||
for (String t : npm.listResources("StructureDefinition")) {
|
||||
res.getStructures().see((StructureDefinition) new JsonParser().parse(npm.loadResource(t)));
|
||||
}
|
||||
for (String t : npm.listResources("OperationDefinition")) {
|
||||
res.getOperations().see((OperationDefinition) new JsonParser().parse(npm.loadResource(t)));
|
||||
}
|
||||
for (String t : npm.listResources("SearchParameter")) {
|
||||
res.getSearchParams().see((SearchParameter) new JsonParser().parse(npm.loadResource(t)));
|
||||
}
|
||||
for (String t : npm.listResources("CompartmentDefinition")) {
|
||||
res.getCompartments().see((CompartmentDefinition) new JsonParser().parse(npm.loadResource(t)));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue