Merge pull request #1729 from hapifhir/EllipseSupport
Added support for tracking whether elements are ellipsed and for rend…
This commit is contained in:
commit
6314ad61bb
|
@ -162,6 +162,7 @@ public class Element extends Base implements NamedItem {
|
|||
private FhirFormat format;
|
||||
private Object nativeObject;
|
||||
private List<SliceDefinition> sliceDefinitions;
|
||||
private boolean elided;
|
||||
|
||||
public Element(String name) {
|
||||
super();
|
||||
|
@ -1429,6 +1430,8 @@ public class Element extends Base implements NamedItem {
|
|||
public Base copy() {
|
||||
Element element = new Element(this);
|
||||
this.copyValues(element);
|
||||
if (this.isElided())
|
||||
element.setElided(true);
|
||||
return element;
|
||||
}
|
||||
|
||||
|
@ -1638,4 +1641,11 @@ public class Element extends Base implements NamedItem {
|
|||
return FhirPublication.fromCode(property.getStructure().getVersion());
|
||||
}
|
||||
|
||||
public void setElided(boolean elided) {
|
||||
this.elided = elided;
|
||||
}
|
||||
|
||||
public boolean isElided() {
|
||||
return this.elided;
|
||||
}
|
||||
}
|
|
@ -62,6 +62,7 @@ import org.hl7.fhir.r5.formats.JsonCreatorDirect;
|
|||
import org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
import org.hl7.fhir.r5.utils.ToolingExtensions;
|
||||
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
|
||||
import org.hl7.fhir.utilities.StringPair;
|
||||
import org.hl7.fhir.utilities.TextFile;
|
||||
|
@ -85,6 +86,8 @@ public class JsonParser extends ParserBase {
|
|||
|
||||
private JsonCreator json;
|
||||
private boolean allowComments;
|
||||
private boolean elideElements;
|
||||
// private boolean suppressResourceType;
|
||||
|
||||
private Element baseElement;
|
||||
private boolean markedXhtml;
|
||||
|
@ -782,7 +785,8 @@ public class JsonParser extends ParserBase {
|
|||
}
|
||||
checkComposeComments(e);
|
||||
json.beginObject();
|
||||
prop("resourceType", e.getType(), null);
|
||||
// if (!isSuppressResourceType())
|
||||
prop("resourceType", e.getType(), null);
|
||||
Set<String> done = new HashSet<String>();
|
||||
for (Element child : e.getChildren()) {
|
||||
compose(e.getName(), e, done, child);
|
||||
|
@ -807,7 +811,8 @@ public class JsonParser extends ParserBase {
|
|||
checkComposeComments(e);
|
||||
json.beginObject();
|
||||
|
||||
prop("resourceType", e.getType(), linkResolver == null ? null : linkResolver.resolveProperty(e.getProperty()));
|
||||
// if (!isSuppressResourceType())
|
||||
prop("resourceType", e.getType(), linkResolver == null ? null : linkResolver.resolveProperty(e.getProperty()));
|
||||
Set<String> done = new HashSet<String>();
|
||||
for (Element child : e.getChildren()) {
|
||||
compose(e.getName(), e, done, child);
|
||||
|
@ -821,15 +826,50 @@ public class JsonParser extends ParserBase {
|
|||
if (wantCompose(path, child)) {
|
||||
boolean isList = child.hasElementProperty() ? child.getElementProperty().isList() : child.getProperty().isList();
|
||||
if (!isList) {// for specials, ignore the cardinality of the stated type
|
||||
compose(path, child);
|
||||
if (child.isElided() && isElideElements() && json.canElide())
|
||||
json.elide();
|
||||
else
|
||||
compose(path, child);
|
||||
} else if (!done.contains(child.getName())) {
|
||||
done.add(child.getName());
|
||||
List<Element> list = e.getChildrenByName(child.getName());
|
||||
composeList(path, list);
|
||||
if (child.getProperty().getDefinition().hasExtension(ToolingExtensions.EXT_JSON_PROP_KEY))
|
||||
composeKeyList(path, list);
|
||||
else
|
||||
composeList(path, list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void composeKeyList(String path, List<Element> list) throws IOException {
|
||||
String keyName = list.get(0).getProperty().getDefinition().getExtensionString(ToolingExtensions.EXT_JSON_PROP_KEY);
|
||||
json.name(list.get(0).getName());
|
||||
json.beginObject();
|
||||
for (Element e: list) {
|
||||
Element key = null;
|
||||
Element value = null;
|
||||
for (Element child: e.getChildren()) {
|
||||
if (child.getName().equals(keyName))
|
||||
key = child;
|
||||
else
|
||||
value = child;
|
||||
}
|
||||
if (value.isPrimitive())
|
||||
primitiveValue(key.getValue(), value);
|
||||
else {
|
||||
json.name(key.getValue());
|
||||
checkComposeComments(e);
|
||||
json.beginObject();
|
||||
Set<String> done = new HashSet<String>();
|
||||
for (Element child : value.getChildren()) {
|
||||
compose(value.getName(), value, done, child);
|
||||
}
|
||||
json.endObject();
|
||||
compose(path + "." + key.getValue(), value);
|
||||
}
|
||||
}
|
||||
json.endObject();
|
||||
}
|
||||
|
||||
private void composeList(String path, List<Element> list) throws IOException {
|
||||
// there will be at least one element
|
||||
|
@ -847,7 +887,9 @@ public class JsonParser extends ParserBase {
|
|||
if (prim) {
|
||||
openArray(name, linkResolver == null ? null : linkResolver.resolveProperty(list.get(0).getProperty()));
|
||||
for (Element item : list) {
|
||||
if (item.hasValue()) {
|
||||
if (item.isElided() && json.canElide())
|
||||
json.elide();
|
||||
else if (item.hasValue()) {
|
||||
if (linkResolver != null && item.getProperty().isReference()) {
|
||||
String ref = linkResolver.resolveReference(getReferenceForElement(item));
|
||||
if (ref != null) {
|
||||
|
@ -866,7 +908,9 @@ public class JsonParser extends ParserBase {
|
|||
openArray(name, linkResolver == null ? null : linkResolver.resolveProperty(list.get(0).getProperty()));
|
||||
int i = 0;
|
||||
for (Element item : list) {
|
||||
if (item.hasChildren()) {
|
||||
if (item.isElided() && json.canElide())
|
||||
json.elide();
|
||||
else if (item.hasChildren()) {
|
||||
open(null,null);
|
||||
if (item.getProperty().isResource()) {
|
||||
prop("resourceType", item.getType(), linkResolver == null ? null : linkResolver.resolveType(item.getType()));
|
||||
|
@ -933,9 +977,10 @@ public class JsonParser extends ParserBase {
|
|||
json.externalLink(ref);
|
||||
}
|
||||
}
|
||||
|
||||
Set<String> done = new HashSet<String>();
|
||||
for (Element child : element.getChildren()) {
|
||||
compose(path+"."+element.getName(), element, done, child);
|
||||
compose(path + "." + element.getName(), element, done, child);
|
||||
}
|
||||
close();
|
||||
}
|
||||
|
@ -951,5 +996,23 @@ public class JsonParser extends ParserBase {
|
|||
return this;
|
||||
}
|
||||
|
||||
public boolean isElideElements() {
|
||||
return elideElements;
|
||||
}
|
||||
|
||||
public JsonParser setElideElements(boolean elideElements) {
|
||||
this.elideElements = elideElements;
|
||||
return this;
|
||||
}
|
||||
/*
|
||||
public boolean isSuppressResourceType() {
|
||||
return suppressResourceType;
|
||||
}
|
||||
|
||||
public JsonParser setSuppressResourceType(boolean suppressResourceType) {
|
||||
this.suppressResourceType = suppressResourceType;
|
||||
return this;
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
|
@ -94,6 +94,7 @@ import org.xml.sax.XMLReader;
|
|||
public class XmlParser extends ParserBase {
|
||||
private boolean allowXsiLocation;
|
||||
private String version;
|
||||
private boolean elideElements;
|
||||
|
||||
public XmlParser(IWorkerContext context) {
|
||||
super(context);
|
||||
|
@ -805,92 +806,125 @@ public class XmlParser extends ParserBase {
|
|||
}
|
||||
|
||||
private void composeElement(IXMLWriter xml, Element element, String elementName, boolean root) throws IOException, FHIRException {
|
||||
if (showDecorations) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<ElementDecoration> decorations = (List<ElementDecoration>) element.getUserData("fhir.decorations");
|
||||
if (decorations != null)
|
||||
for (ElementDecoration d : decorations)
|
||||
xml.decorate(d);
|
||||
}
|
||||
for (String s : element.getComments()) {
|
||||
xml.comment(s, true);
|
||||
if (!(isElideElements() && element.isElided())) {
|
||||
if (showDecorations) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<ElementDecoration> decorations = (List<ElementDecoration>) element.getUserData("fhir.decorations");
|
||||
if (decorations != null)
|
||||
for (ElementDecoration d : decorations)
|
||||
xml.decorate(d);
|
||||
}
|
||||
for (String s : element.getComments()) {
|
||||
xml.comment(s, true);
|
||||
}
|
||||
}
|
||||
if (isText(element.getProperty())) {
|
||||
if (linkResolver != null)
|
||||
xml.link(linkResolver.resolveProperty(element.getProperty()));
|
||||
xml.enter(element.getProperty().getXmlNamespace(),elementName);
|
||||
if (linkResolver != null && element.getProperty().isReference()) {
|
||||
String ref = linkResolver.resolveReference(getReferenceForElement(element));
|
||||
if (ref != null) {
|
||||
xml.externalLink(ref);
|
||||
if (isElideElements() && element.isElided() && xml.canElide())
|
||||
xml.elide();
|
||||
else {
|
||||
if (linkResolver != null)
|
||||
xml.link(linkResolver.resolveProperty(element.getProperty()));
|
||||
xml.enter(element.getProperty().getXmlNamespace(),elementName);
|
||||
if (linkResolver != null && element.getProperty().isReference()) {
|
||||
String ref = linkResolver.resolveReference(getReferenceForElement(element));
|
||||
if (ref != null) {
|
||||
xml.externalLink(ref);
|
||||
}
|
||||
}
|
||||
xml.text(element.getValue());
|
||||
xml.exit(element.getProperty().getXmlNamespace(),elementName);
|
||||
}
|
||||
xml.text(element.getValue());
|
||||
xml.exit(element.getProperty().getXmlNamespace(),elementName);
|
||||
} else if (!element.hasChildren() && !element.hasValue()) {
|
||||
if (element.getExplicitType() != null)
|
||||
xml.attribute("xsi:type", element.getExplicitType());
|
||||
xml.element(elementName);
|
||||
if (isElideElements() && element.isElided() && xml.canElide())
|
||||
xml.elide();
|
||||
else {
|
||||
if (element.getExplicitType() != null)
|
||||
xml.attribute("xsi:type", element.getExplicitType());
|
||||
xml.element(elementName);
|
||||
}
|
||||
} else if (element.isPrimitive() || (element.hasType() && isPrimitive(element.getType()))) {
|
||||
if (element.getType().equals("xhtml")) {
|
||||
String rawXhtml = element.getValue();
|
||||
if (isCdaText(element.getProperty())) {
|
||||
new CDANarrativeFormat().convert(xml, new XhtmlParser().parseFragment(rawXhtml));
|
||||
} else {
|
||||
xml.escapedText(rawXhtml);
|
||||
if (!markedXhtml) {
|
||||
xml.anchor("end-xhtml");
|
||||
markedXhtml = true;
|
||||
if (isElideElements() && element.isElided() && xml.canElide())
|
||||
xml.elide();
|
||||
else {
|
||||
String rawXhtml = element.getValue();
|
||||
if (isCdaText(element.getProperty())) {
|
||||
new CDANarrativeFormat().convert(xml, new XhtmlParser().parseFragment(rawXhtml));
|
||||
} else {
|
||||
xml.escapedText(rawXhtml);
|
||||
if (!markedXhtml) {
|
||||
xml.anchor("end-xhtml");
|
||||
markedXhtml = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (isText(element.getProperty())) {
|
||||
if (linkResolver != null)
|
||||
xml.link(linkResolver.resolveProperty(element.getProperty()));
|
||||
xml.text(element.getValue());
|
||||
} else {
|
||||
setXsiTypeIfIsTypeAttr(xml, element);
|
||||
if (element.hasValue()) {
|
||||
if (isElideElements() && element.isElided() && xml.canElide())
|
||||
xml.elide();
|
||||
else {
|
||||
if (linkResolver != null)
|
||||
xml.link(linkResolver.resolveType(element.getType()));
|
||||
xml.attribute("value", element.getValue());
|
||||
xml.link(linkResolver.resolveProperty(element.getProperty()));
|
||||
xml.text(element.getValue());
|
||||
}
|
||||
if (linkResolver != null)
|
||||
xml.link(linkResolver.resolveProperty(element.getProperty()));
|
||||
if (element.hasChildren()) {
|
||||
xml.enter(element.getProperty().getXmlNamespace(), elementName);
|
||||
if (linkResolver != null && element.getProperty().isReference()) {
|
||||
String ref = linkResolver.resolveReference(getReferenceForElement(element));
|
||||
if (ref != null) {
|
||||
xml.externalLink(ref);
|
||||
}
|
||||
} else {
|
||||
if (isElideElements() && element.isElided())
|
||||
xml.attributeElide();
|
||||
else {
|
||||
setXsiTypeIfIsTypeAttr(xml, element);
|
||||
if (element.hasValue()) {
|
||||
if (linkResolver != null)
|
||||
xml.link(linkResolver.resolveType(element.getType()));
|
||||
xml.attribute("value", element.getValue());
|
||||
}
|
||||
for (Element child : element.getChildren())
|
||||
composeElement(xml, child, child.getName(), false);
|
||||
xml.exit(element.getProperty().getXmlNamespace(),elementName);
|
||||
} else
|
||||
xml.element(elementName);
|
||||
if (linkResolver != null)
|
||||
xml.link(linkResolver.resolveProperty(element.getProperty()));
|
||||
if (element.hasChildren()) {
|
||||
xml.enter(element.getProperty().getXmlNamespace(), elementName);
|
||||
if (linkResolver != null && element.getProperty().isReference()) {
|
||||
String ref = linkResolver.resolveReference(getReferenceForElement(element));
|
||||
if (ref != null) {
|
||||
xml.externalLink(ref);
|
||||
}
|
||||
}
|
||||
for (Element child : element.getChildren())
|
||||
composeElement(xml, child, child.getName(), false);
|
||||
xml.exit(element.getProperty().getXmlNamespace(),elementName);
|
||||
} else
|
||||
xml.element(elementName);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
setXsiTypeIfIsTypeAttr(xml, element);
|
||||
Set<String> handled = new HashSet<>();
|
||||
if (isElideElements() && element.isElided() && xml.canElide())
|
||||
xml.elide();
|
||||
else {
|
||||
setXsiTypeIfIsTypeAttr(xml, element);
|
||||
Set<String> handled = new HashSet<>();
|
||||
for (Element child : element.getChildren()) {
|
||||
if (!handled.contains(child.getName()) && isAttr(child.getProperty()) && wantCompose(element.getPath(), child)) {
|
||||
handled.add(child.getName());
|
||||
String av = child.getValue();
|
||||
if (child.getProperty().isList()) {
|
||||
for (Element c2 : element.getChildren()) {
|
||||
if (c2 != child && c2.getName().equals(child.getName())) {
|
||||
av = av + " "+c2.getValue();
|
||||
if (isElideElements() && child.isElided())
|
||||
xml.attributeElide();
|
||||
else {
|
||||
String av = child.getValue();
|
||||
if (child.getProperty().isList()) {
|
||||
for (Element c2 : element.getChildren()) {
|
||||
if (c2 != child && c2.getName().equals(child.getName())) {
|
||||
if (c2.isElided())
|
||||
av = av + " ...";
|
||||
else
|
||||
av = av + " " + c2.getValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (linkResolver != null)
|
||||
xml.link(linkResolver.resolveType(child.getType()));
|
||||
if (ToolingExtensions.hasExtension(child.getProperty().getDefinition(), ToolingExtensions.EXT_DATE_FORMAT))
|
||||
av = convertForDateFormatToExternal(ToolingExtensions.readStringExtension(child.getProperty().getDefinition(), ToolingExtensions.EXT_DATE_FORMAT), av);
|
||||
xml.attribute(child.getProperty().getXmlNamespace(), child.getProperty().getXmlName(), av);
|
||||
}
|
||||
if (linkResolver != null)
|
||||
xml.link(linkResolver.resolveType(child.getType()));
|
||||
if (ToolingExtensions.hasExtension(child.getProperty().getDefinition(), ToolingExtensions.EXT_DATE_FORMAT))
|
||||
av = convertForDateFormatToExternal(ToolingExtensions.readStringExtension(child.getProperty().getDefinition(), ToolingExtensions.EXT_DATE_FORMAT), av);
|
||||
xml.attribute(child.getProperty().getXmlNamespace(),child.getProperty().getXmlName(), av);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!element.getProperty().getDefinition().hasExtension(ToolingExtensions.EXT_ID_CHOICE_GROUP)) {
|
||||
if (linkResolver != null)
|
||||
xml.link(linkResolver.resolveProperty(element.getProperty()));
|
||||
|
@ -914,12 +948,16 @@ public class XmlParser extends ParserBase {
|
|||
}
|
||||
for (Element child : element.getChildren()) {
|
||||
if (wantCompose(element.getPath(), child)) {
|
||||
if (isText(child.getProperty())) {
|
||||
if (linkResolver != null)
|
||||
xml.link(linkResolver.resolveProperty(element.getProperty()));
|
||||
xml.text(child.getValue());
|
||||
} else if (!isAttr(child.getProperty())) {
|
||||
composeElement(xml, child, child.getName(), false);
|
||||
if (isElideElements() && child.isElided() && xml.canElide())
|
||||
xml.elide();
|
||||
else {
|
||||
if (isText(child.getProperty())) {
|
||||
if (linkResolver != null)
|
||||
xml.link(linkResolver.resolveProperty(element.getProperty()));
|
||||
xml.text(child.getValue());
|
||||
} else if (!isAttr(child.getProperty())) {
|
||||
composeElement(xml, child, child.getName(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1034,4 +1072,13 @@ public class XmlParser extends ParserBase {
|
|||
// do nothing
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isElideElements() {
|
||||
return elideElements;
|
||||
}
|
||||
|
||||
public void setElideElements(boolean elideElements) {
|
||||
this.elideElements = elideElements;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
package org.hl7.fhir.r5.formats;
|
||||
|
||||
package org.hl7.fhir.r5.formats;
|
||||
|
||||
/*
|
||||
Copyright (c) 2011+, HL7, Inc.
|
||||
All rights reserved.
|
||||
|
@ -28,47 +28,49 @@ package org.hl7.fhir.r5.formats;
|
|||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* Facade to GSON writer, or something that imposes property ordering first
|
||||
*
|
||||
* @author Grahame
|
||||
*
|
||||
*/
|
||||
public interface JsonCreator {
|
||||
|
||||
void comment(String comment);
|
||||
|
||||
void beginObject() throws IOException;
|
||||
|
||||
void endObject() throws IOException;
|
||||
|
||||
void nullValue() throws IOException;
|
||||
|
||||
void name(String name) throws IOException;
|
||||
|
||||
void value(String value) throws IOException;
|
||||
|
||||
void value(Boolean value) throws IOException;
|
||||
|
||||
void value(BigDecimal value) throws IOException;
|
||||
void valueNum(String value) throws IOException; // allow full control of representation
|
||||
|
||||
void value(Integer value) throws IOException;
|
||||
|
||||
void beginArray() throws IOException;
|
||||
|
||||
void endArray() throws IOException;
|
||||
|
||||
void finish() throws IOException;
|
||||
|
||||
// only used by an creator that actually produces xhtml
|
||||
void link(String href);
|
||||
void anchor(String string);
|
||||
void externalLink(String string);
|
||||
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* Facade to GSON writer, or something that imposes property ordering first
|
||||
*
|
||||
* @author Grahame
|
||||
*
|
||||
*/
|
||||
public interface JsonCreator {
|
||||
|
||||
void comment(String comment);
|
||||
|
||||
void beginObject() throws IOException;
|
||||
|
||||
void endObject() throws IOException;
|
||||
|
||||
void nullValue() throws IOException;
|
||||
|
||||
void name(String name) throws IOException;
|
||||
|
||||
void value(String value) throws IOException;
|
||||
|
||||
void value(Boolean value) throws IOException;
|
||||
|
||||
void value(BigDecimal value) throws IOException;
|
||||
void valueNum(String value) throws IOException; // allow full control of representation
|
||||
|
||||
void value(Integer value) throws IOException;
|
||||
|
||||
void beginArray() throws IOException;
|
||||
|
||||
void endArray() throws IOException;
|
||||
|
||||
void finish() throws IOException;
|
||||
|
||||
// only used by an creator that actually produces xhtml
|
||||
void link(String href);
|
||||
void anchor(String string);
|
||||
void externalLink(String string);
|
||||
void elide();
|
||||
boolean canElide();
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
package org.hl7.fhir.r5.formats;
|
||||
|
||||
package org.hl7.fhir.r5.formats;
|
||||
|
||||
/*
|
||||
Copyright (c) 2011+, HL7, Inc.
|
||||
All rights reserved.
|
||||
|
@ -28,257 +28,264 @@ package org.hl7.fhir.r5.formats;
|
|||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class JsonCreatorCanonical implements JsonCreator {
|
||||
|
||||
public class JsonCanValue {
|
||||
String name;
|
||||
private JsonCanValue(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
private class JsonCanNumberValue extends JsonCanValue {
|
||||
private BigDecimal value;
|
||||
private JsonCanNumberValue(String name, BigDecimal value) {
|
||||
super(name);
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
private class JsonCanPresentedNumberValue extends JsonCanValue {
|
||||
private String value;
|
||||
private JsonCanPresentedNumberValue(String name, String value) {
|
||||
super(name);
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
private class JsonCanIntegerValue extends JsonCanValue {
|
||||
private Integer value;
|
||||
private JsonCanIntegerValue(String name, Integer value) {
|
||||
super(name);
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
private class JsonCanBooleanValue extends JsonCanValue {
|
||||
private Boolean value;
|
||||
private JsonCanBooleanValue(String name, Boolean value) {
|
||||
super(name);
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
private class JsonCanStringValue extends JsonCanValue {
|
||||
private String value;
|
||||
private JsonCanStringValue(String name, String value) {
|
||||
super(name);
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
private class JsonCanNullValue extends JsonCanValue {
|
||||
private JsonCanNullValue(String name) {
|
||||
super(name);
|
||||
}
|
||||
}
|
||||
|
||||
public class JsonCanObject extends JsonCanValue {
|
||||
|
||||
boolean array;
|
||||
List<JsonCanValue> children = new ArrayList<JsonCanValue>();
|
||||
|
||||
public JsonCanObject(String name, boolean array) {
|
||||
super(name);
|
||||
this.array = array;
|
||||
}
|
||||
|
||||
public void addProp(JsonCanValue obj) {
|
||||
children.add(obj);
|
||||
}
|
||||
}
|
||||
|
||||
Stack<JsonCanObject> stack;
|
||||
JsonCanObject root;
|
||||
JsonCreatorDirect jj;
|
||||
String name;
|
||||
|
||||
public JsonCreatorCanonical(OutputStreamWriter osw) {
|
||||
stack = new Stack<JsonCreatorCanonical.JsonCanObject>();
|
||||
jj = new JsonCreatorDirect(osw, false, false);
|
||||
name = null;
|
||||
}
|
||||
|
||||
private String takeName() {
|
||||
String res = name;
|
||||
name = null;
|
||||
return res;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginObject() throws IOException {
|
||||
JsonCanObject obj = new JsonCanObject(takeName(), false);
|
||||
if (stack.isEmpty())
|
||||
root = obj;
|
||||
else
|
||||
stack.peek().addProp(obj);
|
||||
stack.push(obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endObject() throws IOException {
|
||||
stack.pop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nullValue() throws IOException {
|
||||
stack.peek().addProp(new JsonCanNullValue(takeName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void name(String name) throws IOException {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void value(String value) throws IOException {
|
||||
stack.peek().addProp(new JsonCanStringValue(takeName(), value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void value(Boolean value) throws IOException {
|
||||
stack.peek().addProp(new JsonCanBooleanValue(takeName(), value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void value(BigDecimal value) throws IOException {
|
||||
stack.peek().addProp(new JsonCanNumberValue(takeName(), value));
|
||||
}
|
||||
@Override
|
||||
public void valueNum(String value) throws IOException {
|
||||
stack.peek().addProp(new JsonCanPresentedNumberValue(takeName(), value));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void value(Integer value) throws IOException {
|
||||
stack.peek().addProp(new JsonCanIntegerValue(takeName(), value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginArray() throws IOException {
|
||||
JsonCanObject obj = new JsonCanObject(takeName(), true);
|
||||
if (!stack.isEmpty())
|
||||
stack.peek().addProp(obj);
|
||||
stack.push(obj);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endArray() throws IOException {
|
||||
stack.pop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish() throws IOException {
|
||||
writeObject(root);
|
||||
}
|
||||
|
||||
private void writeObject(JsonCanObject obj) throws IOException {
|
||||
jj.beginObject();
|
||||
List<String> names = new ArrayList<String>();
|
||||
for (JsonCanValue v : obj.children)
|
||||
names.add(v.name);
|
||||
Collections.sort(names);
|
||||
for (String n : names) {
|
||||
jj.name(n);
|
||||
JsonCanValue v = getPropForName(n, obj.children);
|
||||
if (v instanceof JsonCanNumberValue)
|
||||
jj.value(((JsonCanNumberValue) v).value);
|
||||
else if (v instanceof JsonCanPresentedNumberValue)
|
||||
jj.valueNum(((JsonCanPresentedNumberValue) v).value);
|
||||
else if (v instanceof JsonCanIntegerValue)
|
||||
jj.value(((JsonCanIntegerValue) v).value);
|
||||
else if (v instanceof JsonCanBooleanValue)
|
||||
jj.value(((JsonCanBooleanValue) v).value);
|
||||
else if (v instanceof JsonCanStringValue)
|
||||
jj.value(((JsonCanStringValue) v).value);
|
||||
else if (v instanceof JsonCanNullValue)
|
||||
jj.nullValue();
|
||||
else if (v instanceof JsonCanObject) {
|
||||
JsonCanObject o = (JsonCanObject) v;
|
||||
if (o.array)
|
||||
writeArray(o);
|
||||
else
|
||||
writeObject(o);
|
||||
} else
|
||||
throw new Error("not possible");
|
||||
}
|
||||
jj.endObject();
|
||||
}
|
||||
|
||||
private JsonCanValue getPropForName(String name, List<JsonCanValue> children) {
|
||||
for (JsonCanValue child : children)
|
||||
if (child.name.equals(name))
|
||||
return child;
|
||||
return null;
|
||||
}
|
||||
|
||||
private void writeArray(JsonCanObject arr) throws IOException {
|
||||
jj.beginArray();
|
||||
for (JsonCanValue v : arr.children) {
|
||||
if (v instanceof JsonCanNumberValue)
|
||||
jj.value(((JsonCanNumberValue) v).value);
|
||||
else if (v instanceof JsonCanIntegerValue)
|
||||
jj.value(((JsonCanIntegerValue) v).value);
|
||||
else if (v instanceof JsonCanBooleanValue)
|
||||
jj.value(((JsonCanBooleanValue) v).value);
|
||||
else if (v instanceof JsonCanStringValue)
|
||||
jj.value(((JsonCanStringValue) v).value);
|
||||
else if (v instanceof JsonCanNullValue)
|
||||
jj.nullValue();
|
||||
else if (v instanceof JsonCanObject) {
|
||||
JsonCanObject o = (JsonCanObject) v;
|
||||
if (o.array)
|
||||
writeArray(o);
|
||||
else
|
||||
writeObject(o);
|
||||
} else
|
||||
throw new Error("not possible");
|
||||
}
|
||||
jj.endArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void comment(String content) {
|
||||
// canonical JSON ignores comments
|
||||
}
|
||||
|
||||
@Override
|
||||
public void link(String href) {
|
||||
// not used
|
||||
}
|
||||
|
||||
@Override
|
||||
public void anchor(String name) {
|
||||
// not used
|
||||
}
|
||||
|
||||
@Override
|
||||
public void externalLink(String string) {
|
||||
// not used
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class JsonCreatorCanonical implements JsonCreator {
|
||||
|
||||
public class JsonCanValue {
|
||||
String name;
|
||||
private JsonCanValue(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
private class JsonCanNumberValue extends JsonCanValue {
|
||||
private BigDecimal value;
|
||||
private JsonCanNumberValue(String name, BigDecimal value) {
|
||||
super(name);
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
private class JsonCanPresentedNumberValue extends JsonCanValue {
|
||||
private String value;
|
||||
private JsonCanPresentedNumberValue(String name, String value) {
|
||||
super(name);
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
private class JsonCanIntegerValue extends JsonCanValue {
|
||||
private Integer value;
|
||||
private JsonCanIntegerValue(String name, Integer value) {
|
||||
super(name);
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
private class JsonCanBooleanValue extends JsonCanValue {
|
||||
private Boolean value;
|
||||
private JsonCanBooleanValue(String name, Boolean value) {
|
||||
super(name);
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
private class JsonCanStringValue extends JsonCanValue {
|
||||
private String value;
|
||||
private JsonCanStringValue(String name, String value) {
|
||||
super(name);
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
private class JsonCanNullValue extends JsonCanValue {
|
||||
private JsonCanNullValue(String name) {
|
||||
super(name);
|
||||
}
|
||||
}
|
||||
|
||||
public class JsonCanObject extends JsonCanValue {
|
||||
|
||||
boolean array;
|
||||
List<JsonCanValue> children = new ArrayList<JsonCanValue>();
|
||||
|
||||
public JsonCanObject(String name, boolean array) {
|
||||
super(name);
|
||||
this.array = array;
|
||||
}
|
||||
|
||||
public void addProp(JsonCanValue obj) {
|
||||
children.add(obj);
|
||||
}
|
||||
}
|
||||
|
||||
Stack<JsonCanObject> stack;
|
||||
JsonCanObject root;
|
||||
JsonCreatorDirect jj;
|
||||
String name;
|
||||
|
||||
public JsonCreatorCanonical(OutputStreamWriter osw) {
|
||||
stack = new Stack<JsonCreatorCanonical.JsonCanObject>();
|
||||
jj = new JsonCreatorDirect(osw, false, false);
|
||||
name = null;
|
||||
}
|
||||
|
||||
private String takeName() {
|
||||
String res = name;
|
||||
name = null;
|
||||
return res;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginObject() throws IOException {
|
||||
JsonCanObject obj = new JsonCanObject(takeName(), false);
|
||||
if (stack.isEmpty())
|
||||
root = obj;
|
||||
else
|
||||
stack.peek().addProp(obj);
|
||||
stack.push(obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endObject() throws IOException {
|
||||
stack.pop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nullValue() throws IOException {
|
||||
stack.peek().addProp(new JsonCanNullValue(takeName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void name(String name) throws IOException {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void value(String value) throws IOException {
|
||||
stack.peek().addProp(new JsonCanStringValue(takeName(), value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void value(Boolean value) throws IOException {
|
||||
stack.peek().addProp(new JsonCanBooleanValue(takeName(), value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void value(BigDecimal value) throws IOException {
|
||||
stack.peek().addProp(new JsonCanNumberValue(takeName(), value));
|
||||
}
|
||||
@Override
|
||||
public void valueNum(String value) throws IOException {
|
||||
stack.peek().addProp(new JsonCanPresentedNumberValue(takeName(), value));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void value(Integer value) throws IOException {
|
||||
stack.peek().addProp(new JsonCanIntegerValue(takeName(), value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginArray() throws IOException {
|
||||
JsonCanObject obj = new JsonCanObject(takeName(), true);
|
||||
if (!stack.isEmpty())
|
||||
stack.peek().addProp(obj);
|
||||
stack.push(obj);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endArray() throws IOException {
|
||||
stack.pop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish() throws IOException {
|
||||
writeObject(root);
|
||||
}
|
||||
|
||||
private void writeObject(JsonCanObject obj) throws IOException {
|
||||
jj.beginObject();
|
||||
List<String> names = new ArrayList<String>();
|
||||
for (JsonCanValue v : obj.children)
|
||||
names.add(v.name);
|
||||
Collections.sort(names);
|
||||
for (String n : names) {
|
||||
jj.name(n);
|
||||
JsonCanValue v = getPropForName(n, obj.children);
|
||||
if (v instanceof JsonCanNumberValue)
|
||||
jj.value(((JsonCanNumberValue) v).value);
|
||||
else if (v instanceof JsonCanPresentedNumberValue)
|
||||
jj.valueNum(((JsonCanPresentedNumberValue) v).value);
|
||||
else if (v instanceof JsonCanIntegerValue)
|
||||
jj.value(((JsonCanIntegerValue) v).value);
|
||||
else if (v instanceof JsonCanBooleanValue)
|
||||
jj.value(((JsonCanBooleanValue) v).value);
|
||||
else if (v instanceof JsonCanStringValue)
|
||||
jj.value(((JsonCanStringValue) v).value);
|
||||
else if (v instanceof JsonCanNullValue)
|
||||
jj.nullValue();
|
||||
else if (v instanceof JsonCanObject) {
|
||||
JsonCanObject o = (JsonCanObject) v;
|
||||
if (o.array)
|
||||
writeArray(o);
|
||||
else
|
||||
writeObject(o);
|
||||
} else
|
||||
throw new Error("not possible");
|
||||
}
|
||||
jj.endObject();
|
||||
}
|
||||
|
||||
private JsonCanValue getPropForName(String name, List<JsonCanValue> children) {
|
||||
for (JsonCanValue child : children)
|
||||
if (child.name.equals(name))
|
||||
return child;
|
||||
return null;
|
||||
}
|
||||
|
||||
private void writeArray(JsonCanObject arr) throws IOException {
|
||||
jj.beginArray();
|
||||
for (JsonCanValue v : arr.children) {
|
||||
if (v instanceof JsonCanNumberValue)
|
||||
jj.value(((JsonCanNumberValue) v).value);
|
||||
else if (v instanceof JsonCanIntegerValue)
|
||||
jj.value(((JsonCanIntegerValue) v).value);
|
||||
else if (v instanceof JsonCanBooleanValue)
|
||||
jj.value(((JsonCanBooleanValue) v).value);
|
||||
else if (v instanceof JsonCanStringValue)
|
||||
jj.value(((JsonCanStringValue) v).value);
|
||||
else if (v instanceof JsonCanNullValue)
|
||||
jj.nullValue();
|
||||
else if (v instanceof JsonCanObject) {
|
||||
JsonCanObject o = (JsonCanObject) v;
|
||||
if (o.array)
|
||||
writeArray(o);
|
||||
else
|
||||
writeObject(o);
|
||||
} else
|
||||
throw new Error("not possible");
|
||||
}
|
||||
jj.endArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void comment(String content) {
|
||||
// canonical JSON ignores comments
|
||||
}
|
||||
|
||||
@Override
|
||||
public void link(String href) {
|
||||
// not used
|
||||
}
|
||||
|
||||
@Override
|
||||
public void anchor(String name) {
|
||||
// not used
|
||||
}
|
||||
|
||||
@Override
|
||||
public void externalLink(String string) {
|
||||
// not used
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canElide() { return false; }
|
||||
|
||||
@Override
|
||||
public void elide() {
|
||||
// not used
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
package org.hl7.fhir.r5.formats;
|
||||
|
||||
package org.hl7.fhir.r5.formats;
|
||||
|
||||
/*
|
||||
Copyright (c) 2011+, HL7, Inc.
|
||||
All rights reserved.
|
||||
|
@ -28,219 +28,227 @@ package org.hl7.fhir.r5.formats;
|
|||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
|
||||
/**
|
||||
* A little implementation of a json write to replace Gson .... because Gson screws up decimal values, and *we care*
|
||||
*
|
||||
* @author Grahame Grieve
|
||||
*
|
||||
*/
|
||||
public class JsonCreatorDirect implements JsonCreator {
|
||||
|
||||
private Writer writer;
|
||||
private boolean pretty;
|
||||
private boolean comments;
|
||||
private boolean named;
|
||||
private List<Boolean> valued = new ArrayList<Boolean>();
|
||||
private int indent;
|
||||
private List<String> commentList = new ArrayList<>();
|
||||
|
||||
public JsonCreatorDirect(Writer writer, boolean pretty, boolean comments) {
|
||||
super();
|
||||
this.writer = writer;
|
||||
this.pretty = pretty;
|
||||
this.comments = pretty && comments;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void comment(String content) {
|
||||
if (comments) {
|
||||
commentList.add(content);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginObject() throws IOException {
|
||||
checkState();
|
||||
writer.write("{");
|
||||
stepIn();
|
||||
if (!valued.isEmpty()) {
|
||||
valued.set(0, true);
|
||||
}
|
||||
valued.add(0, false);
|
||||
}
|
||||
|
||||
private void commitComments() throws IOException {
|
||||
if (comments) {
|
||||
for (String s : commentList) {
|
||||
writer.write("// ");
|
||||
writer.write(s);
|
||||
writer.write("\r\n");
|
||||
for (int i = 0; i < indent; i++) {
|
||||
writer.write(" ");
|
||||
}
|
||||
}
|
||||
commentList.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void stepIn() throws IOException {
|
||||
if (pretty) {
|
||||
indent++;
|
||||
writer.write("\r\n");
|
||||
for (int i = 0; i < indent; i++) {
|
||||
writer.write(" ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void stepOut() throws IOException {
|
||||
if (pretty) {
|
||||
indent--;
|
||||
writer.write("\r\n");
|
||||
for (int i = 0; i < indent; i++) {
|
||||
writer.write(" ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkState() throws IOException {
|
||||
commitComments();
|
||||
if (named) {
|
||||
if (pretty)
|
||||
writer.write(" : ");
|
||||
else
|
||||
writer.write(":");
|
||||
named = false;
|
||||
}
|
||||
if (!valued.isEmpty() && valued.get(0)) {
|
||||
writer.write(",");
|
||||
if (pretty) {
|
||||
writer.write("\r\n");
|
||||
for (int i = 0; i < indent; i++) {
|
||||
writer.write(" ");
|
||||
}
|
||||
}
|
||||
valued.set(0, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endObject() throws IOException {
|
||||
stepOut();
|
||||
writer.write("}");
|
||||
valued.remove(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nullValue() throws IOException {
|
||||
checkState();
|
||||
writer.write("null");
|
||||
valued.set(0, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void name(String name) throws IOException {
|
||||
checkState();
|
||||
writer.write("\""+name+"\"");
|
||||
named = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void value(String value) throws IOException {
|
||||
checkState();
|
||||
writer.write("\""+Utilities.escapeJson(value)+"\"");
|
||||
valued.set(0, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void value(Boolean value) throws IOException {
|
||||
checkState();
|
||||
if (value == null)
|
||||
writer.write("null");
|
||||
else if (value.booleanValue())
|
||||
writer.write("true");
|
||||
else
|
||||
writer.write("false");
|
||||
valued.set(0, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void value(BigDecimal value) throws IOException {
|
||||
checkState();
|
||||
if (value == null)
|
||||
writer.write("null");
|
||||
else
|
||||
writer.write(value.toString());
|
||||
valued.set(0, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void valueNum(String value) throws IOException {
|
||||
checkState();
|
||||
if (value == null)
|
||||
writer.write("null");
|
||||
else
|
||||
writer.write(value);
|
||||
valued.set(0, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void value(Integer value) throws IOException {
|
||||
checkState();
|
||||
if (value == null)
|
||||
writer.write("null");
|
||||
else
|
||||
writer.write(value.toString());
|
||||
valued.set(0, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginArray() throws IOException {
|
||||
checkState();
|
||||
writer.write("[");
|
||||
if (!valued.isEmpty()) {
|
||||
valued.set(0, true);
|
||||
}
|
||||
valued.add(0, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endArray() throws IOException {
|
||||
writer.write("]");
|
||||
valued.remove(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish() throws IOException {
|
||||
writer.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void link(String href) {
|
||||
// not used
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void anchor(String name) {
|
||||
// not used
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void externalLink(String string) {
|
||||
// not used
|
||||
}
|
||||
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
|
||||
/**
|
||||
* A little implementation of a json write to replace Gson .... because Gson screws up decimal values, and *we care*
|
||||
*
|
||||
* @author Grahame Grieve
|
||||
*
|
||||
*/
|
||||
public class JsonCreatorDirect implements JsonCreator {
|
||||
|
||||
private Writer writer;
|
||||
private boolean pretty;
|
||||
private boolean comments;
|
||||
private boolean named;
|
||||
private List<Boolean> valued = new ArrayList<Boolean>();
|
||||
private int indent;
|
||||
private List<String> commentList = new ArrayList<>();
|
||||
|
||||
public JsonCreatorDirect(Writer writer, boolean pretty, boolean comments) {
|
||||
super();
|
||||
this.writer = writer;
|
||||
this.pretty = pretty;
|
||||
this.comments = pretty && comments;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void comment(String content) {
|
||||
if (comments) {
|
||||
commentList.add(content);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginObject() throws IOException {
|
||||
checkState();
|
||||
writer.write("{");
|
||||
stepIn();
|
||||
if (!valued.isEmpty()) {
|
||||
valued.set(0, true);
|
||||
}
|
||||
valued.add(0, false);
|
||||
}
|
||||
|
||||
private void commitComments() throws IOException {
|
||||
if (comments) {
|
||||
for (String s : commentList) {
|
||||
writer.write("// ");
|
||||
writer.write(s);
|
||||
writer.write("\r\n");
|
||||
for (int i = 0; i < indent; i++) {
|
||||
writer.write(" ");
|
||||
}
|
||||
}
|
||||
commentList.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void stepIn() throws IOException {
|
||||
if (pretty) {
|
||||
indent++;
|
||||
writer.write("\r\n");
|
||||
for (int i = 0; i < indent; i++) {
|
||||
writer.write(" ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void stepOut() throws IOException {
|
||||
if (pretty) {
|
||||
indent--;
|
||||
writer.write("\r\n");
|
||||
for (int i = 0; i < indent; i++) {
|
||||
writer.write(" ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkState() throws IOException {
|
||||
commitComments();
|
||||
if (named) {
|
||||
if (pretty)
|
||||
writer.write(" : ");
|
||||
else
|
||||
writer.write(":");
|
||||
named = false;
|
||||
}
|
||||
if (!valued.isEmpty() && valued.get(0)) {
|
||||
writer.write(",");
|
||||
if (pretty) {
|
||||
writer.write("\r\n");
|
||||
for (int i = 0; i < indent; i++) {
|
||||
writer.write(" ");
|
||||
}
|
||||
}
|
||||
valued.set(0, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endObject() throws IOException {
|
||||
stepOut();
|
||||
writer.write("}");
|
||||
valued.remove(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nullValue() throws IOException {
|
||||
checkState();
|
||||
writer.write("null");
|
||||
valued.set(0, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void name(String name) throws IOException {
|
||||
checkState();
|
||||
writer.write("\""+name+"\"");
|
||||
named = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void value(String value) throws IOException {
|
||||
checkState();
|
||||
writer.write("\""+Utilities.escapeJson(value)+"\"");
|
||||
valued.set(0, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void value(Boolean value) throws IOException {
|
||||
checkState();
|
||||
if (value == null)
|
||||
writer.write("null");
|
||||
else if (value.booleanValue())
|
||||
writer.write("true");
|
||||
else
|
||||
writer.write("false");
|
||||
valued.set(0, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void value(BigDecimal value) throws IOException {
|
||||
checkState();
|
||||
if (value == null)
|
||||
writer.write("null");
|
||||
else
|
||||
writer.write(value.toString());
|
||||
valued.set(0, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void valueNum(String value) throws IOException {
|
||||
checkState();
|
||||
if (value == null)
|
||||
writer.write("null");
|
||||
else
|
||||
writer.write(value);
|
||||
valued.set(0, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void value(Integer value) throws IOException {
|
||||
checkState();
|
||||
if (value == null)
|
||||
writer.write("null");
|
||||
else
|
||||
writer.write(value.toString());
|
||||
valued.set(0, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginArray() throws IOException {
|
||||
checkState();
|
||||
writer.write("[");
|
||||
if (!valued.isEmpty()) {
|
||||
valued.set(0, true);
|
||||
}
|
||||
valued.add(0, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endArray() throws IOException {
|
||||
writer.write("]");
|
||||
valued.remove(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish() throws IOException {
|
||||
writer.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void link(String href) {
|
||||
// not used
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void anchor(String name) {
|
||||
// not used
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void externalLink(String string) {
|
||||
// not used
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canElide() { return false; }
|
||||
|
||||
@Override
|
||||
public void elide() {
|
||||
// not used
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
package org.hl7.fhir.r5.formats;
|
||||
|
||||
package org.hl7.fhir.r5.formats;
|
||||
|
||||
/*
|
||||
Copyright (c) 2011+, HL7, Inc.
|
||||
All rights reserved.
|
||||
|
@ -28,103 +28,111 @@ package org.hl7.fhir.r5.formats;
|
|||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
|
||||
public class JsonCreatorGson implements JsonCreator {
|
||||
|
||||
JsonWriter gson;
|
||||
|
||||
public JsonCreatorGson(OutputStreamWriter osw) {
|
||||
gson = new JsonWriter(osw);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginObject() throws IOException {
|
||||
gson.beginObject();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endObject() throws IOException {
|
||||
gson.endObject();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nullValue() throws IOException {
|
||||
gson.nullValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void name(String name) throws IOException {
|
||||
gson.name(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void value(String value) throws IOException {
|
||||
gson.value(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void value(Boolean value) throws IOException {
|
||||
gson.value(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void value(BigDecimal value) throws IOException {
|
||||
gson.value(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void value(Integer value) throws IOException {
|
||||
gson.value(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginArray() throws IOException {
|
||||
gson.beginArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endArray() throws IOException {
|
||||
gson.endArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish() {
|
||||
// nothing to do here
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void link(String href) {
|
||||
// not used
|
||||
}
|
||||
|
||||
@Override
|
||||
public void valueNum(String value) throws IOException {
|
||||
value(new BigDecimal(value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void anchor(String name) {
|
||||
// not used
|
||||
}
|
||||
|
||||
@Override
|
||||
public void comment(String content) {
|
||||
// gson (dense json) ignores comments
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void externalLink(String string) {
|
||||
// not used
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
|
||||
public class JsonCreatorGson implements JsonCreator {
|
||||
|
||||
JsonWriter gson;
|
||||
|
||||
public JsonCreatorGson(OutputStreamWriter osw) {
|
||||
gson = new JsonWriter(osw);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginObject() throws IOException {
|
||||
gson.beginObject();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endObject() throws IOException {
|
||||
gson.endObject();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nullValue() throws IOException {
|
||||
gson.nullValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void name(String name) throws IOException {
|
||||
gson.name(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void value(String value) throws IOException {
|
||||
gson.value(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void value(Boolean value) throws IOException {
|
||||
gson.value(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void value(BigDecimal value) throws IOException {
|
||||
gson.value(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void value(Integer value) throws IOException {
|
||||
gson.value(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginArray() throws IOException {
|
||||
gson.beginArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endArray() throws IOException {
|
||||
gson.endArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish() {
|
||||
// nothing to do here
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void link(String href) {
|
||||
// not used
|
||||
}
|
||||
|
||||
@Override
|
||||
public void valueNum(String value) throws IOException {
|
||||
value(new BigDecimal(value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void anchor(String name) {
|
||||
// not used
|
||||
}
|
||||
|
||||
@Override
|
||||
public void comment(String content) {
|
||||
// gson (dense json) ignores comments
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void externalLink(String string) {
|
||||
// not used
|
||||
}
|
||||
|
||||
@Override
|
||||
public void elide() {
|
||||
// not used
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canElide() { return false;}
|
||||
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
package org.hl7.fhir.utilities.xml;
|
||||
|
||||
package org.hl7.fhir.utilities.xml;
|
||||
|
||||
/*
|
||||
Copyright (c) 2011+, HL7, Inc.
|
||||
All rights reserved.
|
||||
|
@ -28,80 +28,85 @@ package org.hl7.fhir.utilities.xml;
|
|||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.hl7.fhir.utilities.ElementDecoration;
|
||||
|
||||
|
||||
/**
|
||||
* Generalize
|
||||
* @author dennisn
|
||||
*/
|
||||
public interface IXMLWriter {
|
||||
|
||||
public abstract void start() throws IOException;
|
||||
public abstract void end() throws IOException;
|
||||
|
||||
public abstract void attribute(String namespace, String name, String value, boolean onlyIfNotEmpty) throws IOException;
|
||||
public abstract void attribute(String namespace, String name, String value) throws IOException;
|
||||
public abstract void attribute(String name, String value, boolean onlyIfNotEmpty) throws IOException;
|
||||
public abstract void attribute(String name, String value) throws IOException;
|
||||
public abstract void attributeNoLines(String name, String value) throws IOException;
|
||||
|
||||
public abstract boolean namespaceDefined(String namespace);
|
||||
public abstract boolean abbreviationDefined(String abbreviation);
|
||||
public abstract String getDefaultNamespace();
|
||||
public abstract void namespace(String namespace) throws IOException;
|
||||
public abstract void setDefaultNamespace(String namespace) throws IOException;
|
||||
public abstract void namespace(String namespace, String abbreviation) throws IOException;
|
||||
|
||||
public abstract void comment(String comment, boolean doPretty) throws IOException;
|
||||
public abstract void decorate(ElementDecoration decoration) throws IOException;
|
||||
public abstract void setSchemaLocation(String ns, String loc) throws IOException;
|
||||
|
||||
public abstract void enter(String name) throws IOException;
|
||||
public abstract void enter(String namespace, String name) throws IOException;
|
||||
public abstract void enter(String namespace, String name, String comment) throws IOException;
|
||||
|
||||
public abstract void exit() throws IOException;
|
||||
public abstract void exit(String name) throws IOException;
|
||||
public abstract void exit(String namespace, String name) throws IOException;
|
||||
public abstract void exitToLevel(int count) throws IOException;
|
||||
|
||||
|
||||
public abstract void element(String namespace, String name, String content, boolean onlyIfNotEmpty) throws IOException;
|
||||
public abstract void element(String namespace, String name, String content, String comment) throws IOException;
|
||||
public abstract void element(String namespace, String name, String content) throws IOException;
|
||||
public abstract void element(String name, String content, boolean onlyIfNotEmpty) throws IOException;
|
||||
public abstract void element(String name, String content) throws IOException;
|
||||
public abstract void element(String name) throws IOException;
|
||||
|
||||
public abstract void text(String content) throws IOException;
|
||||
public abstract void text(String content, boolean dontEscape) throws IOException;
|
||||
|
||||
public abstract void cData(String text) throws IOException;
|
||||
|
||||
public abstract void writeBytes(byte[] bytes) throws IOException;
|
||||
|
||||
public abstract boolean isPretty() throws IOException;
|
||||
public abstract void setPretty(boolean pretty) throws IOException;
|
||||
|
||||
/**
|
||||
* Start comment inserts a <!-- in the stream, but allows the user to
|
||||
* go on creating xml content as usual, with proper formatting applied etc.
|
||||
* Any comments inserted inside a comment will be terminated with -- > instead of -->
|
||||
* so the comment doesn't close prematurely.
|
||||
* @throws IOException
|
||||
*/
|
||||
public abstract void startCommentBlock() throws IOException;
|
||||
public abstract void endCommentBlock() throws IOException;
|
||||
public abstract void escapedText(String content) throws IOException;
|
||||
|
||||
// this is only implemented by an implementation that is producing an xhtml representation, and is able to render elements as hyperlinks
|
||||
public abstract void link(String href);
|
||||
public abstract void anchor(String name);
|
||||
public abstract void externalLink(String ref) throws IOException;
|
||||
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.hl7.fhir.utilities.ElementDecoration;
|
||||
|
||||
|
||||
/**
|
||||
* Generalize
|
||||
* @author dennisn
|
||||
*/
|
||||
public interface IXMLWriter {
|
||||
|
||||
public abstract void start() throws IOException;
|
||||
public abstract void end() throws IOException;
|
||||
|
||||
public abstract void attribute(String namespace, String name, String value, boolean onlyIfNotEmpty) throws IOException;
|
||||
public abstract void attribute(String namespace, String name, String value) throws IOException;
|
||||
public abstract void attribute(String name, String value, boolean onlyIfNotEmpty) throws IOException;
|
||||
public abstract void attribute(String name, String value) throws IOException;
|
||||
public abstract void attributeNoLines(String name, String value) throws IOException;
|
||||
|
||||
public abstract boolean namespaceDefined(String namespace);
|
||||
public abstract boolean abbreviationDefined(String abbreviation);
|
||||
public abstract String getDefaultNamespace();
|
||||
public abstract void namespace(String namespace) throws IOException;
|
||||
public abstract void setDefaultNamespace(String namespace) throws IOException;
|
||||
public abstract void namespace(String namespace, String abbreviation) throws IOException;
|
||||
|
||||
public abstract void comment(String comment, boolean doPretty) throws IOException;
|
||||
public abstract void decorate(ElementDecoration decoration) throws IOException;
|
||||
public abstract void setSchemaLocation(String ns, String loc) throws IOException;
|
||||
|
||||
public abstract void enter(String name) throws IOException;
|
||||
public abstract void enter(String namespace, String name) throws IOException;
|
||||
public abstract void enter(String namespace, String name, String comment) throws IOException;
|
||||
|
||||
public abstract void exit() throws IOException;
|
||||
public abstract void exit(String name) throws IOException;
|
||||
public abstract void exit(String namespace, String name) throws IOException;
|
||||
public abstract void exitToLevel(int count) throws IOException;
|
||||
|
||||
|
||||
public abstract void element(String namespace, String name, String content, boolean onlyIfNotEmpty) throws IOException;
|
||||
public abstract void element(String namespace, String name, String content, String comment) throws IOException;
|
||||
public abstract void element(String namespace, String name, String content) throws IOException;
|
||||
public abstract void element(String name, String content, boolean onlyIfNotEmpty) throws IOException;
|
||||
public abstract void element(String name, String content) throws IOException;
|
||||
public abstract void element(String name) throws IOException;
|
||||
|
||||
public abstract void text(String content) throws IOException;
|
||||
public abstract void text(String content, boolean dontEscape) throws IOException;
|
||||
|
||||
public abstract void cData(String text) throws IOException;
|
||||
|
||||
public abstract void writeBytes(byte[] bytes) throws IOException;
|
||||
|
||||
public abstract boolean isPretty() throws IOException;
|
||||
public abstract void setPretty(boolean pretty) throws IOException;
|
||||
|
||||
/**
|
||||
* Start comment inserts a <!-- in the stream, but allows the user to
|
||||
* go on creating xml content as usual, with proper formatting applied etc.
|
||||
* Any comments inserted inside a comment will be terminated with -- > instead of -->
|
||||
* so the comment doesn't close prematurely.
|
||||
* @throws IOException
|
||||
*/
|
||||
public abstract void startCommentBlock() throws IOException;
|
||||
public abstract void endCommentBlock() throws IOException;
|
||||
public abstract void escapedText(String content) throws IOException;
|
||||
|
||||
// this is only implemented by an implementation that is producing an xhtml representation, and is able to render elements as hyperlinks
|
||||
public abstract void link(String href);
|
||||
public abstract void anchor(String name);
|
||||
public abstract void externalLink(String ref) throws IOException;
|
||||
|
||||
// this is only implemented by an implementation that is producing an xhtml representation and handles ellipsing elements
|
||||
public abstract boolean canElide();
|
||||
public abstract void elide() throws IOException;
|
||||
public abstract void attributeElide();
|
||||
}
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue