Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix xml namespace #344

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 31 additions & 4 deletions aom/src/main/java/com/nedap/archie/aom/Archetype.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,18 @@
import com.nedap.archie.definitions.AdlCodeDefinitions;
import com.nedap.archie.query.AOMPathQuery;
import com.nedap.archie.xml.adapters.ArchetypeTerminologyAdapter;
import com.nedap.archie.xml.adapters.StringDictionaryMapAdapter;
import com.nedap.archie.xml.adapters.StringDictionaryUtil;
import com.nedap.archie.xml.types.StringDictionaryItem;

import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import java.util.LinkedHashMap;
Expand Down Expand Up @@ -46,7 +52,7 @@
"buildUid",
"rmRelease",
"generated",
"otherMetaData"
"xmlOtherMetaData"
})
public class Archetype extends AuthoredResource {

Expand All @@ -70,10 +76,31 @@ public class Archetype extends AuthoredResource {
private String rmRelease;
@XmlAttribute(name="is_generated")
private Boolean generated = false;
//this is a specific map type to make a JAXB-adapter work. ugly jaxb
//alternative: define an extra field, use hooks to fill it just in time instead
@XmlTransient
private LinkedHashMap<String, String> otherMetaData = new LinkedHashMap<>();

@XmlElement(name="other_meta_data")
//TODO: this probably requires a custom XmlAdapter
private Map<String, String> otherMetaData = new LinkedHashMap<>();
@JsonIgnore
private List<StringDictionaryItem> xmlOtherMetaData;

// Invoked by Jaxb Marshaller after unmarshalling
public void afterUnmarshal(Unmarshaller unmarshaller, Object parent) {
if(xmlOtherMetaData != null) {
otherMetaData = StringDictionaryUtil.convertStringDictionaryListToStringMap(xmlOtherMetaData);
}
}

// Invoked by Jaxb Marshaller before marshalling
public boolean beforeMarshal(Marshaller marshaller) {
if(otherMetaData == null) {
xmlOtherMetaData = null;
} else {
xmlOtherMetaData = StringDictionaryUtil.convertStringMapIntoStringDictionaryList(otherMetaData);
}
return true;
}

public String getParentArchetypeId() {
return parentArchetypeId;
Expand Down Expand Up @@ -162,7 +189,7 @@ public Map<String, String> getOtherMetaData() {
}

public void setOtherMetaData(Map<String, String> otherMetaData) {
this.otherMetaData = otherMetaData;
this.otherMetaData = new LinkedHashMap<>(otherMetaData);
}

public void addOtherMetadata(String text, String value) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.nedap.archie.base.OpenEHRBase;
import com.nedap.archie.base.terminology.TerminologyCode;

import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

Expand Down
75 changes: 73 additions & 2 deletions aom/src/main/java/com/nedap/archie/aom/OperationalTemplate.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,26 @@
package com.nedap.archie.aom;

import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import com.nedap.archie.aom.terminology.ArchetypeTerm;
import com.nedap.archie.aom.terminology.ArchetypeTerminology;
import com.nedap.archie.aom.utils.AOMUtils;
import com.nedap.archie.paths.PathSegment;
import com.nedap.archie.xml.adapters.ArchetypeTerminologyAdapter;
import com.nedap.archie.xml.adapters.StringDictionaryUtil;
import com.nedap.archie.xml.types.StringDictionaryItem;
import com.nedap.archie.xml.types.XmlArchetypeTerminology;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
Expand All @@ -26,11 +36,72 @@ public class OperationalTemplate extends AuthoredArchetype {
/**
* terminology extracts from subarchetypes, for example snomed codes, multiple choice thingies, etc
*/
@XmlElement(name="terminology_extracts") //TODO: requires an adapter for JAXB to work
@XmlTransient
private Map<String, ArchetypeTerminology> terminologyExtracts = new ConcurrentHashMap<>();//TODO: is this correct?
@XmlElement(name="component_terminologies") //TODO: requires an adapter for JAXB to work
@XmlTransient
private Map<String, ArchetypeTerminology> componentTerminologies = new ConcurrentHashMap<>();

@XmlElement(name="terminology_extracts")
private List<XmlArchetypeTerminology> xmlTerminologyExtracts;
@XmlElement(name="component_terminologies")
private List<XmlArchetypeTerminology> xmlComponentTerminologies;

@Override
public void afterUnmarshal(Unmarshaller unmarshaller, Object parent) {
super.afterUnmarshal(unmarshaller, parent);
if(xmlTerminologyExtracts != null) {
ArchetypeTerminologyAdapter archetypeTerminologyAdapter = new ArchetypeTerminologyAdapter();
for(XmlArchetypeTerminology terminology:xmlTerminologyExtracts) {
try {
ArchetypeTerminology converted = archetypeTerminologyAdapter.unmarshal(terminology);
terminologyExtracts.put(terminology.getArchetypeId(), converted);
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}
}
if(xmlComponentTerminologies != null) {
ArchetypeTerminologyAdapter archetypeTerminologyAdapter = new ArchetypeTerminologyAdapter();
for(XmlArchetypeTerminology terminology:xmlComponentTerminologies) {
try {
ArchetypeTerminology converted = archetypeTerminologyAdapter.unmarshal(terminology);
componentTerminologies.put(terminology.getArchetypeId(), converted);
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}
}
}

// Invoked by Marshaller after it has created an instance of this object.
@Override
public boolean beforeMarshal(Marshaller marshaller) {
super.beforeMarshal(marshaller);
if(terminologyExtracts != null && !terminologyExtracts.isEmpty()) {
ArchetypeTerminologyAdapter archetypeTerminologyAdapter = new ArchetypeTerminologyAdapter();
xmlTerminologyExtracts = new ArrayList<>();
for(Map.Entry<String, ArchetypeTerminology> terminology:terminologyExtracts.entrySet()) {
XmlArchetypeTerminology converted = archetypeTerminologyAdapter.marshal(terminology.getValue());
converted.setArchetypeId(terminology.getKey());
xmlTerminologyExtracts.add(converted);
}
} else {
xmlTerminologyExtracts = null;
}
if(componentTerminologies != null && !componentTerminologies.isEmpty()) {
ArchetypeTerminologyAdapter archetypeTerminologyAdapter = new ArchetypeTerminologyAdapter();
xmlComponentTerminologies = new ArrayList<>();
for(Map.Entry<String, ArchetypeTerminology> terminology:componentTerminologies.entrySet()) {
XmlArchetypeTerminology converted = archetypeTerminologyAdapter.marshal(terminology.getValue());
converted.setArchetypeId(terminology.getKey());
xmlComponentTerminologies.add(converted);
}
} else {
xmlComponentTerminologies = null;
}
return true;
}


public Map<String, ArchetypeTerminology> getTerminologyExtracts() {
return terminologyExtracts;
Expand Down
5 changes: 5 additions & 0 deletions aom/src/main/java/com/nedap/archie/aom/package-info.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@javax.xml.bind.annotation.XmlSchema(namespace = "http://schemas.openehr.org/v1", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED, attributeFormDefault = javax.xml.bind.annotation.XmlNsForm.UNQUALIFIED)

package com.nedap.archie.aom;

import javax.xml.bind.annotation.XmlNs;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@javax.xml.bind.annotation.XmlSchema(namespace = "http://schemas.openehr.org/v1", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED, attributeFormDefault = javax.xml.bind.annotation.XmlNsForm.UNQUALIFIED)

package com.nedap.archie.aom.primitives;

import javax.xml.bind.annotation.XmlNs;
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,11 @@ public class ArchetypeTerminology extends ArchetypeModelObject {
private String originalLanguage;
@XmlElement(name="concept_code")
private String conceptCode;
@XmlTransient//TODO!
//@XmlElement(name="term_definitions")
@XmlTransient //converted to XmlArchetypeTerminology, so not used in jaxb
private Map<String, Map<String, ArchetypeTerm>> termDefinitions = new ConcurrentHashMap<>();
//@XmlElement(name="term_bindings")
@XmlTransient//TODO!
@XmlTransient //converted to XmlArchetypeTerminology, so not used in jaxb
private Map<String, Map<String, URI>> termBindings = new ConcurrentHashMap<>();
//@XmlElement(name="terminology_extracts")
@XmlTransient//TODO!
@XmlTransient //converted to XmlArchetypeTerminology, so not used in jaxb
private Map<String, Map<String, ArchetypeTerm>> terminologyExtracts = new ConcurrentHashMap<>();
@XmlElement(name="value_sets")
private Map<String, ValueSet> valueSets = new ConcurrentHashMap<>();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@javax.xml.bind.annotation.XmlSchema(namespace = "http://schemas.openehr.org/v1", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED, attributeFormDefault = javax.xml.bind.annotation.XmlNsForm.UNQUALIFIED)

package com.nedap.archie.aom.terminology;

import javax.xml.bind.annotation.XmlNs;
5 changes: 5 additions & 0 deletions aom/src/main/java/com/nedap/archie/rules/package-info.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@javax.xml.bind.annotation.XmlSchema(namespace = "http://schemas.openehr.org/v1", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED, attributeFormDefault = javax.xml.bind.annotation.XmlNsForm.UNQUALIFIED)

package com.nedap.archie.rules;

import javax.xml.bind.annotation.XmlNs;
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import javax.xml.bind.annotation.adapters.XmlAdapter;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
Expand All @@ -23,7 +24,7 @@
public class ArchetypeTerminologyAdapter extends XmlAdapter<XmlArchetypeTerminology, ArchetypeTerminology> {

@Override
public XmlArchetypeTerminology marshal(ArchetypeTerminology terminology) throws Exception {
public XmlArchetypeTerminology marshal(ArchetypeTerminology terminology) {
if(terminology == null) {
return null;
}
Expand Down Expand Up @@ -71,7 +72,7 @@ private List<CodeDefinitionSet> convertIntoCodeDefinitionSetList(Map<String, Map
}

@Override
public ArchetypeTerminology unmarshal(XmlArchetypeTerminology xmlTerminology) throws Exception {
public ArchetypeTerminology unmarshal(XmlArchetypeTerminology xmlTerminology) throws URISyntaxException {
if(xmlTerminology == null) {
return null;
}
Expand All @@ -97,7 +98,7 @@ private Map<String, ValueSet> convertIntoValueSetMap(List<ValueSet> valueSets) {
return result;
}

private Map<String, Map<String, URI>> convertIntoTermBindingsMap(List<TermBindingSet> termBindings) throws Exception{
private Map<String, Map<String, URI>> convertIntoTermBindingsMap(List<TermBindingSet> termBindings) throws URISyntaxException {
Map<String, Map<String, URI>> result = new LinkedHashMap<>();
for(TermBindingSet set:termBindings) {
Map<String, URI> termMap = StringDictionaryUtil.convertStringDictionaryListToUriMap(set.getItems());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.nedap.archie.xml.adapters;

import com.nedap.archie.aom.TranslationDetails;
import com.nedap.archie.xml.types.StringDictionaryItem;
import com.nedap.archie.xml.types.XmlTranslationDetails;

import javax.xml.bind.annotation.adapters.XmlAdapter;
import java.util.ArrayList;
import java.util.LinkedHashMap;

public class StringDictionaryMapAdapter extends XmlAdapter<ArrayList<StringDictionaryItem>, LinkedHashMap<String, String>> {
@Override
public LinkedHashMap<String, String> unmarshal(ArrayList<StringDictionaryItem> v) throws Exception {
return StringDictionaryUtil.convertStringDictionaryListToStringMap(v);
}

@Override
public ArrayList<StringDictionaryItem> marshal(LinkedHashMap<String, String> v) throws Exception {
return StringDictionaryUtil.convertStringMapIntoStringDictionaryList(v);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,11 @@ public static Map<String, URI> convertStringDictionaryListToUriMap(List<StringDi
return termMap;
}

public static Map<String, String> convertStringDictionaryListToStringMap(List<StringDictionaryItem> items) {
public static LinkedHashMap<String, String> convertStringDictionaryListToStringMap(List<StringDictionaryItem> items) {
if(items == null) {
return null;
}
Map<String, String> termMap = new LinkedHashMap<>();
LinkedHashMap<String, String> termMap = new LinkedHashMap<>();
for(StringDictionaryItem term:items) {
termMap.put(term.getId(),term.getValue());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
@XmlAccessorType(XmlAccessType.FIELD)
public class XmlArchetypeTerminology {

@XmlAttribute(name="archetype_id")
private String archetypeId;
@XmlAttribute(name="is_differential")
private Boolean differential;
@XmlAttribute(name="original_language")
Expand All @@ -34,6 +36,14 @@ public class XmlArchetypeTerminology {
@XmlElement(name="value_sets")
private List<ValueSet> valueSets = new ArrayList<>();

public String getArchetypeId() {
return archetypeId;
}

public void setArchetypeId(String archetypeId) {
this.archetypeId = archetypeId;
}

public List<CodeDefinitionSet> getTermDefinitions() {
return termDefinitions;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public class XmlResourceDescription {
private List<StringDictionaryItem> conversionDetails;
@XmlElement(name = "other_details")
private List<StringDictionaryItem> otherDetails;
@XmlElement(required = true, type = ResourceDescriptionItem.class)
@XmlElement(required = true, type = XmlResourceDescriptionItem.class)
private List<XmlResourceDescriptionItem> details;

public List<StringDictionaryItem> getOriginalAuthor() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@javax.xml.bind.annotation.XmlSchema(namespace = "http://schemas.openehr.org/v1", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED, attributeFormDefault = javax.xml.bind.annotation.XmlNsForm.UNQUALIFIED)

package com.nedap.archie.xml.types;

import javax.xml.bind.annotation.XmlNs;
26 changes: 26 additions & 0 deletions archie-utils/src/main/java/com/nedap/archie/xml/JAXBUtil.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
package com.nedap.archie.xml;

import com.google.common.collect.Lists;
import com.nedap.archie.aom.AuthoredResource;
import com.nedap.archie.aom.LanguageSection;
import com.nedap.archie.aom.ResourceDescription;
import com.nedap.archie.aom.ResourceDescriptionItem;
import com.nedap.archie.aom.TranslationDetails;
import com.nedap.archie.aom.terminology.ArchetypeTerminology;
import com.nedap.archie.rminfo.ArchieAOMInfoLookup;
import com.nedap.archie.rminfo.ArchieRMInfoLookup;
import com.nedap.archie.xml.types.XmlResourceDescriptionItem;
Expand Down Expand Up @@ -39,6 +45,7 @@ private static synchronized void initArchieJaxbContext() {
classes.addAll(ArchieRMInfoLookup.getInstance().getRmTypeNameToClassMap().values());
//extra classes from the adapters package that are not directly referenced.\
classes.add(XmlResourceDescriptionItem.class);
removeClasses(classes);
archieJaxbContext = JAXBContext.newInstance(classes.toArray(new Class[0]));
} catch (JAXBException e) {
throw new RuntimeException(e);//programmer error, tests will fail
Expand All @@ -51,6 +58,7 @@ public static synchronized JAXBContext createAOMContext() {
List<Class<?>> classes = Lists.newArrayList(ArchieAOMInfoLookup.getInstance().getRmTypeNameToClassMap().values());
//extra classes from the adapters package that are not directly referenced.\
classes.add(XmlResourceDescriptionItem.class);
removeClasses(classes);
return JAXBContext.newInstance(classes.toArray(new Class[0]));
} catch (JAXBException e) {
throw new RuntimeException(e);//programmer error, tests will fail
Expand All @@ -60,10 +68,28 @@ public static synchronized JAXBContext createAOMContext() {
public static synchronized JAXBContext createRMContext() {
try {
List<Class<?>> classes = Lists.newArrayList(ArchieRMInfoLookup.getInstance().getRmTypeNameToClassMap().values());
removeClasses(classes);
return JAXBContext.newInstance(classes.toArray(new Class[0]));
} catch (JAXBException e) {
throw new RuntimeException(e);//programmer error, tests will fail
}
}

private static void removeClasses(List<Class<?>> classes) {
//remove classes that are adapted to other classes anyway, particularly those using maps
removeAllInstances(classes, ResourceDescription.class);
removeAllInstances(classes, ResourceDescriptionItem.class);
removeAllInstances(classes, LanguageSection.class);
removeAllInstances(classes, ArchetypeTerminology.class);
removeAllInstances(classes, TranslationDetails.class);
removeAllInstances(classes, AuthoredResource.class);
}

private static <T> void removeAllInstances(List<T> something, T instance) {
boolean found;
do {
found = something.remove(instance);
} while(found);
}

}
Loading