IPS development

This commit is contained in:
Grahame Grieve 2023-12-22 21:23:34 +11:00
parent 74893e42e7
commit 70af787438
7 changed files with 628 additions and 14 deletions

View File

@ -0,0 +1,440 @@
package org.hl7.fhir.r5.ips;
import java.util.Date;
import java.util.List;
import org.hl7.fhir.r5.ips.IPSBuilder.TypeAndId;
import org.hl7.fhir.r5.model.Age;
import org.hl7.fhir.r5.model.Annotation;
import org.hl7.fhir.r5.model.Bundle;
import org.hl7.fhir.r5.model.Bundle.BundleEntryComponent;
import org.hl7.fhir.r5.model.Bundle.BundleType;
import org.hl7.fhir.r5.model.CodeableConcept;
import org.hl7.fhir.r5.model.CodeableReference;
import org.hl7.fhir.r5.model.Coding;
import org.hl7.fhir.r5.model.Composition;
import org.hl7.fhir.r5.model.Patient;
import org.hl7.fhir.r5.model.Period;
import org.hl7.fhir.r5.model.Quantity;
import org.hl7.fhir.r5.model.Range;
import org.hl7.fhir.r5.model.Reference;
import org.hl7.fhir.r5.model.Composition.SectionComponent;
import org.hl7.fhir.r5.model.Condition;
import org.hl7.fhir.r5.model.Condition.ConditionParticipantComponent;
import org.hl7.fhir.r5.model.DataType;
import org.hl7.fhir.r5.model.Device;
import org.hl7.fhir.r5.model.DomainResource;
import org.hl7.fhir.r5.model.Dosage;
import org.hl7.fhir.r5.model.Enumerations.CompositionStatus;
import org.hl7.fhir.r5.model.Identifier;
import org.hl7.fhir.r5.model.Medication;
import org.hl7.fhir.r5.model.MedicationStatement;
import org.hl7.fhir.r5.model.Narrative.NarrativeStatus;
import org.hl7.fhir.r5.utils.client.FHIRToolingClient;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.VersionUtil;
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
public class IPSBuilder {
public static class TypeAndId {
private String type;
private String id;
protected TypeAndId(String type, String id) {
super();
this.type = type;
this.id = id;
}
public String getType() {
return type;
}
public String getId() {
return id;
}
}
public static Bundle generateIPS(FHIRToolingClient server, String patientId) {
Patient pat = server.fetchResource(Patient.class, patientId);
Bundle bnd = initBundle();
Composition cmp = initComposition(bnd, server.getAddress(), pat);
pat = processPatient(bnd, server.getAddress(), pat);
// addMedications(bnd, cmp, server, patientId);
addConditions(bnd, cmp, server, patientId);
return bnd;
}
private static Bundle initBundle() {
Bundle bnd = new Bundle();
bnd.getIdentifier().setSystem("urn:ietf:rfc:3986");
bnd.getIdentifier().setValue(Utilities.makeUuidUrn());
bnd.setType(BundleType.DOCUMENT);
bnd.setTimestamp(new Date());
return bnd;
}
private static Composition initComposition(Bundle bnd, String url, Patient pat) {
Composition cmp = new Composition();
cmp.setIdBase(Utilities.makeUuidLC());
cmp.setStatus(CompositionStatus.FINAL);
cmp.getType().addCoding().setSystem("http://loinc.org").setCode("60591-5");
cmp.setDate(new Date());
cmp.setTitle("International Patient Summary");
cmp.addSubject().setReference("Patient/"+pat.getIdBase());
cmp.addAuthor().setReference("Device/java");
bnd.addEntry().setResource(cmp).setFullUrl(Utilities.pathURL(url, "Composition", cmp.getIdBase()));
Device dev = new Device();
dev.setId("java");
dev.addName().setValue("Java Core Library");
dev.addVersion().setValue(VersionUtil.getVersion());
bnd.addEntry().setResource(dev).setFullUrl(Utilities.pathURL(url, "Device", dev.getIdBase()));
return cmp;
}
private static Patient processPatient(Bundle bnd, String url, Patient pat) {
bnd.addEntry().setResource(pat).setFullUrl(Utilities.pathURL(url, "Patient", pat.getIdBase()));
return pat;
}
private static void addMedications(Bundle bnd, Composition cmp, FHIRToolingClient server, String patientId) {
Bundle sb = server.search("MedicationStatement", "?patient="+patientId+"&_include=MedicationStatement:medication&_include=MedicationStatement:source");
SectionComponent sct = cmp.addSection();
sct.setTitle("Medications");
sct.getCode().addCoding().setSystem("http://loinc.org").setCode("10160-0");
sct.getText().setStatus(NarrativeStatus.GENERATED);
var x = sct.getText().getDiv();
var tbl = x.table("grid");
var tr = tbl.tr();
tr.th().tx("Medication");
tr.th().tx("Category");
tr.th().tx("Status");
tr.th().tx("When");
tr.th().tx("Dosage");
tr.th().tx("Reason");
tr.th().tx("Source");
tr.th().tx("Notes");
boolean ok = false;
for (BundleEntryComponent be : sb.getEntry()) {
if (be.hasResource() && be.getResource() instanceof MedicationStatement) {
MedicationStatement mdstmt = (MedicationStatement) be.getResource();
ok = true;
bnd.addEntry().setResource(mdstmt).setFullUrl(Utilities.pathURL(server.getAddress(), "MedicationStatement", mdstmt.getIdBase()));
sct.addEntry().setReference("MedicationStatement/"+mdstmt.getIdBase());
tr = tbl.tr();
if (mdstmt.hasMedication() && mdstmt.getMedication().hasReference()) {
Medication med = findMedication(sb, server, mdstmt, mdstmt.getMedication().getReference());
if (med == null) {
tr.td().b().tx("Unknown?");
} else {
tr.td().tx(summarise(med));
bnd.addEntry().setResource(med).setFullUrl(Utilities.pathURL(server.getAddress(), "Medication", med.getIdBase()));
}
} else {
tr.td().tx(genCC(mdstmt.getMedication().getConcept()));
}
tr.td().tx(genCC(mdstmt.getCategory()));
var td = tr.td();
td.tx(mdstmt.getStatus().getDisplay());
if (mdstmt.hasReason()) {
td.tx(" (");
for (CodeableReference cc : mdstmt.getReason()) {
if (cc.hasConcept()) {
td.tx(genCC(cc.getConcept()));
} else {
td.tx(genReference(mdstmt, cc.getReference(), bnd, sb, server));
}
}
td.tx(")");
}
tr.td().tx(genDT(mdstmt.getEffective()));
genDosages(tr.td(), mdstmt.getDosage());
for (Reference is : mdstmt.getInformationSource()) {
tr.td().tx(genReference(mdstmt, is, bnd, sb, server));
}
genNotes(tr.td(), mdstmt.getNote());
}
}
if (!ok) {
Condition cnd = new Condition();
cnd.setId(Utilities.makeUuidLC());
cnd.getText().setStatus(NarrativeStatus.GENERATED);
var rx = cnd.getText().getDiv();
rx.tx("No information is provided about the patient's medical problems");
tr = tbl.tr();
tr.td().colspan(7).tx("No information is provided about the patient's medical problems");
cnd.getClinicalStatus().addCoding().setSystem("http://terminology.hl7.org/CodeSystem/condition-clinical").setCode("active").setDisplay("Active");
cnd.getCode().addCoding().setSystem("http://hl7.org/fhir/uv/ips/CodeSystem/absent-unknown-uv-ips").setCode("no-problem-info").setDisplay("No information about current problems");
cnd.getSubject().setReference("Patient/"+patientId);
}
}
private static void genDosages(XhtmlNode x, List<Dosage> dosages) {
if (dosages == null || dosages.size() == 0) {
} else if (dosages.size() == 1) {
genDosage(x, dosages.get(0));
} else {
var ul = x.ul();
for (Dosage d : dosages) {
genDosage(ul.li(), d);
}
}
}
private static void genDosage(XhtmlNode x, Dosage dosage) {
x.tx(dosage.getText());
if (dosage.hasAsNeeded() || dosage.hasAsNeededFor()) {
x.nbsp();
if (dosage.hasAsNeeded()) {
if (dosage.getAsNeeded()) {
x.tx(" (as needed)");
}
} else {
for (CodeableConcept cc : dosage.getAsNeededFor()) {
x.tx(genDT(cc));
}
}
} else if (dosage.hasTiming()) {
x.nbsp();
x.tx(genDT(dosage.getTiming()));
}
if (dosage.hasSite()) {
x.tx(". ");
x.tx(genDT(dosage.getSite()));
}
if (dosage.hasRoute()) {
x.tx(". ");
x.tx(genDT(dosage.getRoute()));
}
}
private static Medication findMedication(Bundle sb, FHIRToolingClient server, MedicationStatement mdstmt, Reference ref) {
if (ref == null || !ref.hasReference()) {
return null;
}
if (ref.getReference().startsWith("#")) {
} else {
}
return null;
}
private static void addConditions(Bundle bnd, Composition cmp, FHIRToolingClient server, String patientId) {
Bundle sb = server.search("Condition", "?patient="+patientId+"&_include=Condition:asserter");
SectionComponent sct = cmp.addSection();
sct.setTitle("Problems");
sct.getCode().addCoding().setSystem("http://loinc.org").setCode("11450-4");
sct.getText().setStatus(NarrativeStatus.GENERATED);
var x = sct.getText().getDiv();
var tbl = x.table("grid");
var tr = tbl.tr();
tr.th().tx("Code");
tr.th().tx("Category");
tr.th().tx("Severity");
tr.th().tx("Status");
tr.th().tx("Onset");
tr.th().tx("Abatement");
tr.th().tx("Source");
tr.th().tx("Notes");
boolean ok = false;
for (BundleEntryComponent be : sb.getEntry()) {
if (be.hasResource() && be.getResource() instanceof Condition) {
Condition cnd = (Condition) be.getResource();
ok = true;
bnd.addEntry().setResource(cnd).setFullUrl(Utilities.pathURL(server.getAddress(), "Condition", cnd.getIdBase()));
sct.addEntry().setReference("Condition/"+cnd.getIdBase());
tr = tbl.tr();
tr.td().tx(genCC(cnd.getCode()));
tr.td().tx(genCC(cnd.getCategory()));
tr.td().tx(genCC(cnd.getSeverity()));
tr.td().tx(genStatus(cnd));
tr.td().tx(genDT(cnd.getOnset()));
tr.td().tx(genDT(cnd.getAbatement()));
tr.td().tx(genSource(cnd, bnd, sb, server));
genNotes(tr.td(), cnd.getNote());
}
}
if (!ok) {
Condition cnd = new Condition();
cnd.setId(Utilities.makeUuidLC());
cnd.getText().setStatus(NarrativeStatus.GENERATED);
var rx = cnd.getText().getDiv();
rx.tx("No information is provided about the patient's medical problems");
tr = tbl.tr();
tr.td().colspan(7).tx("No information is provided about the patient's medical problems");
cnd.getClinicalStatus().addCoding().setSystem("http://terminology.hl7.org/CodeSystem/condition-clinical").setCode("active").setDisplay("Active");
cnd.getCode().addCoding().setSystem("http://hl7.org/fhir/uv/ips/CodeSystem/absent-unknown-uv-ips").setCode("no-problem-info").setDisplay("No information about current problems");
cnd.getSubject().setReference("Patient/"+patientId);
}
}
private static String genReference(DomainResource src, Reference ref, Bundle bnd, Bundle search, FHIRToolingClient server) {
if (ref == null || ref.isEmpty()) {
return null;
}
boolean contained = false;
DomainResource tgt = null;
if (ref.hasReference()) {
if (ref.getReference().startsWith("#")) {
tgt = (DomainResource) src.getContained(ref.getReference());
contained = true;
} else {
TypeAndId tid = getTypeAndId(server.getAddress(), ref.getReference());
if (tid != null) {
tgt = findInBundle(bnd, Utilities.pathURL(server.getAddress(), tid.getType(), tid.getId()));
if (tgt == null) {
tgt = findInBundle(search, Utilities.pathURL(server.getAddress(), tid.getType(), tid.getId()));
if (tgt == null) {
tgt = (DomainResource) server.read(tid.getType(), tid.getId());
}
} else {
contained = true;
}
}
}
}
if (tgt != null) {
if (!contained) {
bnd.addEntry().setResource(tgt).setFullUrl(Utilities.pathURL(server.getAddress(), tgt.fhirType(), tgt.getIdBase()));
}
return summarise(tgt);
} else if (ref.hasDisplay()) {
return ref.getDisplay();
} else if (ref.hasReference()) {
return ref.getReference();
} else if (ref.hasIdentifier()) {
return genIdentifier(ref.getIdentifier());
} else {
return "unknown";
}
}
private static TypeAndId getTypeAndId(String baseUrl, String url) {
if (Utilities.noString(url)) {
return null;
}
if (url.startsWith(baseUrl+"/")) {
url = url.substring(baseUrl.length()+1);
}
String[] p = url.split("\\/");
if (p.length > 1) {
if ("_history".equals(p[p.length-2]) && p.length > 3) {
return new TypeAndId(p[p.length-4], p[p.length-3]);
} else {
return new TypeAndId(p[p.length-2], p[p.length-1]);
}
}
return null;
}
private static DomainResource findInBundle(Bundle bnd, String url) {
for (BundleEntryComponent be : bnd.getEntry()) {
if (url.equals(be.getFullUrl()) && be.hasResource() && be.getResource() instanceof DomainResource) {
return (DomainResource) be.getResource();
}
}
return null;
}
private static String summarise(DomainResource tgt) {
// TODO Auto-generated method stub
return null;
}
private static String genIdentifier(Identifier id) {
return id.getValue();
}
private static void genNotes(XhtmlNode td, List<Annotation> notes) {
if (notes.size() > 0) {
if (notes.size() == 1) {
genNote(td, notes.get(0));
} else {
var ul = td.ul();
for (Annotation a : notes) {
genNote(ul.li(), a);
}
}
}
}
private static void genNote(XhtmlNode td, Annotation annotation) {
td.tx(annotation.getText());
}
private static String genSource(Condition cnd, Bundle bnd, Bundle sb, FHIRToolingClient server) {
for (ConditionParticipantComponent t: cnd.getParticipant()) {
return genCC(t.getFunction()) + " : "+genReference(cnd, t.getActor(), bnd, sb, server);
}
return "";
}
private static String genDT(DataType v) {
if (v == null) {
return null;
}
if (v.isPrimitive()) {
return v.primitiveValue();
}
if (v instanceof Age) {
return genQty((Age) v);
}
if (v instanceof Period) {
Period p = (Period) v;
return genDT(p.getStartElement())+" - "+genDT(p.getStartElement());
}
if (v instanceof Range) {
Range p = (Range) v;
return genDT(p.getLow())+" - "+genDT(p.getHigh());
}
return "not done: "+v.fhirType();
}
private static String genQty(Quantity v) {
return v.getValue().toPlainString()+v.getUnit();
}
private static String genStatus(Condition cnd) {
if (cnd.hasClinicalStatus() && cnd.hasVerificationStatus()) {
return genCC(cnd.getClinicalStatus()) +"/"+genCC(cnd.getVerificationStatus());
} else if (cnd.hasClinicalStatus()) {
return genCC(cnd.getClinicalStatus());
} else if (cnd.hasVerificationStatus()) {
return genCC(cnd.getVerificationStatus());
} else {
return null;
}
}
private static String genCC(List<CodeableConcept> list) {
if (list != null && list.size() == 1) {
return genCC(list.get(0));
} else {
return null;
}
}
private static String genCC(CodeableConcept code) {
if (code.hasText()) {
return code.getText();
} else if (code.hasCoding()) {
Coding c = code.getCodingFirstRep();
if (c.hasDisplay()) {
return c.getDisplay();
} else {
return c.getCode();
}
} else {
return null;
}
}
}

View File

@ -0,0 +1,100 @@
package org.hl7.fhir.r5.ips;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.hl7.fhir.r5.ips.IPSRenderer.InternalTemplateEngine;
import org.hl7.fhir.r5.model.Bundle;
import org.hl7.fhir.r5.model.Composition;
import org.hl7.fhir.r5.model.Composition.SectionComponent;
import org.hl7.fhir.r5.model.DomainResource;
import org.hl7.fhir.r5.model.Reference;
import org.hl7.fhir.r5.terminologies.client.ITerminologyClient;
import org.hl7.fhir.utilities.xhtml.NodeType;
import org.hl7.fhir.utilities.xhtml.XhtmlComposer;
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
public class IPSRenderer {
public class InternalTemplateEngine implements ITemplateImplementer {
@Override
public String buildPage(Map<String, String> headers, String content) {
// TODO Auto-generated method stub
return null;
}
}
private interface ITemplateImplementer {
public String buildPage(Map<String, String> headers, String content);
}
private ITerminologyClient tx;
private String folder; // for images etc
private Map<String, byte[]> binaries; // from the pubpack
private ITemplateImplementer templater;
private Map<String, String> headers;
public IPSRenderer(ITerminologyClient tx, String folder, Map<String, byte[]> binaries, ITemplateImplementer templater) {
super();
this.tx = tx;
this.folder = folder;
this.binaries = binaries;
this.templater = templater;
}
public IPSRenderer(ITerminologyClient tx, String folder, Map<String, byte[]> binaries) {
super();
this.tx = tx;
this.folder = folder;
this.binaries = binaries;
this.templater = new InternalTemplateEngine();
}
public String render(Bundle document) throws IOException {
headers = new HashMap<>();
XhtmlNode x = new XhtmlNode(NodeType.Element, "div");
generate(x, document);
return templater.buildPage(headers, new XhtmlComposer(false, true).compose(x));
}
private void generate(XhtmlNode x, Bundle document) {
Composition cmp = (Composition) document.getEntryFirstRep().getResource();
int sectionDepth = findSectionDepth(cmp.getSection());
XhtmlNode table = x.table("grid");
// row 1: header
XhtmlNode tr = table.tr();
XhtmlNode td = tr.td().colspan(1+sectionDepth);
td.b().tx("Provided");
td = tr.td().colspan(1+sectionDepth);
td.b().tx("Generated");
// row 2: Subject
DomainResource subject = findResource(document, cmp.getSubjectFirstRep());
tr = table.tr();
td = tr.td().colspan(1+sectionDepth);
// genNarrative("subject", subject, td);
td = tr.td().colspan(1+sectionDepth);
td.b().tx("Generated");
}
private DomainResource findResource(Bundle document, Reference subject) {
// TODO Auto-generated method stub
return null;
}
private int findSectionDepth(List<SectionComponent> list) {
int i = 1;
for (SectionComponent sect : list) {
i = Integer.max(i, 1+findSectionDepth(sect.getSection()));
}
return i;
}
}

View File

@ -3,6 +3,10 @@ package org.hl7.fhir.r5.utils.client;
import okhttp3.Headers;
import okhttp3.internal.http2.Header;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r5.model.Bundle;
import org.hl7.fhir.r5.model.OperationOutcome;
import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.r5.utils.client.EFhirClientException;
/*
Copyright (c) 2011+, HL7, Inc.
@ -200,6 +204,23 @@ public class FHIRToolingClient extends FHIRBaseToolingClient {
return capabilities;
}
public Resource read(String resourceClass, String id) {// TODO Change this to AddressableResource
ResourceRequest<Resource> result = null;
try {
result = client.issueGetResourceRequest(resourceAddress.resolveGetUriFromResourceClassAndId(resourceClass, id),
getPreferredResourceFormat(), generateHeaders(), "Read " + resourceClass + "/" + id,
timeoutNormal);
if (result.isUnsuccessfulRequest()) {
throw new EFhirClientException("Server returned error code " + result.getHttpStatus(),
(OperationOutcome) result.getPayload());
}
} catch (Exception e) {
throw new FHIRException(e);
}
return result.getPayload();
}
public <T extends Resource> T read(Class<T> resourceClass, String id) {//TODO Change this to AddressableResource
ResourceRequest<T> result = null;
try {
@ -622,7 +643,25 @@ public class FHIRToolingClient extends FHIRBaseToolingClient {
public void setLanguage(String lang) {
this.acceptLang = lang;
}
public Bundle search(String type, String criteria) {
return fetchFeed(Utilities.pathURL(base, type+criteria));
}
public <T extends Resource> T fetchResource(Class<T> resourceClass, String id) {
org.hl7.fhir.r5.utils.client.network.ResourceRequest<Resource> result = null;
try {
result = client.issueGetResourceRequest(resourceAddress.resolveGetResource(resourceClass, id),
getPreferredResourceFormat(), generateHeaders(), resourceClass.getName()+"/"+id, timeoutNormal);
} catch (IOException e) {
throw new FHIRException(e);
}
if (result.isUnsuccessfulRequest()) {
throw new EFhirClientException("Server returned error code " + result.getHttpStatus(),
(OperationOutcome) result.getPayload());
}
return (T) result.getPayload();
}
}

View File

@ -78,6 +78,15 @@ public class ResourceAddress {
return this.baseServiceUri;
}
public URI resolveGetUriFromResourceClassAndId(String resourceClass, String id) {
return baseServiceUri.resolve(resourceClass + "/" + id);
}
public <T extends Resource> URI resolveGetResource(Class<T> resourceClass, String id) {
return baseServiceUri.resolve(nameForClassWithSlash(resourceClass) + "/" + id);
}
public <T extends Resource> URI resolveOperationURLFromClass(Class<T> resourceClass, String name, String parameters) {
return baseServiceUri.resolve(nameForClassWithSlash(resourceClass) +"$"+name+"?"+ parameters);
}

View File

@ -1038,6 +1038,7 @@ public class I18nConstants {
public static final String XHTML_IDREF_NOT_FOUND = "XHTML_IDREF_NOT_FOUND";
public static final String XHTML_IDREF_NOT_MULTIPLE_MATCHES = "XHTML_IDREF_NOT_MULTIPLE_MATCHES";
public static final String SD_CONTEXT_SHOULD_NOT_BE_FHIRPATH = "SD_CONTEXT_SHOULD_NOT_BE_FHIRPATH";
public static final String TX_GENERAL_CC_ERROR_MESSAGE = "TX_GENERAL_CC_ERROR_MESSAGE";
}

View File

@ -49,6 +49,7 @@ public class JsonLexer {
private boolean allowUnquotedStrings;
private List<JsonComment> comments = new ArrayList<>();
private boolean isUnquoted;
private String sourceName;
public JsonLexer(String source, boolean allowComments, boolean allowUnquotedStrings) throws IOException {
this.source = source;
@ -116,7 +117,7 @@ public class JsonLexer {
}
public IOException error(String msg) {
return new IOException("Error parsing JSON source: "+msg+" at Line "+Integer.toString(location.getLine())+" (path=["+path()+"])");
return new IOException("Error parsing JSON source: "+msg+" at Line "+Integer.toString(location.getLine())+" (path=["+path()+"])"+(sourceName == null ? "" : " from '"+sourceName+"'"));
}
private String path() {
@ -300,5 +301,13 @@ public class JsonLexer {
return "JsonLexer [cursor=" + cursor + ", peek=" + peek + ", type=" + type + ", location=" + location.toString() + "]";
}
public String getSourceName() {
return sourceName;
}
public void setSourceName(String sourceName) {
this.sourceName = sourceName;
}
}

View File

@ -52,43 +52,46 @@ import org.hl7.fhir.utilities.json.parser.JsonLexer.TokenType;
public class JsonParser {
public static JsonObject parseObject(InputStream stream) throws IOException, JsonException {
return parseObject(TextFile.streamToString(stream));
return new JsonParser().parseJsonObject(TextFile.streamToString(stream), false, false);
}
public static JsonObject parseObject(byte[] stream) throws IOException, JsonException {
return parseObject(TextFile.bytesToString(stream));
public static JsonObject parseObject(byte[] content) throws IOException, JsonException {
return new JsonParser().parseJsonObject(TextFile.bytesToString(content), false, false);
}
public static JsonObject parseObject(String source) throws IOException, JsonException {
return parseObject(source, false);
return new JsonParser().parseJsonObject(source, false, false);
}
public static JsonObject parseObject(File source) throws IOException, JsonException {
return parseObject(TextFile.fileToString(source));
if (!source.exists()) {
throw new IOException("File "+source+" not found");
}
return new JsonParser().setSourceName(source.getAbsolutePath()).parseJsonObject(TextFile.fileToString(source), false, false);
}
public static JsonObject parseObjectFromFile(String source) throws IOException, JsonException {
return parseObject(TextFile.fileToString(source));
return new JsonParser().setSourceName(source).parseJsonObject(TextFile.fileToString(source), false, false);
}
public static JsonObject parseObjectFromUrl(String source) throws IOException, JsonException {
return parseObject(fetch(source));
return new JsonParser().setSourceName(source).parseJsonObject(TextFile.bytesToString(fetch(source)), false, false);
}
public static JsonObject parseObject(InputStream stream, boolean isJson5) throws IOException, JsonException {
return parseObject(TextFile.streamToString(stream), isJson5);
return new JsonParser().parseJsonObject(TextFile.streamToString(stream), isJson5, false);
}
public static JsonObject parseObject(byte[] stream, boolean isJson5) throws IOException, JsonException {
return parseObject(TextFile.bytesToString(stream), isJson5);
public static JsonObject parseObject(byte[] content, boolean isJson5) throws IOException, JsonException {
return new JsonParser().parseJsonObject(TextFile.bytesToString(content), isJson5, false);
}
public static JsonObject parseObject(String source, boolean isJson5) throws IOException, JsonException {
return parseObject(source, isJson5, false);
return new JsonParser().parseJsonObject(source, isJson5, false);
}
public static JsonObject parseObjectFromUrl(String source, boolean isJson5) throws IOException, JsonException {
return parseObject(fetch(source), isJson5);
return new JsonParser().setSourceName(source).parseJsonObject(TextFile.bytesToString(fetch(source)), isJson5, false);
}
public static JsonObject parseObject(InputStream stream, boolean isJson5, boolean allowDuplicates) throws IOException, JsonException {
@ -98,7 +101,7 @@ public class JsonParser {
public static JsonObject parseObject(byte[] stream, boolean isJson5, boolean allowDuplicates) throws IOException, JsonException {
return parseObject(TextFile.bytesToString(stream), isJson5, allowDuplicates);
}
public static JsonObject parseObject(String source, boolean isJson5, boolean allowDuplicates) throws IOException, JsonException {
return new JsonParser().parseJsonObject(source, isJson5, allowDuplicates);
}
@ -216,6 +219,7 @@ public class JsonParser {
private boolean allowUnquotedStrings;
private boolean itemUnquoted;
private boolean valueUnquoted;
private String sourceName;
private JsonObject parseJsonObject(String source, boolean isJson5, boolean allowDuplicates) throws IOException, JsonException {
this.allowDuplicates = allowDuplicates;
@ -227,6 +231,7 @@ public class JsonParser {
private JsonObject parseSource(String source) throws IOException, JsonException {
lexer = new JsonLexer(source, allowComments, allowUnquotedStrings);
lexer.setSourceName(sourceName);
JsonObject result = new JsonObject();
lexer.takeComments(result);
result.setStart(lexer.getLastLocationAWS().copy());
@ -671,4 +676,15 @@ public class JsonParser {
res.checkThrowException();
return res.getContent();
}
public String getSourceName() {
return sourceName;
}
public JsonParser setSourceName(String sourceName) {
this.sourceName = sourceName;
return this;
}
}