Fix a number of problems reported by ErrorProne
This commit is contained in:
parent
22cd9d8641
commit
a782bd7630
|
@ -73,6 +73,7 @@ public class IgPackUploader extends BaseCommand {
|
|||
.and(StructureDefinition.URL.matches().value(nextResourceUrl))
|
||||
.execute();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new ParseException("This command does not support FHIR version " + ctx.getVersion().getVersion());
|
||||
}
|
||||
|
|
|
@ -1,5 +1,25 @@
|
|||
package org.hl7.fhir.convertors;
|
||||
|
||||
/*-
|
||||
* #%L
|
||||
* HAPI FHIR - Converter
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2017 University Health Network
|
||||
* %%
|
||||
* 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.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
|
|
@ -97,7 +97,7 @@ public class ConnectionWrapper implements Connection {
|
|||
|
||||
@Override
|
||||
public String getClientInfo(String theName) throws SQLException {
|
||||
return getClientInfo(theName);
|
||||
return myWrap.getClientInfo(theName);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -118,8 +118,13 @@ public abstract class BaseJpaTest {
|
|||
|
||||
protected List<String> toUnqualifiedVersionlessIdValues(IBundleProvider theFound) {
|
||||
List<String> retVal = new ArrayList<String>();
|
||||
int size = theFound.size();
|
||||
Integer size = theFound.size();
|
||||
ourLog.info("Found {} results", size);
|
||||
|
||||
if (size == null) {
|
||||
size = 99999;
|
||||
}
|
||||
|
||||
List<IBaseResource> resources = theFound.getResources(0, size);
|
||||
for (IBaseResource next : resources) {
|
||||
retVal.add(next.getIdElement().toUnqualifiedVersionless().getValue());
|
||||
|
|
|
@ -102,6 +102,7 @@ public class FhirResourceDaoDstu2ValidateTest extends BaseJpaDstu2Test {
|
|||
} catch (PreconditionFailedException e) {
|
||||
return (OperationOutcome) e.getOperationOutcome();
|
||||
}
|
||||
break;
|
||||
case XML:
|
||||
encoded = myFhirCtx.newXmlParser().encodeResourceToString(input);
|
||||
try {
|
||||
|
@ -110,6 +111,7 @@ public class FhirResourceDaoDstu2ValidateTest extends BaseJpaDstu2Test {
|
|||
} catch (PreconditionFailedException e) {
|
||||
return (OperationOutcome) e.getOperationOutcome();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
throw new IllegalStateException(); // shouldn't get here
|
||||
|
|
|
@ -133,6 +133,7 @@ public class FhirResourceDaoDstu3ValidateTest extends BaseJpaDstu3Test {
|
|||
} catch (PreconditionFailedException e) {
|
||||
return (OperationOutcome) e.getOperationOutcome();
|
||||
}
|
||||
break;
|
||||
case XML:
|
||||
encoded = myFhirCtx.newXmlParser().encodeResourceToString(input);
|
||||
try {
|
||||
|
@ -141,6 +142,7 @@ public class FhirResourceDaoDstu3ValidateTest extends BaseJpaDstu3Test {
|
|||
} catch (PreconditionFailedException e) {
|
||||
return (OperationOutcome) e.getOperationOutcome();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
throw new IllegalStateException(); // shouldn't get here
|
||||
|
|
|
@ -133,6 +133,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
|
|||
} catch (PreconditionFailedException e) {
|
||||
return (OperationOutcome) e.getOperationOutcome();
|
||||
}
|
||||
break;
|
||||
case XML:
|
||||
encoded = myFhirCtx.newXmlParser().encodeResourceToString(input);
|
||||
try {
|
||||
|
@ -141,6 +142,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
|
|||
} catch (PreconditionFailedException e) {
|
||||
return (OperationOutcome) e.getOperationOutcome();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
throw new IllegalStateException(); // shouldn't get here
|
||||
|
|
|
@ -1772,8 +1772,9 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
case BUNDLED : return "b";
|
||||
case CONTAINED : return "c";
|
||||
case REFERENCED: return "r";
|
||||
default: return "?";
|
||||
}
|
||||
return "?";
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -2232,7 +2233,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
if (definition != null && definition.hasShort()) {
|
||||
if (!c.getPieces().isEmpty()) c.addPiece(gen.new Piece("br"));
|
||||
c.addPiece(checkForNoChange(definition.getShortElement(), gen.new Piece(null, gt(definition.getShortElement()), null)));
|
||||
} else if (fallback != null && fallback != null && fallback.hasShort()) {
|
||||
} else if (fallback != null && fallback.hasShort()) {
|
||||
if (!c.getPieces().isEmpty()) c.addPiece(gen.new Piece("br"));
|
||||
c.addPiece(checkForNoChange(fallback.getShortElement(), gen.new Piece(null, gt(fallback.getShortElement()), null)));
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,494 +1,501 @@
|
|||
package org.hl7.fhir.dstu3.utils;
|
||||
|
||||
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.*;
|
||||
|
||||
|
||||
/**
|
||||
* 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
package org.hl7.fhir.dstu3.utils;
|
||||
|
||||
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.*;
|
||||
|
||||
|
||||
/**
|
||||
* 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");
|
||||
case End:
|
||||
// TODO: anything?\
|
||||
break;
|
||||
}
|
||||
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");
|
||||
case End:
|
||||
case Boolean:
|
||||
// TODO: anything?
|
||||
break;
|
||||
}
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1628,7 +1628,7 @@ public class ProfileUtilities {
|
|||
if (definition != null && definition.hasShort()) {
|
||||
if (!c.getPieces().isEmpty()) c.addPiece(gen.new Piece("br"));
|
||||
c.addPiece(checkForNoChange(definition.getShortElement(), gen.new Piece(null, definition.getShort(), null)));
|
||||
} else if (fallback != null && fallback != null && fallback.hasShort()) {
|
||||
} else if (fallback != null && fallback.hasShort()) {
|
||||
if (!c.getPieces().isEmpty()) c.addPiece(gen.new Piece("br"));
|
||||
c.addPiece(checkForNoChange(fallback.getShortElement(), gen.new Piece(null, fallback.getShort(), null)));
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -35,6 +35,7 @@ public class OperationOutcomeUtilities {
|
|||
case ERROR : return IssueSeverity.ERROR;
|
||||
case WARNING : return IssueSeverity.WARNING;
|
||||
case INFORMATION : return IssueSeverity.INFORMATION;
|
||||
case NULL : return IssueSeverity.NULL;
|
||||
}
|
||||
return IssueSeverity.NULL;
|
||||
}
|
||||
|
@ -70,6 +71,7 @@ public class OperationOutcomeUtilities {
|
|||
case TIMEOUT: return IssueType.TIMEOUT;
|
||||
case THROTTLED: return IssueType.THROTTLED;
|
||||
case INFORMATIONAL: return IssueType.INFORMATIONAL;
|
||||
case NULL: return IssueType.NULL;
|
||||
}
|
||||
return IssueType.NULL;
|
||||
}
|
||||
|
|
|
@ -589,20 +589,20 @@ public class QuestionnaireBuilder {
|
|||
private Type convertType(Base value, QuestionnaireItemType af, ValueSet vs, String path) throws FHIRException {
|
||||
switch (af) {
|
||||
// simple cases
|
||||
case BOOLEAN: if (value instanceof BooleanType) return (Type) value;
|
||||
case DECIMAL: if (value instanceof DecimalType) return (Type) value;
|
||||
case INTEGER: if (value instanceof IntegerType) return (Type) value;
|
||||
case DATE: if (value instanceof DateType) return (Type) value;
|
||||
case DATETIME: if (value instanceof DateTimeType) return (Type) value;
|
||||
case TIME: if (value instanceof TimeType) return (Type) value;
|
||||
case BOOLEAN: if (value instanceof BooleanType) return (Type) value; break;
|
||||
case DECIMAL: if (value instanceof DecimalType) return (Type) value; break;
|
||||
case INTEGER: if (value instanceof IntegerType) return (Type) value; break;
|
||||
case DATE: if (value instanceof DateType) return (Type) value; break;
|
||||
case DATETIME: if (value instanceof DateTimeType) return (Type) value; break;
|
||||
case TIME: if (value instanceof TimeType) return (Type) value; break;
|
||||
case STRING:
|
||||
if (value instanceof StringType)
|
||||
return (Type) value;
|
||||
else if (value instanceof UriType)
|
||||
return new StringType(((UriType) value).asStringValue());
|
||||
|
||||
case TEXT: if (value instanceof StringType) return (Type) value;
|
||||
case QUANTITY: if (value instanceof Quantity) return (Type) value;
|
||||
break;
|
||||
case TEXT: if (value instanceof StringType) return (Type) value; break;
|
||||
case QUANTITY: if (value instanceof Quantity) return (Type) value; break;
|
||||
|
||||
// complex cases:
|
||||
// ? QuestionnaireItemTypeAttachment: ...?
|
||||
|
@ -621,6 +621,7 @@ public class QuestionnaireBuilder {
|
|||
cc.setSystem(getSystemForCode(vs, cc.getCode(), path));
|
||||
return cc;
|
||||
}
|
||||
break;
|
||||
|
||||
case REFERENCE:
|
||||
if (value instanceof Reference)
|
||||
|
@ -629,6 +630,9 @@ public class QuestionnaireBuilder {
|
|||
Reference r = new Reference();
|
||||
r.setReference(((StringType) value).asStringValue());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
throw new FHIRException("Unable to convert from '"+value.getClass().toString()+"' for Answer Format "+af.toCode()+", path = "+path);
|
||||
|
|
|
@ -365,11 +365,14 @@ public class StructureMapUtilities {
|
|||
private static void renderGroup(StringBuilder b, StructureMapGroupComponent g) {
|
||||
b.append("group ");
|
||||
switch (g.getTypeMode()) {
|
||||
case TYPES: b.append("for types");
|
||||
case TYPEANDTYPES: b.append("for type+types ");
|
||||
case TYPES:
|
||||
b.append("for types");
|
||||
break;
|
||||
case TYPEANDTYPES:
|
||||
b.append("for type+types ");
|
||||
break;
|
||||
default: // NONE, NULL
|
||||
}
|
||||
b.append("for types ");
|
||||
b.append(g.getName());
|
||||
if (g.hasExtends()) {
|
||||
b.append(" extends ");
|
||||
|
|
|
@ -364,6 +364,9 @@ public class JsonTrackingParser {
|
|||
break;
|
||||
case Eof :
|
||||
throw lexer.error("Unexpected End of File");
|
||||
case End:
|
||||
// TODO GG: This isn't handled. Should it be?
|
||||
break;
|
||||
}
|
||||
next();
|
||||
}
|
||||
|
@ -405,6 +408,10 @@ public class JsonTrackingParser {
|
|||
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();
|
||||
}
|
||||
|
|
|
@ -270,7 +270,7 @@ public class TestingUtilities {
|
|||
JsonArray a1 = (JsonArray) n1;
|
||||
JsonArray a2 = (JsonArray) n2;
|
||||
|
||||
if (a1.size() != a1.size())
|
||||
if (a1.size() != a2.size())
|
||||
return "array properties differ at "+path+": count "+Integer.toString(a1.size())+"/"+Integer.toString(a2.size());
|
||||
for (int i = 0; i < a1.size(); i++) {
|
||||
String s = compareNodes(path+"["+Integer.toString(i)+"]", a1.get(i), a2.get(i));
|
||||
|
|
|
@ -1,24 +1,31 @@
|
|||
package ca.uhn.fhir.to;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.defaultString;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.*;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||
import ca.uhn.fhir.model.api.ExtensionDt;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Conformance;
|
||||
import ca.uhn.fhir.model.primitive.DecimalDt;
|
||||
import ca.uhn.fhir.rest.api.Constants;
|
||||
import ca.uhn.fhir.rest.api.EncodingEnum;
|
||||
import ca.uhn.fhir.rest.client.api.IClientInterceptor;
|
||||
import ca.uhn.fhir.rest.client.api.IHttpRequest;
|
||||
import ca.uhn.fhir.rest.client.api.IHttpResponse;
|
||||
import ca.uhn.fhir.rest.client.impl.GenericClient;
|
||||
import ca.uhn.fhir.to.model.HomeRequest;
|
||||
import ca.uhn.fhir.util.ExtensionConstants;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.StringEscapeUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
import org.hl7.fhir.dstu3.model.*;
|
||||
import org.hl7.fhir.dstu3.model.CapabilityStatement;
|
||||
import org.hl7.fhir.dstu3.model.CapabilityStatement.CapabilityStatementRestComponent;
|
||||
import org.hl7.fhir.dstu3.model.CapabilityStatement.CapabilityStatementRestResourceComponent;
|
||||
import org.hl7.fhir.dstu3.model.DecimalType;
|
||||
import org.hl7.fhir.dstu3.model.Extension;
|
||||
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IDomainResource;
|
||||
|
@ -26,23 +33,19 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||
import org.springframework.ui.ModelMap;
|
||||
import org.thymeleaf.TemplateEngine;
|
||||
|
||||
import ca.uhn.fhir.context.*;
|
||||
import ca.uhn.fhir.model.api.ExtensionDt;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Conformance;
|
||||
import ca.uhn.fhir.model.primitive.DecimalDt;
|
||||
import ca.uhn.fhir.rest.api.Constants;
|
||||
import ca.uhn.fhir.rest.api.EncodingEnum;
|
||||
import ca.uhn.fhir.rest.client.api.*;
|
||||
import ca.uhn.fhir.rest.client.impl.GenericClient;
|
||||
import ca.uhn.fhir.to.model.HomeRequest;
|
||||
import ca.uhn.fhir.util.ExtensionConstants;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.*;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.defaultString;
|
||||
|
||||
public class BaseController {
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseController.class);
|
||||
static final String PARAM_RESOURCE = "resource";
|
||||
static final String RESOURCE_COUNT_EXT_URL = "http://hl7api.sourceforge.net/hapi-fhir/res/extdefs.html#resourceCount";
|
||||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseController.class);
|
||||
@Autowired
|
||||
protected TesterConfig myConfig;
|
||||
private Map<FhirVersionEnum, FhirContext> myContexts = new HashMap<FhirVersionEnum, FhirContext>();
|
||||
|
@ -294,13 +297,15 @@ public class BaseController {
|
|||
|
||||
private IBaseResource loadAndAddConf(HttpServletRequest theServletRequest, final HomeRequest theRequest, final ModelMap theModel) {
|
||||
switch (theRequest.getFhirVersion(myConfig)) {
|
||||
case DSTU2:
|
||||
return loadAndAddConfDstu2(theServletRequest, theRequest, theModel);
|
||||
case DSTU3:
|
||||
return loadAndAddConfDstu3(theServletRequest, theRequest, theModel);
|
||||
case DSTU2_1:
|
||||
case DSTU2_HL7ORG:
|
||||
break;
|
||||
case DSTU2:
|
||||
return loadAndAddConfDstu2(theServletRequest, theRequest, theModel);
|
||||
case DSTU3:
|
||||
return loadAndAddConfDstu3(theServletRequest, theRequest, theModel);
|
||||
case R4:
|
||||
return loadAndAddConfR4(theServletRequest, theRequest, theModel);
|
||||
case DSTU2_1:
|
||||
case DSTU2_HL7ORG:
|
||||
break;
|
||||
}
|
||||
throw new IllegalStateException("Unknown version: " + theRequest.getFhirVersion(myConfig));
|
||||
}
|
||||
|
@ -379,7 +384,7 @@ public class BaseController {
|
|||
}
|
||||
|
||||
theModel.put("jsonEncodedConf", getContext(theRequest).newJsonParser().encodeResourceToString(capabilityStatement));
|
||||
|
||||
|
||||
Map<String, Number> resourceCounts = new HashMap<String, Number>();
|
||||
long total = 0;
|
||||
|
||||
|
@ -427,6 +432,67 @@ public class BaseController {
|
|||
return capabilityStatement;
|
||||
}
|
||||
|
||||
private IBaseResource loadAndAddConfR4(HttpServletRequest theServletRequest, final HomeRequest theRequest, final ModelMap theModel) {
|
||||
CaptureInterceptor interceptor = new CaptureInterceptor();
|
||||
GenericClient client = theRequest.newClient(theServletRequest, getContext(theRequest), myConfig, interceptor);
|
||||
|
||||
org.hl7.fhir.r4.model.CapabilityStatement capabilityStatement = new org.hl7.fhir.r4.model.CapabilityStatement();
|
||||
try {
|
||||
capabilityStatement = client.fetchConformance().ofType(org.hl7.fhir.r4.model.CapabilityStatement.class).execute();
|
||||
} catch (Exception ex) {
|
||||
ourLog.warn("Failed to load conformance statement, error was: {}", ex.toString());
|
||||
theModel.put("errorMsg", toDisplayError("Failed to load conformance statement, error was: " + ex.toString(), ex));
|
||||
}
|
||||
|
||||
theModel.put("jsonEncodedConf", getContext(theRequest).newJsonParser().encodeResourceToString(capabilityStatement));
|
||||
|
||||
Map<String, Number> resourceCounts = new HashMap<String, Number>();
|
||||
long total = 0;
|
||||
|
||||
for (org.hl7.fhir.r4.model.CapabilityStatement.CapabilityStatementRestComponent nextRest : capabilityStatement.getRest()) {
|
||||
for (org.hl7.fhir.r4.model.CapabilityStatement.CapabilityStatementRestResourceComponent nextResource : nextRest.getResource()) {
|
||||
List<org.hl7.fhir.r4.model.Extension> exts = nextResource.getExtensionsByUrl(RESOURCE_COUNT_EXT_URL);
|
||||
if (exts != null && exts.size() > 0) {
|
||||
Number nextCount = ((org.hl7.fhir.r4.model.DecimalType) (exts.get(0).getValue())).getValueAsNumber();
|
||||
resourceCounts.put(nextResource.getTypeElement().getValue(), nextCount);
|
||||
total += nextCount.longValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
theModel.put("resourceCounts", resourceCounts);
|
||||
|
||||
if (total > 0) {
|
||||
for (org.hl7.fhir.r4.model.CapabilityStatement.CapabilityStatementRestComponent nextRest : capabilityStatement.getRest()) {
|
||||
Collections.sort(nextRest.getResource(), new Comparator<org.hl7.fhir.r4.model.CapabilityStatement.CapabilityStatementRestResourceComponent>() {
|
||||
@Override
|
||||
public int compare(org.hl7.fhir.r4.model.CapabilityStatement.CapabilityStatementRestResourceComponent theO1, org.hl7.fhir.r4.model.CapabilityStatement.CapabilityStatementRestResourceComponent theO2) {
|
||||
org.hl7.fhir.r4.model.DecimalType count1 = new org.hl7.fhir.r4.model.DecimalType();
|
||||
List<org.hl7.fhir.r4.model.Extension> count1exts = theO1.getExtensionsByUrl(RESOURCE_COUNT_EXT_URL);
|
||||
if (count1exts != null && count1exts.size() > 0) {
|
||||
count1 = (org.hl7.fhir.r4.model.DecimalType) count1exts.get(0).getValue();
|
||||
}
|
||||
org.hl7.fhir.r4.model.DecimalType count2 = new org.hl7.fhir.r4.model.DecimalType();
|
||||
List<org.hl7.fhir.r4.model.Extension> count2exts = theO2.getExtensionsByUrl(RESOURCE_COUNT_EXT_URL);
|
||||
if (count2exts != null && count2exts.size() > 0) {
|
||||
count2 = (org.hl7.fhir.r4.model.DecimalType) count2exts.get(0).getValue();
|
||||
}
|
||||
int retVal = count2.compareTo(count1);
|
||||
if (retVal == 0) {
|
||||
retVal = theO1.getTypeElement().getValue().compareTo(theO2.getTypeElement().getValue());
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
theModel.put("requiredParamExtension", ExtensionConstants.PARAM_IS_REQUIRED);
|
||||
|
||||
theModel.put("conf", capabilityStatement);
|
||||
return capabilityStatement;
|
||||
}
|
||||
|
||||
protected String logPrefix(ModelMap theModel) {
|
||||
return "[server=" + theModel.get("serverId") + "] - ";
|
||||
}
|
||||
|
@ -485,7 +551,7 @@ public class BaseController {
|
|||
}
|
||||
|
||||
protected void processAndAddLastClientInvocation(GenericClient theClient, ResultType theResultType, ModelMap theModelMap, long theLatency, String outcomeDescription,
|
||||
CaptureInterceptor theInterceptor, HomeRequest theRequest) {
|
||||
CaptureInterceptor theInterceptor, HomeRequest theRequest) {
|
||||
try {
|
||||
// ApacheHttpRequest lastRequest = theInterceptor.getLastRequest();
|
||||
// HttpResponse lastResponse = theInterceptor.getLastResponse();
|
||||
|
@ -505,7 +571,7 @@ public class BaseController {
|
|||
// ContentType ct = lastResponse != null ? ContentType.get(lastResponse.getEntity()) : null;
|
||||
// String mimeType = ct != null ? ct.getMimeType() : null;
|
||||
|
||||
|
||||
|
||||
IHttpRequest lastRequest = theInterceptor.getLastRequest();
|
||||
IHttpResponse lastResponse = theInterceptor.getLastResponse();
|
||||
String requestBody = null;
|
||||
|
@ -524,7 +590,7 @@ public class BaseController {
|
|||
resultStatus = "HTTP " + lastResponse.getStatus() + " " + lastResponse.getStatusInfo();
|
||||
lastResponse.bufferEntity();
|
||||
resultBody = IOUtils.toString(lastResponse.readEntity(), Constants.CHARSET_UTF8);
|
||||
|
||||
|
||||
List<String> ctStrings = lastResponse.getHeaders(Constants.HEADER_CONTENT_TYPE);
|
||||
if (ctStrings != null && ctStrings.isEmpty() == false) {
|
||||
ct = ContentType.parse(ctStrings.get(0));
|
||||
|
@ -543,25 +609,25 @@ public class BaseController {
|
|||
resultDescription.append("Non-FHIR response");
|
||||
} else {
|
||||
switch (ctEnum) {
|
||||
case JSON:
|
||||
if (theResultType == ResultType.RESOURCE) {
|
||||
narrativeString = parseNarrative(theRequest, ctEnum, resultBody);
|
||||
resultDescription.append("JSON resource");
|
||||
} else if (theResultType == ResultType.BUNDLE) {
|
||||
resultDescription.append("JSON bundle");
|
||||
riBundle = context.newJsonParser().parseResource(resultBody);
|
||||
}
|
||||
break;
|
||||
case XML:
|
||||
default:
|
||||
if (theResultType == ResultType.RESOURCE) {
|
||||
narrativeString = parseNarrative(theRequest, ctEnum, resultBody);
|
||||
resultDescription.append("XML resource");
|
||||
} else if (theResultType == ResultType.BUNDLE) {
|
||||
resultDescription.append("XML bundle");
|
||||
riBundle = context.newXmlParser().parseResource(resultBody);
|
||||
}
|
||||
break;
|
||||
case JSON:
|
||||
if (theResultType == ResultType.RESOURCE) {
|
||||
narrativeString = parseNarrative(theRequest, ctEnum, resultBody);
|
||||
resultDescription.append("JSON resource");
|
||||
} else if (theResultType == ResultType.BUNDLE) {
|
||||
resultDescription.append("JSON bundle");
|
||||
riBundle = context.newJsonParser().parseResource(resultBody);
|
||||
}
|
||||
break;
|
||||
case XML:
|
||||
default:
|
||||
if (theResultType == ResultType.RESOURCE) {
|
||||
narrativeString = parseNarrative(theRequest, ctEnum, resultBody);
|
||||
resultDescription.append("XML resource");
|
||||
} else if (theResultType == ResultType.BUNDLE) {
|
||||
resultDescription.append("XML bundle");
|
||||
riBundle = context.newXmlParser().parseResource(resultBody);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -599,6 +665,22 @@ public class BaseController {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* A hook to be overridden by subclasses. The overriding method can modify the error message
|
||||
* based on its content and/or the related exception.
|
||||
*
|
||||
* @param theErrorMsg The original error message to be displayed to the user.
|
||||
* @param theException The exception that occurred. May be null.
|
||||
* @return The modified error message to be displayed to the user.
|
||||
*/
|
||||
protected String toDisplayError(String theErrorMsg, Exception theException) {
|
||||
return theErrorMsg;
|
||||
}
|
||||
|
||||
protected enum ResultType {
|
||||
BUNDLE, NONE, RESOURCE, TAGLIST
|
||||
}
|
||||
|
||||
public static class CaptureInterceptor implements IClientInterceptor {
|
||||
|
||||
private IHttpRequest myLastRequest;
|
||||
|
@ -620,7 +702,7 @@ public class BaseController {
|
|||
@Override
|
||||
public void interceptRequest(IHttpRequest theRequest) {
|
||||
assert myLastRequest == null;
|
||||
|
||||
|
||||
myLastRequest = theRequest;
|
||||
}
|
||||
|
||||
|
@ -667,20 +749,4 @@ public class BaseController {
|
|||
|
||||
}
|
||||
|
||||
protected enum ResultType {
|
||||
BUNDLE, NONE, RESOURCE, TAGLIST
|
||||
}
|
||||
|
||||
/**
|
||||
* A hook to be overridden by subclasses. The overriding method can modify the error message
|
||||
* based on its content and/or the related exception.
|
||||
*
|
||||
* @param theErrorMsg The original error message to be displayed to the user.
|
||||
* @param theException The exception that occurred. May be null.
|
||||
* @return The modified error message to be displayed to the user.
|
||||
*/
|
||||
protected String toDisplayError(String theErrorMsg, Exception theException) {
|
||||
return theErrorMsg;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue