NPMPackage direct loading, + refactor JSON parser Location

This commit is contained in:
Grahame Grieve 2019-04-10 11:02:06 +10:00
parent 079f3cb8b8
commit d3ef2d7624
11 changed files with 49 additions and 1086 deletions

View File

@ -41,13 +41,13 @@ import org.hl7.fhir.dstu3.formats.JsonCreatorCanonical;
import org.hl7.fhir.dstu3.formats.JsonCreatorGson;
import org.hl7.fhir.dstu3.model.ElementDefinition.TypeRefComponent;
import org.hl7.fhir.dstu3.model.StructureDefinition;
import org.hl7.fhir.dstu3.utils.formats.JsonTrackingParser;
import org.hl7.fhir.dstu3.utils.formats.JsonTrackingParser.LocationData;
import org.hl7.fhir.exceptions.DefinitionException;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.FHIRFormatError;
import org.hl7.fhir.utilities.TextFile;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.json.JsonTrackingParser;
import org.hl7.fhir.utilities.json.JsonTrackingParser.LocationData;
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType;
import org.hl7.fhir.utilities.xhtml.XhtmlParser;

View File

@ -1,519 +0,0 @@
package org.hl7.fhir.dstu3.utils.formats;
/*-
* #%L
* org.hl7.fhir.dstu3
* %%
* Copyright (C) 2014 - 2019 Health Level 7
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import java.math.BigDecimal;
import java.util.Map;
import java.util.Stack;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.utilities.Utilities;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonNull;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
/**
* This is created to get a json parser that can track line numbers... grr...
*
* @author Grahame Grieve
*
*/
public class JsonTrackingParser {
public enum TokenType {
Open, Close, String, Number, Colon, Comma, OpenArray, CloseArray, Eof, Null, Boolean;
}
public class LocationData {
private int line;
private int col;
protected LocationData(int line, int col) {
super();
this.line = line;
this.col = col;
}
public int getLine() {
return line;
}
public int getCol() {
return col;
}
public void newLine() {
line++;
col = 1;
}
public LocationData copy() {
return new LocationData(line, col);
}
}
private class State {
private String name;
private boolean isProp;
protected State(String name, boolean isProp) {
super();
this.name = name;
this.isProp = isProp;
}
public String getName() {
return name;
}
public boolean isProp() {
return isProp;
}
}
private class Lexer {
private String source;
private int cursor;
private String peek;
private String value;
private TokenType type;
private Stack<State> states = new Stack<State>();
private LocationData lastLocationBWS;
private LocationData lastLocationAWS;
private LocationData location;
private StringBuilder b = new StringBuilder();
public Lexer(String source) throws FHIRException {
this.source = source;
cursor = -1;
location = new LocationData(1, 1);
start();
}
private boolean more() {
return peek != null || cursor < source.length();
}
private String getNext(int length) throws FHIRException {
String result = "";
if (peek != null) {
if (peek.length() > length) {
result = peek.substring(0, length);
peek = peek.substring(length);
} else {
result = peek;
peek = null;
}
}
if (result.length() < length) {
int len = length - result.length();
if (cursor > source.length() - len)
throw error("Attempt to read past end of source");
result = result + source.substring(cursor+1, cursor+len+1);
cursor = cursor + len;
}
for (char ch : result.toCharArray())
if (ch == '\n')
location.newLine();
else
location.col++;
return result;
}
private char getNextChar() throws FHIRException {
if (peek != null) {
char ch = peek.charAt(0);
peek = peek.length() == 1 ? null : peek.substring(1);
return ch;
} else {
cursor++;
if (cursor >= source.length())
return (char) 0;
char ch = source.charAt(cursor);
if (ch == '\n') {
location.newLine();
} else {
location.col++;
}
return ch;
}
}
private void push(char ch){
peek = peek == null ? String.valueOf(ch) : String.valueOf(ch)+peek;
}
private void parseWord(String word, char ch, TokenType type) throws FHIRException {
this.type = type;
value = ""+ch+getNext(word.length()-1);
if (!value.equals(word))
throw error("Syntax error in json reading special word "+word);
}
private FHIRException error(String msg) {
return new FHIRException("Error parsing JSON source: "+msg+" at Line "+Integer.toString(location.line)+" (path=["+path()+"])");
}
private String path() {
if (states.empty())
return value;
else {
String result = "";
for (State s : states)
result = result + '/'+ s.getName();
result = result + value;
return result;
}
}
public void start() throws FHIRException {
// char ch = getNextChar();
// if (ch = '\.uEF')
// begin
// // skip BOM
// getNextChar();
// getNextChar();
// end
// else
// push(ch);
next();
}
public TokenType getType() {
return type;
}
public String getValue() {
return value;
}
public LocationData getLastLocationBWS() {
return lastLocationBWS;
}
public LocationData getLastLocationAWS() {
return lastLocationAWS;
}
public void next() throws FHIRException {
lastLocationBWS = location.copy();
char ch;
do {
ch = getNextChar();
} while (more() && Utilities.charInSet(ch, ' ', '\r', '\n', '\t'));
lastLocationAWS = location.copy();
if (!more()) {
type = TokenType.Eof;
} else {
switch (ch) {
case '{' :
type = TokenType.Open;
break;
case '}' :
type = TokenType.Close;
break;
case '"' :
type = TokenType.String;
b.setLength(0);
do {
ch = getNextChar();
if (ch == '\\') {
ch = getNextChar();
switch (ch) {
case '"': b.append('"'); break;
case '\\': b.append('\\'); break;
case '/': b.append('/'); break;
case 'n': b.append('\n'); break;
case 'r': b.append('\r'); break;
case 't': b.append('\t'); break;
case 'u': b.append((char) Integer.parseInt(getNext(4), 16)); break;
default :
throw error("unknown escape sequence: \\"+ch);
}
ch = ' ';
} else if (ch != '"')
b.append(ch);
} while (more() && (ch != '"'));
if (!more())
throw error("premature termination of json stream during a string");
value = b.toString();
break;
case ':' :
type = TokenType.Colon;
break;
case ',' :
type = TokenType.Comma;
break;
case '[' :
type = TokenType.OpenArray;
break;
case ']' :
type = TokenType.CloseArray;
break;
case 't' :
parseWord("true", ch, TokenType.Boolean);
break;
case 'f' :
parseWord("false", ch, TokenType.Boolean);
break;
case 'n' :
parseWord("null", ch, TokenType.Null);
break;
default:
if ((ch >= '0' && ch <= '9') || ch == '-') {
type = TokenType.Number;
b.setLength(0);
while (more() && ((ch >= '0' && ch <= '9') || ch == '-' || ch == '.')) {
b.append(ch);
ch = getNextChar();
}
value = b.toString();
push(ch);
} else
throw error("Unexpected char '"+ch+"' in json stream");
}
}
}
public String consume(TokenType type) throws FHIRException {
if (this.type != type)
throw error("JSON syntax error - found "+type.toString()+" expecting "+type.toString());
String result = value;
next();
return result;
}
}
enum ItemType {
Object, String, Number, Boolean, Array, End, Eof, Null;
}
private Map<JsonElement, LocationData> map;
private Lexer lexer;
private ItemType itemType = ItemType.Object;
private String itemName;
private String itemValue;
public static JsonObject parse(String source, Map<JsonElement, LocationData> map) throws FHIRException {
JsonTrackingParser self = new JsonTrackingParser();
self.map = map;
return self.parse(source);
}
private JsonObject parse(String source) throws FHIRException {
lexer = new Lexer(source);
JsonObject result = new JsonObject();
LocationData loc = lexer.location.copy();
if (lexer.getType() == TokenType.Open) {
lexer.next();
lexer.states.push(new State("", false));
}
else
throw lexer.error("Unexpected content at start of JSON: "+lexer.getType().toString());
parseProperty();
readObject(result, true);
map.put(result, loc);
return result;
}
private void readObject(JsonObject obj, boolean root) throws FHIRException {
map.put(obj, lexer.location.copy());
while (!(itemType == ItemType.End) || (root && (itemType == ItemType.Eof))) {
if (obj.has(itemName))
throw lexer.error("Duplicated property name: "+itemName);
switch (itemType) {
case Object:
JsonObject child = new JsonObject(); //(obj.path+'.'+ItemName);
LocationData loc = lexer.location.copy();
obj.add(itemName, child);
next();
readObject(child, false);
map.put(obj, loc);
break;
case Boolean :
JsonPrimitive v = new JsonPrimitive(Boolean.valueOf(itemValue));
obj.add(itemName, v);
map.put(v, lexer.location.copy());
break;
case String:
v = new JsonPrimitive(itemValue);
obj.add(itemName, v);
map.put(v, lexer.location.copy());
break;
case Number:
v = new JsonPrimitive(new BigDecimal(itemValue));
obj.add(itemName, v);
map.put(v, lexer.location.copy());
break;
case Null:
JsonNull n = new JsonNull();
obj.add(itemName, n);
map.put(n, lexer.location.copy());
break;
case Array:
JsonArray arr = new JsonArray(); // (obj.path+'.'+ItemName);
loc = lexer.location.copy();
obj.add(itemName, arr);
next();
readArray(arr, false);
map.put(arr, loc);
break;
case Eof :
throw lexer.error("Unexpected End of File");
}
next();
}
}
private void readArray(JsonArray arr, boolean root) throws FHIRException {
while (!((itemType == ItemType.End) || (root && (itemType == ItemType.Eof)))) {
switch (itemType) {
case Object:
JsonObject obj = new JsonObject(); // (arr.path+'['+inttostr(i)+']');
LocationData loc = lexer.location.copy();
arr.add(obj);
next();
readObject(obj, false);
map.put(obj, loc);
break;
case String:
JsonPrimitive v = new JsonPrimitive(itemValue);
arr.add(v);
map.put(v, lexer.location.copy());
break;
case Number:
v = new JsonPrimitive(new BigDecimal(itemValue));
arr.add(v);
map.put(v, lexer.location.copy());
break;
case Null :
JsonNull n = new JsonNull();
arr.add(n);
map.put(n, lexer.location.copy());
break;
case Array:
JsonArray child = new JsonArray(); // (arr.path+'['+inttostr(i)+']');
loc = lexer.location.copy();
arr.add(child);
next();
readArray(child, false);
map.put(arr, loc);
break;
case Eof :
throw lexer.error("Unexpected End of File");
}
next();
}
}
private void next() throws FHIRException {
switch (itemType) {
case Object :
lexer.consume(TokenType.Open);
lexer.states.push(new State(itemName, false));
if (lexer.getType() == TokenType.Close) {
itemType = ItemType.End;
lexer.next();
} else
parseProperty();
break;
case Null:
case String:
case Number:
case End:
case Boolean :
if (itemType == ItemType.End)
lexer.states.pop();
if (lexer.getType() == TokenType.Comma) {
lexer.next();
parseProperty();
} else if (lexer.getType() == TokenType.Close) {
itemType = ItemType.End;
lexer.next();
} else if (lexer.getType() == TokenType.CloseArray) {
itemType = ItemType.End;
lexer.next();
} else if (lexer.getType() == TokenType.Eof) {
itemType = ItemType.Eof;
} else
throw lexer.error("Unexpected JSON syntax");
break;
case Array :
lexer.next();
lexer.states.push(new State(itemName+"[]", true));
parseProperty();
break;
case Eof :
throw lexer.error("JSON Syntax Error - attempt to read past end of json stream");
default:
throw lexer.error("not done yet (a): "+itemType.toString());
}
}
private void parseProperty() throws FHIRException {
if (!lexer.states.peek().isProp) {
itemName = lexer.consume(TokenType.String);
itemValue = null;
lexer.consume(TokenType.Colon);
}
switch (lexer.getType()) {
case Null :
itemType = ItemType.Null;
itemValue = lexer.value;
lexer.next();
break;
case String :
itemType = ItemType.String;
itemValue = lexer.value;
lexer.next();
break;
case Boolean :
itemType = ItemType.Boolean;
itemValue = lexer.value;
lexer.next();
break;
case Number :
itemType = ItemType.Number;
itemValue = lexer.value;
lexer.next();
break;
case Open :
itemType = ItemType.Object;
break;
case OpenArray :
itemType = ItemType.Array;
break;
case CloseArray :
itemType = ItemType.End;
break;
// case Close, , case Colon, case Comma, case OpenArray, !
default:
throw lexer.error("not done yet (b): "+lexer.getType().toString());
}
}
}

View File

@ -44,10 +44,10 @@ import org.hl7.fhir.r4.formats.JsonCreatorCanonical;
import org.hl7.fhir.r4.formats.JsonCreatorGson;
import org.hl7.fhir.r4.model.ElementDefinition.TypeRefComponent;
import org.hl7.fhir.r4.model.StructureDefinition;
import org.hl7.fhir.r4.utils.formats.JsonTrackingParser;
import org.hl7.fhir.r4.utils.formats.JsonTrackingParser.LocationData;
import org.hl7.fhir.utilities.TextFile;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.json.JsonTrackingParser;
import org.hl7.fhir.utilities.json.JsonTrackingParser.LocationData;
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType;
import org.hl7.fhir.utilities.xhtml.XhtmlParser;

View File

@ -55,8 +55,8 @@ import org.hl7.fhir.exceptions.FHIRFormatError;
// Generated on Thu, Dec 13, 2018 14:07+1100 for FHIR v4.0.0
import org.hl7.fhir.r4.model.*;
import org.hl7.fhir.r4.utils.formats.JsonTrackingParser.PresentedBigDecimal;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.json.JsonTrackingParser.PresentedBigDecimal;
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
import com.google.gson.JsonArray;

View File

@ -64,9 +64,9 @@ import org.hl7.fhir.r4.model.IdType;
import org.hl7.fhir.r4.model.Resource;
import org.hl7.fhir.r4.model.StringType;
import org.hl7.fhir.r4.model.Type;
import org.hl7.fhir.r4.utils.formats.JsonTrackingParser;
import org.hl7.fhir.utilities.TextFile;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.json.JsonTrackingParser;
import org.hl7.fhir.utilities.xhtml.XhtmlComposer;
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
import org.hl7.fhir.utilities.xhtml.XhtmlParser;

View File

@ -1,556 +0,0 @@
package org.hl7.fhir.r4.utils.formats;
/*-
* #%L
* org.hl7.fhir.r4
* %%
* Copyright (C) 2014 - 2019 Health Level 7
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Map;
import java.util.Stack;
import org.hl7.fhir.utilities.Utilities;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonNull;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
/**
* This is created to get a json parser that can track line numbers... grr...
*
* @author Grahame Grieve
*
*/
public class JsonTrackingParser {
public class PresentedBigDecimal extends BigDecimal {
public String presentation;
public PresentedBigDecimal(String value) {
super(value);
presentation = value;
}
public String getPresentation() {
return presentation;
}
}
public enum TokenType {
Open, Close, String, Number, Colon, Comma, OpenArray, CloseArray, Eof, Null, Boolean;
}
public class LocationData {
private int line;
private int col;
protected LocationData(int line, int col) {
super();
this.line = line;
this.col = col;
}
public int getLine() {
return line;
}
public int getCol() {
return col;
}
public void newLine() {
line++;
col = 1;
}
public LocationData copy() {
return new LocationData(line, col);
}
}
private class State {
private String name;
private boolean isProp;
protected State(String name, boolean isProp) {
super();
this.name = name;
this.isProp = isProp;
}
public String getName() {
return name;
}
public boolean isProp() {
return isProp;
}
}
private class Lexer {
private String source;
private int cursor;
private String peek;
private String value;
private TokenType type;
private Stack<State> states = new Stack<State>();
private LocationData lastLocationBWS;
private LocationData lastLocationAWS;
private LocationData location;
private StringBuilder b = new StringBuilder();
public Lexer(String source) throws IOException {
this.source = source;
cursor = -1;
location = new LocationData(1, 1);
start();
}
private boolean more() {
return peek != null || cursor < source.length();
}
private String getNext(int length) throws IOException {
String result = "";
if (peek != null) {
if (peek.length() > length) {
result = peek.substring(0, length);
peek = peek.substring(length);
} else {
result = peek;
peek = null;
}
}
if (result.length() < length) {
int len = length - result.length();
if (cursor > source.length() - len)
throw error("Attempt to read past end of source");
result = result + source.substring(cursor+1, cursor+len+1);
cursor = cursor + len;
}
for (char ch : result.toCharArray())
if (ch == '\n')
location.newLine();
else
location.col++;
return result;
}
private char getNextChar() throws IOException {
if (peek != null) {
char ch = peek.charAt(0);
peek = peek.length() == 1 ? null : peek.substring(1);
return ch;
} else {
cursor++;
if (cursor >= source.length())
return (char) 0;
char ch = source.charAt(cursor);
if (ch == '\n') {
location.newLine();
} else {
location.col++;
}
return ch;
}
}
private void push(char ch){
peek = peek == null ? String.valueOf(ch) : String.valueOf(ch)+peek;
}
private void parseWord(String word, char ch, TokenType type) throws IOException {
this.type = type;
value = ""+ch+getNext(word.length()-1);
if (!value.equals(word))
throw error("Syntax error in json reading special word "+word);
}
private IOException error(String msg) {
return new IOException("Error parsing JSON source: "+msg+" at Line "+Integer.toString(location.line)+" (path=["+path()+"])");
}
private String path() {
if (states.empty())
return value;
else {
String result = "";
for (State s : states)
result = result + '/'+ s.getName();
result = result + value;
return result;
}
}
public void start() throws IOException {
// char ch = getNextChar();
// if (ch = '\.uEF')
// begin
// // skip BOM
// getNextChar();
// getNextChar();
// end
// else
// push(ch);
next();
}
public TokenType getType() {
return type;
}
public String getValue() {
return value;
}
public LocationData getLastLocationBWS() {
return lastLocationBWS;
}
public LocationData getLastLocationAWS() {
return lastLocationAWS;
}
public void next() throws IOException {
lastLocationBWS = location.copy();
char ch;
do {
ch = getNextChar();
} while (more() && Utilities.charInSet(ch, ' ', '\r', '\n', '\t'));
lastLocationAWS = location.copy();
if (!more()) {
type = TokenType.Eof;
} else {
switch (ch) {
case '{' :
type = TokenType.Open;
break;
case '}' :
type = TokenType.Close;
break;
case '"' :
type = TokenType.String;
b.setLength(0);
do {
ch = getNextChar();
if (ch == '\\') {
ch = getNextChar();
switch (ch) {
case '"': b.append('"'); break;
case '\'': b.append('\''); break;
case '\\': b.append('\\'); break;
case '/': b.append('/'); break;
case 'n': b.append('\n'); break;
case 'r': b.append('\r'); break;
case 't': b.append('\t'); break;
case 'u': b.append((char) Integer.parseInt(getNext(4), 16)); break;
default :
throw error("unknown escape sequence: \\"+ch);
}
ch = ' ';
} else if (ch != '"')
b.append(ch);
} while (more() && (ch != '"'));
if (!more())
throw error("premature termination of json stream during a string");
value = b.toString();
break;
case ':' :
type = TokenType.Colon;
break;
case ',' :
type = TokenType.Comma;
break;
case '[' :
type = TokenType.OpenArray;
break;
case ']' :
type = TokenType.CloseArray;
break;
case 't' :
parseWord("true", ch, TokenType.Boolean);
break;
case 'f' :
parseWord("false", ch, TokenType.Boolean);
break;
case 'n' :
parseWord("null", ch, TokenType.Null);
break;
default:
if ((ch >= '0' && ch <= '9') || ch == '-') {
type = TokenType.Number;
b.setLength(0);
while (more() && ((ch >= '0' && ch <= '9') || ch == '-' || ch == '.') || ch == '+' || ch == 'e' || ch == 'E') {
b.append(ch);
ch = getNextChar();
}
value = b.toString();
push(ch);
} else
throw error("Unexpected char '"+ch+"' in json stream");
}
}
}
public String consume(TokenType type) throws IOException {
if (this.type != type)
throw error("JSON syntax error - found "+type.toString()+" expecting "+type.toString());
String result = value;
next();
return result;
}
}
enum ItemType {
Object, String, Number, Boolean, Array, End, Eof, Null;
}
private Map<JsonElement, LocationData> map;
private Lexer lexer;
private ItemType itemType = ItemType.Object;
private String itemName;
private String itemValue;
public static JsonObject parse(String source, Map<JsonElement, LocationData> map) throws IOException {
JsonTrackingParser self = new JsonTrackingParser();
self.map = map;
return self.parse(source);
}
private JsonObject parse(String source) throws IOException {
lexer = new Lexer(source);
JsonObject result = new JsonObject();
LocationData loc = lexer.location.copy();
if (lexer.getType() == TokenType.Open) {
lexer.next();
lexer.states.push(new State("", false));
}
else
throw lexer.error("Unexpected content at start of JSON: "+lexer.getType().toString());
parseProperty();
readObject(result, true);
if (map != null)
map.put(result, loc);
return result;
}
private void readObject(JsonObject obj, boolean root) throws IOException {
if (map != null)
map.put(obj, lexer.location.copy());
while (!(itemType == ItemType.End) || (root && (itemType == ItemType.Eof))) {
if (obj.has(itemName))
throw lexer.error("Duplicated property name: "+itemName);
switch (itemType) {
case Object:
JsonObject child = new JsonObject(); //(obj.path+'.'+ItemName);
LocationData loc = lexer.location.copy();
obj.add(itemName, child);
next();
readObject(child, false);
if (map != null)
map.put(obj, loc);
break;
case Boolean :
JsonPrimitive v = new JsonPrimitive(Boolean.valueOf(itemValue));
obj.add(itemName, v);
if (map != null)
map.put(v, lexer.location.copy());
break;
case String:
v = new JsonPrimitive(itemValue);
obj.add(itemName, v);
if (map != null)
map.put(v, lexer.location.copy());
break;
case Number:
v = new JsonPrimitive(new PresentedBigDecimal(itemValue));
obj.add(itemName, v);
if (map != null)
map.put(v, lexer.location.copy());
break;
case Null:
JsonNull n = new JsonNull();
obj.add(itemName, n);
if (map != null)
map.put(n, lexer.location.copy());
break;
case Array:
JsonArray arr = new JsonArray(); // (obj.path+'.'+ItemName);
loc = lexer.location.copy();
obj.add(itemName, arr);
next();
readArray(arr, false);
if (map != null)
map.put(arr, loc);
break;
case Eof :
throw lexer.error("Unexpected End of File");
case End:
// TODO GG: This isn't handled. Should it be?
break;
}
next();
}
}
private void readArray(JsonArray arr, boolean root) throws IOException {
while (!((itemType == ItemType.End) || (root && (itemType == ItemType.Eof)))) {
switch (itemType) {
case Object:
JsonObject obj = new JsonObject(); // (arr.path+'['+inttostr(i)+']');
LocationData loc = lexer.location.copy();
arr.add(obj);
next();
readObject(obj, false);
if (map != null)
map.put(obj, loc);
break;
case String:
JsonPrimitive v = new JsonPrimitive(itemValue);
arr.add(v);
if (map != null)
map.put(v, lexer.location.copy());
break;
case Number:
v = new JsonPrimitive(new BigDecimal(itemValue));
arr.add(v);
if (map != null)
map.put(v, lexer.location.copy());
break;
case Null :
JsonNull n = new JsonNull();
arr.add(n);
if (map != null)
map.put(n, lexer.location.copy());
break;
case Array:
JsonArray child = new JsonArray(); // (arr.path+'['+inttostr(i)+']');
loc = lexer.location.copy();
arr.add(child);
next();
readArray(child, false);
if (map != null)
map.put(arr, loc);
break;
case Eof :
throw lexer.error("Unexpected End of File");
case End:
case Boolean:
// TODO GG: These aren't handled. SHould they be?
break;
}
next();
}
}
private void next() throws IOException {
switch (itemType) {
case Object :
lexer.consume(TokenType.Open);
lexer.states.push(new State(itemName, false));
if (lexer.getType() == TokenType.Close) {
itemType = ItemType.End;
lexer.next();
} else
parseProperty();
break;
case Null:
case String:
case Number:
case End:
case Boolean :
if (itemType == ItemType.End)
lexer.states.pop();
if (lexer.getType() == TokenType.Comma) {
lexer.next();
parseProperty();
} else if (lexer.getType() == TokenType.Close) {
itemType = ItemType.End;
lexer.next();
} else if (lexer.getType() == TokenType.CloseArray) {
itemType = ItemType.End;
lexer.next();
} else if (lexer.getType() == TokenType.Eof) {
itemType = ItemType.Eof;
} else
throw lexer.error("Unexpected JSON syntax");
break;
case Array :
lexer.next();
lexer.states.push(new State(itemName+"[]", true));
parseProperty();
break;
case Eof :
throw lexer.error("JSON Syntax Error - attempt to read past end of json stream");
default:
throw lexer.error("not done yet (a): "+itemType.toString());
}
}
private void parseProperty() throws IOException {
if (!lexer.states.peek().isProp) {
itemName = lexer.consume(TokenType.String);
itemValue = null;
lexer.consume(TokenType.Colon);
}
switch (lexer.getType()) {
case Null :
itemType = ItemType.Null;
itemValue = lexer.value;
lexer.next();
break;
case String :
itemType = ItemType.String;
itemValue = lexer.value;
lexer.next();
break;
case Boolean :
itemType = ItemType.Boolean;
itemValue = lexer.value;
lexer.next();
break;
case Number :
itemType = ItemType.Number;
itemValue = lexer.value;
lexer.next();
break;
case Open :
itemType = ItemType.Object;
break;
case OpenArray :
itemType = ItemType.Array;
break;
case CloseArray :
itemType = ItemType.End;
break;
// case Close, , case Colon, case Comma, case OpenArray, !
default:
throw lexer.error("not done yet (b): "+lexer.getType().toString());
}
}
}

View File

@ -44,10 +44,10 @@ import org.hl7.fhir.r5.formats.JsonCreatorCanonical;
import org.hl7.fhir.r5.formats.JsonCreatorGson;
import org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent;
import org.hl7.fhir.r5.model.StructureDefinition;
import org.hl7.fhir.r5.utils.formats.JsonTrackingParser;
import org.hl7.fhir.r5.utils.formats.JsonTrackingParser.LocationData;
import org.hl7.fhir.utilities.TextFile;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.json.JsonTrackingParser;
import org.hl7.fhir.utilities.json.JsonTrackingParser.LocationData;
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType;
import org.hl7.fhir.utilities.xhtml.XhtmlParser;

View File

@ -55,8 +55,8 @@ import org.hl7.fhir.exceptions.FHIRFormatError;
// Generated on Thu, Dec 13, 2018 14:07+1100 for FHIR v4.0.0
import org.hl7.fhir.r5.model.*;
import org.hl7.fhir.r5.utils.formats.JsonTrackingParser.PresentedBigDecimal;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.json.JsonTrackingParser.PresentedBigDecimal;
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
import com.google.gson.JsonArray;

View File

@ -64,9 +64,9 @@ import org.hl7.fhir.r5.model.IdType;
import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.r5.model.StringType;
import org.hl7.fhir.r5.model.Type;
import org.hl7.fhir.r5.utils.formats.JsonTrackingParser;
import org.hl7.fhir.utilities.TextFile;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.json.JsonTrackingParser;
import org.hl7.fhir.utilities.xhtml.XhtmlComposer;
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
import org.hl7.fhir.utilities.xhtml.XhtmlParser;

View File

@ -37,11 +37,16 @@ import java.util.Map.Entry;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
import org.apache.commons.io.FileUtils;
import org.hl7.fhir.utilities.IniFile;
import org.hl7.fhir.utilities.TextFile;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.cache.PackageCacheManager.PackageEntry;
import org.hl7.fhir.utilities.cache.PackageGenerator.PackageType;
import org.hl7.fhir.utilities.json.JsonTrackingParser;
import com.google.gson.JsonObject;
@ -91,6 +96,39 @@ import com.google.gson.JsonObject;
return names;
}
private static final int BUFFER_SIZE = 1024;
public static NpmPackage fromPackage(InputStream tgz) throws IOException {
NpmPackage res = new NpmPackage(null);
GzipCompressorInputStream gzipIn = new GzipCompressorInputStream(tgz);
try (TarArchiveInputStream tarIn = new TarArchiveInputStream(gzipIn)) {
TarArchiveEntry entry;
int i = 0;
int c = 12;
while ((entry = (TarArchiveEntry) tarIn.getNextEntry()) != null) {
i++;
if (entry.isDirectory()) {
res.folders.add(entry.getName());
} else {
int count;
byte data[] = new byte[BUFFER_SIZE];
ByteArrayOutputStream fos = new ByteArrayOutputStream();
try (BufferedOutputStream dest = new BufferedOutputStream(fos, BUFFER_SIZE)) {
while ((count = tarIn.read(data, 0, BUFFER_SIZE)) != -1) {
dest.write(data, 0, count);
}
}
fos.close();
res.content.put(entry.getName(), fos.toByteArray());
}
}
}
res.npm = JsonTrackingParser.parseJson(res.content.get("package/package.json"));
return res;
}
public static NpmPackage fromZip(InputStream stream, boolean dropRootFolder) throws IOException {
NpmPackage res = new NpmPackage(null);
ZipInputStream zip = new ZipInputStream(stream);

View File

@ -1,4 +1,4 @@
package org.hl7.fhir.r5.utils.formats;
package org.hl7.fhir.utilities.json;
import java.io.File;