diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/profile/ProfileUtilities.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/profile/ProfileUtilities.java index 6a59b1615..bc3deedf1 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/profile/ProfileUtilities.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/profile/ProfileUtilities.java @@ -4452,6 +4452,14 @@ public class ProfileUtilities extends TranslatingUtilities { return value != null && !value.isProhibited(); } + public static boolean isComplexExtension(StructureDefinition sd) { + if (!isExtensionDefinition(sd)) { + return false; + } + ElementDefinition value = sd.getSnapshot().getElementByPath("Extension.value"); + return value == null || value.isProhibited(); + } + public static boolean isModifierExtension(StructureDefinition sd) { ElementDefinition defn = sd.getSnapshot().getElementByPath("Extension"); return defn.getIsModifier(); diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEBuilder.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEBuilder.java index a75050191..2063a9045 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEBuilder.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEBuilder.java @@ -1,5 +1,33 @@ package org.hl7.fhir.r5.profilemodel; +/* + 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.util.ArrayList; import java.util.List; @@ -340,7 +368,11 @@ public class PEBuilder { } else if (isTypeSlicing(defn)) { res.add(new PEDefinitionTypeSlice(this, list.get(i).getSliceName(), profile, list.get(i), defn, parent.path())); } else { - res.add(new PEDefinitionSlice(this, list.get(i).getSliceName(), profile, list.get(i), defn, parent.path())); + if (ProfileUtilities.isComplexExtension(profile) && defn.getPath().endsWith(".extension")) { + res.add(new PEDefinitionSubExtension(this, profile, list.get(i), parent.path())); + } else { + res.add(new PEDefinitionSlice(this, list.get(i).getSliceName(), profile, list.get(i), defn, parent.path())); + } } i++; } @@ -364,6 +396,15 @@ public class PEBuilder { } } + protected PEDefinition makeChild(PEDefinition parent, StructureDefinition profileStructure, ElementDefinition definition) { + PEDefinitionElement pe = new PEDefinitionElement(this, profileStructure, definition, parent.path()); + if (context.isPrimitiveType(definition.getTypeFirstRep().getWorkingCode()) && "value".equals(pe.name())) { + pe.setMustHaveValue(definition.getMustHaveValue()); + } + pe.setInFixedValue(definition.hasFixed() || definition.hasPattern() || parent.isInFixedValue()); + return pe; + } + private boolean passElementPropsCheck(ElementDefinition bdefn) { switch (elementProps) { case EXTENSION: @@ -417,7 +458,7 @@ public class PEBuilder { } } } - return false; + return !defn.getPath().contains("."); } @@ -463,6 +504,10 @@ public class PEBuilder { } + protected PEType makeType(String tn, String url) { + return new PEType(tn, tn, url); + } + protected PEType makeType(String tn) { return new PEType(tn, tn, "http://hl7.org/fhir/StructureDefinition/"+ tn); } @@ -484,15 +529,15 @@ public class PEBuilder { } protected void populateByProfile(Base base, PEDefinition definition) { - for (PEDefinition pe : definition.children(true)) { - System.out.println("PopulateByProfile for "+pe.path); - if (pe.fixedValue()) { - if (pe.definition().hasPattern()) { - base.setProperty(pe.schemaName(), pe.definition().getPattern()); - } else { - base.setProperty(pe.schemaName(), pe.definition().getFixed()); - } - } else if (!pe.isSlicer()) { + if (definition.types().size() == 1) { + for (PEDefinition pe : definition.directChildren(true)) { + if (pe.fixedValue()) { + if (pe.definition().hasPattern()) { + base.setProperty(pe.schemaName(), pe.definition().getPattern()); + } else { + base.setProperty(pe.schemaName(), pe.definition().getFixed()); + } + } else if (!pe.isSlicer() && pe.max() == 1) { for (int i = 0; i < pe.min(); i++) { Base b = null; if (pe.schemaName().endsWith("[x]")) { @@ -507,6 +552,7 @@ public class PEBuilder { if (b != null) { populateByProfile(b, pe); } + } } } } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinition.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinition.java index 970a8056a..f185e127b 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinition.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinition.java @@ -1,5 +1,33 @@ package org.hl7.fhir.r5.profilemodel; +/* + 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.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -32,6 +60,7 @@ public abstract class PEDefinition { private boolean mustHaveValue; private boolean inFixedValue; private boolean isSlicer; + private List slices; // if there are some... // /** // * Don't create one of these directly - always use the public methods on ProfiledElementBuilder @@ -77,7 +106,19 @@ public abstract class PEDefinition { * @return The name of the element in the resource (may be different to the slice name) */ public String schemaName() { - return definition.getName(); + String n = definition.getName(); + return n; + } + + /** + * @return The name of the element in the resource (may be different to the slice name) + */ + public String schemaNameWithType() { + String n = definition.getName(); + if (n.endsWith("[x]") && types().size() == 1) { + n = n.replace("[x]", Utilities.capitalize(types.get(0).getType())); + } + return n; } /** @@ -249,7 +290,7 @@ public abstract class PEDefinition { public boolean isList() { - return "*".equals(definition.getBase().getMax()); + return "*".equals(definition.getMax()); } @@ -314,6 +355,38 @@ public abstract class PEDefinition { return selfKey; } + + public boolean isPrimitive() { + return types().size() == 1 && builder.getContext().isPrimitiveType(types.get(0).getName()); + } + + + public boolean isBasePrimitive() { + ElementDefinition ed = baseDefinition(); + return ed != null && ed.getType().size() == 1 && builder.getContext().isPrimitiveType(ed.getType().get(0).getWorkingCode()); + } + + + // extensions do something different here + public List directChildren(boolean allFixed) { + return children(allFixed); + } + + + public List getSlices() { + return slices; + } + + + public void setSlices(List slices) { + this.slices = slices; + } + + + public boolean isExtension() { + return false; + } + } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinitionElement.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinitionElement.java index c4cb4475b..916b0928c 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinitionElement.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinitionElement.java @@ -1,5 +1,33 @@ package org.hl7.fhir.r5.profilemodel; +/* + 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.util.List; import org.hl7.fhir.r5.model.CanonicalType; @@ -35,21 +63,21 @@ public class PEDefinitionElement extends PEDefinition { @Override public String fhirpath() { String base = definition.getName().replace("[x]", ""); - if (definition.hasSlicing()) { - // get all the slices - CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder(" or "); + CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder(" or "); + if (getSlices() != null) { + for (PEDefinition slice : getSlices()) { + b.append("("+builder.makeSliceExpression(slice.profile, definition.getSlicing(), slice.definition())+")"); + } + } else if (definition.hasSlicing()) { List slices = builder.listSlices(profile, definition, this); - // list all the fhirpaths for (PEDefinition slice : slices) { b.append("("+builder.makeSliceExpression(profile, definition.getSlicing(), slice.definition())+")"); } - if (b.count() == 0) - return base; - else - return base+".where(("+b.toString()+").not())"; - } else { - return base; } + if (b.count() == 0) + return base; + else + return base+".where(("+b.toString()+").not())"; } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinitionExtension.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinitionExtension.java index bb66d9d8f..7dc468fd8 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinitionExtension.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinitionExtension.java @@ -1,7 +1,37 @@ package org.hl7.fhir.r5.profilemodel; +/* + 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.util.ArrayList; import java.util.List; +import org.hl7.fhir.r5.conformance.profile.ProfileUtilities; import org.hl7.fhir.r5.model.CanonicalType; import org.hl7.fhir.r5.model.ElementDefinition; import org.hl7.fhir.r5.model.ElementDefinition.SlicingRules; @@ -37,6 +67,8 @@ public class PEDefinitionExtension extends PEDefinition { types.add(builder.makeType(t.getWorkingCode())); } } + } else if (ProfileUtilities.isComplexExtension(extension)) { + types.add(builder.makeType(extension.getName(), extension.getUrl())); } else { types.add(builder.makeType("Extension")); } @@ -47,10 +79,14 @@ public class PEDefinitionExtension extends PEDefinition { if (ved.isRequired() || eed.isProhibited()) { children.addAll(builder.listChildren(allFixed, this, extension, ved, typeUrl)); } else { + List slices = builder.listSlices(extension, eed, this); if (eed.getSlicing().getRules() != SlicingRules.CLOSED) { children.addAll(builder.listChildren(allFixed, this, extension, eed, "http://hl7.org/fhir/StructureDefinition/Extension", "value[x]", "url")); + if (!children.isEmpty()) { + children.get(0).setSlices(slices); + } } - children.addAll(builder.listSlices(extension, eed, this)); + children.addAll(slices); } } @@ -66,4 +102,17 @@ public class PEDefinitionExtension extends PEDefinition { public PEDefinitionElementMode mode() { return PEDefinitionElementMode.Extension; } + + public List directChildren(boolean allFixed) { + List children = new ArrayList<>(); + children.addAll(builder.listChildren(allFixed, this, extension, extension.getSnapshot().getElementFirstRep(), "http://hl7.org/fhir/StructureDefinition/Extension")); + return children; + } + + + public boolean isExtension() { + return true; + } + + } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinitionResource.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinitionResource.java index b7a6babe2..c1c497151 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinitionResource.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinitionResource.java @@ -1,5 +1,33 @@ package org.hl7.fhir.r5.profilemodel; +/* + 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.util.List; import org.hl7.fhir.r5.model.StructureDefinition; diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinitionSlice.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinitionSlice.java index a5b6003f5..207b5646d 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinitionSlice.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinitionSlice.java @@ -1,5 +1,33 @@ package org.hl7.fhir.r5.profilemodel; +/* + 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.util.List; import org.hl7.fhir.r5.model.CanonicalType; diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinitionSubExtension.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinitionSubExtension.java index 4b8bcb128..49ebc9721 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinitionSubExtension.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinitionSubExtension.java @@ -1,5 +1,34 @@ package org.hl7.fhir.r5.profilemodel; +/* + 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.util.ArrayList; import java.util.List; import org.hl7.fhir.r5.model.CanonicalType; @@ -48,6 +77,12 @@ public class PEDefinitionSubExtension extends PEDefinition { } return null; } + + public List directChildren(boolean allFixed) { + List children = new ArrayList<>(); + children.addAll(builder.listChildren(allFixed, this, profile, definition, "http://hl7.org/fhir/StructureDefinition/Extension")); + return children; + } @Override protected void makeChildren(String typeUrl, List children, boolean allFixed) { @@ -74,4 +109,9 @@ public class PEDefinitionSubExtension extends PEDefinition { return PEDefinitionElementMode.Extension; } + public boolean isExtension() { + return true; + } + + } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinitionTypeSlice.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinitionTypeSlice.java index 02d44f021..7a9a15cf0 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinitionTypeSlice.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinitionTypeSlice.java @@ -1,5 +1,33 @@ package org.hl7.fhir.r5.profilemodel; +/* + 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.util.List; import org.hl7.fhir.r5.model.CanonicalType; diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEInstance.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEInstance.java index 650a1535e..a139b1ea9 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEInstance.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEInstance.java @@ -1,5 +1,33 @@ package org.hl7.fhir.r5.profilemodel; +/* + 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.util.ArrayList; import java.util.Date; import java.util.List; @@ -8,10 +36,13 @@ import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.r5.model.Base; import org.hl7.fhir.r5.model.BaseDateTimeType; import org.hl7.fhir.r5.model.CodeableConcept; +import org.hl7.fhir.r5.model.Coding; import org.hl7.fhir.r5.model.ContactPoint; import org.hl7.fhir.r5.model.Identifier; import org.hl7.fhir.r5.model.DataType; import org.hl7.fhir.r5.model.DateTimeType; +import org.hl7.fhir.r5.model.DateType; +import org.hl7.fhir.r5.model.Extension; import org.hl7.fhir.r5.model.HumanName; import org.hl7.fhir.r5.context.IWorkerContext; import org.hl7.fhir.r5.model.Address; @@ -19,6 +50,7 @@ import org.hl7.fhir.r5.model.PrimitiveType; import org.hl7.fhir.r5.model.Quantity; import org.hl7.fhir.r5.model.Reference; import org.hl7.fhir.r5.model.Resource; +import org.hl7.fhir.r5.model.StringType; /** * This class provides a profile centric view of a resource, as driven by a profile @@ -109,6 +141,9 @@ public class PEInstance { if (defn.name().equals(name)) { return defn; } + if (defn.name().equals(name+"[x]")) { + return defn; + } } throw new FHIRException("No children with the name '"+name+"'"); } @@ -118,7 +153,7 @@ public class PEInstance { */ public PEInstance makeChild(String name) { PEDefinition child = byName(definition.children(), name); - Base b = data.addChild(child.schemaName()); + Base b = child.isBaseList() || !child.isBasePrimitive() ? data.addChild(child.schemaNameWithType()) : data.makeProperty(child.schemaNameWithType().hashCode(), child.schemaNameWithType()); builder.populateByProfile(b, child); return new PEInstance(builder, child, resource, b, path+"."+child.name()); } @@ -141,10 +176,16 @@ public class PEInstance { /** * remove the nominated child from the resource */ - public boolean removeChild(PEInstance child) { - return data.removeChild(child.definition().schemaName(), child.data); + public void removeChild(PEInstance child) { + data.removeChild(child.definition().schemaName(), child.data); } + public void clear(String name) { + List children = children(name); + for (PEInstance child : children) { + removeChild(child); + } + } public enum PEInstanceDataKind { Resource, Complex, DataType, Primitive @@ -251,4 +292,19 @@ public class PEInstance { public IWorkerContext getContext() { return builder.getContext(); } + + public void addChild(String name, DataType value) { + PEDefinition child = byName(definition.children(), name); + Base b = data.setProperty(child.schemaName(), value); + } + + public void addChild(String name, String value) { + PEDefinition child = byName(definition.children(), name); + Base b = data.setProperty(child.schemaName(), new StringType(value)); + } + + public void addChild(String name, Date value) { + PEDefinition child = byName(definition.children(), name); + Base b = data.setProperty(child.schemaName(), new DateType(value)); + } } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEType.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEType.java index c481eb4e3..002de92bb 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEType.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEType.java @@ -1,5 +1,33 @@ package org.hl7.fhir.r5.profilemodel; +/* + 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. + */ + public class PEType { private String name; private String type; diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/gen/PECodeGenerator.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/gen/PECodeGenerator.java index 70f1f6aa4..f7ee1744e 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/gen/PECodeGenerator.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/gen/PECodeGenerator.java @@ -1,10 +1,39 @@ package org.hl7.fhir.r5.profilemodel.gen; +/* + 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.File; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.List; import java.util.Locale; +import java.util.TimeZone; import java.util.ArrayList; import java.util.Date; @@ -23,14 +52,21 @@ import org.hl7.fhir.r5.profilemodel.PEType; import org.hl7.fhir.utilities.TextFile; import org.hl7.fhir.utilities.Utilities; + public class PECodeGenerator { + + public static final String DEFAULT_DATE() { + SimpleDateFormat sdf = new SimpleDateFormat("EEE, MMM d, yyyy HH:mmZ", new Locale("en", "US")); + sdf.setTimeZone(TimeZone.getTimeZone("UTC")); + return sdf.format(new Date()); + } + + public enum ExtensionPolicy { None, Complexes, Primitives; } - public static final SimpleDateFormat DATE_FORMAT() { - return new SimpleDateFormat("EEE, MMM d, yyyy HH:mmZ", new Locale("en", "US")); - } + private class PEGenClass { private String name; private String base; @@ -44,18 +80,24 @@ public class PECodeGenerator { private StringBuilder copy = new StringBuilder(); private StringBuilder accessors = new StringBuilder(); private StringBuilder hash = new StringBuilder(); - public void genId() { if (isResource) { genField(true, "id", "String", "id", "", false, ""); genAccessors(true, false, "id", "String", "", "String", "String", "Id", "Ids", false, "", false); - genLoad(true, false, "id", "IdType", "", "String", "String", "Id", "Ids", false, false, null); + genLoad(true, false, "id", "id", "IdType", "", "String", "String", "Id", "Ids", false, false, null); + genSave(true, false, "id", "id", "IdType", "", "String", "String", "Id", "Ids", false, false, false, null); genClear(false, "id"); } } - public void write(StringBuilder b) { + public void write(StringBuilder b, String copyright) { w(b); - w(b, "// Generated by the HAPI Java Profile Generator, "+DATE_FORMAT().format(new Date())); + if (copyright != null) { + w(b, "/*"); + w(b, copyright); + w(b, " */"); + w(b); + } + w(b, "// Generated by the HAPI Java Profile Generator, "+genDate); w(b); jdoc(b, doco, 0, true); w(b, "public class "+name+" extends PEGeneratedBase {"); @@ -167,9 +209,11 @@ public class PECodeGenerator { String cname = Utilities.capitalize(name); String csname = Utilities.capitalize(sname); String nn = field.min() == 1 ? "// @NotNull" : ""; + boolean isExtension = field.isExtension(); genField(isPrim, name, ptype, ltype, nn, field.isList(), field.shortDocumentation()); genAccessors(isPrim, isAbstract, name, type, init, ptype, ltype, cname, csname, field.isList(), field.documentation(), field.fixedValue()); - genLoad(isPrim, isAbstract, name, type, init, ptype, ltype, cname, csname, field.isList(), field.fixedValue(), field.types().get(0)); + genLoad(isPrim, isAbstract, name, sname, type, init, ptype, ltype, cname, csname, field.isList(), field.fixedValue(), field.types().get(0)); + genSave(isPrim, isAbstract, name, sname, type, init, ptype, ltype, cname, csname, field.isList(), field.fixedValue(), isExtension, field.types().get(0)); genClear(field.isList(), name); } } else { @@ -179,16 +223,26 @@ public class PECodeGenerator { } private void genClear(boolean list, String name) { - w(clear, " "+name+" = null;"); + if (list) { + w(clear, " "+name+".clear();"); + } else { + w(clear, " "+name+" = null;"); + } } - private void genLoad(boolean isPrim, boolean isAbstract, String name, String type, String init, String ptype, String ltype, String cname, String csname, boolean isList, boolean isFixed, PEType typeInfo) { + + private void genLoad(boolean isPrim, boolean isAbstract, String name, String sname, String type, String init, String ptype, String ltype, String cname, String csname, boolean isList, boolean isFixed, PEType typeInfo) { if (isList) { - w(load, " for (PEInstance item : src.children(\""+name+"\")) {"); + w(load, " for (PEInstance item : src.children(\""+sname+"\")) {"); w(load, " "+name+".add(("+type+") item.asDataType());"); w(load, " }"); } else if (isPrim) { w(load, " if (src.hasChild(\""+name+"\")) {"); - w(load, " "+name+" = (("+type+") src.child(\""+name+"\").asDataType()).getValue();"); + if ("CodeType".equals(type)) { + // might be code or enum + w(load, " "+name+" = src.child(\""+name+"\").asDataType().primitiveValue();"); + } else { + w(load, " "+name+" = (("+type+") src.child(\""+name+"\").asDataType()).getValue();"); + } w(load, " }"); } else if (typeInfo != null && typeInfo.getUrl() != null && !typeInfo.getUrl().startsWith("http://hl7.org/fhir/StructureDefinition")) { w(load, " if (src.hasChild(\""+name+"\")) {"); @@ -201,6 +255,41 @@ public class PECodeGenerator { } } + private void genSave(boolean isPrim, boolean isAbstract, String name, String sname, String type, String init, String ptype, String ltype, String cname, String csname, boolean isList, boolean isFixed, boolean isExtension, PEType typeInfo) { + w(save, " tgt.clear(\""+sname+"\");"); + if (isList) { + w(save, " for ("+type+" item : "+name+") {"); + if (isExtension) { + w(save, " tgt.makeChild(\""+sname+"\").data().setProperty(\"value[x]\", item);"); + } else { + w(save, " tgt.addChild(\""+sname+"\", item);"); + } + w(save, " }"); + } else if (isPrim) { + w(save, " if ("+name+" != null) {"); + if (isExtension) { + w(save, " tgt.makeChild(\""+sname+"\").data().setProperty(\"value[x]\", new "+type+"("+name+"));"); + } else if (Utilities.existsInList(type, "DateType", "InstantType", "DateTimeType")) { + w(save, " tgt.addChild(\""+sname+"\", new "+type+"("+name+"));"); + } else { + w(save, " tgt.makeChild(\""+sname+"\").data().setProperty(\"value\", new "+type+"("+name+"));"); + } + w(save, " }"); + } else if (typeInfo != null && typeInfo.getUrl() != null && !typeInfo.getUrl().startsWith("http://hl7.org/fhir/StructureDefinition")) { + w(save, " if ("+name+" != null) {"); + w(save, " "+name+".save(tgt.makeChild(\""+sname+"\"), nulls);"); + w(save, " }"); + } else if (isExtension) { + w(save, " if ("+name+" != null) {"); + w(save, " tgt.makeChild(\""+sname+"\").data().setProperty(\"value[x]\", "+name+");"); + w(save, " }"); + } else { + w(save, " if ("+name+" != null) {"); + w(save, " tgt.addChild(\""+sname+"\", "+name+");"); + w(save, " }"); + } + } + private void genAccessors(boolean isPrim, boolean isAbstract, String name, String type, String init, String ptype, String ltype, String cname, String csname, boolean isList, String shortDoco, boolean isFixed) { jdoc(accessors, doco, 2, true); if (isPrim && extensionPolicy != ExtensionPolicy.Primitives && !isList) { @@ -294,6 +383,8 @@ public class PECodeGenerator { // jdoc(fields, field.documentation(), 2, true); if (isPrim && extensionPolicy != ExtensionPolicy.Primitives && !isList) { w(fields, " private "+ptype+" "+name+";"+nn+" // "+shortDoco); + } else if (isList) { + w(fields, " private "+ltype+" "+name+" = new ArrayList<>();"+nn+" // "+shortDoco); } else { w(fields, " private "+ltype+" "+name+";"+nn+" // "+shortDoco); } @@ -311,7 +402,9 @@ public class PECodeGenerator { private boolean contained; private boolean meta; private String language; - private boolean keyELementsOnly; + private boolean keyElementsOnly; + private String genDate = DEFAULT_DATE(); + public PECodeGenerator(IWorkerContext workerContext) { super(); @@ -377,12 +470,12 @@ public class PECodeGenerator { this.language = language; } - public boolean isKeyELementsOnly() { - return keyELementsOnly; + public boolean isKeyElementsOnly() { + return keyElementsOnly; } - public void setKeyELementsOnly(boolean keyELementsOnly) { - this.keyELementsOnly = keyELementsOnly; + public void setKeyElementsOnly(boolean keyElementsOnly) { + this.keyElementsOnly = keyElementsOnly; } public boolean isContained() { @@ -393,6 +486,14 @@ public class PECodeGenerator { this.contained = contained; } + public String getGenDate() { + return genDate; + } + + public void setGenDate(String genDate) { + this.genDate = genDate; + } + private StringBuilder imports = new StringBuilder(); /** @@ -420,7 +521,7 @@ public class PECodeGenerator { jdoc(b, source.getProfile().getCopyright(), 0, false); } w(b, imports.toString()); - cls.write(b); + cls.write(b, source.getProfile().getCopyright()); TextFile.stringToFile(b.toString(), Utilities.path(folder, cls.name+".java")); } @@ -498,7 +599,7 @@ public class PECodeGenerator { if (child.definition().getBase().getPath().equals("DomainResource.contained")) { return contained; } - return !keyELementsOnly || (child.isKeyElement()); + return !keyElementsOnly || (child.isKeyElement()); } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/gen/PEGeneratedBase.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/gen/PEGeneratedBase.java index f576261ab..4043f6f7a 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/gen/PEGeneratedBase.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/gen/PEGeneratedBase.java @@ -1,5 +1,33 @@ package org.hl7.fhir.r5.profilemodel.gen; +/* + 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 org.hl7.fhir.r5.context.IWorkerContext; import org.hl7.fhir.r5.model.Base; import org.hl7.fhir.r5.profilemodel.PEInstance; diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/gen/ProfileExample.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/gen/ProfileExample.java deleted file mode 100644 index a966abe1e..000000000 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/gen/ProfileExample.java +++ /dev/null @@ -1,232 +0,0 @@ -package org.hl7.fhir.r5.profilemodel.gen; - -import java.util.ArrayList; -import java.util.List; - -import org.hl7.fhir.r5.context.IWorkerContext; -import org.hl7.fhir.r5.model.CodeType; -import org.hl7.fhir.r5.model.CodeableConcept; -import org.hl7.fhir.r5.model.Coding; -import org.hl7.fhir.r5.model.Enumerations.ObservationStatus; -import org.hl7.fhir.r5.model.Observation; -import org.hl7.fhir.r5.model.StringType; -import org.hl7.fhir.r5.profilemodel.PEBuilder; -import org.hl7.fhir.r5.profilemodel.PEBuilder.PEElementPropertiesPolicy; -import org.hl7.fhir.r5.profilemodel.PEInstance; - -/** - * This class is a manually written example of the code that a POJO code - * generator for Profiles would produce - * - * Should you generate code? If you can bind at compile time, then you should. - * If you can't - and most systems can't, given the nature of profiles, then - * you should use PEInstance directly - * - * @author grahamegrieve - * - */ -public class ProfileExample extends PEGeneratedBase { - - public enum LOINCCodesForCholesterolInSerumPlasma { - L14647_2, L2093_3, L35200_5, L9342_7; - - public String getCode() { - switch (this) { - case L14647_2: return "14647-2"; - case L2093_3: return "2093-3"; - case L35200_5: return "35200-5"; - case L9342_7: return "9342-7"; - } - return null; - } - - public String getDisplay() { - switch (this) { - case L14647_2: return "Cholesterol [Moles/Volume]"; - case L2093_3: return "Cholesterol [Mass/Volume]"; - case L35200_5: return "Cholesterol [Mass Or Moles/Volume]"; - case L9342_7: return "Cholesterol [Percentile]"; - } - return null; - } - - public static LOINCCodesForCholesterolInSerumPlasma fromCode(String code) { - if (code != null) { - switch (code) { - case "14647-2": return L14647_2; - case "2093-3": return L2093_3; - case "35200-5": return L35200_5; - case "9342-7": return L9342_7; - } - } - return null; - } - } - - - public static class ProfileExampleComplexSlice3 extends PEGeneratedBase { - private ProfileExampleComplexSlice3(PEInstance instance) { - super(); - this.instance = instance; - } - - public List getSlice3a() { - List res = new ArrayList<>(); - for (PEInstance pe : instance.children("slice3a")) { - res.add((Coding) pe.asDataType()); - } - return res; - } - - public boolean hasSlice3a() { - return instance.children("slice3a").size() > 0; - } - - public ProfileExampleComplexSlice3 clearSlice3a() { - removeChildren("slice3a"); - return this; - } - - - public List getSlice3b() { - List res = new ArrayList<>(); - for (PEInstance pe : instance.children("slice3b")) { - res.add((StringType) pe.asDataType()); - } - return res; - } - - public boolean hasSlice3b() { - return instance.children("slice3b").size() > 0; - } - - public ProfileExampleComplexSlice3 clearSlice3b() { - removeChildren("slice3b"); - return this; - } - } - - public static class ProfileExampleComplex extends PEGeneratedBase { - private ProfileExampleComplex(PEInstance instance) { - super(); - this.instance = instance; - } - - public List getSlice1() { - List res = new ArrayList<>(); - for (PEInstance pe : instance.children("slice1")) { - res.add((Coding) pe.asDataType()); - } - return res; - } - - public boolean hasSlice1() { - return instance.children("slice1").size() > 0; - } - - public ProfileExampleComplex clearSlice1() { - removeChildren("slice1"); - return this; - } - - public List getSlice2() { - List res = new ArrayList<>(); - for (PEInstance pe : instance.children("slice2")) { - res.add((StringType) pe.asDataType()); - } - return res; - } - - public boolean hasSlice2() { - return instance.children("slice2").size() > 0; - } - - public ProfileExampleComplex clearSlice2() { - removeChildren("slice1"); - return this; - } - - public ProfileExampleComplexSlice3 getSlice3() { - PEInstance pe = instance.forceChild("slice3"); - return new ProfileExampleComplexSlice3(pe); - } - - public boolean hasComplex() { - return instance.child("slice3") != null; - } - - public ProfileExampleComplex clearComplex() { - removeChild("slice3"); - return this; - } - - } - - public ProfileExample(IWorkerContext context, Observation observation) { - super(); - PEBuilder builder = new PEBuilder(context, PEElementPropertiesPolicy.EXTENSION_ID, true); - instance = builder.buildPEInstance("http://hl7.org/fhir/test/StructureDefinition/pe-profile1", "0.1", observation); - } - - /** - * this is public for testing purposes, but you generally shouldn't use it. If you do, make - * sure the parameters are (PEElementPropertiesPolicy.EXTENSION_ID, true) when building the PEBuilder - * - * @param instance - */ - public ProfileExample(PEInstance instance) { - super(); - this.instance = instance; - } - - /** - * @return fixed value "final" - */ - public ObservationStatus getStatus() { - return ObservationStatus.FINAL; - } - - public CodeableConcept getCode() { - return instance.forceChild("code").asCodeableConcept(); - } - - /** - * Extension http://hl7.org/fhir/test/StructureDefinition/pe-extension-simple, type code - * @return - */ - public LOINCCodesForCholesterolInSerumPlasma getSimple() { - return LOINCCodesForCholesterolInSerumPlasma.fromCode(((CodeType) instance.forceChild("simple").asDataType()).primitiveValue()); - } - - public boolean hasSimple() { - return instance.child("simple") != null; - } - - public ProfileExample clearSimple() { - removeChild("simple"); - return this; - } - - public ProfileExampleComplex getComplex() { - PEInstance pe = instance.child("complex"); - return new ProfileExampleComplex(pe); - } - - public boolean hasComplex() { - return instance.child("complex") != null; - } - - public ProfileExample clearComplex() { - removeChild("complex"); - return this; - } - - /* - * this doesn't exist, because of the way infrastructure works. - * You get the value and set the properties - */ -// public void setSimple() { -// return (CodeType) instance.forceChild("simple").asDataType(); -// } - -} diff --git a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/profiles/GeneratedPEModelTest.java b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/profiles/GeneratedPEModelTest.java new file mode 100644 index 000000000..b033a8c28 --- /dev/null +++ b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/profiles/GeneratedPEModelTest.java @@ -0,0 +1,82 @@ +package org.hl7.fhir.r5.profiles; + + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import org.hl7.fhir.exceptions.FHIRException; +import org.hl7.fhir.r5.context.IWorkerContext; +import org.hl7.fhir.r5.model.CodeableConcept; +import org.hl7.fhir.r5.model.Identifier; +import org.hl7.fhir.r5.model.Observation; +import org.hl7.fhir.r5.model.Patient; +import org.hl7.fhir.r5.model.Reference; +import org.hl7.fhir.r5.context.SimpleWorkerContext; +import org.hl7.fhir.r5.formats.IParser.OutputStyle; +import org.hl7.fhir.r5.formats.JsonParser; +import org.hl7.fhir.r5.formats.XmlParser; +import org.hl7.fhir.r5.profilemodel.PEBuilder; +import org.hl7.fhir.r5.test.utils.CompareUtilities; +import org.hl7.fhir.r5.test.utils.TestPackageLoader; +import org.hl7.fhir.r5.test.utils.TestingUtilities; +import org.hl7.fhir.utilities.Utilities; +import org.hl7.fhir.utilities.npm.NpmPackage; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager; + +public class GeneratedPEModelTest { + + private IWorkerContext ctxt; + + public void load() throws Exception { + if (ctxt == null) { + ctxt = TestingUtilities.getSharedWorkerContext(); + FilesystemPackageCacheManager pc = new FilesystemPackageCacheManager(true); + NpmPackage npm = pc.loadPackage("hl7.fhir.us.core", "5.0.0"); + ctxt.loadFromPackage(npm, new TestPackageLoader(Utilities.strings("StructureDefinition" ))); + + ctxt.cacheResource(new JsonParser().parse(TestingUtilities.loadTestResource("r5", "profiles", "pe-extension-simple.json"))); + ctxt.cacheResource(new JsonParser().parse(TestingUtilities.loadTestResource("r5", "profiles", "pe-extension-complex.json"))); + ctxt.cacheResource(new JsonParser().parse(TestingUtilities.loadTestResource("r5", "profiles", "pe-profile2.json"))); + ctxt.cacheResource(new JsonParser().parse(TestingUtilities.loadTestResource("r5", "profiles", "pe-profile1.json"))); + } + } + + @Test + public void testPEGenLoad() throws Exception { + load(); + Observation obs = (Observation) new XmlParser().parse(TestingUtilities.loadTestResourceStream("r5", "profiles", "pe-instance.xml")); + TestProfile tp = TestProfile.fromSource(ctxt, obs); + Assertions.assertEquals("pe-instance", tp.getId()); + Assertions.assertNotNull(tp); + Assertions.assertEquals("pe-instance", tp.getId()); + Assertions.assertEquals("something", tp.getIdentifier().getValue()); + Assertions.assertEquals("final", tp.getStatus()); + Assertions.assertEquals("Sexual Orientation", tp.getCode().getText()); + Assertions.assertEquals("Patient/us-example", tp.getSubject().getReference()); + Assertions.assertNull(tp.getEncounter().getReference()); + Assertions.assertNotNull(tp.getEffective()); + Assertions.assertEquals(0, tp.getPerformers().size()); + TestDatatypeProfile dt = tp.getValueCodeableConcept(); + Assertions.assertNotNull(dt); + Assertions.assertEquals("42035005", dt.getSnomedct().getCode()); + Assertions.assertEquals("LA22876-9", dt.getLoinc().getCode()); + Assertions.assertFalse(dt.hasCoding()); + + Assertions.assertEquals("code", tp.getSimple()); + Assertions.assertEquals("14647-2", tp.getComplex().getSlice1().getCode()); + Assertions.assertEquals("something", tp.getComplex().getSlice2s().get(0).getValue()); + Assertions.assertEquals(0, tp.getComplex().getExtensions().size()); + + Observation tgt = tp.build(ctxt); + new XmlParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(Utilities.path("[tmp]", "pe-instance-gen.xml")), tgt); + + String msg = CompareUtilities.checkXMLIsSame(TestingUtilities.loadTestResourceStream("r5", "profiles", "pe-instance.xml"), new FileInputStream(Utilities.path("[tmp]", "pe-instance-gen.xml"))); + Assertions.assertNull(msg, msg); + } + +} diff --git a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/profiles/PETests.java b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/profiles/PETests.java index a8d999ec6..ffeb63f83 100644 --- a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/profiles/PETests.java +++ b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/profiles/PETests.java @@ -1,7 +1,39 @@ package org.hl7.fhir.r5.profiles; +/* + 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.File; +import java.io.FileNotFoundException; import java.io.IOException; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; import java.util.List; import org.hl7.fhir.r5.context.IWorkerContext; @@ -16,15 +48,12 @@ import org.hl7.fhir.r5.profilemodel.PEInstance; import org.hl7.fhir.r5.profilemodel.PEType; import org.hl7.fhir.r5.profilemodel.gen.PECodeGenerator; import org.hl7.fhir.r5.profilemodel.gen.PECodeGenerator.ExtensionPolicy; -import org.hl7.fhir.r5.profilemodel.gen.ProfileExample; -import org.hl7.fhir.r5.profilemodel.gen.ProfileExample.LOINCCodesForCholesterolInSerumPlasma; -import org.hl7.fhir.r5.profilemodel.gen.ProfileExample.ProfileExampleComplex; -import org.hl7.fhir.r5.profilemodel.gen.ProfileExample.ProfileExampleComplexSlice3; import org.hl7.fhir.r5.profilemodel.PEBuilder; import org.hl7.fhir.r5.profilemodel.PEBuilder.PEElementPropertiesPolicy; import org.hl7.fhir.r5.profilemodel.PEInstance.PEInstanceDataKind; import org.hl7.fhir.r5.test.utils.TestPackageLoader; import org.hl7.fhir.r5.test.utils.TestingUtilities; +import org.hl7.fhir.utilities.TextFile; import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager; import org.hl7.fhir.utilities.npm.NpmPackage; @@ -78,7 +107,7 @@ public class PETests { checkElement(children.get(4), "contained", "contained", 0, Integer.MAX_VALUE, false, "http://hl7.org/fhir/StructureDefinition/Resource", 4, "contained"); checkElement(children.get(5), "extension", "extension", 0, Integer.MAX_VALUE, false, "http://hl7.org/fhir/StructureDefinition/Extension", 3, "extension.where(((url = 'http://hl7.org/fhir/test/StructureDefinition/pe-extension-simple') or (url = 'http://hl7.org/fhir/test/StructureDefinition/pe-extension-complex')).not())"); checkElement(children.get(6), "extension", "simple", 0, 1, false, "http://hl7.org/fhir/StructureDefinition/code", 2, "extension('http://hl7.org/fhir/test/StructureDefinition/pe-extension-simple').value"); - checkElement(children.get(7), "extension", "complex", 0, 1, false, "http://hl7.org/fhir/StructureDefinition/Extension", 4, "extension('http://hl7.org/fhir/test/StructureDefinition/pe-extension-complex')"); + checkElement(children.get(7), "extension", "complex", 0, 1, false, "http://hl7.org/fhir/test/StructureDefinition/pe-extension-complex", 4, "extension('http://hl7.org/fhir/test/StructureDefinition/pe-extension-complex')"); checkElement(children.get(8), "identifier", "identifier", 0, 1, false, "http://hl7.org/fhir/StructureDefinition/Identifier", 7, "identifier"); checkElement(children.get(9), "status", "status", 1, 1, true, "http://hl7.org/fhir/StructureDefinition/code", 2, "status"); checkElement(children.get(10), "category", "category", 0, Integer.MAX_VALUE, false, "http://hl7.org/fhir/StructureDefinition/CodeableConcept", 3, "category"); @@ -107,7 +136,7 @@ public class PETests { checkElement(ggchildren.get(1), "value", "value", 1, 1, false, null, 3, "value"); gchildren = children.get(7).children("http://hl7.org/fhir/StructureDefinition/Extension"); - checkElement(gchildren.get(0), "extension", "extension", 0, Integer.MAX_VALUE, false, "http://hl7.org/fhir/StructureDefinition/Extension", 3, "extension"); + checkElement(gchildren.get(0), "extension", "extension", 0, Integer.MAX_VALUE, false, "http://hl7.org/fhir/StructureDefinition/Extension", 3, "extension.where(((url = 'slice1') or (url = 'slice2') or (url = 'slice3')).not())"); checkElement(gchildren.get(1), "extension", "slice1", 0, 2, false, "http://hl7.org/fhir/StructureDefinition/Coding", 6, "extension('slice1').value"); checkElement(gchildren.get(2), "extension", "slice2", 0, Integer.MAX_VALUE, false, "http://hl7.org/fhir/StructureDefinition/string", 2, "extension('slice2').value"); checkElement(gchildren.get(3), "extension", "slice3", 1, 1, false, "http://hl7.org/fhir/StructureDefinition/Extension", 3, "extension('slice3')"); @@ -171,7 +200,7 @@ public class PETests { Assertions.assertEquals("extension", pe.schemaName()); Assertions.assertEquals(0, pe.min()); Assertions.assertEquals(1, pe.max()); - Assertions.assertEquals("Extension", pe.types().get(0).getName()); + Assertions.assertEquals("USCoreEthnicityExtension", pe.types().get(0).getName()); Assertions.assertNotNull(pe.definition()); Assertions.assertNotNull(pe.baseDefinition()); Assertions.assertEquals("US Core ethnicity Extension", pe.shortDocumentation()); @@ -359,36 +388,41 @@ public class PETests { PEInstance slice3 = complex.child("slice3"); Assertions.assertNotNull(slice3); Assertions.assertEquals("TestProfile.complex.slice3", slice3.getPath()); - - ProfileExample ex = new ProfileExample(obs); - Assertions.assertEquals(ObservationStatus.FINAL, ex.getStatus()); - Assertions.assertEquals("76690-7", ex.getCode().getCodingFirstRep().getCode()); - Assertions.assertEquals(LOINCCodesForCholesterolInSerumPlasma.L14647_2, ex.getSimple()); - ProfileExampleComplex cplx = ex.getComplex(); - Assertions.assertNotNull(cplx); - Assertions.assertEquals("18767-4", cplx.getSlice1().get(0).getCode()); - Assertions.assertEquals("A string value", cplx.getSlice2().get(0).primitiveValue()); - ProfileExampleComplexSlice3 sl3 = cplx.getSlice3(); - Assertions.assertEquals("56874-1", sl3.getSlice3a().get(0).getCode()); - Assertions.assertEquals("Another string value", sl3.getSlice3b().get(0).primitiveValue()); } - @Test public void testGenerate() throws IOException { load(); PECodeGenerator gen = new PECodeGenerator(ctxt); + gen.setFolder(Utilities.path("[tmp]")); - gen.setCanonical("http://hl7.org/fhir/test/StructureDefinition/pe-profile1"); - gen.setPkgName("org.hl7.fhir.r5.profiles"); - gen.setExtensionPolicy(ExtensionPolicy.None); + gen.setExtensionPolicy(ExtensionPolicy.Complexes); gen.setNarrative(false); gen.setMeta(false); gen.setLanguage("en-AU"); gen.setContained(false); - gen.setKeyELementsOnly(true); + gen.setKeyElementsOnly(true); + gen.setGenDate("{date}"); + + gen.setCanonical("http://hl7.org/fhir/test/StructureDefinition/pe-profile1"); + gen.setPkgName("org.hl7.fhir.r5.profiles"); gen.execute(); gen.setCanonical("http://hl7.org/fhir/test/StructureDefinition/pe-profile2"); gen.execute(); + gen.setCanonical("http://hl7.org/fhir/test/StructureDefinition/pe-extension-complex"); + gen.execute(); + + checkGeneratedJava("TestComplexExtension"); + checkGeneratedJava("TestDatatypeProfile"); + checkGeneratedJava("TestProfile"); + } + + + private void checkGeneratedJava(String name) throws FileNotFoundException, IOException { + String actual = TextFile.fileToString(Utilities.path("[tmp]", name+".java")); + String expected = TestingUtilities.loadTestResource("r5", "profiles", name+".java"); + if (!actual.equals(expected)) { + Assertions.fail("Generated code for "+name+" is different"); + } } } diff --git a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/profiles/TestComplexExtension.java b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/profiles/TestComplexExtension.java new file mode 100644 index 000000000..2a9da7618 --- /dev/null +++ b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/profiles/TestComplexExtension.java @@ -0,0 +1,218 @@ +package org.hl7.fhir.r5.profiles; + +import java.util.List; +import java.util.ArrayList; +import javax.annotation.Nullable; +import java.util.Date; + + +import org.hl7.fhir.r5.context.IWorkerContext; +import org.hl7.fhir.r5.model.*; +import org.hl7.fhir.r5.profilemodel.PEBuilder; +import org.hl7.fhir.r5.profilemodel.PEInstance; +import org.hl7.fhir.r5.profilemodel.PEBuilder.PEElementPropertiesPolicy; +import org.hl7.fhir.r5.profilemodel.gen.PEGeneratedBase; +import java.util.List; +import java.util.ArrayList; +import javax.annotation.Nullable; +import java.util.Date; + + +import org.hl7.fhir.r5.context.IWorkerContext; +import org.hl7.fhir.r5.model.*; +import org.hl7.fhir.r5.profilemodel.PEBuilder; +import org.hl7.fhir.r5.profilemodel.PEInstance; +import org.hl7.fhir.r5.profilemodel.PEBuilder.PEElementPropertiesPolicy; +import org.hl7.fhir.r5.profilemodel.gen.PEGeneratedBase; +import java.util.List; +import java.util.ArrayList; +import javax.annotation.Nullable; +import java.util.Date; + + +import org.hl7.fhir.r5.context.IWorkerContext; +import org.hl7.fhir.r5.model.*; +import org.hl7.fhir.r5.profilemodel.PEBuilder; +import org.hl7.fhir.r5.profilemodel.PEInstance; +import org.hl7.fhir.r5.profilemodel.PEBuilder.PEElementPropertiesPolicy; +import org.hl7.fhir.r5.profilemodel.gen.PEGeneratedBase; + + +// Generated by the HAPI Java Profile Generator, Tue, Sep 26, 2023 00:00+1000 + +/** + * A complex extension - an extension with 2 levels + * + */ +public class TestComplexExtension extends PEGeneratedBase { + + private static final String CANONICAL_URL = "http://hl7.org/fhir/test/StructureDefinition/pe-extension-complex|0.1"; + + private List extensions = new ArrayList<>();// @NotNull // Additional content defined by implementations + private Coding slice1; // A code + private List slice2s = new ArrayList<>(); // More Details + private Extension slice3;// @NotNull // Justification Details + + /** + * Parameter-less constructor. If you use this, the fixed values won't be filled + * out - they'll be missing. They'll be filled in if/when you call build, so they + * won't be missing from the resource, only from this particular object model + * + */ + public TestComplexExtension() { + // todo + } + + /** + * Used when loading other models + * + */ + public static TestComplexExtension fromSource(PEInstance source) { + TestComplexExtension theThing = new TestComplexExtension(); + theThing.workerContext = source.getContext(); + theThing.load(source); + return theThing; + } + + public void load(PEInstance src) { + clear(); + for (PEInstance item : src.children("extension")) { + extensions.add((Extension) item.asDataType()); + } + if (src.hasChild("slice1")) { + slice1 = (Coding) src.child("slice1").asDataType(); + } + for (PEInstance item : src.children("slice2")) { + slice2s.add((StringType) item.asDataType()); + } + if (src.hasChild("slice3")) { + slice3 = (Extension) src.child("slice3").asDataType(); + } + + } + + public void save(PEInstance tgt, boolean nulls) { + tgt.clear("extension"); + for (Extension item : extensions) { + tgt.addChild("extension", item); + } + tgt.clear("slice1"); + if (slice1 != null) { + tgt.makeChild("slice1").data().setProperty("value[x]", slice1); + } + tgt.clear("slice2"); + for (StringType item : slice2s) { + tgt.makeChild("slice2").data().setProperty("value[x]", item); + } + tgt.clear("slice3"); + if (slice3 != null) { + tgt.makeChild("slice3").data().setProperty("value[x]", slice3); + } + + } + + /** + * A complex extension - an extension with 2 levels + * + */ + public List getExtensions() { + if (extensions == null) { extensions = new ArrayList<>(); } + return extensions; + } + + public boolean hasExtensions() { + return extensions != null && !extensions.isEmpty(); + } + + public Extension addExtension() { + Extension theThing = new Extension(); + getExtensions().add(theThing); + return theThing; + } + + public boolean hasExtension(Extension item) { + return hasExtensions() && extensions.contains(item); + } + + public void removeExtension(Extension item) { + if (hasExtension(item)) { + extensions.remove(item); + } + } + + + /** + * A complex extension - an extension with 2 levels + * + */ + public Coding getSlice1() { + if (slice1 == null) { slice1 = new Coding(); } + return slice1; + } + + public TestComplexExtension setSlice1(Coding value) { + this.slice1 = value; + return this; + } + public boolean hasSlice1() { + return slice1 != null; + } + + /** + * A complex extension - an extension with 2 levels + * + */ + public List getSlice2s() { + if (slice2s == null) { slice2s = new ArrayList<>(); } + return slice2s; + } + + public boolean hasSlice2s() { + return slice2s != null && !slice2s.isEmpty(); + } + + public StringType addSlice2() { + StringType theThing = new StringType(); + getSlice2s().add(theThing); + return theThing; + } + + public boolean hasSlice2(StringType item) { + return hasSlice2s() && slice2s.contains(item); + } + + public void removeSlice2(StringType item) { + if (hasSlice2(item)) { + slice2s.remove(item); + } + } + + + /** + * A complex extension - an extension with 2 levels + * + */ + public Extension getSlice3() { + if (slice3 == null) { slice3 = new Extension(); } + return slice3; + } + + public TestComplexExtension setSlice3(Extension value) { + this.slice3 = value; + return this; + } + public boolean hasSlice3() { + return slice3 != null; + } + + + + public void clear() { + extensions.clear(); + slice1 = null; + slice2s.clear(); + slice3 = null; + + } + +} diff --git a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/profiles/TestDatatypeProfile.java b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/profiles/TestDatatypeProfile.java index 018dacfc5..acdad868a 100644 --- a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/profiles/TestDatatypeProfile.java +++ b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/profiles/TestDatatypeProfile.java @@ -36,9 +36,9 @@ public class TestDatatypeProfile extends PEGeneratedBase { private static final String CANONICAL_URL = "http://hl7.org/fhir/test/StructureDefinition/pe-profile2|0.1"; - private List codings;// @NotNull // Code defined by a terminology system - private List snomedcts;// @NotNull // Code defined by a terminology system - private List loincs; // Code defined by a terminology system + private Coding coding;// @NotNull // Code defined by a terminology system + private Coding snomedct;// @NotNull // Code defined by a terminology system + private Coding loinc; // Code defined by a terminology system private String text;// @NotNull // Plain text representation of the concept /** @@ -64,14 +64,14 @@ public class TestDatatypeProfile extends PEGeneratedBase { public void load(PEInstance src) { clear(); - for (PEInstance item : src.children("codings")) { - codings.add((Coding) item.asDataType()); + if (src.hasChild("coding")) { + coding = (Coding) src.child("coding").asDataType(); } - for (PEInstance item : src.children("snomedcts")) { - snomedcts.add((Coding) item.asDataType()); + if (src.hasChild("snomedct")) { + snomedct = (Coding) src.child("snomedct").asDataType(); } - for (PEInstance item : src.children("loincs")) { - loincs.add((Coding) item.asDataType()); + if (src.hasChild("loinc")) { + loinc = (Coding) src.child("loinc").asDataType(); } if (src.hasChild("text")) { text = ((StringType) src.child("text").asDataType()).getValue(); @@ -80,6 +80,22 @@ public class TestDatatypeProfile extends PEGeneratedBase { } public void save(PEInstance tgt, boolean nulls) { + tgt.clear("coding"); + if (coding != null) { + tgt.addChild("coding", coding); + } + tgt.clear("snomedct"); + if (snomedct != null) { + tgt.addChild("snomedct", snomedct); + } + tgt.clear("loinc"); + if (loinc != null) { + tgt.addChild("loinc", loinc); + } + tgt.clear("text"); + if (text != null) { + tgt.makeChild("text").data().setProperty("value", new StringType(text)); + } } @@ -87,92 +103,53 @@ public class TestDatatypeProfile extends PEGeneratedBase { * Test CodeableConcept Profile. * */ - public List getCodings() { - if (codings == null) { codings = new ArrayList<>(); } - return codings; + public Coding getCoding() { + if (coding == null) { coding = new Coding(); } + return coding; } - public boolean hasCodings() { - return codings != null && !codings.isEmpty(); + public TestDatatypeProfile setCoding(Coding value) { + this.coding = value; + return this; } - - public Coding addCoding() { - Coding theThing = new Coding(); - getCodings().add(theThing); - return theThing; + public boolean hasCoding() { + return coding != null; } - public boolean hasCoding(Coding item) { - return hasCodings() && codings.contains(item); - } - - public void removeCoding(Coding item) { - if (hasCoding(item)) { - codings.remove(item); - } - } - - /** * Test CodeableConcept Profile. * */ - public List getSnomedcts() { - if (snomedcts == null) { snomedcts = new ArrayList<>(); } - return snomedcts; + public Coding getSnomedct() { + if (snomedct == null) { snomedct = new Coding(); } + return snomedct; } - public boolean hasSnomedcts() { - return snomedcts != null && !snomedcts.isEmpty(); + public TestDatatypeProfile setSnomedct(Coding value) { + this.snomedct = value; + return this; } - - public Coding addSnomedct() { - Coding theThing = new Coding(); - getSnomedcts().add(theThing); - return theThing; + public boolean hasSnomedct() { + return snomedct != null; } - public boolean hasSnomedct(Coding item) { - return hasSnomedcts() && snomedcts.contains(item); - } - - public void removeSnomedct(Coding item) { - if (hasSnomedct(item)) { - snomedcts.remove(item); - } - } - - /** * Test CodeableConcept Profile. * */ - public List getLoincs() { - if (loincs == null) { loincs = new ArrayList<>(); } - return loincs; + public Coding getLoinc() { + if (loinc == null) { loinc = new Coding(); } + return loinc; } - public boolean hasLoincs() { - return loincs != null && !loincs.isEmpty(); + public TestDatatypeProfile setLoinc(Coding value) { + this.loinc = value; + return this; } - - public Coding addLoinc() { - Coding theThing = new Coding(); - getLoincs().add(theThing); - return theThing; + public boolean hasLoinc() { + return loinc != null; } - public boolean hasLoinc(Coding item) { - return hasLoincs() && loincs.contains(item); - } - - public void removeLoinc(Coding item) { - if (hasLoinc(item)) { - loincs.remove(item); - } - } - - /** * Test CodeableConcept Profile. * @@ -193,9 +170,9 @@ public class TestDatatypeProfile extends PEGeneratedBase { public void clear() { - codings = null; - snomedcts = null; - loincs = null; + coding = null; + snomedct = null; + loinc = null; text = null; } diff --git a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/profiles/TestProfile.java b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/profiles/TestProfile.java index 47c0863a1..129bf97a4 100644 --- a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/profiles/TestProfile.java +++ b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/profiles/TestProfile.java @@ -37,13 +37,16 @@ public class TestProfile extends PEGeneratedBase { private static final String CANONICAL_URL = "http://hl7.org/fhir/test/StructureDefinition/pe-profile1|0.1"; private String id; // - private List identifiers; // Business Identifier for observation + private List extensions = new ArrayList<>(); // Extension + private String simple; // A simple extension + private TestComplexExtension complex; // A complex extension + private Identifier identifier; // Business Identifier for observation private String status;// @NotNull // registered | preliminary | final | amended + private CodeableConcept code;// @NotNull // Sexual Orientation private Reference subject;// @NotNull // Who and/or what the observation is about private Reference encounter; // Healthcare event during which this observation is made private Date effective;// @NotNull // Clinically relevant time/time-period for observation - private List performers; // Who is responsible for the observation + private List performers = new ArrayList<>(); // Who is responsible for the observation private TestDatatypeProfile valueCodeableConcept; // Sexual Orientation /** @@ -86,11 +89,20 @@ public class TestProfile extends PEGeneratedBase { if (src.hasChild("id")) { id = ((IdType) src.child("id").asDataType()).getValue(); } - for (PEInstance item : src.children("identifiers")) { - identifiers.add((Identifier) item.asDataType()); + for (PEInstance item : src.children("extension")) { + extensions.add((Extension) item.asDataType()); + } + if (src.hasChild("simple")) { + simple = src.child("simple").asDataType().primitiveValue(); + } + if (src.hasChild("complex")) { + complex = TestComplexExtension.fromSource(src.child("complex")); + } + if (src.hasChild("identifier")) { + identifier = (Identifier) src.child("identifier").asDataType(); } if (src.hasChild("status")) { - status = ((CodeType) src.child("status").asDataType()).getValue(); + status = src.child("status").asDataType().primitiveValue(); } if (src.hasChild("code")) { code = (CodeableConcept) src.child("code").asDataType(); @@ -104,7 +116,7 @@ public class TestProfile extends PEGeneratedBase { if (src.hasChild("effective")) { effective = ((DateTimeType) src.child("effective").asDataType()).getValue(); } - for (PEInstance item : src.children("performers")) { + for (PEInstance item : src.children("performer")) { performers.add((Reference) item.asDataType()); } if (src.hasChild("valueCodeableConcept")) { @@ -139,6 +151,54 @@ public class TestProfile extends PEGeneratedBase { } public void save(PEInstance tgt, boolean nulls) { + tgt.clear("id"); + if (id != null) { + tgt.makeChild("id").data().setProperty("value", new IdType(id)); + } + tgt.clear("extension"); + for (Extension item : extensions) { + tgt.addChild("extension", item); + } + tgt.clear("simple"); + if (simple != null) { + tgt.makeChild("simple").data().setProperty("value[x]", new CodeType(simple)); + } + tgt.clear("complex"); + if (complex != null) { + complex.save(tgt.makeChild("complex"), nulls); + } + tgt.clear("identifier"); + if (identifier != null) { + tgt.addChild("identifier", identifier); + } + tgt.clear("status"); + if (status != null) { + tgt.makeChild("status").data().setProperty("value", new StringType(status)); + } + tgt.clear("code"); + if (code != null) { + tgt.addChild("code", code); + } + tgt.clear("subject"); + if (subject != null) { + tgt.addChild("subject", subject); + } + tgt.clear("encounter"); + if (encounter != null) { + tgt.addChild("encounter", encounter); + } + tgt.clear("effective"); + if (effective != null) { + tgt.addChild("effective", new DateTimeType(effective)); + } + tgt.clear("performer"); + for (Reference item : performers) { + tgt.addChild("performer", item); + } + tgt.clear("valueCodeableConcept"); + if (valueCodeableConcept != null) { + valueCodeableConcept.save(tgt.makeChild("valueCodeableConcept"), nulls); + } } @@ -163,32 +223,83 @@ public class TestProfile extends PEGeneratedBase { * Test Observation Profile. * */ - public List getIdentifiers() { - if (identifiers == null) { identifiers = new ArrayList<>(); } - return identifiers; + public List getExtensions() { + if (extensions == null) { extensions = new ArrayList<>(); } + return extensions; } - public boolean hasIdentifiers() { - return identifiers != null && !identifiers.isEmpty(); + public boolean hasExtensions() { + return extensions != null && !extensions.isEmpty(); } - public Identifier addIdentifier() { - Identifier theThing = new Identifier(); - getIdentifiers().add(theThing); + public Extension addExtension() { + Extension theThing = new Extension(); + getExtensions().add(theThing); return theThing; } - public boolean hasIdentifier(Identifier item) { - return hasIdentifiers() && identifiers.contains(item); + public boolean hasExtension(Extension item) { + return hasExtensions() && extensions.contains(item); } - public void removeIdentifier(Identifier item) { - if (hasIdentifier(item)) { - identifiers.remove(item); + public void removeExtension(Extension item) { + if (hasExtension(item)) { + extensions.remove(item); } } + /** + * Test Observation Profile. + * + */ + public String getSimple() { + return simple; + } + + public TestProfile setSimple(String value) { + this.simple = value; + return this; + } + + public boolean hasSimple() { + return simple != null; + } + + /** + * Test Observation Profile. + * + */ + public TestComplexExtension getComplex() { + if (complex == null) { complex = new TestComplexExtension(); } + return complex; + } + + public TestProfile setComplex(TestComplexExtension value) { + this.complex = value; + return this; + } + public boolean hasComplex() { + return complex != null; + } + + /** + * Test Observation Profile. + * + */ + public Identifier getIdentifier() { + if (identifier == null) { identifier = new Identifier(); } + return identifier; + } + + public TestProfile setIdentifier(Identifier value) { + this.identifier = value; + return this; + } + public boolean hasIdentifier() { + return identifier != null; + } + /** * Test Observation Profile. * @@ -321,13 +432,16 @@ public class TestProfile extends PEGeneratedBase { public void clear() { id = null; - identifiers = null; + extensions.clear(); + simple = null; + complex = null; + identifier = null; status = null; code = null; subject = null; encounter = null; effective = null; - performers = null; + performers.clear(); valueCodeableConcept = null; }