Fix problem with profiled resources being called examples in IG publisher
This commit is contained in:
parent
09e010b486
commit
516ec50afa
|
@ -338,8 +338,9 @@ public class ImplementationGuide40_50 {
|
|||
tgt.setDescriptionElement(String40_50.convertString(src.getDescriptionElement()));
|
||||
if (src.hasIsExample())
|
||||
tgt.setExample(ConversionContext40_50.INSTANCE.getVersionConvertor_40_50().convertType(src.getIsExampleElement()));
|
||||
if (src.hasProfile())
|
||||
if (src.hasProfile() && (!src.hasIsExample() || src.getIsExample())) {
|
||||
tgt.setExample(ConversionContext40_50.INSTANCE.getVersionConvertor_40_50().convertType(src.getProfile().get(0)));
|
||||
}
|
||||
if (src.hasGroupingId())
|
||||
tgt.setGroupingIdElement(Id40_50.convertId(src.getGroupingIdElement()));
|
||||
return tgt;
|
||||
|
|
|
@ -1,586 +0,0 @@
|
|||
package org.hl7.fhir.dstu3.model;
|
||||
|
||||
/*
|
||||
Copyright (c) 2011+, HL7, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of HL7 nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
|
||||
public class ExpressionNode {
|
||||
|
||||
public enum Kind {
|
||||
Name, Function, Constant, Group
|
||||
}
|
||||
public static class SourceLocation {
|
||||
private int line;
|
||||
private int column;
|
||||
public SourceLocation(int line, int column) {
|
||||
super();
|
||||
this.line = line;
|
||||
this.column = column;
|
||||
}
|
||||
public int getLine() {
|
||||
return line;
|
||||
}
|
||||
public int getColumn() {
|
||||
return column;
|
||||
}
|
||||
public void setLine(int line) {
|
||||
this.line = line;
|
||||
}
|
||||
public void setColumn(int column) {
|
||||
this.column = column;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return Integer.toString(line)+", "+Integer.toString(column);
|
||||
}
|
||||
}
|
||||
public enum Function {
|
||||
Custom,
|
||||
|
||||
Empty, Not, Exists, SubsetOf, SupersetOf, IsDistinct, Distinct, Count, Where, Select, All, Repeat, Item /*implicit from name[]*/, As, Is, Single,
|
||||
First, Last, Tail, Skip, Take, Iif, ToInteger, ToDecimal, ToString, Substring, StartsWith, EndsWith, Matches, ReplaceMatches, Contains, Replace, Length,
|
||||
Children, Descendants, MemberOf, Trace, Today, Now, Resolve, Extension, HasValue, AliasAs, Alias;
|
||||
|
||||
public static Function fromCode(String name) {
|
||||
if (name.equals("empty")) return Function.Empty;
|
||||
if (name.equals("not")) return Function.Not;
|
||||
if (name.equals("exists")) return Function.Exists;
|
||||
if (name.equals("subsetOf")) return Function.SubsetOf;
|
||||
if (name.equals("supersetOf")) return Function.SupersetOf;
|
||||
if (name.equals("isDistinct")) return Function.IsDistinct;
|
||||
if (name.equals("distinct")) return Function.Distinct;
|
||||
if (name.equals("count")) return Function.Count;
|
||||
if (name.equals("where")) return Function.Where;
|
||||
if (name.equals("select")) return Function.Select;
|
||||
if (name.equals("all")) return Function.All;
|
||||
if (name.equals("repeat")) return Function.Repeat;
|
||||
if (name.equals("item")) return Function.Item;
|
||||
if (name.equals("as")) return Function.As;
|
||||
if (name.equals("is")) return Function.Is;
|
||||
if (name.equals("single")) return Function.Single;
|
||||
if (name.equals("first")) return Function.First;
|
||||
if (name.equals("last")) return Function.Last;
|
||||
if (name.equals("tail")) return Function.Tail;
|
||||
if (name.equals("skip")) return Function.Skip;
|
||||
if (name.equals("take")) return Function.Take;
|
||||
if (name.equals("iif")) return Function.Iif;
|
||||
if (name.equals("toInteger")) return Function.ToInteger;
|
||||
if (name.equals("toDecimal")) return Function.ToDecimal;
|
||||
if (name.equals("toString")) return Function.ToString;
|
||||
if (name.equals("substring")) return Function.Substring;
|
||||
if (name.equals("startsWith")) return Function.StartsWith;
|
||||
if (name.equals("endsWith")) return Function.EndsWith;
|
||||
if (name.equals("matches")) return Function.Matches;
|
||||
if (name.equals("replaceMatches")) return Function.ReplaceMatches;
|
||||
if (name.equals("contains")) return Function.Contains;
|
||||
if (name.equals("replace")) return Function.Replace;
|
||||
if (name.equals("length")) return Function.Length;
|
||||
if (name.equals("children")) return Function.Children;
|
||||
if (name.equals("descendants")) return Function.Descendants;
|
||||
if (name.equals("memberOf")) return Function.MemberOf;
|
||||
if (name.equals("trace")) return Function.Trace;
|
||||
if (name.equals("today")) return Function.Today;
|
||||
if (name.equals("now")) return Function.Now;
|
||||
if (name.equals("resolve")) return Function.Resolve;
|
||||
if (name.equals("extension")) return Function.Extension;
|
||||
if (name.equals("hasValue")) return Function.HasValue;
|
||||
if (name.equals("alias")) return Function.Alias;
|
||||
if (name.equals("aliasAs")) return Function.AliasAs;
|
||||
return null;
|
||||
}
|
||||
public String toCode() {
|
||||
switch (this) {
|
||||
case Empty : return "empty";
|
||||
case Not : return "not";
|
||||
case Exists : return "exists";
|
||||
case SubsetOf : return "subsetOf";
|
||||
case SupersetOf : return "supersetOf";
|
||||
case IsDistinct : return "isDistinct";
|
||||
case Distinct : return "distinct";
|
||||
case Count : return "count";
|
||||
case Where : return "where";
|
||||
case Select : return "select";
|
||||
case All : return "all";
|
||||
case Repeat : return "repeat";
|
||||
case Item : return "item";
|
||||
case As : return "as";
|
||||
case Is : return "is";
|
||||
case Single : return "single";
|
||||
case First : return "first";
|
||||
case Last : return "last";
|
||||
case Tail : return "tail";
|
||||
case Skip : return "skip";
|
||||
case Take : return "take";
|
||||
case Iif : return "iif";
|
||||
case ToInteger : return "toInteger";
|
||||
case ToDecimal : return "toDecimal";
|
||||
case ToString : return "toString";
|
||||
case Substring : return "substring";
|
||||
case StartsWith : return "startsWith";
|
||||
case EndsWith : return "endsWith";
|
||||
case Matches : return "matches";
|
||||
case ReplaceMatches : return "replaceMatches";
|
||||
case Contains : return "contains";
|
||||
case Replace : return "replace";
|
||||
case Length : return "length";
|
||||
case Children : return "children";
|
||||
case Descendants : return "descendants";
|
||||
case MemberOf : return "memberOf";
|
||||
case Trace : return "trace";
|
||||
case Today : return "today";
|
||||
case Now : return "now";
|
||||
case Resolve : return "resolve";
|
||||
case Extension : return "extension";
|
||||
case HasValue : return "hasValue";
|
||||
case Alias : return "alias";
|
||||
case AliasAs : return "aliasAs";
|
||||
default: return "??";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum Operation {
|
||||
Equals, Equivalent, NotEquals, NotEquivalent, LessThen, Greater, LessOrEqual, GreaterOrEqual, Is, As, Union, Or, And, Xor, Implies,
|
||||
Times, DivideBy, Plus, Minus, Concatenate, Div, Mod, In, Contains;
|
||||
|
||||
public static Operation fromCode(String name) {
|
||||
if (Utilities.noString(name))
|
||||
return null;
|
||||
if (name.equals("="))
|
||||
return Operation.Equals;
|
||||
if (name.equals("~"))
|
||||
return Operation.Equivalent;
|
||||
if (name.equals("!="))
|
||||
return Operation.NotEquals;
|
||||
if (name.equals("!~"))
|
||||
return Operation.NotEquivalent;
|
||||
if (name.equals(">"))
|
||||
return Operation.Greater;
|
||||
if (name.equals("<"))
|
||||
return Operation.LessThen;
|
||||
if (name.equals(">="))
|
||||
return Operation.GreaterOrEqual;
|
||||
if (name.equals("<="))
|
||||
return Operation.LessOrEqual;
|
||||
if (name.equals("|"))
|
||||
return Operation.Union;
|
||||
if (name.equals("or"))
|
||||
return Operation.Or;
|
||||
if (name.equals("and"))
|
||||
return Operation.And;
|
||||
if (name.equals("xor"))
|
||||
return Operation.Xor;
|
||||
if (name.equals("is"))
|
||||
return Operation.Is;
|
||||
if (name.equals("as"))
|
||||
return Operation.As;
|
||||
if (name.equals("*"))
|
||||
return Operation.Times;
|
||||
if (name.equals("/"))
|
||||
return Operation.DivideBy;
|
||||
if (name.equals("+"))
|
||||
return Operation.Plus;
|
||||
if (name.equals("-"))
|
||||
return Operation.Minus;
|
||||
if (name.equals("&"))
|
||||
return Operation.Concatenate;
|
||||
if (name.equals("implies"))
|
||||
return Operation.Implies;
|
||||
if (name.equals("div"))
|
||||
return Operation.Div;
|
||||
if (name.equals("mod"))
|
||||
return Operation.Mod;
|
||||
if (name.equals("in"))
|
||||
return Operation.In;
|
||||
if (name.equals("contains"))
|
||||
return Operation.Contains;
|
||||
return null;
|
||||
|
||||
}
|
||||
public String toCode() {
|
||||
switch (this) {
|
||||
case Equals : return "=";
|
||||
case Equivalent : return "~";
|
||||
case NotEquals : return "!=";
|
||||
case NotEquivalent : return "!~";
|
||||
case Greater : return ">";
|
||||
case LessThen : return "<";
|
||||
case GreaterOrEqual : return ">=";
|
||||
case LessOrEqual : return "<=";
|
||||
case Union : return "|";
|
||||
case Or : return "or";
|
||||
case And : return "and";
|
||||
case Xor : return "xor";
|
||||
case Times : return "*";
|
||||
case DivideBy : return "/";
|
||||
case Plus : return "+";
|
||||
case Minus : return "-";
|
||||
case Concatenate : return "&";
|
||||
case Implies : return "implies";
|
||||
case Is : return "is";
|
||||
case As : return "as";
|
||||
case Div : return "div";
|
||||
case Mod : return "mod";
|
||||
case In : return "in";
|
||||
case Contains : return "contains";
|
||||
default: return "??";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum CollectionStatus {
|
||||
SINGLETON, ORDERED, UNORDERED;
|
||||
}
|
||||
|
||||
//the expression will have one of either name or constant
|
||||
private String uniqueId;
|
||||
private Kind kind;
|
||||
private String name;
|
||||
private String constant;
|
||||
private Function function;
|
||||
private List<ExpressionNode> parameters; // will be created if there is a function
|
||||
private ExpressionNode inner;
|
||||
private ExpressionNode group;
|
||||
private Operation operation;
|
||||
private boolean proximal; // a proximal operation is the first in the sequence of operations. This is significant when evaluating the outcomes
|
||||
private ExpressionNode opNext;
|
||||
private SourceLocation start;
|
||||
private SourceLocation end;
|
||||
private SourceLocation opStart;
|
||||
private SourceLocation opEnd;
|
||||
private TypeDetails types;
|
||||
private TypeDetails opTypes;
|
||||
|
||||
|
||||
public ExpressionNode(int uniqueId) {
|
||||
super();
|
||||
this.uniqueId = Integer.toString(uniqueId);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder b = new StringBuilder();
|
||||
switch (kind) {
|
||||
case Name:
|
||||
b.append(name);
|
||||
break;
|
||||
case Function:
|
||||
if (function == Function.Item)
|
||||
b.append("[");
|
||||
else {
|
||||
b.append(name);
|
||||
b.append("(");
|
||||
}
|
||||
boolean first = true;
|
||||
for (ExpressionNode n : parameters) {
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
b.append(", ");
|
||||
b.append(n.toString());
|
||||
}
|
||||
if (function == Function.Item)
|
||||
b.append("]");
|
||||
else {
|
||||
b.append(")");
|
||||
}
|
||||
break;
|
||||
case Constant:
|
||||
b.append(Utilities.escapeJava(constant));
|
||||
break;
|
||||
case Group:
|
||||
b.append("(");
|
||||
b.append(group.toString());
|
||||
b.append(")");
|
||||
}
|
||||
if (inner != null) {
|
||||
b.append(".");
|
||||
b.append(inner.toString());
|
||||
}
|
||||
if (operation != null) {
|
||||
b.append(" ");
|
||||
b.append(operation.toCode());
|
||||
b.append(" ");
|
||||
b.append(opNext.toString());
|
||||
}
|
||||
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
public String getConstant() {
|
||||
return constant;
|
||||
}
|
||||
public void setConstant(String constant) {
|
||||
this.constant = constant;
|
||||
}
|
||||
public Function getFunction() {
|
||||
return function;
|
||||
}
|
||||
public void setFunction(Function function) {
|
||||
this.function = function;
|
||||
if (parameters == null)
|
||||
parameters = new ArrayList<ExpressionNode>();
|
||||
}
|
||||
|
||||
public boolean isProximal() {
|
||||
return proximal;
|
||||
}
|
||||
public void setProximal(boolean proximal) {
|
||||
this.proximal = proximal;
|
||||
}
|
||||
public Operation getOperation() {
|
||||
return operation;
|
||||
}
|
||||
public void setOperation(Operation operation) {
|
||||
this.operation = operation;
|
||||
}
|
||||
public ExpressionNode getInner() {
|
||||
return inner;
|
||||
}
|
||||
public void setInner(ExpressionNode value) {
|
||||
this.inner = value;
|
||||
}
|
||||
public ExpressionNode getOpNext() {
|
||||
return opNext;
|
||||
}
|
||||
public void setOpNext(ExpressionNode value) {
|
||||
this.opNext = value;
|
||||
}
|
||||
public List<ExpressionNode> getParameters() {
|
||||
return parameters;
|
||||
}
|
||||
public boolean checkName() {
|
||||
if (!name.startsWith("$"))
|
||||
return true;
|
||||
else
|
||||
return name.equals("$this");
|
||||
}
|
||||
|
||||
public Kind getKind() {
|
||||
return kind;
|
||||
}
|
||||
|
||||
public void setKind(Kind kind) {
|
||||
this.kind = kind;
|
||||
}
|
||||
|
||||
public ExpressionNode getGroup() {
|
||||
return group;
|
||||
}
|
||||
|
||||
public void setGroup(ExpressionNode group) {
|
||||
this.group = group;
|
||||
}
|
||||
|
||||
public SourceLocation getStart() {
|
||||
return start;
|
||||
}
|
||||
|
||||
public void setStart(SourceLocation start) {
|
||||
this.start = start;
|
||||
}
|
||||
|
||||
public SourceLocation getEnd() {
|
||||
return end;
|
||||
}
|
||||
|
||||
public void setEnd(SourceLocation end) {
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
public SourceLocation getOpStart() {
|
||||
return opStart;
|
||||
}
|
||||
|
||||
public void setOpStart(SourceLocation opStart) {
|
||||
this.opStart = opStart;
|
||||
}
|
||||
|
||||
public SourceLocation getOpEnd() {
|
||||
return opEnd;
|
||||
}
|
||||
|
||||
public void setOpEnd(SourceLocation opEnd) {
|
||||
this.opEnd = opEnd;
|
||||
}
|
||||
|
||||
public String getUniqueId() {
|
||||
return uniqueId;
|
||||
}
|
||||
|
||||
|
||||
public int parameterCount() {
|
||||
if (parameters == null)
|
||||
return 0;
|
||||
else
|
||||
return parameters.size();
|
||||
}
|
||||
|
||||
public String Canonical() {
|
||||
StringBuilder b = new StringBuilder();
|
||||
write(b);
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
public String summary() {
|
||||
switch (kind) {
|
||||
case Name: return uniqueId+": "+name;
|
||||
case Function: return uniqueId+": "+function.toString()+"()";
|
||||
case Constant: return uniqueId+": "+constant;
|
||||
case Group: return uniqueId+": (Group)";
|
||||
}
|
||||
return "??";
|
||||
}
|
||||
|
||||
private void write(StringBuilder b) {
|
||||
|
||||
switch (kind) {
|
||||
case Name:
|
||||
b.append(name);
|
||||
break;
|
||||
case Constant:
|
||||
b.append(constant);
|
||||
break;
|
||||
case Function:
|
||||
b.append(function.toCode());
|
||||
b.append('(');
|
||||
boolean f = true;
|
||||
for (ExpressionNode n : parameters) {
|
||||
if (f)
|
||||
f = false;
|
||||
else
|
||||
b.append(", ");
|
||||
n.write(b);
|
||||
}
|
||||
b.append(')');
|
||||
|
||||
break;
|
||||
case Group:
|
||||
b.append('(');
|
||||
group.write(b);
|
||||
b.append(')');
|
||||
}
|
||||
|
||||
if (inner != null) {
|
||||
b.append('.');
|
||||
inner.write(b);
|
||||
}
|
||||
if (operation != null) {
|
||||
b.append(' ');
|
||||
b.append(operation.toCode());
|
||||
b.append(' ');
|
||||
opNext.write(b);
|
||||
}
|
||||
}
|
||||
|
||||
public String check() {
|
||||
|
||||
switch (kind) {
|
||||
case Name:
|
||||
if (Utilities.noString(name))
|
||||
return "No Name provided @ "+location();
|
||||
break;
|
||||
|
||||
case Function:
|
||||
if (function == null)
|
||||
return "No Function id provided @ "+location();
|
||||
for (ExpressionNode n : parameters) {
|
||||
String msg = n.check();
|
||||
if (msg != null)
|
||||
return msg;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Constant:
|
||||
if (Utilities.noString(constant))
|
||||
return "No Constant provided @ "+location();
|
||||
break;
|
||||
|
||||
case Group:
|
||||
if (group == null)
|
||||
return "No Group provided @ "+location();
|
||||
else {
|
||||
String msg = group.check();
|
||||
if (msg != null)
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
if (inner != null) {
|
||||
String msg = inner.check();
|
||||
if (msg != null)
|
||||
return msg;
|
||||
}
|
||||
if (operation == null) {
|
||||
|
||||
if (opNext != null)
|
||||
return "Next provided when it shouldn't be @ "+location();
|
||||
}
|
||||
else {
|
||||
if (opNext == null)
|
||||
return "No Next provided @ "+location();
|
||||
else
|
||||
opNext.check();
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
private String location() {
|
||||
return Integer.toString(start.getLine())+", "+Integer.toString(start.getColumn());
|
||||
}
|
||||
|
||||
public TypeDetails getTypes() {
|
||||
return types;
|
||||
}
|
||||
|
||||
public void setTypes(TypeDetails types) {
|
||||
this.types = types;
|
||||
}
|
||||
|
||||
public TypeDetails getOpTypes() {
|
||||
return opTypes;
|
||||
}
|
||||
|
||||
public void setOpTypes(TypeDetails opTypes) {
|
||||
this.opTypes = opTypes;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,280 +0,0 @@
|
|||
package org.hl7.fhir.dstu3.model;
|
||||
|
||||
/*
|
||||
Copyright (c) 2011+, HL7, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of HL7 nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hl7.fhir.dstu3.context.IWorkerContext;
|
||||
import org.hl7.fhir.dstu3.model.ElementDefinition.ElementDefinitionBindingComponent;
|
||||
import org.hl7.fhir.dstu3.model.ExpressionNode.CollectionStatus;
|
||||
import org.hl7.fhir.exceptions.DefinitionException;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
|
||||
public class TypeDetails {
|
||||
public static class ProfiledType {
|
||||
private String uri;
|
||||
private List<String> profiles; // or, not and
|
||||
private List<ElementDefinitionBindingComponent> bindings;
|
||||
|
||||
public ProfiledType(String n) {
|
||||
uri = ns(n);
|
||||
}
|
||||
|
||||
public String getUri() {
|
||||
return uri;
|
||||
}
|
||||
|
||||
public boolean hasProfiles() {
|
||||
return profiles != null && profiles.size() > 0;
|
||||
}
|
||||
public List<String> getProfiles() {
|
||||
return profiles;
|
||||
}
|
||||
|
||||
public boolean hasBindings() {
|
||||
return bindings != null && bindings.size() > 0;
|
||||
}
|
||||
public List<ElementDefinitionBindingComponent> getBindings() {
|
||||
return bindings;
|
||||
}
|
||||
|
||||
public static String ns(String n) {
|
||||
return Utilities.isAbsoluteUrl(n) ? n : "http://hl7.org/fhir/StructureDefinition/"+n;
|
||||
}
|
||||
|
||||
public void addProfile(String profile) {
|
||||
profiles = new ArrayList<String>();
|
||||
profiles.add(profile);
|
||||
}
|
||||
|
||||
public void addBinding(ElementDefinitionBindingComponent binding) {
|
||||
bindings = new ArrayList<ElementDefinitionBindingComponent>();
|
||||
bindings.add(binding);
|
||||
}
|
||||
|
||||
public boolean hasBinding(ElementDefinitionBindingComponent b) {
|
||||
return false; // todo: do we need to do this?
|
||||
}
|
||||
}
|
||||
|
||||
private List<ProfiledType> types = new ArrayList<ProfiledType>();
|
||||
private CollectionStatus collectionStatus;
|
||||
public TypeDetails(CollectionStatus collectionStatus, String... names) {
|
||||
super();
|
||||
this.collectionStatus = collectionStatus;
|
||||
for (String n : names) {
|
||||
this.types.add(new ProfiledType(n));
|
||||
}
|
||||
}
|
||||
public TypeDetails(CollectionStatus collectionStatus, Set<String> names) {
|
||||
super();
|
||||
this.collectionStatus = collectionStatus;
|
||||
for (String n : names) {
|
||||
addType(new ProfiledType(n));
|
||||
}
|
||||
}
|
||||
public TypeDetails(CollectionStatus collectionStatus, ProfiledType pt) {
|
||||
super();
|
||||
this.collectionStatus = collectionStatus;
|
||||
this.types.add(pt);
|
||||
}
|
||||
public String addType(String n) {
|
||||
ProfiledType pt = new ProfiledType(n);
|
||||
String res = pt.uri;
|
||||
addType(pt);
|
||||
return res;
|
||||
}
|
||||
public String addType(String n, String p) {
|
||||
ProfiledType pt = new ProfiledType(n);
|
||||
pt.addProfile(p);
|
||||
String res = pt.uri;
|
||||
addType(pt);
|
||||
return res;
|
||||
}
|
||||
public void addType(ProfiledType pt) {
|
||||
for (ProfiledType et : types) {
|
||||
if (et.uri.equals(pt.uri)) {
|
||||
if (pt.profiles != null) {
|
||||
for (String p : pt.profiles) {
|
||||
if (et.profiles == null)
|
||||
et.profiles = new ArrayList<String>();
|
||||
if (!et.profiles.contains(p))
|
||||
et.profiles.add(p);
|
||||
}
|
||||
}
|
||||
if (pt.bindings != null) {
|
||||
for (ElementDefinitionBindingComponent b : pt.bindings) {
|
||||
if (et.bindings == null)
|
||||
et.bindings = new ArrayList<ElementDefinitionBindingComponent>();
|
||||
if (!et.hasBinding(b))
|
||||
et.bindings.add(b);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
types.add(pt);
|
||||
}
|
||||
|
||||
public void addTypes(Collection<String> names) {
|
||||
for (String n : names)
|
||||
addType(new ProfiledType(n));
|
||||
}
|
||||
|
||||
public boolean hasType(IWorkerContext context, String... tn) {
|
||||
for (String n: tn) {
|
||||
String t = ProfiledType.ns(n);
|
||||
if (typesContains(t))
|
||||
return true;
|
||||
}
|
||||
for (String n: tn) {
|
||||
String id = n.contains("#") ? n.substring(0, n.indexOf("#")) : n;
|
||||
String tail = null;
|
||||
if (n.contains("#")) {
|
||||
tail = n.substring( n.indexOf("#")+1);
|
||||
tail = tail.substring(tail.indexOf("."));
|
||||
}
|
||||
String t = ProfiledType.ns(n);
|
||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, t);
|
||||
while (sd != null) {
|
||||
if (tail == null && typesContains(sd.getUrl()))
|
||||
return true;
|
||||
if (tail != null && typesContains(sd.getUrl()+"#"+sd.getType()+tail))
|
||||
return true;
|
||||
if (sd.hasBaseDefinition())
|
||||
sd = context.fetchResource(StructureDefinition.class, sd.getBaseDefinition());
|
||||
else
|
||||
sd = null;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean typesContains(String t) {
|
||||
for (ProfiledType pt : types)
|
||||
if (pt.uri.equals(t))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public void update(TypeDetails source) {
|
||||
for (ProfiledType pt : source.types)
|
||||
addType(pt);
|
||||
if (collectionStatus == null)
|
||||
collectionStatus = source.collectionStatus;
|
||||
else if (source.collectionStatus == CollectionStatus.UNORDERED)
|
||||
collectionStatus = source.collectionStatus;
|
||||
else
|
||||
collectionStatus = CollectionStatus.ORDERED;
|
||||
}
|
||||
public TypeDetails union(TypeDetails right) {
|
||||
TypeDetails result = new TypeDetails(null);
|
||||
if (right.collectionStatus == CollectionStatus.UNORDERED || collectionStatus == CollectionStatus.UNORDERED)
|
||||
result.collectionStatus = CollectionStatus.UNORDERED;
|
||||
else
|
||||
result.collectionStatus = CollectionStatus.ORDERED;
|
||||
for (ProfiledType pt : types)
|
||||
result.addType(pt);
|
||||
for (ProfiledType pt : right.types)
|
||||
result.addType(pt);
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean hasNoTypes() {
|
||||
return types.isEmpty();
|
||||
}
|
||||
public Set<String> getTypes() {
|
||||
Set<String> res = new HashSet<String>();
|
||||
for (ProfiledType pt : types)
|
||||
res.add(pt.uri);
|
||||
return res;
|
||||
}
|
||||
public TypeDetails toSingleton() {
|
||||
TypeDetails result = new TypeDetails(CollectionStatus.SINGLETON);
|
||||
result.types.addAll(types);
|
||||
return result;
|
||||
}
|
||||
public CollectionStatus getCollectionStatus() {
|
||||
return collectionStatus;
|
||||
}
|
||||
public boolean hasType(Set<String> tn) {
|
||||
for (String n: tn) {
|
||||
String t = ProfiledType.ns(n);
|
||||
if (typesContains(t))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public String describe() {
|
||||
return getTypes().toString();
|
||||
}
|
||||
public String getType() {
|
||||
for (ProfiledType pt : types)
|
||||
return pt.uri;
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return (collectionStatus == null ? collectionStatus.SINGLETON.toString() : collectionStatus.toString()) + getTypes().toString();
|
||||
}
|
||||
public String getTypeCode() throws DefinitionException {
|
||||
if (types.size() != 1)
|
||||
throw new DefinitionException("Multiple types? ("+types.toString()+")");
|
||||
for (ProfiledType pt : types)
|
||||
if (pt.uri.startsWith("http://hl7.org/fhir/StructureDefinition/"))
|
||||
return pt.uri.substring(40);
|
||||
else
|
||||
return pt.uri;
|
||||
return null;
|
||||
}
|
||||
public List<ProfiledType> getProfiledTypes() {
|
||||
return types;
|
||||
}
|
||||
public boolean hasBinding() {
|
||||
for (ProfiledType pt : types) {
|
||||
if (pt.hasBindings())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public ElementDefinitionBindingComponent getBinding() {
|
||||
for (ProfiledType pt : types) {
|
||||
for (ElementDefinitionBindingComponent b : pt.getBindings())
|
||||
return b;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,374 +0,0 @@
|
|||
package org.hl7.fhir.dstu3.utils;
|
||||
|
||||
/*
|
||||
Copyright (c) 2011+, HL7, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of HL7 nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
import org.hl7.fhir.dstu3.model.ExpressionNode;
|
||||
import org.hl7.fhir.dstu3.model.ExpressionNode.SourceLocation;
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
|
||||
// shared lexer for concrete syntaxes
|
||||
// - FluentPath
|
||||
// - Mapping language
|
||||
|
||||
public class FHIRLexer {
|
||||
public class FHIRLexerException extends FHIRException {
|
||||
|
||||
public FHIRLexerException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public FHIRLexerException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public FHIRLexerException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public FHIRLexerException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
private String source;
|
||||
private int cursor;
|
||||
private int currentStart;
|
||||
private String current;
|
||||
private SourceLocation currentLocation;
|
||||
private SourceLocation currentStartLocation;
|
||||
private int id;
|
||||
|
||||
public FHIRLexer(String source) throws FHIRLexerException {
|
||||
this.source = source;
|
||||
currentLocation = new SourceLocation(1, 1);
|
||||
next();
|
||||
}
|
||||
public String getCurrent() {
|
||||
return current;
|
||||
}
|
||||
public SourceLocation getCurrentLocation() {
|
||||
return currentLocation;
|
||||
}
|
||||
|
||||
public boolean isConstant(boolean incDoubleQuotes) {
|
||||
return current.charAt(0) == '\'' || (incDoubleQuotes && current.charAt(0) == '"') || current.charAt(0) == '@' || current.charAt(0) == '%' ||
|
||||
current.charAt(0) == '-' || current.charAt(0) == '+' || (current.charAt(0) >= '0' && current.charAt(0) <= '9') ||
|
||||
current.equals("true") || current.equals("false") || current.equals("{}");
|
||||
}
|
||||
|
||||
public boolean isStringConstant() {
|
||||
return current.charAt(0) == '\'' || current.charAt(0) == '"';
|
||||
}
|
||||
|
||||
public String take() throws FHIRLexerException {
|
||||
String s = current;
|
||||
next();
|
||||
return s;
|
||||
}
|
||||
|
||||
public int takeInt() throws FHIRLexerException {
|
||||
String s = current;
|
||||
if (!Utilities.isInteger(s))
|
||||
throw error("Found "+current+" expecting an integer");
|
||||
next();
|
||||
return Integer.parseInt(s);
|
||||
}
|
||||
|
||||
public boolean isToken() {
|
||||
if (Utilities.noString(current))
|
||||
return false;
|
||||
|
||||
if (current.startsWith("$"))
|
||||
return true;
|
||||
|
||||
if (current.equals("*") || current.equals("**"))
|
||||
return true;
|
||||
|
||||
if ((current.charAt(0) >= 'A' && current.charAt(0) <= 'Z') || (current.charAt(0) >= 'a' && current.charAt(0) <= 'z')) {
|
||||
for (int i = 1; i < current.length(); i++)
|
||||
if (!( (current.charAt(1) >= 'A' && current.charAt(1) <= 'Z') || (current.charAt(1) >= 'a' && current.charAt(1) <= 'z') ||
|
||||
(current.charAt(1) >= '0' && current.charAt(1) <= '9')))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public FHIRLexerException error(String msg) {
|
||||
return error(msg, currentLocation.toString());
|
||||
}
|
||||
|
||||
public FHIRLexerException error(String msg, String location) {
|
||||
return new FHIRLexerException("Error at "+location+": "+msg);
|
||||
}
|
||||
|
||||
public void next() throws FHIRLexerException {
|
||||
current = null;
|
||||
boolean last13 = false;
|
||||
while (cursor < source.length() && Character.isWhitespace(source.charAt(cursor))) {
|
||||
if (source.charAt(cursor) == '\r') {
|
||||
currentLocation.setLine(currentLocation.getLine() + 1);
|
||||
currentLocation.setColumn(1);
|
||||
last13 = true;
|
||||
} else if (!last13 && (source.charAt(cursor) == '\n')) {
|
||||
currentLocation.setLine(currentLocation.getLine() + 1);
|
||||
currentLocation.setColumn(1);
|
||||
last13 = false;
|
||||
} else {
|
||||
last13 = false;
|
||||
currentLocation.setColumn(currentLocation.getColumn() + 1);
|
||||
}
|
||||
cursor++;
|
||||
}
|
||||
currentStart = cursor;
|
||||
currentStartLocation = currentLocation;
|
||||
if (cursor < source.length()) {
|
||||
char ch = source.charAt(cursor);
|
||||
if (ch == '!' || ch == '>' || ch == '<' || ch == ':' || ch == '-' || ch == '=') {
|
||||
cursor++;
|
||||
if (cursor < source.length() && (source.charAt(cursor) == '=' || source.charAt(cursor) == '~' || source.charAt(cursor) == '-'))
|
||||
cursor++;
|
||||
current = source.substring(currentStart, cursor);
|
||||
} else if (ch == '.' ) {
|
||||
cursor++;
|
||||
if (cursor < source.length() && (source.charAt(cursor) == '.'))
|
||||
cursor++;
|
||||
current = source.substring(currentStart, cursor);
|
||||
} else if (ch >= '0' && ch <= '9') {
|
||||
cursor++;
|
||||
boolean dotted = false;
|
||||
while (cursor < source.length() && ((source.charAt(cursor) >= '0' && source.charAt(cursor) <= '9') || (source.charAt(cursor) == '.') && !dotted)) {
|
||||
if (source.charAt(cursor) == '.')
|
||||
dotted = true;
|
||||
cursor++;
|
||||
}
|
||||
if (source.charAt(cursor-1) == '.')
|
||||
cursor--;
|
||||
current = source.substring(currentStart, cursor);
|
||||
} else if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) {
|
||||
while (cursor < source.length() && ((source.charAt(cursor) >= 'A' && source.charAt(cursor) <= 'Z') || (source.charAt(cursor) >= 'a' && source.charAt(cursor) <= 'z') ||
|
||||
(source.charAt(cursor) >= '0' && source.charAt(cursor) <= '9') || source.charAt(cursor) == '_'))
|
||||
cursor++;
|
||||
current = source.substring(currentStart, cursor);
|
||||
} else if (ch == '%') {
|
||||
cursor++;
|
||||
if (cursor < source.length() && (source.charAt(cursor) == '"')) {
|
||||
cursor++;
|
||||
while (cursor < source.length() && (source.charAt(cursor) != '"'))
|
||||
cursor++;
|
||||
cursor++;
|
||||
} else
|
||||
while (cursor < source.length() && ((source.charAt(cursor) >= 'A' && source.charAt(cursor) <= 'Z') || (source.charAt(cursor) >= 'a' && source.charAt(cursor) <= 'z') ||
|
||||
(source.charAt(cursor) >= '0' && source.charAt(cursor) <= '9') || source.charAt(cursor) == ':' || source.charAt(cursor) == '-'))
|
||||
cursor++;
|
||||
current = source.substring(currentStart, cursor);
|
||||
} else if (ch == '/') {
|
||||
cursor++;
|
||||
if (cursor < source.length() && (source.charAt(cursor) == '/')) {
|
||||
cursor++;
|
||||
while (cursor < source.length() && !((source.charAt(cursor) == '\r') || source.charAt(cursor) == '\n'))
|
||||
cursor++;
|
||||
}
|
||||
current = source.substring(currentStart, cursor);
|
||||
} else if (ch == '$') {
|
||||
cursor++;
|
||||
while (cursor < source.length() && (source.charAt(cursor) >= 'a' && source.charAt(cursor) <= 'z'))
|
||||
cursor++;
|
||||
current = source.substring(currentStart, cursor);
|
||||
} else if (ch == '{') {
|
||||
cursor++;
|
||||
ch = source.charAt(cursor);
|
||||
if (ch == '}')
|
||||
cursor++;
|
||||
current = source.substring(currentStart, cursor);
|
||||
} else if (ch == '"'){
|
||||
cursor++;
|
||||
boolean escape = false;
|
||||
while (cursor < source.length() && (escape || source.charAt(cursor) != '"')) {
|
||||
if (escape)
|
||||
escape = false;
|
||||
else
|
||||
escape = (source.charAt(cursor) == '\\');
|
||||
cursor++;
|
||||
}
|
||||
if (cursor == source.length())
|
||||
throw error("Unterminated string");
|
||||
cursor++;
|
||||
current = "\""+source.substring(currentStart+1, cursor-1)+"\"";
|
||||
} else if (ch == '\''){
|
||||
cursor++;
|
||||
char ech = ch;
|
||||
boolean escape = false;
|
||||
while (cursor < source.length() && (escape || source.charAt(cursor) != ech)) {
|
||||
if (escape)
|
||||
escape = false;
|
||||
else
|
||||
escape = (source.charAt(cursor) == '\\');
|
||||
cursor++;
|
||||
}
|
||||
if (cursor == source.length())
|
||||
throw error("Unterminated string");
|
||||
cursor++;
|
||||
current = source.substring(currentStart, cursor);
|
||||
if (ech == '\'')
|
||||
current = "\'"+current.substring(1, current.length() - 1)+"\'";
|
||||
} else if (ch == '@'){
|
||||
cursor++;
|
||||
while (cursor < source.length() && isDateChar(source.charAt(cursor)))
|
||||
cursor++;
|
||||
current = source.substring(currentStart, cursor);
|
||||
} else { // if CharInSet(ch, ['.', ',', '(', ')', '=', '$']) then
|
||||
cursor++;
|
||||
current = source.substring(currentStart, cursor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private boolean isDateChar(char ch) {
|
||||
return ch == '-' || ch == ':' || ch == 'T' || ch == '+' || ch == 'Z' || Character.isDigit(ch);
|
||||
}
|
||||
public boolean isOp() {
|
||||
return ExpressionNode.Operation.fromCode(current) != null;
|
||||
}
|
||||
public boolean done() {
|
||||
return currentStart >= source.length();
|
||||
}
|
||||
public int nextId() {
|
||||
id++;
|
||||
return id;
|
||||
}
|
||||
public SourceLocation getCurrentStartLocation() {
|
||||
return currentStartLocation;
|
||||
}
|
||||
|
||||
// special case use
|
||||
public void setCurrent(String current) {
|
||||
this.current = current;
|
||||
}
|
||||
|
||||
public boolean hasComment() {
|
||||
return !done() && current.startsWith("//");
|
||||
}
|
||||
public boolean hasToken(String kw) {
|
||||
return !done() && kw.equals(current);
|
||||
}
|
||||
public boolean hasToken(String... names) {
|
||||
if (done())
|
||||
return false;
|
||||
for (String s : names)
|
||||
if (s.equals(current))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public void token(String kw) throws FHIRLexerException {
|
||||
if (!kw.equals(current))
|
||||
throw error("Found \""+current+"\" expecting \""+kw+"\"");
|
||||
next();
|
||||
}
|
||||
|
||||
public String readConstant(String desc) throws FHIRLexerException {
|
||||
if (!isStringConstant())
|
||||
throw error("Found "+current+" expecting \"["+desc+"]\"");
|
||||
|
||||
return processConstant(take());
|
||||
}
|
||||
|
||||
public String processConstant(String s) throws FHIRLexerException {
|
||||
StringBuilder b = new StringBuilder();
|
||||
int i = 1;
|
||||
while (i < s.length()-1) {
|
||||
char ch = s.charAt(i);
|
||||
if (ch == '\\') {
|
||||
i++;
|
||||
switch (s.charAt(i)) {
|
||||
case 't':
|
||||
b.append('\t');
|
||||
break;
|
||||
case 'r':
|
||||
b.append('\r');
|
||||
break;
|
||||
case 'n':
|
||||
b.append('\n');
|
||||
break;
|
||||
case 'f':
|
||||
b.append('\f');
|
||||
break;
|
||||
case '\'':
|
||||
b.append('\'');
|
||||
break;
|
||||
case '\\':
|
||||
b.append('\\');
|
||||
break;
|
||||
case '/':
|
||||
b.append('\\');
|
||||
break;
|
||||
case 'u':
|
||||
i++;
|
||||
int uc = Integer.parseInt(s.substring(i, i+4), 16);
|
||||
b.append((char) uc);
|
||||
i = i + 4;
|
||||
break;
|
||||
default:
|
||||
throw new FHIRLexerException("Unknown character escape \\"+s.charAt(i));
|
||||
}
|
||||
} else {
|
||||
b.append(ch);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return b.toString();
|
||||
|
||||
}
|
||||
public void skipToken(String token) throws FHIRLexerException {
|
||||
if (getCurrent().equals(token))
|
||||
next();
|
||||
|
||||
}
|
||||
public String takeDottedToken() throws FHIRLexerException {
|
||||
StringBuilder b = new StringBuilder();
|
||||
b.append(take());
|
||||
while (!done() && getCurrent().equals(".")) {
|
||||
b.append(take());
|
||||
b.append(take());
|
||||
}
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
void skipComments() throws FHIRLexerException {
|
||||
while (!done() && hasComment())
|
||||
next();
|
||||
}
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,110 +0,0 @@
|
|||
package org.hl7.fhir.dstu3.utils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hl7.fhir.dstu3.model.Base;
|
||||
import org.hl7.fhir.dstu3.model.TypeDetails;
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
|
||||
public class FHIRPathUtilityClasses {
|
||||
|
||||
|
||||
public static class ExecutionContext {
|
||||
private Object appInfo;
|
||||
private Base resource;
|
||||
private Base context;
|
||||
private Base thisItem;
|
||||
private Map<String, Base> aliases;
|
||||
|
||||
public ExecutionContext(Object appInfo, Base resource, Base context, Map<String, Base> aliases, Base thisItem) {
|
||||
this.appInfo = appInfo;
|
||||
this.context = context;
|
||||
this.resource = resource;
|
||||
this.aliases = aliases;
|
||||
this.thisItem = thisItem;
|
||||
}
|
||||
public Base getResource() {
|
||||
return resource;
|
||||
}
|
||||
public Base getThisItem() {
|
||||
return thisItem;
|
||||
}
|
||||
public void addAlias(String name, List<Base> focus) throws FHIRException {
|
||||
if (aliases == null)
|
||||
aliases = new HashMap<String, Base>();
|
||||
else
|
||||
aliases = new HashMap<String, Base>(aliases); // clone it, since it's going to change
|
||||
if (focus.size() > 1)
|
||||
throw new FHIRException("Attempt to alias a collection, not a singleton");
|
||||
aliases.put(name, focus.size() == 0 ? null : focus.get(0));
|
||||
}
|
||||
public Base getAlias(String name) {
|
||||
return aliases == null ? null : aliases.get(name);
|
||||
}
|
||||
public Object getAppInfo() {
|
||||
return appInfo;
|
||||
}
|
||||
public Base getContext() {
|
||||
return context;
|
||||
}
|
||||
public Map<String, Base> getAliases() {
|
||||
return aliases;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class ExecutionTypeContext {
|
||||
private Object appInfo;
|
||||
private String resource;
|
||||
private String context;
|
||||
private TypeDetails thisItem;
|
||||
|
||||
|
||||
public ExecutionTypeContext(Object appInfo, String resource, String context, TypeDetails thisItem) {
|
||||
super();
|
||||
this.appInfo = appInfo;
|
||||
this.resource = resource;
|
||||
this.context = context;
|
||||
this.thisItem = thisItem;
|
||||
|
||||
}
|
||||
public String getResource() {
|
||||
return resource;
|
||||
}
|
||||
public TypeDetails getThisItem() {
|
||||
return thisItem;
|
||||
}
|
||||
public Object getAppInfo() {
|
||||
return appInfo;
|
||||
}
|
||||
public String getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static class FunctionDetails {
|
||||
private String description;
|
||||
private int minParameters;
|
||||
private int maxParameters;
|
||||
public FunctionDetails(String description, int minParameters, int maxParameters) {
|
||||
super();
|
||||
this.description = description;
|
||||
this.minParameters = minParameters;
|
||||
this.maxParameters = maxParameters;
|
||||
}
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
public int getMinParameters() {
|
||||
return minParameters;
|
||||
}
|
||||
public int getMaxParameters() {
|
||||
return maxParameters;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,945 +0,0 @@
|
|||
package org.hl7.fhir.r4.model;
|
||||
|
||||
/*
|
||||
Copyright (c) 2011+, HL7, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of HL7 nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.utilities.SourceLocation;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
|
||||
public class ExpressionNode {
|
||||
|
||||
public enum Kind {
|
||||
Name, Function, Constant, Group, Unary
|
||||
}
|
||||
|
||||
public enum Function {
|
||||
Custom,
|
||||
|
||||
Empty, Not, Exists, SubsetOf, SupersetOf, IsDistinct, Distinct, Count, Where, Select, All, Repeat, Aggregate,
|
||||
Item /* implicit from name[] */, As, Is, Single, First, Last, Tail, Skip, Take, Union, Combine, Intersect, Exclude,
|
||||
Iif, Upper, Lower, ToChars, IndexOf, Substring, StartsWith, EndsWith, Matches, MatchesFull, ReplaceMatches,
|
||||
Contains, Replace, Length, Children, Descendants, MemberOf, Trace, Check, Today, Now, Resolve, Extension, AllFalse,
|
||||
AnyFalse, AllTrue, AnyTrue, HasValue, OfType, Type, ConvertsToBoolean, ConvertsToInteger, ConvertsToString,
|
||||
ConvertsToDecimal, ConvertsToQuantity, ConvertsToDateTime, ConvertsToDate, ConvertsToTime, ToBoolean, ToInteger,
|
||||
ToString, ToDecimal, ToQuantity, ToDateTime, ToTime, ConformsTo, Round, Sqrt, Abs, Ceiling, Exp, Floor, Ln, Log,
|
||||
Power, Truncate,
|
||||
|
||||
// R3 functions
|
||||
Encode, Decode, Escape, Unescape, Trim, Split, Join, LowBoundary, HighBoundary, Precision,
|
||||
|
||||
// Local extensions to FHIRPath
|
||||
HtmlChecks1, HtmlChecks2, AliasAs, Alias, Comparable;
|
||||
|
||||
public static Function fromCode(String name) {
|
||||
if (name.equals("empty"))
|
||||
return Function.Empty;
|
||||
if (name.equals("not"))
|
||||
return Function.Not;
|
||||
if (name.equals("exists"))
|
||||
return Function.Exists;
|
||||
if (name.equals("subsetOf"))
|
||||
return Function.SubsetOf;
|
||||
if (name.equals("supersetOf"))
|
||||
return Function.SupersetOf;
|
||||
if (name.equals("isDistinct"))
|
||||
return Function.IsDistinct;
|
||||
if (name.equals("distinct"))
|
||||
return Function.Distinct;
|
||||
if (name.equals("count"))
|
||||
return Function.Count;
|
||||
if (name.equals("where"))
|
||||
return Function.Where;
|
||||
if (name.equals("select"))
|
||||
return Function.Select;
|
||||
if (name.equals("all"))
|
||||
return Function.All;
|
||||
if (name.equals("repeat"))
|
||||
return Function.Repeat;
|
||||
if (name.equals("aggregate"))
|
||||
return Function.Aggregate;
|
||||
if (name.equals("item"))
|
||||
return Function.Item;
|
||||
if (name.equals("as"))
|
||||
return Function.As;
|
||||
if (name.equals("is"))
|
||||
return Function.Is;
|
||||
if (name.equals("single"))
|
||||
return Function.Single;
|
||||
if (name.equals("first"))
|
||||
return Function.First;
|
||||
if (name.equals("last"))
|
||||
return Function.Last;
|
||||
if (name.equals("tail"))
|
||||
return Function.Tail;
|
||||
if (name.equals("skip"))
|
||||
return Function.Skip;
|
||||
if (name.equals("take"))
|
||||
return Function.Take;
|
||||
if (name.equals("union"))
|
||||
return Function.Union;
|
||||
if (name.equals("combine"))
|
||||
return Function.Combine;
|
||||
if (name.equals("intersect"))
|
||||
return Function.Intersect;
|
||||
if (name.equals("exclude"))
|
||||
return Function.Exclude;
|
||||
if (name.equals("iif"))
|
||||
return Function.Iif;
|
||||
if (name.equals("lower"))
|
||||
return Function.Lower;
|
||||
if (name.equals("upper"))
|
||||
return Function.Upper;
|
||||
if (name.equals("toChars"))
|
||||
return Function.ToChars;
|
||||
if (name.equals("indexOf"))
|
||||
return Function.IndexOf;
|
||||
if (name.equals("substring"))
|
||||
return Function.Substring;
|
||||
if (name.equals("startsWith"))
|
||||
return Function.StartsWith;
|
||||
if (name.equals("endsWith"))
|
||||
return Function.EndsWith;
|
||||
if (name.equals("matches"))
|
||||
return Function.Matches;
|
||||
if (name.equals("matchesFull"))
|
||||
return Function.MatchesFull;
|
||||
if (name.equals("replaceMatches"))
|
||||
return Function.ReplaceMatches;
|
||||
if (name.equals("contains"))
|
||||
return Function.Contains;
|
||||
if (name.equals("replace"))
|
||||
return Function.Replace;
|
||||
if (name.equals("length"))
|
||||
return Function.Length;
|
||||
if (name.equals("children"))
|
||||
return Function.Children;
|
||||
if (name.equals("descendants"))
|
||||
return Function.Descendants;
|
||||
if (name.equals("memberOf"))
|
||||
return Function.MemberOf;
|
||||
if (name.equals("trace"))
|
||||
return Function.Trace;
|
||||
if (name.equals("check"))
|
||||
return Function.Check;
|
||||
if (name.equals("today"))
|
||||
return Function.Today;
|
||||
if (name.equals("now"))
|
||||
return Function.Now;
|
||||
if (name.equals("resolve"))
|
||||
return Function.Resolve;
|
||||
if (name.equals("extension"))
|
||||
return Function.Extension;
|
||||
if (name.equals("allFalse"))
|
||||
return Function.AllFalse;
|
||||
if (name.equals("anyFalse"))
|
||||
return Function.AnyFalse;
|
||||
if (name.equals("allTrue"))
|
||||
return Function.AllTrue;
|
||||
if (name.equals("anyTrue"))
|
||||
return Function.AnyTrue;
|
||||
if (name.equals("hasValue"))
|
||||
return Function.HasValue;
|
||||
if (name.equals("alias"))
|
||||
return Function.Alias;
|
||||
if (name.equals("aliasAs"))
|
||||
return Function.AliasAs;
|
||||
if (name.equals("htmlChecks"))
|
||||
return Function.HtmlChecks1;
|
||||
if (name.equals("htmlchecks"))
|
||||
return Function.HtmlChecks1; // support change of care from R3
|
||||
if (name.equals("htmlChecks2"))
|
||||
return Function.HtmlChecks2;
|
||||
if (name.equals("comparable"))
|
||||
return Function.Comparable;
|
||||
if (name.equals("encode"))
|
||||
return Function.Encode;
|
||||
if (name.equals("decode"))
|
||||
return Function.Decode;
|
||||
if (name.equals("escape"))
|
||||
return Function.Escape;
|
||||
if (name.equals("unescape"))
|
||||
return Function.Unescape;
|
||||
if (name.equals("trim"))
|
||||
return Function.Trim;
|
||||
if (name.equals("split"))
|
||||
return Function.Split;
|
||||
if (name.equals("join"))
|
||||
return Function.Join;
|
||||
if (name.equals("ofType"))
|
||||
return Function.OfType;
|
||||
if (name.equals("type"))
|
||||
return Function.Type;
|
||||
if (name.equals("toInteger"))
|
||||
return Function.ToInteger;
|
||||
if (name.equals("toDecimal"))
|
||||
return Function.ToDecimal;
|
||||
if (name.equals("toString"))
|
||||
return Function.ToString;
|
||||
if (name.equals("toQuantity"))
|
||||
return Function.ToQuantity;
|
||||
if (name.equals("toBoolean"))
|
||||
return Function.ToBoolean;
|
||||
if (name.equals("toDateTime"))
|
||||
return Function.ToDateTime;
|
||||
if (name.equals("toTime"))
|
||||
return Function.ToTime;
|
||||
if (name.equals("convertsToInteger"))
|
||||
return Function.ConvertsToInteger;
|
||||
if (name.equals("convertsToDecimal"))
|
||||
return Function.ConvertsToDecimal;
|
||||
if (name.equals("convertsToString"))
|
||||
return Function.ConvertsToString;
|
||||
if (name.equals("convertsToQuantity"))
|
||||
return Function.ConvertsToQuantity;
|
||||
if (name.equals("convertsToBoolean"))
|
||||
return Function.ConvertsToBoolean;
|
||||
if (name.equals("convertsToDateTime"))
|
||||
return Function.ConvertsToDateTime;
|
||||
if (name.equals("convertsToDate"))
|
||||
return Function.ConvertsToDate;
|
||||
if (name.equals("convertsToTime"))
|
||||
return Function.ConvertsToTime;
|
||||
if (name.equals("conformsTo"))
|
||||
return Function.ConformsTo;
|
||||
if (name.equals("round"))
|
||||
return Function.Round;
|
||||
if (name.equals("sqrt"))
|
||||
return Function.Sqrt;
|
||||
if (name.equals("abs"))
|
||||
return Function.Abs;
|
||||
if (name.equals("ceiling"))
|
||||
return Function.Ceiling;
|
||||
if (name.equals("exp"))
|
||||
return Function.Exp;
|
||||
if (name.equals("floor"))
|
||||
return Function.Floor;
|
||||
if (name.equals("ln"))
|
||||
return Function.Ln;
|
||||
if (name.equals("log"))
|
||||
return Function.Log;
|
||||
if (name.equals("power"))
|
||||
return Function.Power;
|
||||
if (name.equals("truncate"))
|
||||
return Function.Truncate;
|
||||
if (name.equals("lowBoundary"))
|
||||
return Function.LowBoundary;
|
||||
if (name.equals("highBoundary"))
|
||||
return Function.HighBoundary;
|
||||
if (name.equals("precision"))
|
||||
return Function.Precision;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public String toCode() {
|
||||
switch (this) {
|
||||
case Empty:
|
||||
return "empty";
|
||||
case Not:
|
||||
return "not";
|
||||
case Exists:
|
||||
return "exists";
|
||||
case SubsetOf:
|
||||
return "subsetOf";
|
||||
case SupersetOf:
|
||||
return "supersetOf";
|
||||
case IsDistinct:
|
||||
return "isDistinct";
|
||||
case Distinct:
|
||||
return "distinct";
|
||||
case Count:
|
||||
return "count";
|
||||
case Where:
|
||||
return "where";
|
||||
case Select:
|
||||
return "select";
|
||||
case All:
|
||||
return "all";
|
||||
case Repeat:
|
||||
return "repeat";
|
||||
case Aggregate:
|
||||
return "aggregate";
|
||||
case Item:
|
||||
return "item";
|
||||
case As:
|
||||
return "as";
|
||||
case Is:
|
||||
return "is";
|
||||
case Single:
|
||||
return "single";
|
||||
case First:
|
||||
return "first";
|
||||
case Last:
|
||||
return "last";
|
||||
case Tail:
|
||||
return "tail";
|
||||
case Skip:
|
||||
return "skip";
|
||||
case Take:
|
||||
return "take";
|
||||
case Union:
|
||||
return "union";
|
||||
case Combine:
|
||||
return "combine";
|
||||
case Intersect:
|
||||
return "intersect";
|
||||
case Exclude:
|
||||
return "exclude";
|
||||
case Iif:
|
||||
return "iif";
|
||||
case ToChars:
|
||||
return "toChars";
|
||||
case Lower:
|
||||
return "lower";
|
||||
case Upper:
|
||||
return "upper";
|
||||
case IndexOf:
|
||||
return "indexOf";
|
||||
case Substring:
|
||||
return "substring";
|
||||
case StartsWith:
|
||||
return "startsWith";
|
||||
case EndsWith:
|
||||
return "endsWith";
|
||||
case Matches:
|
||||
return "matches";
|
||||
case MatchesFull:
|
||||
return "matchesFull";
|
||||
case ReplaceMatches:
|
||||
return "replaceMatches";
|
||||
case Contains:
|
||||
return "contains";
|
||||
case Replace:
|
||||
return "replace";
|
||||
case Length:
|
||||
return "length";
|
||||
case Children:
|
||||
return "children";
|
||||
case Descendants:
|
||||
return "descendants";
|
||||
case MemberOf:
|
||||
return "memberOf";
|
||||
case Trace:
|
||||
return "trace";
|
||||
case Check:
|
||||
return "check";
|
||||
case Today:
|
||||
return "today";
|
||||
case Now:
|
||||
return "now";
|
||||
case Resolve:
|
||||
return "resolve";
|
||||
case Extension:
|
||||
return "extension";
|
||||
case AllFalse:
|
||||
return "allFalse";
|
||||
case AnyFalse:
|
||||
return "anyFalse";
|
||||
case AllTrue:
|
||||
return "allTrue";
|
||||
case AnyTrue:
|
||||
return "anyTrue";
|
||||
case HasValue:
|
||||
return "hasValue";
|
||||
case Alias:
|
||||
return "alias";
|
||||
case AliasAs:
|
||||
return "aliasAs";
|
||||
case Encode:
|
||||
return "encode";
|
||||
case Decode:
|
||||
return "decode";
|
||||
case Escape:
|
||||
return "escape";
|
||||
case Unescape:
|
||||
return "unescape";
|
||||
case Trim:
|
||||
return "trim";
|
||||
case Split:
|
||||
return "split";
|
||||
case Join:
|
||||
return "join";
|
||||
case HtmlChecks1:
|
||||
return "htmlChecks";
|
||||
case HtmlChecks2:
|
||||
return "htmlChecks2";
|
||||
case Comparable:
|
||||
return "comparable";
|
||||
case OfType:
|
||||
return "ofType";
|
||||
case Type:
|
||||
return "type";
|
||||
case ToInteger:
|
||||
return "toInteger";
|
||||
case ToDecimal:
|
||||
return "toDecimal";
|
||||
case ToString:
|
||||
return "toString";
|
||||
case ToBoolean:
|
||||
return "toBoolean";
|
||||
case ToQuantity:
|
||||
return "toQuantity";
|
||||
case ToDateTime:
|
||||
return "toDateTime";
|
||||
case ToTime:
|
||||
return "toTime";
|
||||
case ConvertsToInteger:
|
||||
return "convertsToInteger";
|
||||
case ConvertsToDecimal:
|
||||
return "convertsToDecimal";
|
||||
case ConvertsToString:
|
||||
return "convertsToString";
|
||||
case ConvertsToBoolean:
|
||||
return "convertsToBoolean";
|
||||
case ConvertsToQuantity:
|
||||
return "convertsToQuantity";
|
||||
case ConvertsToDateTime:
|
||||
return "convertsToDateTime";
|
||||
case ConvertsToDate:
|
||||
return "convertsToDate";
|
||||
case ConvertsToTime:
|
||||
return "isTime";
|
||||
case ConformsTo:
|
||||
return "conformsTo";
|
||||
case Round:
|
||||
return "round";
|
||||
case Sqrt:
|
||||
return "sqrt";
|
||||
case Abs:
|
||||
return "abs";
|
||||
case Ceiling:
|
||||
return "ceiling";
|
||||
case Exp:
|
||||
return "exp";
|
||||
case Floor:
|
||||
return "floor";
|
||||
case Ln:
|
||||
return "ln";
|
||||
case Log:
|
||||
return "log";
|
||||
case Power:
|
||||
return "power";
|
||||
case Truncate:
|
||||
return "truncate";
|
||||
case LowBoundary:
|
||||
return "lowBoundary";
|
||||
case HighBoundary:
|
||||
return "highBoundary";
|
||||
case Precision:
|
||||
return "precision";
|
||||
default:
|
||||
return "?custom?";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum Operation {
|
||||
Equals, Equivalent, NotEquals, NotEquivalent, LessThan, Greater, LessOrEqual, GreaterOrEqual, Is, As, Union, Or,
|
||||
And, Xor, Implies, Times, DivideBy, Plus, Minus, Concatenate, Div, Mod, In, Contains, MemberOf;
|
||||
|
||||
public static Operation fromCode(String name) {
|
||||
if (Utilities.noString(name))
|
||||
return null;
|
||||
if (name.equals("="))
|
||||
return Operation.Equals;
|
||||
if (name.equals("~"))
|
||||
return Operation.Equivalent;
|
||||
if (name.equals("!="))
|
||||
return Operation.NotEquals;
|
||||
if (name.equals("!~"))
|
||||
return Operation.NotEquivalent;
|
||||
if (name.equals(">"))
|
||||
return Operation.Greater;
|
||||
if (name.equals("<"))
|
||||
return Operation.LessThan;
|
||||
if (name.equals(">="))
|
||||
return Operation.GreaterOrEqual;
|
||||
if (name.equals("<="))
|
||||
return Operation.LessOrEqual;
|
||||
if (name.equals("|"))
|
||||
return Operation.Union;
|
||||
if (name.equals("or"))
|
||||
return Operation.Or;
|
||||
if (name.equals("and"))
|
||||
return Operation.And;
|
||||
if (name.equals("xor"))
|
||||
return Operation.Xor;
|
||||
if (name.equals("is"))
|
||||
return Operation.Is;
|
||||
if (name.equals("as"))
|
||||
return Operation.As;
|
||||
if (name.equals("*"))
|
||||
return Operation.Times;
|
||||
if (name.equals("/"))
|
||||
return Operation.DivideBy;
|
||||
if (name.equals("+"))
|
||||
return Operation.Plus;
|
||||
if (name.equals("-"))
|
||||
return Operation.Minus;
|
||||
if (name.equals("&"))
|
||||
return Operation.Concatenate;
|
||||
if (name.equals("implies"))
|
||||
return Operation.Implies;
|
||||
if (name.equals("div"))
|
||||
return Operation.Div;
|
||||
if (name.equals("mod"))
|
||||
return Operation.Mod;
|
||||
if (name.equals("in"))
|
||||
return Operation.In;
|
||||
if (name.equals("contains"))
|
||||
return Operation.Contains;
|
||||
if (name.equals("memberOf"))
|
||||
return Operation.MemberOf;
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
public String toCode() {
|
||||
switch (this) {
|
||||
case Equals:
|
||||
return "=";
|
||||
case Equivalent:
|
||||
return "~";
|
||||
case NotEquals:
|
||||
return "!=";
|
||||
case NotEquivalent:
|
||||
return "!~";
|
||||
case Greater:
|
||||
return ">";
|
||||
case LessThan:
|
||||
return "<";
|
||||
case GreaterOrEqual:
|
||||
return ">=";
|
||||
case LessOrEqual:
|
||||
return "<=";
|
||||
case Union:
|
||||
return "|";
|
||||
case Or:
|
||||
return "or";
|
||||
case And:
|
||||
return "and";
|
||||
case Xor:
|
||||
return "xor";
|
||||
case Times:
|
||||
return "*";
|
||||
case DivideBy:
|
||||
return "/";
|
||||
case Plus:
|
||||
return "+";
|
||||
case Minus:
|
||||
return "-";
|
||||
case Concatenate:
|
||||
return "&";
|
||||
case Implies:
|
||||
return "implies";
|
||||
case Is:
|
||||
return "is";
|
||||
case As:
|
||||
return "as";
|
||||
case Div:
|
||||
return "div";
|
||||
case Mod:
|
||||
return "mod";
|
||||
case In:
|
||||
return "in";
|
||||
case Contains:
|
||||
return "contains";
|
||||
case MemberOf:
|
||||
return "memberOf";
|
||||
default:
|
||||
return "?custom?";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum CollectionStatus {
|
||||
SINGLETON, ORDERED, UNORDERED;
|
||||
}
|
||||
|
||||
// the expression will have one of either name or constant
|
||||
private String uniqueId;
|
||||
private Kind kind;
|
||||
private String name;
|
||||
private Base constant;
|
||||
private Function function;
|
||||
private List<ExpressionNode> parameters; // will be created if there is a function
|
||||
private ExpressionNode inner;
|
||||
private ExpressionNode group;
|
||||
private Operation operation;
|
||||
private boolean proximal; // a proximal operation is the first in the sequence of operations. This is
|
||||
// significant when evaluating the outcomes
|
||||
private ExpressionNode opNext;
|
||||
private SourceLocation start;
|
||||
private SourceLocation end;
|
||||
private SourceLocation opStart;
|
||||
private SourceLocation opEnd;
|
||||
private TypeDetails types;
|
||||
private TypeDetails opTypes;
|
||||
|
||||
public ExpressionNode(int uniqueId) {
|
||||
super();
|
||||
this.uniqueId = Integer.toString(uniqueId);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder b = new StringBuilder();
|
||||
switch (kind) {
|
||||
case Name:
|
||||
b.append(name);
|
||||
break;
|
||||
case Function:
|
||||
if (function == Function.Item)
|
||||
b.append("[");
|
||||
else {
|
||||
b.append(name);
|
||||
b.append("(");
|
||||
}
|
||||
boolean first = true;
|
||||
for (ExpressionNode n : parameters) {
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
b.append(", ");
|
||||
b.append(n.toString());
|
||||
}
|
||||
if (function == Function.Item) {
|
||||
b.append("]");
|
||||
} else {
|
||||
b.append(")");
|
||||
}
|
||||
break;
|
||||
case Constant:
|
||||
if (constant == null) {
|
||||
b.append("{}");
|
||||
} else if (constant instanceof StringType) {
|
||||
b.append("'" + Utilities.escapeJson(constant.primitiveValue()) + "'");
|
||||
} else if (constant instanceof Quantity) {
|
||||
Quantity q = (Quantity) constant;
|
||||
b.append(Utilities.escapeJson(q.getValue().toPlainString()));
|
||||
b.append(" '");
|
||||
b.append(Utilities.escapeJson(q.getUnit()));
|
||||
b.append("'");
|
||||
} else if (constant.primitiveValue() != null) {
|
||||
b.append(Utilities.escapeJson(constant.primitiveValue()));
|
||||
} else {
|
||||
b.append(Utilities.escapeJson(constant.toString()));
|
||||
}
|
||||
break;
|
||||
case Group:
|
||||
b.append("(");
|
||||
b.append(group.toString());
|
||||
b.append(")");
|
||||
}
|
||||
if (inner != null) {
|
||||
if (!((ExpressionNode.Kind.Function == inner.getKind())
|
||||
&& (ExpressionNode.Function.Item == inner.getFunction()))) {
|
||||
b.append(".");
|
||||
}
|
||||
b.append(inner.toString());
|
||||
}
|
||||
if (operation != null) {
|
||||
b.append(" ");
|
||||
b.append(operation.toCode());
|
||||
b.append(" ");
|
||||
b.append(opNext.toString());
|
||||
}
|
||||
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Base getConstant() {
|
||||
return constant;
|
||||
}
|
||||
|
||||
public void setConstant(Base constant) {
|
||||
this.constant = constant;
|
||||
}
|
||||
|
||||
public Function getFunction() {
|
||||
return function;
|
||||
}
|
||||
|
||||
public void setFunction(Function function) {
|
||||
this.function = function;
|
||||
if (parameters == null)
|
||||
parameters = new ArrayList<ExpressionNode>();
|
||||
}
|
||||
|
||||
public boolean isProximal() {
|
||||
return proximal;
|
||||
}
|
||||
|
||||
public void setProximal(boolean proximal) {
|
||||
this.proximal = proximal;
|
||||
}
|
||||
|
||||
public Operation getOperation() {
|
||||
return operation;
|
||||
}
|
||||
|
||||
public void setOperation(Operation operation) {
|
||||
this.operation = operation;
|
||||
}
|
||||
|
||||
public ExpressionNode getInner() {
|
||||
return inner;
|
||||
}
|
||||
|
||||
public void setInner(ExpressionNode value) {
|
||||
this.inner = value;
|
||||
}
|
||||
|
||||
public ExpressionNode getOpNext() {
|
||||
return opNext;
|
||||
}
|
||||
|
||||
public void setOpNext(ExpressionNode value) {
|
||||
this.opNext = value;
|
||||
}
|
||||
|
||||
public List<ExpressionNode> getParameters() {
|
||||
return parameters;
|
||||
}
|
||||
|
||||
public boolean checkName() {
|
||||
if (!name.startsWith("$"))
|
||||
return true;
|
||||
else
|
||||
return Utilities.existsInList(name, "$this", "$total", "$index");
|
||||
}
|
||||
|
||||
public Kind getKind() {
|
||||
return kind;
|
||||
}
|
||||
|
||||
public void setKind(Kind kind) {
|
||||
this.kind = kind;
|
||||
}
|
||||
|
||||
public ExpressionNode getGroup() {
|
||||
return group;
|
||||
}
|
||||
|
||||
public void setGroup(ExpressionNode group) {
|
||||
this.group = group;
|
||||
}
|
||||
|
||||
public SourceLocation getStart() {
|
||||
return start;
|
||||
}
|
||||
|
||||
public void setStart(SourceLocation start) {
|
||||
this.start = start;
|
||||
}
|
||||
|
||||
public SourceLocation getEnd() {
|
||||
return end;
|
||||
}
|
||||
|
||||
public void setEnd(SourceLocation end) {
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
public SourceLocation getOpStart() {
|
||||
return opStart;
|
||||
}
|
||||
|
||||
public void setOpStart(SourceLocation opStart) {
|
||||
this.opStart = opStart;
|
||||
}
|
||||
|
||||
public SourceLocation getOpEnd() {
|
||||
return opEnd;
|
||||
}
|
||||
|
||||
public void setOpEnd(SourceLocation opEnd) {
|
||||
this.opEnd = opEnd;
|
||||
}
|
||||
|
||||
public String getUniqueId() {
|
||||
return uniqueId;
|
||||
}
|
||||
|
||||
public int parameterCount() {
|
||||
if (parameters == null)
|
||||
return 0;
|
||||
else
|
||||
return parameters.size();
|
||||
}
|
||||
|
||||
public String Canonical() {
|
||||
StringBuilder b = new StringBuilder();
|
||||
write(b);
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
public String summary() {
|
||||
switch (kind) {
|
||||
case Name:
|
||||
return uniqueId + ": " + name;
|
||||
case Function:
|
||||
return uniqueId + ": " + function.toString() + "()";
|
||||
case Constant:
|
||||
return uniqueId + ": " + constant;
|
||||
case Group:
|
||||
return uniqueId + ": (Group)";
|
||||
}
|
||||
return "?exp-kind?";
|
||||
}
|
||||
|
||||
private void write(StringBuilder b) {
|
||||
|
||||
switch (kind) {
|
||||
case Name:
|
||||
b.append(name);
|
||||
break;
|
||||
case Constant:
|
||||
b.append(constant);
|
||||
break;
|
||||
case Function:
|
||||
b.append(function.toCode());
|
||||
b.append('(');
|
||||
boolean f = true;
|
||||
for (ExpressionNode n : parameters) {
|
||||
if (f)
|
||||
f = false;
|
||||
else
|
||||
b.append(", ");
|
||||
n.write(b);
|
||||
}
|
||||
b.append(')');
|
||||
|
||||
break;
|
||||
case Group:
|
||||
b.append('(');
|
||||
group.write(b);
|
||||
b.append(')');
|
||||
}
|
||||
|
||||
if (inner != null) {
|
||||
b.append('.');
|
||||
inner.write(b);
|
||||
}
|
||||
if (operation != null) {
|
||||
b.append(' ');
|
||||
b.append(operation.toCode());
|
||||
b.append(' ');
|
||||
opNext.write(b);
|
||||
}
|
||||
}
|
||||
|
||||
public String check() {
|
||||
|
||||
if (kind == null) {
|
||||
return "Error in expression - node has no kind";
|
||||
}
|
||||
switch (kind) {
|
||||
case Name:
|
||||
if (Utilities.noString(name))
|
||||
return "No Name provided @ " + location();
|
||||
break;
|
||||
|
||||
case Function:
|
||||
if (function == null)
|
||||
return "No Function id provided @ " + location();
|
||||
for (ExpressionNode n : parameters) {
|
||||
String msg = n.check();
|
||||
if (msg != null)
|
||||
return msg;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Unary:
|
||||
break;
|
||||
case Constant:
|
||||
if (constant == null)
|
||||
return "No Constant provided @ " + location();
|
||||
break;
|
||||
|
||||
case Group:
|
||||
if (group == null)
|
||||
return "No Group provided @ " + location();
|
||||
else {
|
||||
String msg = group.check();
|
||||
if (msg != null)
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
if (inner != null) {
|
||||
String msg = inner.check();
|
||||
if (msg != null)
|
||||
return msg;
|
||||
}
|
||||
if (operation == null) {
|
||||
|
||||
if (opNext != null)
|
||||
return "Next provided when it shouldn't be @ " + location();
|
||||
} else {
|
||||
if (opNext == null)
|
||||
return "No Next provided @ " + location();
|
||||
else
|
||||
opNext.check();
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
private String location() {
|
||||
return Integer.toString(start.getLine()) + ", " + Integer.toString(start.getColumn());
|
||||
}
|
||||
|
||||
public TypeDetails getTypes() {
|
||||
return types;
|
||||
}
|
||||
|
||||
public void setTypes(TypeDetails types) {
|
||||
this.types = types;
|
||||
}
|
||||
|
||||
public TypeDetails getOpTypes() {
|
||||
return opTypes;
|
||||
}
|
||||
|
||||
public void setOpTypes(TypeDetails opTypes) {
|
||||
this.opTypes = opTypes;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,383 +0,0 @@
|
|||
package org.hl7.fhir.r4.model;
|
||||
|
||||
/*
|
||||
Copyright (c) 2011+, HL7, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of HL7 nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hl7.fhir.exceptions.DefinitionException;
|
||||
import org.hl7.fhir.r4.context.IWorkerContext;
|
||||
import org.hl7.fhir.r4.model.ElementDefinition.ElementDefinitionBindingComponent;
|
||||
import org.hl7.fhir.r4.model.ExpressionNode.CollectionStatus;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
|
||||
public class TypeDetails {
|
||||
public static final String FHIR_NS = "http://hl7.org/fhir/StructureDefinition/";
|
||||
public static final String FP_NS = "http://hl7.org/fhirpath/";
|
||||
public static final String FP_String = "http://hl7.org/fhirpath/String";
|
||||
public static final String FP_Boolean = "http://hl7.org/fhirpath/Boolean";
|
||||
public static final String FP_Integer = "http://hl7.org/fhirpath/Integer";
|
||||
public static final String FP_Decimal = "http://hl7.org/fhirpath/Decimal";
|
||||
public static final String FP_Quantity = "http://hl7.org/fhirpath/Quantity";
|
||||
public static final String FP_DateTime = "http://hl7.org/fhirpath/DateTime";
|
||||
public static final String FP_Time = "http://hl7.org/fhirpath/Time";
|
||||
public static final String FP_SimpleTypeInfo = "http://hl7.org/fhirpath/SimpleTypeInfo";
|
||||
public static final String FP_ClassInfo = "http://hl7.org/fhirpath/ClassInfo";
|
||||
public static final Set<String> FP_NUMBERS = new HashSet<String>(Arrays.asList(FP_Integer, FP_Decimal));
|
||||
|
||||
public static class ProfiledType {
|
||||
private String uri;
|
||||
private List<String> profiles; // or, not and
|
||||
private List<ElementDefinitionBindingComponent> bindings;
|
||||
|
||||
public ProfiledType(String n) {
|
||||
uri = ns(n);
|
||||
}
|
||||
|
||||
public String getUri() {
|
||||
return uri;
|
||||
}
|
||||
|
||||
public boolean hasProfiles() {
|
||||
return profiles != null && profiles.size() > 0;
|
||||
}
|
||||
|
||||
public List<String> getProfiles() {
|
||||
return profiles;
|
||||
}
|
||||
|
||||
public boolean hasBindings() {
|
||||
return bindings != null && bindings.size() > 0;
|
||||
}
|
||||
|
||||
public List<ElementDefinitionBindingComponent> getBindings() {
|
||||
return bindings;
|
||||
}
|
||||
|
||||
public static String ns(String n) {
|
||||
return Utilities.isAbsoluteUrl(n) ? n : FHIR_NS + n;
|
||||
}
|
||||
|
||||
public void addProfile(String profile) {
|
||||
if (profiles == null)
|
||||
profiles = new ArrayList<String>();
|
||||
profiles.add(profile);
|
||||
}
|
||||
|
||||
public void addBinding(ElementDefinitionBindingComponent binding) {
|
||||
bindings = new ArrayList<ElementDefinitionBindingComponent>();
|
||||
bindings.add(binding);
|
||||
}
|
||||
|
||||
public boolean hasBinding(ElementDefinitionBindingComponent b) {
|
||||
return false; // todo: do we need to do this?
|
||||
}
|
||||
|
||||
public void addProfiles(List<CanonicalType> list) {
|
||||
if (profiles == null)
|
||||
profiles = new ArrayList<String>();
|
||||
for (UriType u : list)
|
||||
profiles.add(u.getValue());
|
||||
}
|
||||
|
||||
public boolean isSystemType() {
|
||||
return uri.startsWith(FP_NS);
|
||||
}
|
||||
}
|
||||
|
||||
private List<ProfiledType> types = new ArrayList<ProfiledType>();
|
||||
private CollectionStatus collectionStatus;
|
||||
|
||||
public TypeDetails(CollectionStatus collectionStatus, String... names) {
|
||||
super();
|
||||
this.collectionStatus = collectionStatus;
|
||||
for (String n : names) {
|
||||
this.types.add(new ProfiledType(n));
|
||||
}
|
||||
}
|
||||
|
||||
public TypeDetails(CollectionStatus collectionStatus, Set<String> names) {
|
||||
super();
|
||||
this.collectionStatus = collectionStatus;
|
||||
for (String n : names) {
|
||||
addType(new ProfiledType(n));
|
||||
}
|
||||
}
|
||||
|
||||
public TypeDetails(CollectionStatus collectionStatus, ProfiledType pt) {
|
||||
super();
|
||||
this.collectionStatus = collectionStatus;
|
||||
this.types.add(pt);
|
||||
}
|
||||
|
||||
public String addType(String n) {
|
||||
ProfiledType pt = new ProfiledType(n);
|
||||
String res = pt.uri;
|
||||
addType(pt);
|
||||
return res;
|
||||
}
|
||||
|
||||
public String addType(String n, String p) {
|
||||
ProfiledType pt = new ProfiledType(n);
|
||||
pt.addProfile(p);
|
||||
String res = pt.uri;
|
||||
addType(pt);
|
||||
return res;
|
||||
}
|
||||
|
||||
public void addType(ProfiledType pt) {
|
||||
for (ProfiledType et : types) {
|
||||
if (et.uri.equals(pt.uri)) {
|
||||
if (pt.profiles != null) {
|
||||
for (String p : pt.profiles) {
|
||||
if (et.profiles == null)
|
||||
et.profiles = new ArrayList<String>();
|
||||
if (!et.profiles.contains(p))
|
||||
et.profiles.add(p);
|
||||
}
|
||||
}
|
||||
if (pt.bindings != null) {
|
||||
for (ElementDefinitionBindingComponent b : pt.bindings) {
|
||||
if (et.bindings == null)
|
||||
et.bindings = new ArrayList<ElementDefinitionBindingComponent>();
|
||||
if (!et.hasBinding(b))
|
||||
et.bindings.add(b);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
types.add(pt);
|
||||
}
|
||||
|
||||
public void addTypes(Collection<String> names) {
|
||||
for (String n : names)
|
||||
addType(new ProfiledType(n));
|
||||
}
|
||||
|
||||
public boolean hasType(IWorkerContext context, String... tn) {
|
||||
for (String n : tn) {
|
||||
String t = ProfiledType.ns(n);
|
||||
if (typesContains(t))
|
||||
return true;
|
||||
if (Utilities.existsInList(n, "boolean", "string", "integer", "decimal", "Quantity", "dateTime", "time",
|
||||
"ClassInfo", "SimpleTypeInfo")) {
|
||||
t = FP_NS + Utilities.capitalize(n);
|
||||
if (typesContains(t))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (String n : tn) {
|
||||
String id = n.contains("#") ? n.substring(0, n.indexOf("#")) : n;
|
||||
String tail = null;
|
||||
if (n.contains("#")) {
|
||||
tail = n.substring(n.indexOf("#") + 1);
|
||||
tail = tail.substring(tail.indexOf("."));
|
||||
}
|
||||
String t = ProfiledType.ns(n);
|
||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, t);
|
||||
while (sd != null) {
|
||||
if (tail == null && typesContains(sd.getUrl()))
|
||||
return true;
|
||||
if (tail == null && getSystemType(sd.getUrl()) != null && typesContains(getSystemType(sd.getUrl())))
|
||||
return true;
|
||||
if (tail != null && typesContains(sd.getUrl() + "#" + sd.getType() + tail))
|
||||
return true;
|
||||
if (sd.hasBaseDefinition()) {
|
||||
if (sd.getType().equals("uri"))
|
||||
sd = context.fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/string");
|
||||
else
|
||||
sd = context.fetchResource(StructureDefinition.class, sd.getBaseDefinition());
|
||||
} else
|
||||
sd = null;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private String getSystemType(String url) {
|
||||
if (url.startsWith("http://hl7.org/fhir/StructureDefinition/")) {
|
||||
String code = url.substring(40);
|
||||
if (Utilities.existsInList(code, "string", "boolean", "integer", "decimal", "dateTime", "time", "Quantity"))
|
||||
return FP_NS + Utilities.capitalize(code);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean typesContains(String t) {
|
||||
for (ProfiledType pt : types)
|
||||
if (pt.uri.equals(t))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public void update(TypeDetails source) {
|
||||
for (ProfiledType pt : source.types)
|
||||
addType(pt);
|
||||
if (collectionStatus == null)
|
||||
collectionStatus = source.collectionStatus;
|
||||
else if (source.collectionStatus == CollectionStatus.UNORDERED)
|
||||
collectionStatus = source.collectionStatus;
|
||||
else
|
||||
collectionStatus = CollectionStatus.ORDERED;
|
||||
}
|
||||
|
||||
public TypeDetails union(TypeDetails right) {
|
||||
TypeDetails result = new TypeDetails(null);
|
||||
if (right.collectionStatus == CollectionStatus.UNORDERED || collectionStatus == CollectionStatus.UNORDERED)
|
||||
result.collectionStatus = CollectionStatus.UNORDERED;
|
||||
else
|
||||
result.collectionStatus = CollectionStatus.ORDERED;
|
||||
for (ProfiledType pt : types)
|
||||
result.addType(pt);
|
||||
for (ProfiledType pt : right.types)
|
||||
result.addType(pt);
|
||||
return result;
|
||||
}
|
||||
|
||||
public TypeDetails intersect(TypeDetails right) {
|
||||
TypeDetails result = new TypeDetails(null);
|
||||
if (right.collectionStatus == CollectionStatus.UNORDERED || collectionStatus == CollectionStatus.UNORDERED)
|
||||
result.collectionStatus = CollectionStatus.UNORDERED;
|
||||
else
|
||||
result.collectionStatus = CollectionStatus.ORDERED;
|
||||
for (ProfiledType pt : types) {
|
||||
boolean found = false;
|
||||
for (ProfiledType r : right.types)
|
||||
found = found || pt.uri.equals(r.uri);
|
||||
if (found)
|
||||
result.addType(pt);
|
||||
}
|
||||
for (ProfiledType pt : right.types)
|
||||
result.addType(pt);
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean hasNoTypes() {
|
||||
return types.isEmpty();
|
||||
}
|
||||
|
||||
public Set<String> getTypes() {
|
||||
Set<String> res = new HashSet<String>();
|
||||
for (ProfiledType pt : types)
|
||||
res.add(pt.uri);
|
||||
return res;
|
||||
}
|
||||
|
||||
public TypeDetails toSingleton() {
|
||||
TypeDetails result = new TypeDetails(CollectionStatus.SINGLETON);
|
||||
result.types.addAll(types);
|
||||
return result;
|
||||
}
|
||||
|
||||
public CollectionStatus getCollectionStatus() {
|
||||
return collectionStatus;
|
||||
}
|
||||
|
||||
public boolean hasType(String n) {
|
||||
String t = ProfiledType.ns(n);
|
||||
if (typesContains(t))
|
||||
return true;
|
||||
if (Utilities.existsInList(n, "boolean", "string", "integer", "decimal", "Quantity", "date", "dateTime", "time",
|
||||
"ClassInfo", "SimpleTypeInfo")) {
|
||||
t = FP_NS + Utilities.capitalize(n);
|
||||
if (typesContains(t))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean hasType(Set<String> tn) {
|
||||
for (String n : tn) {
|
||||
String t = ProfiledType.ns(n);
|
||||
if (typesContains(t))
|
||||
return true;
|
||||
if (Utilities.existsInList(n, "boolean", "string", "integer", "decimal", "Quantity", "dateTime", "time",
|
||||
"ClassInfo", "SimpleTypeInfo")) {
|
||||
t = FP_NS + Utilities.capitalize(n);
|
||||
if (typesContains(t))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String describe() {
|
||||
return getTypes().toString();
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
for (ProfiledType pt : types)
|
||||
return pt.uri;
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return (collectionStatus == null ? collectionStatus.SINGLETON.toString() : collectionStatus.toString())
|
||||
+ getTypes().toString();
|
||||
}
|
||||
|
||||
public String getTypeCode() throws DefinitionException {
|
||||
if (types.size() != 1)
|
||||
throw new DefinitionException("Multiple types? (" + types.toString() + ")");
|
||||
for (ProfiledType pt : types)
|
||||
if (pt.uri.startsWith("http://hl7.org/fhir/StructureDefinition/"))
|
||||
return pt.uri.substring(40);
|
||||
else
|
||||
return pt.uri;
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<ProfiledType> getProfiledTypes() {
|
||||
return types;
|
||||
}
|
||||
|
||||
public boolean hasBinding() {
|
||||
for (ProfiledType pt : types) {
|
||||
if (pt.hasBindings())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public ElementDefinitionBindingComponent getBinding() {
|
||||
for (ProfiledType pt : types) {
|
||||
for (ElementDefinitionBindingComponent b : pt.getBindings())
|
||||
return b;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,513 +0,0 @@
|
|||
package org.hl7.fhir.r4.utils;
|
||||
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
|
||||
/*
|
||||
Copyright (c) 2011+, HL7, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of HL7 nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
import org.hl7.fhir.r4.model.ExpressionNode;
|
||||
import org.hl7.fhir.utilities.SourceLocation;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
|
||||
// shared lexer for concrete syntaxes
|
||||
// - FluentPath
|
||||
// - Mapping language
|
||||
|
||||
public class FHIRLexer {
|
||||
public class FHIRLexerException extends FHIRException {
|
||||
|
||||
public FHIRLexerException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public FHIRLexerException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public FHIRLexerException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public FHIRLexerException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private String source;
|
||||
private int cursor;
|
||||
private int currentStart;
|
||||
private String current;
|
||||
private SourceLocation currentLocation;
|
||||
private SourceLocation currentStartLocation;
|
||||
private int id;
|
||||
private String name;
|
||||
|
||||
public FHIRLexer(String source, String name) throws FHIRLexerException {
|
||||
this.source = source;
|
||||
this.name = name == null ? "??" : name;
|
||||
currentLocation = new SourceLocation(1, 1);
|
||||
next();
|
||||
}
|
||||
|
||||
public FHIRLexer(String source, int i) throws FHIRLexerException {
|
||||
this.source = source;
|
||||
this.cursor = i;
|
||||
currentLocation = new SourceLocation(1, 1);
|
||||
next();
|
||||
}
|
||||
|
||||
public String getCurrent() {
|
||||
return current;
|
||||
}
|
||||
|
||||
public SourceLocation getCurrentLocation() {
|
||||
return currentLocation;
|
||||
}
|
||||
|
||||
public boolean isConstant() {
|
||||
return current != null && (current.charAt(0) == '\'' || current.charAt(0) == '"') || current.charAt(0) == '@'
|
||||
|| current.charAt(0) == '%' || current.charAt(0) == '-' || current.charAt(0) == '+'
|
||||
|| (current.charAt(0) >= '0' && current.charAt(0) <= '9') || current.equals("true") || current.equals("false")
|
||||
|| current.equals("{}");
|
||||
}
|
||||
|
||||
public boolean isFixedName() {
|
||||
return current != null && (current.charAt(0) == '`');
|
||||
}
|
||||
|
||||
public boolean isStringConstant() {
|
||||
return current.charAt(0) == '\'' || current.charAt(0) == '"' || current.charAt(0) == '`';
|
||||
}
|
||||
|
||||
public String take() throws FHIRLexerException {
|
||||
String s = current;
|
||||
next();
|
||||
return s;
|
||||
}
|
||||
|
||||
public int takeInt() throws FHIRLexerException {
|
||||
String s = current;
|
||||
if (!Utilities.isInteger(s))
|
||||
throw error("Found " + current + " expecting an integer");
|
||||
next();
|
||||
return Integer.parseInt(s);
|
||||
}
|
||||
|
||||
public boolean isToken() {
|
||||
if (Utilities.noString(current))
|
||||
return false;
|
||||
|
||||
if (current.startsWith("$"))
|
||||
return true;
|
||||
|
||||
if (current.equals("*") || current.equals("**"))
|
||||
return true;
|
||||
|
||||
if ((current.charAt(0) >= 'A' && current.charAt(0) <= 'Z')
|
||||
|| (current.charAt(0) >= 'a' && current.charAt(0) <= 'z')) {
|
||||
for (int i = 1; i < current.length(); i++)
|
||||
if (!((current.charAt(1) >= 'A' && current.charAt(1) <= 'Z')
|
||||
|| (current.charAt(1) >= 'a' && current.charAt(1) <= 'z')
|
||||
|| (current.charAt(1) >= '0' && current.charAt(1) <= '9')))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public FHIRLexerException error(String msg) {
|
||||
return error(msg, currentLocation.toString());
|
||||
}
|
||||
|
||||
public FHIRLexerException error(String msg, String location) {
|
||||
return new FHIRLexerException("Error in " + name + " at " + location + ": " + msg);
|
||||
}
|
||||
|
||||
public void next() throws FHIRLexerException {
|
||||
skipWhitespaceAndComments();
|
||||
current = null;
|
||||
currentStart = cursor;
|
||||
currentStartLocation = currentLocation;
|
||||
if (cursor < source.length()) {
|
||||
char ch = source.charAt(cursor);
|
||||
if (ch == '!' || ch == '>' || ch == '<' || ch == ':' || ch == '-' || ch == '=') {
|
||||
cursor++;
|
||||
if (cursor < source.length()
|
||||
&& (source.charAt(cursor) == '=' || source.charAt(cursor) == '~' || source.charAt(cursor) == '-')
|
||||
|| (ch == '-' && source.charAt(cursor) == '>'))
|
||||
cursor++;
|
||||
current = source.substring(currentStart, cursor);
|
||||
} else if (ch == '.') {
|
||||
cursor++;
|
||||
if (cursor < source.length() && (source.charAt(cursor) == '.'))
|
||||
cursor++;
|
||||
current = source.substring(currentStart, cursor);
|
||||
} else if (ch >= '0' && ch <= '9') {
|
||||
cursor++;
|
||||
boolean dotted = false;
|
||||
while (cursor < source.length() && ((source.charAt(cursor) >= '0' && source.charAt(cursor) <= '9')
|
||||
|| (source.charAt(cursor) == '.') && !dotted)) {
|
||||
if (source.charAt(cursor) == '.')
|
||||
dotted = true;
|
||||
cursor++;
|
||||
}
|
||||
if (source.charAt(cursor - 1) == '.')
|
||||
cursor--;
|
||||
current = source.substring(currentStart, cursor);
|
||||
} else if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) {
|
||||
while (cursor < source.length() && ((source.charAt(cursor) >= 'A' && source.charAt(cursor) <= 'Z')
|
||||
|| (source.charAt(cursor) >= 'a' && source.charAt(cursor) <= 'z')
|
||||
|| (source.charAt(cursor) >= '0' && source.charAt(cursor) <= '9') || source.charAt(cursor) == '_'))
|
||||
cursor++;
|
||||
current = source.substring(currentStart, cursor);
|
||||
} else if (ch == '%') {
|
||||
cursor++;
|
||||
if (cursor < source.length() && (source.charAt(cursor) == '`')) {
|
||||
cursor++;
|
||||
while (cursor < source.length() && (source.charAt(cursor) != '`'))
|
||||
cursor++;
|
||||
cursor++;
|
||||
} else
|
||||
while (cursor < source.length() && ((source.charAt(cursor) >= 'A' && source.charAt(cursor) <= 'Z')
|
||||
|| (source.charAt(cursor) >= 'a' && source.charAt(cursor) <= 'z')
|
||||
|| (source.charAt(cursor) >= '0' && source.charAt(cursor) <= '9') || source.charAt(cursor) == ':'
|
||||
|| source.charAt(cursor) == '-'))
|
||||
cursor++;
|
||||
current = source.substring(currentStart, cursor);
|
||||
} else if (ch == '/') {
|
||||
cursor++;
|
||||
if (cursor < source.length() && (source.charAt(cursor) == '/')) {
|
||||
// this is en error - should already have been skipped
|
||||
error("This shoudn't happen?");
|
||||
}
|
||||
current = source.substring(currentStart, cursor);
|
||||
} else if (ch == '$') {
|
||||
cursor++;
|
||||
while (cursor < source.length() && (source.charAt(cursor) >= 'a' && source.charAt(cursor) <= 'z'))
|
||||
cursor++;
|
||||
current = source.substring(currentStart, cursor);
|
||||
} else if (ch == '{') {
|
||||
cursor++;
|
||||
ch = source.charAt(cursor);
|
||||
if (ch == '}')
|
||||
cursor++;
|
||||
current = source.substring(currentStart, cursor);
|
||||
} else if (ch == '"') {
|
||||
cursor++;
|
||||
boolean escape = false;
|
||||
while (cursor < source.length() && (escape || source.charAt(cursor) != '"')) {
|
||||
if (escape)
|
||||
escape = false;
|
||||
else
|
||||
escape = (source.charAt(cursor) == '\\');
|
||||
cursor++;
|
||||
}
|
||||
if (cursor == source.length())
|
||||
throw error("Unterminated string");
|
||||
cursor++;
|
||||
current = "\"" + source.substring(currentStart + 1, cursor - 1) + "\"";
|
||||
} else if (ch == '`') {
|
||||
cursor++;
|
||||
boolean escape = false;
|
||||
while (cursor < source.length() && (escape || source.charAt(cursor) != '`')) {
|
||||
if (escape)
|
||||
escape = false;
|
||||
else
|
||||
escape = (source.charAt(cursor) == '\\');
|
||||
cursor++;
|
||||
}
|
||||
if (cursor == source.length())
|
||||
throw error("Unterminated string");
|
||||
cursor++;
|
||||
current = "`" + source.substring(currentStart + 1, cursor - 1) + "`";
|
||||
} else if (ch == '\'') {
|
||||
cursor++;
|
||||
char ech = ch;
|
||||
boolean escape = false;
|
||||
while (cursor < source.length() && (escape || source.charAt(cursor) != ech)) {
|
||||
if (escape)
|
||||
escape = false;
|
||||
else
|
||||
escape = (source.charAt(cursor) == '\\');
|
||||
cursor++;
|
||||
}
|
||||
if (cursor == source.length())
|
||||
throw error("Unterminated string");
|
||||
cursor++;
|
||||
current = source.substring(currentStart, cursor);
|
||||
if (ech == '\'')
|
||||
current = "\'" + current.substring(1, current.length() - 1) + "\'";
|
||||
} else if (ch == '`') {
|
||||
cursor++;
|
||||
boolean escape = false;
|
||||
while (cursor < source.length() && (escape || source.charAt(cursor) != '`')) {
|
||||
if (escape)
|
||||
escape = false;
|
||||
else
|
||||
escape = (source.charAt(cursor) == '\\');
|
||||
cursor++;
|
||||
}
|
||||
if (cursor == source.length())
|
||||
throw error("Unterminated string");
|
||||
cursor++;
|
||||
current = "`" + source.substring(currentStart + 1, cursor - 1) + "`";
|
||||
} else if (ch == '@') {
|
||||
int start = cursor;
|
||||
cursor++;
|
||||
while (cursor < source.length() && isDateChar(source.charAt(cursor), start))
|
||||
cursor++;
|
||||
current = source.substring(currentStart, cursor);
|
||||
} else { // if CharInSet(ch, ['.', ',', '(', ')', '=', '$']) then
|
||||
cursor++;
|
||||
current = source.substring(currentStart, cursor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void skipWhitespaceAndComments() {
|
||||
boolean last13 = false;
|
||||
boolean done = false;
|
||||
while (cursor < source.length() && !done) {
|
||||
if (cursor < source.length() - 1 && "//".equals(source.substring(cursor, cursor + 2))) {
|
||||
while (cursor < source.length() && !((source.charAt(cursor) == '\r') || source.charAt(cursor) == '\n'))
|
||||
cursor++;
|
||||
} else if (cursor < source.length() - 1 && "/*".equals(source.substring(cursor, cursor + 2))) {
|
||||
while (cursor < source.length() - 1 && !"*/".equals(source.substring(cursor, cursor + 2))) {
|
||||
last13 = currentLocation.checkChar(source.charAt(cursor), last13);
|
||||
cursor++;
|
||||
}
|
||||
if (cursor >= source.length() - 1) {
|
||||
error("Unfinished comment");
|
||||
} else {
|
||||
cursor = cursor + 2;
|
||||
}
|
||||
} else if (Character.isWhitespace(source.charAt(cursor))) {
|
||||
last13 = currentLocation.checkChar(source.charAt(cursor), last13);
|
||||
cursor++;
|
||||
} else {
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isDateChar(char ch, int start) {
|
||||
int eot = source.charAt(start + 1) == 'T' ? 10 : 20;
|
||||
|
||||
return ch == '-' || ch == ':' || ch == 'T' || ch == '+' || ch == 'Z' || Character.isDigit(ch)
|
||||
|| (cursor - start == eot && ch == '.' && cursor < source.length() - 1
|
||||
&& Character.isDigit(source.charAt(cursor + 1)));
|
||||
}
|
||||
|
||||
public boolean isOp() {
|
||||
return ExpressionNode.Operation.fromCode(current) != null;
|
||||
}
|
||||
|
||||
public boolean done() {
|
||||
return currentStart >= source.length();
|
||||
}
|
||||
|
||||
public int nextId() {
|
||||
id++;
|
||||
return id;
|
||||
}
|
||||
|
||||
public SourceLocation getCurrentStartLocation() {
|
||||
return currentStartLocation;
|
||||
}
|
||||
|
||||
// special case use
|
||||
public void setCurrent(String current) {
|
||||
this.current = current;
|
||||
}
|
||||
|
||||
public boolean hasComment() {
|
||||
return !done() && current.startsWith("//");
|
||||
}
|
||||
|
||||
public boolean hasToken(String kw) {
|
||||
return !done() && kw.equals(current);
|
||||
}
|
||||
|
||||
public boolean hasToken(String... names) {
|
||||
if (done())
|
||||
return false;
|
||||
for (String s : names)
|
||||
if (s.equals(current))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public void token(String kw) throws FHIRLexerException {
|
||||
if (!kw.equals(current))
|
||||
throw error("Found \"" + current + "\" expecting \"" + kw + "\"");
|
||||
next();
|
||||
}
|
||||
|
||||
public String readConstant(String desc) throws FHIRLexerException {
|
||||
if (!isStringConstant())
|
||||
throw error("Found " + current + " expecting \"[" + desc + "]\"");
|
||||
|
||||
return processConstant(take());
|
||||
}
|
||||
|
||||
public String readFixedName(String desc) throws FHIRLexerException {
|
||||
if (!isFixedName())
|
||||
throw error("Found " + current + " expecting \"[" + desc + "]\"");
|
||||
|
||||
return processFixedName(take());
|
||||
}
|
||||
|
||||
public String processConstant(String s) throws FHIRLexerException {
|
||||
StringBuilder b = new StringBuilder();
|
||||
int i = 1;
|
||||
while (i < s.length() - 1) {
|
||||
char ch = s.charAt(i);
|
||||
if (ch == '\\') {
|
||||
i++;
|
||||
switch (s.charAt(i)) {
|
||||
case 't':
|
||||
b.append('\t');
|
||||
break;
|
||||
case 'r':
|
||||
b.append('\r');
|
||||
break;
|
||||
case 'n':
|
||||
b.append('\n');
|
||||
break;
|
||||
case 'f':
|
||||
b.append('\f');
|
||||
break;
|
||||
case '\'':
|
||||
b.append('\'');
|
||||
break;
|
||||
case '"':
|
||||
b.append('"');
|
||||
break;
|
||||
case '`':
|
||||
b.append('`');
|
||||
break;
|
||||
case '\\':
|
||||
b.append('\\');
|
||||
break;
|
||||
case '/':
|
||||
b.append('/');
|
||||
break;
|
||||
case 'u':
|
||||
i++;
|
||||
int uc = Integer.parseInt(s.substring(i, i + 4), 16);
|
||||
b.append((char) uc);
|
||||
i = i + 4;
|
||||
break;
|
||||
default:
|
||||
throw new FHIRLexerException("Unknown character escape \\" + s.charAt(i));
|
||||
}
|
||||
} else {
|
||||
b.append(ch);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
public String processFixedName(String s) throws FHIRLexerException {
|
||||
StringBuilder b = new StringBuilder();
|
||||
int i = 1;
|
||||
while (i < s.length() - 1) {
|
||||
char ch = s.charAt(i);
|
||||
if (ch == '\\') {
|
||||
i++;
|
||||
switch (s.charAt(i)) {
|
||||
case 't':
|
||||
b.append('\t');
|
||||
break;
|
||||
case 'r':
|
||||
b.append('\r');
|
||||
break;
|
||||
case 'n':
|
||||
b.append('\n');
|
||||
break;
|
||||
case 'f':
|
||||
b.append('\f');
|
||||
break;
|
||||
case '\'':
|
||||
b.append('\'');
|
||||
break;
|
||||
case '"':
|
||||
b.append('"');
|
||||
break;
|
||||
case '\\':
|
||||
b.append('\\');
|
||||
break;
|
||||
case '/':
|
||||
b.append('/');
|
||||
break;
|
||||
case 'u':
|
||||
i++;
|
||||
int uc = Integer.parseInt(s.substring(i, i + 4), 16);
|
||||
b.append((char) uc);
|
||||
i = i + 4;
|
||||
break;
|
||||
default:
|
||||
throw new FHIRLexerException("Unknown character escape \\" + s.charAt(i));
|
||||
}
|
||||
} else {
|
||||
b.append(ch);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
public void skipToken(String token) throws FHIRLexerException {
|
||||
if (getCurrent().equals(token))
|
||||
next();
|
||||
|
||||
}
|
||||
|
||||
public String takeDottedToken() throws FHIRLexerException {
|
||||
StringBuilder b = new StringBuilder();
|
||||
b.append(take());
|
||||
while (!done() && getCurrent().equals(".")) {
|
||||
b.append(take());
|
||||
b.append(take());
|
||||
}
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
void skipComments() throws FHIRLexerException {
|
||||
while (!done() && hasComment())
|
||||
next();
|
||||
}
|
||||
|
||||
public int getCurrentStart() {
|
||||
return currentStart;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
package org.hl7.fhir.r4.utils;
|
||||
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
|
||||
public class FHIRPathConstant {
|
||||
|
||||
public static boolean isFHIRPathConstant(String string) {
|
||||
return !Utilities.noString(string) && ((string.charAt(0) == '\'' || string.charAt(0) == '"')
|
||||
|| string.charAt(0) == '@' || string.charAt(0) == '%' || string.charAt(0) == '-' || string.charAt(0) == '+'
|
||||
|| (string.charAt(0) >= '0' && string.charAt(0) <= '9') || string.equals("true") || string.equals("false")
|
||||
|| string.equals("{}"));
|
||||
}
|
||||
|
||||
public static boolean isFHIRPathFixedName(String string) {
|
||||
return string != null && (string.charAt(0) == '`');
|
||||
}
|
||||
|
||||
public static boolean isFHIRPathStringConstant(String string) {
|
||||
return string.charAt(0) == '\'' || string.charAt(0) == '"' || string.charAt(0) == '`';
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,210 +0,0 @@
|
|||
package org.hl7.fhir.r4.utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.r4.model.Base;
|
||||
import org.hl7.fhir.r4.model.Element;
|
||||
import org.hl7.fhir.r4.model.ElementDefinition;
|
||||
import org.hl7.fhir.r4.model.IntegerType;
|
||||
import org.hl7.fhir.r4.model.Property;
|
||||
import org.hl7.fhir.r4.model.Resource;
|
||||
import org.hl7.fhir.r4.model.StringType;
|
||||
import org.hl7.fhir.r4.model.StructureDefinition;
|
||||
import org.hl7.fhir.r4.model.TypeDetails;
|
||||
import org.hl7.fhir.r4.model.ElementDefinition.TypeRefComponent;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.i18n.I18nConstants;
|
||||
|
||||
public class FHIRPathUtilityClasses {
|
||||
|
||||
|
||||
public static class FHIRConstant extends Base {
|
||||
|
||||
private static final long serialVersionUID = -8933773658248269439L;
|
||||
private String value;
|
||||
|
||||
public FHIRConstant(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String fhirType() {
|
||||
return "%constant";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void listChildren(List<Property> result) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdBase() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIdBase(String value) {
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String primitiveValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Base copy() {
|
||||
throw new Error("Not Implemented");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class ClassTypeInfo extends Base {
|
||||
private static final long serialVersionUID = 4909223114071029317L;
|
||||
private Base instance;
|
||||
|
||||
public ClassTypeInfo(Base instance) {
|
||||
super();
|
||||
this.instance = instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String fhirType() {
|
||||
return "ClassInfo";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void listChildren(List<Property> result) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdBase() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIdBase(String value) {
|
||||
}
|
||||
|
||||
public Base[] getProperty(int hash, String name, boolean checkValid) throws FHIRException {
|
||||
if (name.equals("name")) {
|
||||
return new Base[] { new StringType(getName()) };
|
||||
} else if (name.equals("namespace")) {
|
||||
return new Base[] { new StringType(getNamespace()) };
|
||||
} else {
|
||||
return super.getProperty(hash, name, checkValid);
|
||||
}
|
||||
}
|
||||
|
||||
private String getNamespace() {
|
||||
if ((instance instanceof Resource)) {
|
||||
return "FHIR";
|
||||
} else if (!(instance instanceof Element) || ((Element) instance).isDisallowExtensions()) {
|
||||
return "System";
|
||||
} else {
|
||||
return "FHIR";
|
||||
}
|
||||
}
|
||||
|
||||
private String getName() {
|
||||
if ((instance instanceof Resource)) {
|
||||
return instance.fhirType();
|
||||
} else if (!(instance instanceof Element) || ((Element) instance).isDisallowExtensions()) {
|
||||
return Utilities.capitalize(instance.fhirType());
|
||||
} else {
|
||||
return instance.fhirType();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Base copy() {
|
||||
throw new Error("Not Implemented");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class TypedElementDefinition {
|
||||
private ElementDefinition element;
|
||||
private String type;
|
||||
private StructureDefinition src;
|
||||
|
||||
public TypedElementDefinition(StructureDefinition src, ElementDefinition element, String type) {
|
||||
super();
|
||||
this.element = element;
|
||||
this.type = type;
|
||||
this.src = src;
|
||||
}
|
||||
|
||||
public TypedElementDefinition(ElementDefinition element) {
|
||||
super();
|
||||
this.element = element;
|
||||
}
|
||||
|
||||
public ElementDefinition getElement() {
|
||||
return element;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public List<TypeRefComponent> getTypes() {
|
||||
List<TypeRefComponent> res = new ArrayList<ElementDefinition.TypeRefComponent>();
|
||||
for (TypeRefComponent tr : element.getType()) {
|
||||
if (type == null || type.equals(tr.getCode())) {
|
||||
res.add(tr);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public boolean hasType(String tn) {
|
||||
if (type != null) {
|
||||
return tn.equals(type);
|
||||
} else {
|
||||
for (TypeRefComponent t : element.getType()) {
|
||||
if (tn.equals(t.getCode())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public StructureDefinition getSrc() {
|
||||
return src;
|
||||
}
|
||||
}
|
||||
|
||||
public static class FunctionDetails {
|
||||
private String description;
|
||||
private int minParameters;
|
||||
private int maxParameters;
|
||||
|
||||
public FunctionDetails(String description, int minParameters, int maxParameters) {
|
||||
super();
|
||||
this.description = description;
|
||||
this.minParameters = minParameters;
|
||||
this.maxParameters = maxParameters;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public int getMinParameters() {
|
||||
return minParameters;
|
||||
}
|
||||
|
||||
public int getMaxParameters() {
|
||||
return maxParameters;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,945 +0,0 @@
|
|||
package org.hl7.fhir.r4b.model;
|
||||
|
||||
/*
|
||||
Copyright (c) 2011+, HL7, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of HL7 nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.utilities.SourceLocation;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
|
||||
public class ExpressionNode {
|
||||
|
||||
public enum Kind {
|
||||
Name, Function, Constant, Group, Unary
|
||||
}
|
||||
|
||||
public enum Function {
|
||||
Custom,
|
||||
|
||||
Empty, Not, Exists, SubsetOf, SupersetOf, IsDistinct, Distinct, Count, Where, Select, All, Repeat, Aggregate,
|
||||
Item /* implicit from name[] */, As, Is, Single, First, Last, Tail, Skip, Take, Union, Combine, Intersect, Exclude,
|
||||
Iif, Upper, Lower, ToChars, IndexOf, Substring, StartsWith, EndsWith, Matches, MatchesFull, ReplaceMatches,
|
||||
Contains, Replace, Length, Children, Descendants, MemberOf, Trace, Check, Today, Now, Resolve, Extension, AllFalse,
|
||||
AnyFalse, AllTrue, AnyTrue, HasValue, OfType, Type, ConvertsToBoolean, ConvertsToInteger, ConvertsToString,
|
||||
ConvertsToDecimal, ConvertsToQuantity, ConvertsToDateTime, ConvertsToDate, ConvertsToTime, ToBoolean, ToInteger,
|
||||
ToString, ToDecimal, ToQuantity, ToDateTime, ToTime, ConformsTo, Round, Sqrt, Abs, Ceiling, Exp, Floor, Ln, Log,
|
||||
Power, Truncate,
|
||||
|
||||
// R3 functions
|
||||
Encode, Decode, Escape, Unescape, Trim, Split, Join, LowBoundary, HighBoundary, Precision,
|
||||
|
||||
// Local extensions to FHIRPath
|
||||
HtmlChecks1, HtmlChecks2, AliasAs, Alias, Comparable;
|
||||
|
||||
public static Function fromCode(String name) {
|
||||
if (name.equals("empty"))
|
||||
return Function.Empty;
|
||||
if (name.equals("not"))
|
||||
return Function.Not;
|
||||
if (name.equals("exists"))
|
||||
return Function.Exists;
|
||||
if (name.equals("subsetOf"))
|
||||
return Function.SubsetOf;
|
||||
if (name.equals("supersetOf"))
|
||||
return Function.SupersetOf;
|
||||
if (name.equals("isDistinct"))
|
||||
return Function.IsDistinct;
|
||||
if (name.equals("distinct"))
|
||||
return Function.Distinct;
|
||||
if (name.equals("count"))
|
||||
return Function.Count;
|
||||
if (name.equals("where"))
|
||||
return Function.Where;
|
||||
if (name.equals("select"))
|
||||
return Function.Select;
|
||||
if (name.equals("all"))
|
||||
return Function.All;
|
||||
if (name.equals("repeat"))
|
||||
return Function.Repeat;
|
||||
if (name.equals("aggregate"))
|
||||
return Function.Aggregate;
|
||||
if (name.equals("item"))
|
||||
return Function.Item;
|
||||
if (name.equals("as"))
|
||||
return Function.As;
|
||||
if (name.equals("is"))
|
||||
return Function.Is;
|
||||
if (name.equals("single"))
|
||||
return Function.Single;
|
||||
if (name.equals("first"))
|
||||
return Function.First;
|
||||
if (name.equals("last"))
|
||||
return Function.Last;
|
||||
if (name.equals("tail"))
|
||||
return Function.Tail;
|
||||
if (name.equals("skip"))
|
||||
return Function.Skip;
|
||||
if (name.equals("take"))
|
||||
return Function.Take;
|
||||
if (name.equals("union"))
|
||||
return Function.Union;
|
||||
if (name.equals("combine"))
|
||||
return Function.Combine;
|
||||
if (name.equals("intersect"))
|
||||
return Function.Intersect;
|
||||
if (name.equals("exclude"))
|
||||
return Function.Exclude;
|
||||
if (name.equals("iif"))
|
||||
return Function.Iif;
|
||||
if (name.equals("lower"))
|
||||
return Function.Lower;
|
||||
if (name.equals("upper"))
|
||||
return Function.Upper;
|
||||
if (name.equals("toChars"))
|
||||
return Function.ToChars;
|
||||
if (name.equals("indexOf"))
|
||||
return Function.IndexOf;
|
||||
if (name.equals("substring"))
|
||||
return Function.Substring;
|
||||
if (name.equals("startsWith"))
|
||||
return Function.StartsWith;
|
||||
if (name.equals("endsWith"))
|
||||
return Function.EndsWith;
|
||||
if (name.equals("matches"))
|
||||
return Function.Matches;
|
||||
if (name.equals("matchesFull"))
|
||||
return Function.MatchesFull;
|
||||
if (name.equals("replaceMatches"))
|
||||
return Function.ReplaceMatches;
|
||||
if (name.equals("contains"))
|
||||
return Function.Contains;
|
||||
if (name.equals("replace"))
|
||||
return Function.Replace;
|
||||
if (name.equals("length"))
|
||||
return Function.Length;
|
||||
if (name.equals("children"))
|
||||
return Function.Children;
|
||||
if (name.equals("descendants"))
|
||||
return Function.Descendants;
|
||||
if (name.equals("memberOf"))
|
||||
return Function.MemberOf;
|
||||
if (name.equals("trace"))
|
||||
return Function.Trace;
|
||||
if (name.equals("check"))
|
||||
return Function.Check;
|
||||
if (name.equals("today"))
|
||||
return Function.Today;
|
||||
if (name.equals("now"))
|
||||
return Function.Now;
|
||||
if (name.equals("resolve"))
|
||||
return Function.Resolve;
|
||||
if (name.equals("extension"))
|
||||
return Function.Extension;
|
||||
if (name.equals("allFalse"))
|
||||
return Function.AllFalse;
|
||||
if (name.equals("anyFalse"))
|
||||
return Function.AnyFalse;
|
||||
if (name.equals("allTrue"))
|
||||
return Function.AllTrue;
|
||||
if (name.equals("anyTrue"))
|
||||
return Function.AnyTrue;
|
||||
if (name.equals("hasValue"))
|
||||
return Function.HasValue;
|
||||
if (name.equals("alias"))
|
||||
return Function.Alias;
|
||||
if (name.equals("aliasAs"))
|
||||
return Function.AliasAs;
|
||||
if (name.equals("htmlChecks"))
|
||||
return Function.HtmlChecks1;
|
||||
if (name.equals("htmlchecks"))
|
||||
return Function.HtmlChecks1; // support change of care from R3
|
||||
if (name.equals("htmlChecks2"))
|
||||
return Function.HtmlChecks2;
|
||||
if (name.equals("comparable"))
|
||||
return Function.Comparable;
|
||||
if (name.equals("encode"))
|
||||
return Function.Encode;
|
||||
if (name.equals("decode"))
|
||||
return Function.Decode;
|
||||
if (name.equals("escape"))
|
||||
return Function.Escape;
|
||||
if (name.equals("unescape"))
|
||||
return Function.Unescape;
|
||||
if (name.equals("trim"))
|
||||
return Function.Trim;
|
||||
if (name.equals("split"))
|
||||
return Function.Split;
|
||||
if (name.equals("join"))
|
||||
return Function.Join;
|
||||
if (name.equals("ofType"))
|
||||
return Function.OfType;
|
||||
if (name.equals("type"))
|
||||
return Function.Type;
|
||||
if (name.equals("toInteger"))
|
||||
return Function.ToInteger;
|
||||
if (name.equals("toDecimal"))
|
||||
return Function.ToDecimal;
|
||||
if (name.equals("toString"))
|
||||
return Function.ToString;
|
||||
if (name.equals("toQuantity"))
|
||||
return Function.ToQuantity;
|
||||
if (name.equals("toBoolean"))
|
||||
return Function.ToBoolean;
|
||||
if (name.equals("toDateTime"))
|
||||
return Function.ToDateTime;
|
||||
if (name.equals("toTime"))
|
||||
return Function.ToTime;
|
||||
if (name.equals("convertsToInteger"))
|
||||
return Function.ConvertsToInteger;
|
||||
if (name.equals("convertsToDecimal"))
|
||||
return Function.ConvertsToDecimal;
|
||||
if (name.equals("convertsToString"))
|
||||
return Function.ConvertsToString;
|
||||
if (name.equals("convertsToQuantity"))
|
||||
return Function.ConvertsToQuantity;
|
||||
if (name.equals("convertsToBoolean"))
|
||||
return Function.ConvertsToBoolean;
|
||||
if (name.equals("convertsToDateTime"))
|
||||
return Function.ConvertsToDateTime;
|
||||
if (name.equals("convertsToDate"))
|
||||
return Function.ConvertsToDate;
|
||||
if (name.equals("convertsToTime"))
|
||||
return Function.ConvertsToTime;
|
||||
if (name.equals("conformsTo"))
|
||||
return Function.ConformsTo;
|
||||
if (name.equals("round"))
|
||||
return Function.Round;
|
||||
if (name.equals("sqrt"))
|
||||
return Function.Sqrt;
|
||||
if (name.equals("abs"))
|
||||
return Function.Abs;
|
||||
if (name.equals("ceiling"))
|
||||
return Function.Ceiling;
|
||||
if (name.equals("exp"))
|
||||
return Function.Exp;
|
||||
if (name.equals("floor"))
|
||||
return Function.Floor;
|
||||
if (name.equals("ln"))
|
||||
return Function.Ln;
|
||||
if (name.equals("log"))
|
||||
return Function.Log;
|
||||
if (name.equals("power"))
|
||||
return Function.Power;
|
||||
if (name.equals("truncate"))
|
||||
return Function.Truncate;
|
||||
if (name.equals("lowBoundary"))
|
||||
return Function.LowBoundary;
|
||||
if (name.equals("highBoundary"))
|
||||
return Function.HighBoundary;
|
||||
if (name.equals("precision"))
|
||||
return Function.Precision;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public String toCode() {
|
||||
switch (this) {
|
||||
case Empty:
|
||||
return "empty";
|
||||
case Not:
|
||||
return "not";
|
||||
case Exists:
|
||||
return "exists";
|
||||
case SubsetOf:
|
||||
return "subsetOf";
|
||||
case SupersetOf:
|
||||
return "supersetOf";
|
||||
case IsDistinct:
|
||||
return "isDistinct";
|
||||
case Distinct:
|
||||
return "distinct";
|
||||
case Count:
|
||||
return "count";
|
||||
case Where:
|
||||
return "where";
|
||||
case Select:
|
||||
return "select";
|
||||
case All:
|
||||
return "all";
|
||||
case Repeat:
|
||||
return "repeat";
|
||||
case Aggregate:
|
||||
return "aggregate";
|
||||
case Item:
|
||||
return "item";
|
||||
case As:
|
||||
return "as";
|
||||
case Is:
|
||||
return "is";
|
||||
case Single:
|
||||
return "single";
|
||||
case First:
|
||||
return "first";
|
||||
case Last:
|
||||
return "last";
|
||||
case Tail:
|
||||
return "tail";
|
||||
case Skip:
|
||||
return "skip";
|
||||
case Take:
|
||||
return "take";
|
||||
case Union:
|
||||
return "union";
|
||||
case Combine:
|
||||
return "combine";
|
||||
case Intersect:
|
||||
return "intersect";
|
||||
case Exclude:
|
||||
return "exclude";
|
||||
case Iif:
|
||||
return "iif";
|
||||
case ToChars:
|
||||
return "toChars";
|
||||
case Lower:
|
||||
return "lower";
|
||||
case Upper:
|
||||
return "upper";
|
||||
case IndexOf:
|
||||
return "indexOf";
|
||||
case Substring:
|
||||
return "substring";
|
||||
case StartsWith:
|
||||
return "startsWith";
|
||||
case EndsWith:
|
||||
return "endsWith";
|
||||
case Matches:
|
||||
return "matches";
|
||||
case MatchesFull:
|
||||
return "matchesFull";
|
||||
case ReplaceMatches:
|
||||
return "replaceMatches";
|
||||
case Contains:
|
||||
return "contains";
|
||||
case Replace:
|
||||
return "replace";
|
||||
case Length:
|
||||
return "length";
|
||||
case Children:
|
||||
return "children";
|
||||
case Descendants:
|
||||
return "descendants";
|
||||
case MemberOf:
|
||||
return "memberOf";
|
||||
case Trace:
|
||||
return "trace";
|
||||
case Check:
|
||||
return "check";
|
||||
case Today:
|
||||
return "today";
|
||||
case Now:
|
||||
return "now";
|
||||
case Resolve:
|
||||
return "resolve";
|
||||
case Extension:
|
||||
return "extension";
|
||||
case AllFalse:
|
||||
return "allFalse";
|
||||
case AnyFalse:
|
||||
return "anyFalse";
|
||||
case AllTrue:
|
||||
return "allTrue";
|
||||
case AnyTrue:
|
||||
return "anyTrue";
|
||||
case HasValue:
|
||||
return "hasValue";
|
||||
case Alias:
|
||||
return "alias";
|
||||
case AliasAs:
|
||||
return "aliasAs";
|
||||
case Encode:
|
||||
return "encode";
|
||||
case Decode:
|
||||
return "decode";
|
||||
case Escape:
|
||||
return "escape";
|
||||
case Unescape:
|
||||
return "unescape";
|
||||
case Trim:
|
||||
return "trim";
|
||||
case Split:
|
||||
return "split";
|
||||
case Join:
|
||||
return "join";
|
||||
case HtmlChecks1:
|
||||
return "htmlChecks";
|
||||
case HtmlChecks2:
|
||||
return "htmlChecks2";
|
||||
case Comparable:
|
||||
return "comparable";
|
||||
case OfType:
|
||||
return "ofType";
|
||||
case Type:
|
||||
return "type";
|
||||
case ToInteger:
|
||||
return "toInteger";
|
||||
case ToDecimal:
|
||||
return "toDecimal";
|
||||
case ToString:
|
||||
return "toString";
|
||||
case ToBoolean:
|
||||
return "toBoolean";
|
||||
case ToQuantity:
|
||||
return "toQuantity";
|
||||
case ToDateTime:
|
||||
return "toDateTime";
|
||||
case ToTime:
|
||||
return "toTime";
|
||||
case ConvertsToInteger:
|
||||
return "convertsToInteger";
|
||||
case ConvertsToDecimal:
|
||||
return "convertsToDecimal";
|
||||
case ConvertsToString:
|
||||
return "convertsToString";
|
||||
case ConvertsToBoolean:
|
||||
return "convertsToBoolean";
|
||||
case ConvertsToQuantity:
|
||||
return "convertsToQuantity";
|
||||
case ConvertsToDateTime:
|
||||
return "convertsToDateTime";
|
||||
case ConvertsToDate:
|
||||
return "convertsToDate";
|
||||
case ConvertsToTime:
|
||||
return "isTime";
|
||||
case ConformsTo:
|
||||
return "conformsTo";
|
||||
case Round:
|
||||
return "round";
|
||||
case Sqrt:
|
||||
return "sqrt";
|
||||
case Abs:
|
||||
return "abs";
|
||||
case Ceiling:
|
||||
return "ceiling";
|
||||
case Exp:
|
||||
return "exp";
|
||||
case Floor:
|
||||
return "floor";
|
||||
case Ln:
|
||||
return "ln";
|
||||
case Log:
|
||||
return "log";
|
||||
case Power:
|
||||
return "power";
|
||||
case Truncate:
|
||||
return "truncate";
|
||||
case LowBoundary:
|
||||
return "lowBoundary";
|
||||
case HighBoundary:
|
||||
return "highBoundary";
|
||||
case Precision:
|
||||
return "precision";
|
||||
default:
|
||||
return "?custom?";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum Operation {
|
||||
Equals, Equivalent, NotEquals, NotEquivalent, LessThan, Greater, LessOrEqual, GreaterOrEqual, Is, As, Union, Or,
|
||||
And, Xor, Implies, Times, DivideBy, Plus, Minus, Concatenate, Div, Mod, In, Contains, MemberOf;
|
||||
|
||||
public static Operation fromCode(String name) {
|
||||
if (Utilities.noString(name))
|
||||
return null;
|
||||
if (name.equals("="))
|
||||
return Operation.Equals;
|
||||
if (name.equals("~"))
|
||||
return Operation.Equivalent;
|
||||
if (name.equals("!="))
|
||||
return Operation.NotEquals;
|
||||
if (name.equals("!~"))
|
||||
return Operation.NotEquivalent;
|
||||
if (name.equals(">"))
|
||||
return Operation.Greater;
|
||||
if (name.equals("<"))
|
||||
return Operation.LessThan;
|
||||
if (name.equals(">="))
|
||||
return Operation.GreaterOrEqual;
|
||||
if (name.equals("<="))
|
||||
return Operation.LessOrEqual;
|
||||
if (name.equals("|"))
|
||||
return Operation.Union;
|
||||
if (name.equals("or"))
|
||||
return Operation.Or;
|
||||
if (name.equals("and"))
|
||||
return Operation.And;
|
||||
if (name.equals("xor"))
|
||||
return Operation.Xor;
|
||||
if (name.equals("is"))
|
||||
return Operation.Is;
|
||||
if (name.equals("as"))
|
||||
return Operation.As;
|
||||
if (name.equals("*"))
|
||||
return Operation.Times;
|
||||
if (name.equals("/"))
|
||||
return Operation.DivideBy;
|
||||
if (name.equals("+"))
|
||||
return Operation.Plus;
|
||||
if (name.equals("-"))
|
||||
return Operation.Minus;
|
||||
if (name.equals("&"))
|
||||
return Operation.Concatenate;
|
||||
if (name.equals("implies"))
|
||||
return Operation.Implies;
|
||||
if (name.equals("div"))
|
||||
return Operation.Div;
|
||||
if (name.equals("mod"))
|
||||
return Operation.Mod;
|
||||
if (name.equals("in"))
|
||||
return Operation.In;
|
||||
if (name.equals("contains"))
|
||||
return Operation.Contains;
|
||||
if (name.equals("memberOf"))
|
||||
return Operation.MemberOf;
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
public String toCode() {
|
||||
switch (this) {
|
||||
case Equals:
|
||||
return "=";
|
||||
case Equivalent:
|
||||
return "~";
|
||||
case NotEquals:
|
||||
return "!=";
|
||||
case NotEquivalent:
|
||||
return "!~";
|
||||
case Greater:
|
||||
return ">";
|
||||
case LessThan:
|
||||
return "<";
|
||||
case GreaterOrEqual:
|
||||
return ">=";
|
||||
case LessOrEqual:
|
||||
return "<=";
|
||||
case Union:
|
||||
return "|";
|
||||
case Or:
|
||||
return "or";
|
||||
case And:
|
||||
return "and";
|
||||
case Xor:
|
||||
return "xor";
|
||||
case Times:
|
||||
return "*";
|
||||
case DivideBy:
|
||||
return "/";
|
||||
case Plus:
|
||||
return "+";
|
||||
case Minus:
|
||||
return "-";
|
||||
case Concatenate:
|
||||
return "&";
|
||||
case Implies:
|
||||
return "implies";
|
||||
case Is:
|
||||
return "is";
|
||||
case As:
|
||||
return "as";
|
||||
case Div:
|
||||
return "div";
|
||||
case Mod:
|
||||
return "mod";
|
||||
case In:
|
||||
return "in";
|
||||
case Contains:
|
||||
return "contains";
|
||||
case MemberOf:
|
||||
return "memberOf";
|
||||
default:
|
||||
return "?custom?";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum CollectionStatus {
|
||||
SINGLETON, ORDERED, UNORDERED;
|
||||
}
|
||||
|
||||
// the expression will have one of either name or constant
|
||||
private String uniqueId;
|
||||
private Kind kind;
|
||||
private String name;
|
||||
private Base constant;
|
||||
private Function function;
|
||||
private List<ExpressionNode> parameters; // will be created if there is a function
|
||||
private ExpressionNode inner;
|
||||
private ExpressionNode group;
|
||||
private Operation operation;
|
||||
private boolean proximal; // a proximal operation is the first in the sequence of operations. This is
|
||||
// significant when evaluating the outcomes
|
||||
private ExpressionNode opNext;
|
||||
private SourceLocation start;
|
||||
private SourceLocation end;
|
||||
private SourceLocation opStart;
|
||||
private SourceLocation opEnd;
|
||||
private TypeDetails types;
|
||||
private TypeDetails opTypes;
|
||||
|
||||
public ExpressionNode(int uniqueId) {
|
||||
super();
|
||||
this.uniqueId = Integer.toString(uniqueId);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder b = new StringBuilder();
|
||||
switch (kind) {
|
||||
case Name:
|
||||
b.append(name);
|
||||
break;
|
||||
case Function:
|
||||
if (function == Function.Item)
|
||||
b.append("[");
|
||||
else {
|
||||
b.append(name);
|
||||
b.append("(");
|
||||
}
|
||||
boolean first = true;
|
||||
for (ExpressionNode n : parameters) {
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
b.append(", ");
|
||||
b.append(n.toString());
|
||||
}
|
||||
if (function == Function.Item) {
|
||||
b.append("]");
|
||||
} else {
|
||||
b.append(")");
|
||||
}
|
||||
break;
|
||||
case Constant:
|
||||
if (constant == null) {
|
||||
b.append("{}");
|
||||
} else if (constant instanceof StringType) {
|
||||
b.append("'" + Utilities.escapeJson(constant.primitiveValue()) + "'");
|
||||
} else if (constant instanceof Quantity) {
|
||||
Quantity q = (Quantity) constant;
|
||||
b.append(Utilities.escapeJson(q.getValue().toPlainString()));
|
||||
b.append(" '");
|
||||
b.append(Utilities.escapeJson(q.getUnit()));
|
||||
b.append("'");
|
||||
} else if (constant.primitiveValue() != null) {
|
||||
b.append(Utilities.escapeJson(constant.primitiveValue()));
|
||||
} else {
|
||||
b.append(Utilities.escapeJson(constant.toString()));
|
||||
}
|
||||
break;
|
||||
case Group:
|
||||
b.append("(");
|
||||
b.append(group.toString());
|
||||
b.append(")");
|
||||
}
|
||||
if (inner != null) {
|
||||
if (!((ExpressionNode.Kind.Function == inner.getKind())
|
||||
&& (ExpressionNode.Function.Item == inner.getFunction()))) {
|
||||
b.append(".");
|
||||
}
|
||||
b.append(inner.toString());
|
||||
}
|
||||
if (operation != null) {
|
||||
b.append(" ");
|
||||
b.append(operation.toCode());
|
||||
b.append(" ");
|
||||
b.append(opNext.toString());
|
||||
}
|
||||
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Base getConstant() {
|
||||
return constant;
|
||||
}
|
||||
|
||||
public void setConstant(Base constant) {
|
||||
this.constant = constant;
|
||||
}
|
||||
|
||||
public Function getFunction() {
|
||||
return function;
|
||||
}
|
||||
|
||||
public void setFunction(Function function) {
|
||||
this.function = function;
|
||||
if (parameters == null)
|
||||
parameters = new ArrayList<ExpressionNode>();
|
||||
}
|
||||
|
||||
public boolean isProximal() {
|
||||
return proximal;
|
||||
}
|
||||
|
||||
public void setProximal(boolean proximal) {
|
||||
this.proximal = proximal;
|
||||
}
|
||||
|
||||
public Operation getOperation() {
|
||||
return operation;
|
||||
}
|
||||
|
||||
public void setOperation(Operation operation) {
|
||||
this.operation = operation;
|
||||
}
|
||||
|
||||
public ExpressionNode getInner() {
|
||||
return inner;
|
||||
}
|
||||
|
||||
public void setInner(ExpressionNode value) {
|
||||
this.inner = value;
|
||||
}
|
||||
|
||||
public ExpressionNode getOpNext() {
|
||||
return opNext;
|
||||
}
|
||||
|
||||
public void setOpNext(ExpressionNode value) {
|
||||
this.opNext = value;
|
||||
}
|
||||
|
||||
public List<ExpressionNode> getParameters() {
|
||||
return parameters;
|
||||
}
|
||||
|
||||
public boolean checkName() {
|
||||
if (!name.startsWith("$"))
|
||||
return true;
|
||||
else
|
||||
return Utilities.existsInList(name, "$this", "$total", "$index");
|
||||
}
|
||||
|
||||
public Kind getKind() {
|
||||
return kind;
|
||||
}
|
||||
|
||||
public void setKind(Kind kind) {
|
||||
this.kind = kind;
|
||||
}
|
||||
|
||||
public ExpressionNode getGroup() {
|
||||
return group;
|
||||
}
|
||||
|
||||
public void setGroup(ExpressionNode group) {
|
||||
this.group = group;
|
||||
}
|
||||
|
||||
public SourceLocation getStart() {
|
||||
return start;
|
||||
}
|
||||
|
||||
public void setStart(SourceLocation start) {
|
||||
this.start = start;
|
||||
}
|
||||
|
||||
public SourceLocation getEnd() {
|
||||
return end;
|
||||
}
|
||||
|
||||
public void setEnd(SourceLocation end) {
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
public SourceLocation getOpStart() {
|
||||
return opStart;
|
||||
}
|
||||
|
||||
public void setOpStart(SourceLocation opStart) {
|
||||
this.opStart = opStart;
|
||||
}
|
||||
|
||||
public SourceLocation getOpEnd() {
|
||||
return opEnd;
|
||||
}
|
||||
|
||||
public void setOpEnd(SourceLocation opEnd) {
|
||||
this.opEnd = opEnd;
|
||||
}
|
||||
|
||||
public String getUniqueId() {
|
||||
return uniqueId;
|
||||
}
|
||||
|
||||
public int parameterCount() {
|
||||
if (parameters == null)
|
||||
return 0;
|
||||
else
|
||||
return parameters.size();
|
||||
}
|
||||
|
||||
public String Canonical() {
|
||||
StringBuilder b = new StringBuilder();
|
||||
write(b);
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
public String summary() {
|
||||
switch (kind) {
|
||||
case Name:
|
||||
return uniqueId + ": " + name;
|
||||
case Function:
|
||||
return uniqueId + ": " + function.toString() + "()";
|
||||
case Constant:
|
||||
return uniqueId + ": " + constant;
|
||||
case Group:
|
||||
return uniqueId + ": (Group)";
|
||||
}
|
||||
return "?exp-kind?";
|
||||
}
|
||||
|
||||
private void write(StringBuilder b) {
|
||||
|
||||
switch (kind) {
|
||||
case Name:
|
||||
b.append(name);
|
||||
break;
|
||||
case Constant:
|
||||
b.append(constant);
|
||||
break;
|
||||
case Function:
|
||||
b.append(function.toCode());
|
||||
b.append('(');
|
||||
boolean f = true;
|
||||
for (ExpressionNode n : parameters) {
|
||||
if (f)
|
||||
f = false;
|
||||
else
|
||||
b.append(", ");
|
||||
n.write(b);
|
||||
}
|
||||
b.append(')');
|
||||
|
||||
break;
|
||||
case Group:
|
||||
b.append('(');
|
||||
group.write(b);
|
||||
b.append(')');
|
||||
}
|
||||
|
||||
if (inner != null) {
|
||||
b.append('.');
|
||||
inner.write(b);
|
||||
}
|
||||
if (operation != null) {
|
||||
b.append(' ');
|
||||
b.append(operation.toCode());
|
||||
b.append(' ');
|
||||
opNext.write(b);
|
||||
}
|
||||
}
|
||||
|
||||
public String check() {
|
||||
|
||||
if (kind == null) {
|
||||
return "Error in expression - node has no kind";
|
||||
}
|
||||
switch (kind) {
|
||||
case Name:
|
||||
if (Utilities.noString(name))
|
||||
return "No Name provided @ " + location();
|
||||
break;
|
||||
|
||||
case Function:
|
||||
if (function == null)
|
||||
return "No Function id provided @ " + location();
|
||||
for (ExpressionNode n : parameters) {
|
||||
String msg = n.check();
|
||||
if (msg != null)
|
||||
return msg;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Unary:
|
||||
break;
|
||||
case Constant:
|
||||
if (constant == null)
|
||||
return "No Constant provided @ " + location();
|
||||
break;
|
||||
|
||||
case Group:
|
||||
if (group == null)
|
||||
return "No Group provided @ " + location();
|
||||
else {
|
||||
String msg = group.check();
|
||||
if (msg != null)
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
if (inner != null) {
|
||||
String msg = inner.check();
|
||||
if (msg != null)
|
||||
return msg;
|
||||
}
|
||||
if (operation == null) {
|
||||
|
||||
if (opNext != null)
|
||||
return "Next provided when it shouldn't be @ " + location();
|
||||
} else {
|
||||
if (opNext == null)
|
||||
return "No Next provided @ " + location();
|
||||
else
|
||||
opNext.check();
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
private String location() {
|
||||
return Integer.toString(start.getLine()) + ", " + Integer.toString(start.getColumn());
|
||||
}
|
||||
|
||||
public TypeDetails getTypes() {
|
||||
return types;
|
||||
}
|
||||
|
||||
public void setTypes(TypeDetails types) {
|
||||
this.types = types;
|
||||
}
|
||||
|
||||
public TypeDetails getOpTypes() {
|
||||
return opTypes;
|
||||
}
|
||||
|
||||
public void setOpTypes(TypeDetails opTypes) {
|
||||
this.opTypes = opTypes;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,383 +0,0 @@
|
|||
package org.hl7.fhir.r4b.model;
|
||||
|
||||
/*
|
||||
Copyright (c) 2011+, HL7, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of HL7 nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hl7.fhir.exceptions.DefinitionException;
|
||||
import org.hl7.fhir.r4b.context.IWorkerContext;
|
||||
import org.hl7.fhir.r4b.model.ElementDefinition.ElementDefinitionBindingComponent;
|
||||
import org.hl7.fhir.r4b.model.ExpressionNode.CollectionStatus;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
|
||||
public class TypeDetails {
|
||||
public static final String FHIR_NS = "http://hl7.org/fhir/StructureDefinition/";
|
||||
public static final String FP_NS = "http://hl7.org/fhirpath/";
|
||||
public static final String FP_String = "http://hl7.org/fhirpath/String";
|
||||
public static final String FP_Boolean = "http://hl7.org/fhirpath/Boolean";
|
||||
public static final String FP_Integer = "http://hl7.org/fhirpath/Integer";
|
||||
public static final String FP_Decimal = "http://hl7.org/fhirpath/Decimal";
|
||||
public static final String FP_Quantity = "http://hl7.org/fhirpath/Quantity";
|
||||
public static final String FP_DateTime = "http://hl7.org/fhirpath/DateTime";
|
||||
public static final String FP_Time = "http://hl7.org/fhirpath/Time";
|
||||
public static final String FP_SimpleTypeInfo = "http://hl7.org/fhirpath/SimpleTypeInfo";
|
||||
public static final String FP_ClassInfo = "http://hl7.org/fhirpath/ClassInfo";
|
||||
public static final Set<String> FP_NUMBERS = new HashSet<String>(Arrays.asList(FP_Integer, FP_Decimal));
|
||||
|
||||
public static class ProfiledType {
|
||||
private String uri;
|
||||
private List<String> profiles; // or, not and
|
||||
private List<ElementDefinitionBindingComponent> bindings;
|
||||
|
||||
public ProfiledType(String n) {
|
||||
uri = ns(n);
|
||||
}
|
||||
|
||||
public String getUri() {
|
||||
return uri;
|
||||
}
|
||||
|
||||
public boolean hasProfiles() {
|
||||
return profiles != null && profiles.size() > 0;
|
||||
}
|
||||
|
||||
public List<String> getProfiles() {
|
||||
return profiles;
|
||||
}
|
||||
|
||||
public boolean hasBindings() {
|
||||
return bindings != null && bindings.size() > 0;
|
||||
}
|
||||
|
||||
public List<ElementDefinitionBindingComponent> getBindings() {
|
||||
return bindings;
|
||||
}
|
||||
|
||||
public static String ns(String n) {
|
||||
return Utilities.isAbsoluteUrl(n) ? n : FHIR_NS + n;
|
||||
}
|
||||
|
||||
public void addProfile(String profile) {
|
||||
if (profiles == null)
|
||||
profiles = new ArrayList<String>();
|
||||
profiles.add(profile);
|
||||
}
|
||||
|
||||
public void addBinding(ElementDefinitionBindingComponent binding) {
|
||||
bindings = new ArrayList<ElementDefinitionBindingComponent>();
|
||||
bindings.add(binding);
|
||||
}
|
||||
|
||||
public boolean hasBinding(ElementDefinitionBindingComponent b) {
|
||||
return false; // todo: do we need to do this?
|
||||
}
|
||||
|
||||
public void addProfiles(List<CanonicalType> list) {
|
||||
if (profiles == null)
|
||||
profiles = new ArrayList<String>();
|
||||
for (UriType u : list)
|
||||
profiles.add(u.getValue());
|
||||
}
|
||||
|
||||
public boolean isSystemType() {
|
||||
return uri.startsWith(FP_NS);
|
||||
}
|
||||
}
|
||||
|
||||
private List<ProfiledType> types = new ArrayList<ProfiledType>();
|
||||
private CollectionStatus collectionStatus;
|
||||
|
||||
public TypeDetails(CollectionStatus collectionStatus, String... names) {
|
||||
super();
|
||||
this.collectionStatus = collectionStatus;
|
||||
for (String n : names) {
|
||||
this.types.add(new ProfiledType(n));
|
||||
}
|
||||
}
|
||||
|
||||
public TypeDetails(CollectionStatus collectionStatus, Set<String> names) {
|
||||
super();
|
||||
this.collectionStatus = collectionStatus;
|
||||
for (String n : names) {
|
||||
addType(new ProfiledType(n));
|
||||
}
|
||||
}
|
||||
|
||||
public TypeDetails(CollectionStatus collectionStatus, ProfiledType pt) {
|
||||
super();
|
||||
this.collectionStatus = collectionStatus;
|
||||
this.types.add(pt);
|
||||
}
|
||||
|
||||
public String addType(String n) {
|
||||
ProfiledType pt = new ProfiledType(n);
|
||||
String res = pt.uri;
|
||||
addType(pt);
|
||||
return res;
|
||||
}
|
||||
|
||||
public String addType(String n, String p) {
|
||||
ProfiledType pt = new ProfiledType(n);
|
||||
pt.addProfile(p);
|
||||
String res = pt.uri;
|
||||
addType(pt);
|
||||
return res;
|
||||
}
|
||||
|
||||
public void addType(ProfiledType pt) {
|
||||
for (ProfiledType et : types) {
|
||||
if (et.uri.equals(pt.uri)) {
|
||||
if (pt.profiles != null) {
|
||||
for (String p : pt.profiles) {
|
||||
if (et.profiles == null)
|
||||
et.profiles = new ArrayList<String>();
|
||||
if (!et.profiles.contains(p))
|
||||
et.profiles.add(p);
|
||||
}
|
||||
}
|
||||
if (pt.bindings != null) {
|
||||
for (ElementDefinitionBindingComponent b : pt.bindings) {
|
||||
if (et.bindings == null)
|
||||
et.bindings = new ArrayList<ElementDefinitionBindingComponent>();
|
||||
if (!et.hasBinding(b))
|
||||
et.bindings.add(b);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
types.add(pt);
|
||||
}
|
||||
|
||||
public void addTypes(Collection<String> names) {
|
||||
for (String n : names)
|
||||
addType(new ProfiledType(n));
|
||||
}
|
||||
|
||||
public boolean hasType(IWorkerContext context, String... tn) {
|
||||
for (String n : tn) {
|
||||
String t = ProfiledType.ns(n);
|
||||
if (typesContains(t))
|
||||
return true;
|
||||
if (Utilities.existsInList(n, "boolean", "string", "integer", "decimal", "Quantity", "dateTime", "time",
|
||||
"ClassInfo", "SimpleTypeInfo")) {
|
||||
t = FP_NS + Utilities.capitalize(n);
|
||||
if (typesContains(t))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (String n : tn) {
|
||||
String id = n.contains("#") ? n.substring(0, n.indexOf("#")) : n;
|
||||
String tail = null;
|
||||
if (n.contains("#")) {
|
||||
tail = n.substring(n.indexOf("#") + 1);
|
||||
tail = tail.substring(tail.indexOf("."));
|
||||
}
|
||||
String t = ProfiledType.ns(n);
|
||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, t);
|
||||
while (sd != null) {
|
||||
if (tail == null && typesContains(sd.getUrl()))
|
||||
return true;
|
||||
if (tail == null && getSystemType(sd.getUrl()) != null && typesContains(getSystemType(sd.getUrl())))
|
||||
return true;
|
||||
if (tail != null && typesContains(sd.getUrl() + "#" + sd.getType() + tail))
|
||||
return true;
|
||||
if (sd.hasBaseDefinition()) {
|
||||
if (sd.getType().equals("uri"))
|
||||
sd = context.fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/string");
|
||||
else
|
||||
sd = context.fetchResource(StructureDefinition.class, sd.getBaseDefinition());
|
||||
} else
|
||||
sd = null;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private String getSystemType(String url) {
|
||||
if (url.startsWith("http://hl7.org/fhir/StructureDefinition/")) {
|
||||
String code = url.substring(40);
|
||||
if (Utilities.existsInList(code, "string", "boolean", "integer", "decimal", "dateTime", "time", "Quantity"))
|
||||
return FP_NS + Utilities.capitalize(code);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean typesContains(String t) {
|
||||
for (ProfiledType pt : types)
|
||||
if (pt.uri.equals(t))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public void update(TypeDetails source) {
|
||||
for (ProfiledType pt : source.types)
|
||||
addType(pt);
|
||||
if (collectionStatus == null)
|
||||
collectionStatus = source.collectionStatus;
|
||||
else if (source.collectionStatus == CollectionStatus.UNORDERED)
|
||||
collectionStatus = source.collectionStatus;
|
||||
else
|
||||
collectionStatus = CollectionStatus.ORDERED;
|
||||
}
|
||||
|
||||
public TypeDetails union(TypeDetails right) {
|
||||
TypeDetails result = new TypeDetails(null);
|
||||
if (right.collectionStatus == CollectionStatus.UNORDERED || collectionStatus == CollectionStatus.UNORDERED)
|
||||
result.collectionStatus = CollectionStatus.UNORDERED;
|
||||
else
|
||||
result.collectionStatus = CollectionStatus.ORDERED;
|
||||
for (ProfiledType pt : types)
|
||||
result.addType(pt);
|
||||
for (ProfiledType pt : right.types)
|
||||
result.addType(pt);
|
||||
return result;
|
||||
}
|
||||
|
||||
public TypeDetails intersect(TypeDetails right) {
|
||||
TypeDetails result = new TypeDetails(null);
|
||||
if (right.collectionStatus == CollectionStatus.UNORDERED || collectionStatus == CollectionStatus.UNORDERED)
|
||||
result.collectionStatus = CollectionStatus.UNORDERED;
|
||||
else
|
||||
result.collectionStatus = CollectionStatus.ORDERED;
|
||||
for (ProfiledType pt : types) {
|
||||
boolean found = false;
|
||||
for (ProfiledType r : right.types)
|
||||
found = found || pt.uri.equals(r.uri);
|
||||
if (found)
|
||||
result.addType(pt);
|
||||
}
|
||||
for (ProfiledType pt : right.types)
|
||||
result.addType(pt);
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean hasNoTypes() {
|
||||
return types.isEmpty();
|
||||
}
|
||||
|
||||
public Set<String> getTypes() {
|
||||
Set<String> res = new HashSet<String>();
|
||||
for (ProfiledType pt : types)
|
||||
res.add(pt.uri);
|
||||
return res;
|
||||
}
|
||||
|
||||
public TypeDetails toSingleton() {
|
||||
TypeDetails result = new TypeDetails(CollectionStatus.SINGLETON);
|
||||
result.types.addAll(types);
|
||||
return result;
|
||||
}
|
||||
|
||||
public CollectionStatus getCollectionStatus() {
|
||||
return collectionStatus;
|
||||
}
|
||||
|
||||
public boolean hasType(String n) {
|
||||
String t = ProfiledType.ns(n);
|
||||
if (typesContains(t))
|
||||
return true;
|
||||
if (Utilities.existsInList(n, "boolean", "string", "integer", "decimal", "Quantity", "date", "dateTime", "time",
|
||||
"ClassInfo", "SimpleTypeInfo")) {
|
||||
t = FP_NS + Utilities.capitalize(n);
|
||||
if (typesContains(t))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean hasType(Set<String> tn) {
|
||||
for (String n : tn) {
|
||||
String t = ProfiledType.ns(n);
|
||||
if (typesContains(t))
|
||||
return true;
|
||||
if (Utilities.existsInList(n, "boolean", "string", "integer", "decimal", "Quantity", "dateTime", "time",
|
||||
"ClassInfo", "SimpleTypeInfo")) {
|
||||
t = FP_NS + Utilities.capitalize(n);
|
||||
if (typesContains(t))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String describe() {
|
||||
return getTypes().toString();
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
for (ProfiledType pt : types)
|
||||
return pt.uri;
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return (collectionStatus == null ? collectionStatus.SINGLETON.toString() : collectionStatus.toString())
|
||||
+ getTypes().toString();
|
||||
}
|
||||
|
||||
public String getTypeCode() throws DefinitionException {
|
||||
if (types.size() != 1)
|
||||
throw new DefinitionException("Multiple types? (" + types.toString() + ")");
|
||||
for (ProfiledType pt : types)
|
||||
if (pt.uri.startsWith("http://hl7.org/fhir/StructureDefinition/"))
|
||||
return pt.uri.substring(40);
|
||||
else
|
||||
return pt.uri;
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<ProfiledType> getProfiledTypes() {
|
||||
return types;
|
||||
}
|
||||
|
||||
public boolean hasBinding() {
|
||||
for (ProfiledType pt : types) {
|
||||
if (pt.hasBindings())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public ElementDefinitionBindingComponent getBinding() {
|
||||
for (ProfiledType pt : types) {
|
||||
for (ElementDefinitionBindingComponent b : pt.getBindings())
|
||||
return b;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,603 +0,0 @@
|
|||
package org.hl7.fhir.r4b.utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
import org.apache.poi.xssf.model.Comments;
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
|
||||
/*
|
||||
Copyright (c) 2011+, HL7, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of HL7 nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
import org.hl7.fhir.r4b.model.ExpressionNode;
|
||||
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
|
||||
import org.hl7.fhir.utilities.SourceLocation;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
|
||||
// shared lexer for concrete syntaxes
|
||||
// - FluentPath
|
||||
// - Mapping language
|
||||
|
||||
public class FHIRLexer {
|
||||
public class FHIRLexerException extends FHIRException {
|
||||
|
||||
private SourceLocation location;
|
||||
|
||||
// public FHIRLexerException() {
|
||||
// super();
|
||||
// }
|
||||
//
|
||||
// public FHIRLexerException(String message, Throwable cause) {
|
||||
// super(message, cause);
|
||||
// }
|
||||
//
|
||||
// public FHIRLexerException(String message) {
|
||||
// super(message);
|
||||
// }
|
||||
//
|
||||
// public FHIRLexerException(Throwable cause) {
|
||||
// super(cause);
|
||||
// }
|
||||
|
||||
public FHIRLexerException(String message, SourceLocation location) {
|
||||
super(message);
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
public SourceLocation getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
}
|
||||
private String source;
|
||||
private int cursor;
|
||||
private int currentStart;
|
||||
private String current;
|
||||
private List<String> comments = new ArrayList<>();
|
||||
private SourceLocation currentLocation;
|
||||
private SourceLocation currentStartLocation;
|
||||
private int id;
|
||||
private String name;
|
||||
private boolean liquidMode; // in liquid mode, || terminates the expression and hands the parser back to the host
|
||||
private SourceLocation commentLocation;
|
||||
private boolean metadataFormat;
|
||||
private boolean allowDoubleQuotes;
|
||||
|
||||
public FHIRLexer(String source, String name) throws FHIRLexerException {
|
||||
this.source = source == null ? "" : source;
|
||||
this.name = name == null ? "??" : name;
|
||||
currentLocation = new SourceLocation(1, 1);
|
||||
next();
|
||||
}
|
||||
public FHIRLexer(String source, int i) throws FHIRLexerException {
|
||||
this.source = source;
|
||||
this.cursor = i;
|
||||
currentLocation = new SourceLocation(1, 1);
|
||||
next();
|
||||
}
|
||||
public FHIRLexer(String source, int i, boolean allowDoubleQuotes) throws FHIRLexerException {
|
||||
this.source = source;
|
||||
this.cursor = i;
|
||||
this.allowDoubleQuotes = allowDoubleQuotes;
|
||||
currentLocation = new SourceLocation(1, 1);
|
||||
next();
|
||||
}
|
||||
public FHIRLexer(String source, String name, boolean metadataFormat, boolean allowDoubleQuotes) throws FHIRLexerException {
|
||||
this.source = source == null ? "" : source;
|
||||
this.name = name == null ? "??" : name;
|
||||
this.metadataFormat = metadataFormat;
|
||||
this.allowDoubleQuotes = allowDoubleQuotes;
|
||||
currentLocation = new SourceLocation(1, 1);
|
||||
next();
|
||||
}
|
||||
public String getCurrent() {
|
||||
return current;
|
||||
}
|
||||
public SourceLocation getCurrentLocation() {
|
||||
return currentLocation;
|
||||
}
|
||||
|
||||
public boolean isConstant() {
|
||||
return FHIRPathConstant.isFHIRPathConstant(current);
|
||||
}
|
||||
|
||||
public boolean isFixedName() {
|
||||
return FHIRPathConstant.isFHIRPathFixedName(current);
|
||||
}
|
||||
|
||||
public boolean isStringConstant() {
|
||||
return FHIRPathConstant.isFHIRPathStringConstant(current);
|
||||
}
|
||||
|
||||
public String take() throws FHIRLexerException {
|
||||
String s = current;
|
||||
next();
|
||||
return s;
|
||||
}
|
||||
|
||||
public int takeInt() throws FHIRLexerException {
|
||||
String s = current;
|
||||
if (!Utilities.isInteger(s))
|
||||
throw error("Found "+current+" expecting an integer");
|
||||
next();
|
||||
return Integer.parseInt(s);
|
||||
}
|
||||
|
||||
public boolean isToken() {
|
||||
if (Utilities.noString(current))
|
||||
return false;
|
||||
|
||||
if (current.startsWith("$"))
|
||||
return true;
|
||||
|
||||
if (current.equals("*") || current.equals("**"))
|
||||
return true;
|
||||
|
||||
if ((current.charAt(0) >= 'A' && current.charAt(0) <= 'Z') || (current.charAt(0) >= 'a' && current.charAt(0) <= 'z')) {
|
||||
for (int i = 1; i < current.length(); i++)
|
||||
if (!( (current.charAt(1) >= 'A' && current.charAt(1) <= 'Z') || (current.charAt(1) >= 'a' && current.charAt(1) <= 'z') ||
|
||||
(current.charAt(1) >= '0' && current.charAt(1) <= '9')))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public FHIRLexerException error(String msg) {
|
||||
return error(msg, currentLocation.toString(), currentLocation);
|
||||
}
|
||||
|
||||
public FHIRLexerException error(String msg, String location, SourceLocation loc) {
|
||||
return new FHIRLexerException("Error @"+location+": "+msg, loc);
|
||||
}
|
||||
|
||||
public void next() throws FHIRLexerException {
|
||||
skipWhitespaceAndComments();
|
||||
current = null;
|
||||
currentStart = cursor;
|
||||
currentStartLocation = currentLocation;
|
||||
if (cursor < source.length()) {
|
||||
char ch = source.charAt(cursor);
|
||||
if (ch == '!' || ch == '>' || ch == '<' || ch == ':' || ch == '-' || ch == '=') {
|
||||
cursor++;
|
||||
if (cursor < source.length() && (source.charAt(cursor) == '=' || source.charAt(cursor) == '~' || source.charAt(cursor) == '-') || (ch == '-' && source.charAt(cursor) == '>'))
|
||||
cursor++;
|
||||
current = source.substring(currentStart, cursor);
|
||||
} else if (ch == '.' ) {
|
||||
cursor++;
|
||||
if (cursor < source.length() && (source.charAt(cursor) == '.'))
|
||||
cursor++;
|
||||
current = source.substring(currentStart, cursor);
|
||||
} else if (ch >= '0' && ch <= '9') {
|
||||
cursor++;
|
||||
boolean dotted = false;
|
||||
while (cursor < source.length() && ((source.charAt(cursor) >= '0' && source.charAt(cursor) <= '9') || (source.charAt(cursor) == '.') && !dotted)) {
|
||||
if (source.charAt(cursor) == '.')
|
||||
dotted = true;
|
||||
cursor++;
|
||||
}
|
||||
if (source.charAt(cursor-1) == '.')
|
||||
cursor--;
|
||||
current = source.substring(currentStart, cursor);
|
||||
} else if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) {
|
||||
while (cursor < source.length() && ((source.charAt(cursor) >= 'A' && source.charAt(cursor) <= 'Z') || (source.charAt(cursor) >= 'a' && source.charAt(cursor) <= 'z') ||
|
||||
(source.charAt(cursor) >= '0' && source.charAt(cursor) <= '9') || source.charAt(cursor) == '_'))
|
||||
cursor++;
|
||||
current = source.substring(currentStart, cursor);
|
||||
} else if (ch == '%') {
|
||||
cursor++;
|
||||
if (cursor < source.length() && (source.charAt(cursor) == '`')) {
|
||||
cursor++;
|
||||
while (cursor < source.length() && (source.charAt(cursor) != '`'))
|
||||
cursor++;
|
||||
cursor++;
|
||||
} else
|
||||
while (cursor < source.length() && ((source.charAt(cursor) >= 'A' && source.charAt(cursor) <= 'Z') || (source.charAt(cursor) >= 'a' && source.charAt(cursor) <= 'z') ||
|
||||
(source.charAt(cursor) >= '0' && source.charAt(cursor) <= '9') || source.charAt(cursor) == ':' || source.charAt(cursor) == '-'))
|
||||
cursor++;
|
||||
current = source.substring(currentStart, cursor);
|
||||
} else if (ch == '/') {
|
||||
cursor++;
|
||||
if (cursor < source.length() && (source.charAt(cursor) == '/')) {
|
||||
// we've run into metadata
|
||||
cursor++;
|
||||
cursor++;
|
||||
current = source.substring(currentStart, cursor);
|
||||
} else {
|
||||
current = source.substring(currentStart, cursor);
|
||||
}
|
||||
} else if (ch == '$') {
|
||||
cursor++;
|
||||
while (cursor < source.length() && (source.charAt(cursor) >= 'a' && source.charAt(cursor) <= 'z'))
|
||||
cursor++;
|
||||
current = source.substring(currentStart, cursor);
|
||||
} else if (ch == '{') {
|
||||
cursor++;
|
||||
ch = source.charAt(cursor);
|
||||
if (ch == '}')
|
||||
cursor++;
|
||||
current = source.substring(currentStart, cursor);
|
||||
} else if (ch == '"' && allowDoubleQuotes) {
|
||||
cursor++;
|
||||
boolean escape = false;
|
||||
while (cursor < source.length() && (escape || source.charAt(cursor) != '"')) {
|
||||
if (escape)
|
||||
escape = false;
|
||||
else
|
||||
escape = (source.charAt(cursor) == '\\');
|
||||
cursor++;
|
||||
}
|
||||
if (cursor == source.length())
|
||||
throw error("Unterminated string");
|
||||
cursor++;
|
||||
current = "\""+source.substring(currentStart+1, cursor-1)+"\"";
|
||||
} else if (ch == '`') {
|
||||
cursor++;
|
||||
boolean escape = false;
|
||||
while (cursor < source.length() && (escape || source.charAt(cursor) != '`')) {
|
||||
if (escape)
|
||||
escape = false;
|
||||
else
|
||||
escape = (source.charAt(cursor) == '\\');
|
||||
cursor++;
|
||||
}
|
||||
if (cursor == source.length())
|
||||
throw error("Unterminated string");
|
||||
cursor++;
|
||||
current = "`"+source.substring(currentStart+1, cursor-1)+"`";
|
||||
} else if (ch == '\''){
|
||||
cursor++;
|
||||
char ech = ch;
|
||||
boolean escape = false;
|
||||
while (cursor < source.length() && (escape || source.charAt(cursor) != ech)) {
|
||||
if (escape)
|
||||
escape = false;
|
||||
else
|
||||
escape = (source.charAt(cursor) == '\\');
|
||||
cursor++;
|
||||
}
|
||||
if (cursor == source.length())
|
||||
throw error("Unterminated string");
|
||||
cursor++;
|
||||
current = source.substring(currentStart, cursor);
|
||||
if (ech == '\'')
|
||||
current = "\'"+current.substring(1, current.length() - 1)+"\'";
|
||||
} else if (ch == '`') {
|
||||
cursor++;
|
||||
boolean escape = false;
|
||||
while (cursor < source.length() && (escape || source.charAt(cursor) != '`')) {
|
||||
if (escape)
|
||||
escape = false;
|
||||
else
|
||||
escape = (source.charAt(cursor) == '\\');
|
||||
cursor++;
|
||||
}
|
||||
if (cursor == source.length())
|
||||
throw error("Unterminated string");
|
||||
cursor++;
|
||||
current = "`"+source.substring(currentStart+1, cursor-1)+"`";
|
||||
} else if (ch == '|' && liquidMode) {
|
||||
cursor++;
|
||||
ch = source.charAt(cursor);
|
||||
if (ch == '|')
|
||||
cursor++;
|
||||
current = source.substring(currentStart, cursor);
|
||||
} else if (ch == '@'){
|
||||
int start = cursor;
|
||||
cursor++;
|
||||
while (cursor < source.length() && isDateChar(source.charAt(cursor), start))
|
||||
cursor++;
|
||||
current = source.substring(currentStart, cursor);
|
||||
} else { // if CharInSet(ch, ['.', ',', '(', ')', '=', '$']) then
|
||||
cursor++;
|
||||
current = source.substring(currentStart, cursor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void skipWhitespaceAndComments() {
|
||||
comments.clear();
|
||||
commentLocation = null;
|
||||
boolean last13 = false;
|
||||
boolean done = false;
|
||||
while (cursor < source.length() && !done) {
|
||||
if (cursor < source.length() -1 && "//".equals(source.substring(cursor, cursor+2)) && !isMetadataStart()) {
|
||||
if (commentLocation == null) {
|
||||
commentLocation = currentLocation.copy();
|
||||
}
|
||||
int start = cursor+2;
|
||||
while (cursor < source.length() && !((source.charAt(cursor) == '\r') || source.charAt(cursor) == '\n')) {
|
||||
cursor++;
|
||||
}
|
||||
comments.add(source.substring(start, cursor).trim());
|
||||
} else if (cursor < source.length() - 1 && "/*".equals(source.substring(cursor, cursor+2))) {
|
||||
if (commentLocation == null) {
|
||||
commentLocation = currentLocation.copy();
|
||||
}
|
||||
int start = cursor+2;
|
||||
while (cursor < source.length() - 1 && !"*/".equals(source.substring(cursor, cursor+2))) {
|
||||
last13 = currentLocation.checkChar(source.charAt(cursor), last13);
|
||||
cursor++;
|
||||
}
|
||||
if (cursor >= source.length() -1) {
|
||||
error("Unfinished comment");
|
||||
} else {
|
||||
comments.add(source.substring(start, cursor).trim());
|
||||
cursor = cursor + 2;
|
||||
}
|
||||
} else if (Utilities.isWhitespace(source.charAt(cursor))) {
|
||||
last13 = currentLocation.checkChar(source.charAt(cursor), last13);
|
||||
cursor++;
|
||||
} else {
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isMetadataStart() {
|
||||
return metadataFormat && cursor < source.length() - 2 && "///".equals(source.substring(cursor, cursor+3));
|
||||
}
|
||||
|
||||
private boolean isDateChar(char ch,int start) {
|
||||
int eot = source.charAt(start+1) == 'T' ? 10 : 20;
|
||||
|
||||
return ch == '-' || ch == ':' || ch == 'T' || ch == '+' || ch == 'Z' || Character.isDigit(ch) || (cursor-start == eot && ch == '.' && cursor < source.length()-1&& Character.isDigit(source.charAt(cursor+1)));
|
||||
}
|
||||
public boolean isOp() {
|
||||
return ExpressionNode.Operation.fromCode(current) != null;
|
||||
}
|
||||
public boolean done() {
|
||||
return currentStart >= source.length();
|
||||
}
|
||||
public int nextId() {
|
||||
id++;
|
||||
return id;
|
||||
}
|
||||
public SourceLocation getCurrentStartLocation() {
|
||||
return currentStartLocation;
|
||||
}
|
||||
|
||||
// special case use
|
||||
public void setCurrent(String current) {
|
||||
this.current = current;
|
||||
}
|
||||
|
||||
public boolean hasComments() {
|
||||
return comments.size() > 0;
|
||||
}
|
||||
|
||||
public List<String> getComments() {
|
||||
return comments;
|
||||
}
|
||||
|
||||
public String getAllComments() {
|
||||
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder("\r\n");
|
||||
b.addAll(comments);
|
||||
comments.clear();
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
public String getFirstComment() {
|
||||
if (hasComments()) {
|
||||
String s = comments.get(0);
|
||||
comments.remove(0);
|
||||
return s;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasToken(String kw) {
|
||||
return !done() && kw.equals(current);
|
||||
}
|
||||
public boolean hasToken(String... names) {
|
||||
if (done())
|
||||
return false;
|
||||
for (String s : names)
|
||||
if (s.equals(current))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public void token(String kw) throws FHIRLexerException {
|
||||
if (!kw.equals(current))
|
||||
throw error("Found \""+current+"\" expecting \""+kw+"\"");
|
||||
next();
|
||||
}
|
||||
|
||||
public String readConstant(String desc) throws FHIRLexerException {
|
||||
if (!isStringConstant())
|
||||
throw error("Found "+current+" expecting \"["+desc+"]\"");
|
||||
|
||||
return processConstant(take());
|
||||
}
|
||||
|
||||
public String readFixedName(String desc) throws FHIRLexerException {
|
||||
if (!isFixedName())
|
||||
throw error("Found "+current+" expecting \"["+desc+"]\"");
|
||||
|
||||
return processFixedName(take());
|
||||
}
|
||||
|
||||
public String processConstant(String s) throws FHIRLexerException {
|
||||
StringBuilder b = new StringBuilder();
|
||||
int i = 1;
|
||||
while (i < s.length()-1) {
|
||||
char ch = s.charAt(i);
|
||||
if (ch == '\\') {
|
||||
i++;
|
||||
switch (s.charAt(i)) {
|
||||
case 't':
|
||||
b.append('\t');
|
||||
break;
|
||||
case 'r':
|
||||
b.append('\r');
|
||||
break;
|
||||
case 'n':
|
||||
b.append('\n');
|
||||
break;
|
||||
case 'f':
|
||||
b.append('\f');
|
||||
break;
|
||||
case '\'':
|
||||
b.append('\'');
|
||||
break;
|
||||
case '"':
|
||||
b.append('"');
|
||||
break;
|
||||
case '`':
|
||||
b.append('`');
|
||||
break;
|
||||
case '\\':
|
||||
b.append('\\');
|
||||
break;
|
||||
case '/':
|
||||
b.append('/');
|
||||
break;
|
||||
case 'u':
|
||||
i++;
|
||||
int uc = Integer.parseInt(s.substring(i, i+4), 16);
|
||||
b.append((char) uc);
|
||||
i = i + 4;
|
||||
break;
|
||||
default:
|
||||
throw new FHIRLexerException("Unknown character escape \\"+s.charAt(i), currentLocation);
|
||||
}
|
||||
} else {
|
||||
b.append(ch);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
public String processFixedName(String s) throws FHIRLexerException {
|
||||
StringBuilder b = new StringBuilder();
|
||||
int i = 1;
|
||||
while (i < s.length()-1) {
|
||||
char ch = s.charAt(i);
|
||||
if (ch == '\\') {
|
||||
i++;
|
||||
switch (s.charAt(i)) {
|
||||
case 't':
|
||||
b.append('\t');
|
||||
break;
|
||||
case 'r':
|
||||
b.append('\r');
|
||||
break;
|
||||
case 'n':
|
||||
b.append('\n');
|
||||
break;
|
||||
case 'f':
|
||||
b.append('\f');
|
||||
break;
|
||||
case '\'':
|
||||
b.append('\'');
|
||||
break;
|
||||
case '"':
|
||||
b.append('"');
|
||||
break;
|
||||
case '\\':
|
||||
b.append('\\');
|
||||
break;
|
||||
case '/':
|
||||
b.append('/');
|
||||
break;
|
||||
case 'u':
|
||||
i++;
|
||||
int uc = Integer.parseInt(s.substring(i, i+4), 16);
|
||||
b.append((char) uc);
|
||||
i = i + 4;
|
||||
break;
|
||||
default:
|
||||
throw new FHIRLexerException("Unknown character escape \\"+s.charAt(i), currentLocation);
|
||||
}
|
||||
} else {
|
||||
b.append(ch);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
public void skipToken(String token) throws FHIRLexerException {
|
||||
if (getCurrent().equals(token))
|
||||
next();
|
||||
|
||||
}
|
||||
public String takeDottedToken() throws FHIRLexerException {
|
||||
StringBuilder b = new StringBuilder();
|
||||
b.append(take());
|
||||
while (!done() && getCurrent().equals(".")) {
|
||||
b.append(take());
|
||||
b.append(take());
|
||||
}
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
public int getCurrentStart() {
|
||||
return currentStart;
|
||||
}
|
||||
public String getSource() {
|
||||
return source;
|
||||
}
|
||||
public boolean isLiquidMode() {
|
||||
return liquidMode;
|
||||
}
|
||||
public void setLiquidMode(boolean liquidMode) {
|
||||
this.liquidMode = liquidMode;
|
||||
}
|
||||
public SourceLocation getCommentLocation() {
|
||||
return this.commentLocation;
|
||||
}
|
||||
public boolean isMetadataFormat() {
|
||||
return metadataFormat;
|
||||
}
|
||||
public void setMetadataFormat(boolean metadataFormat) {
|
||||
this.metadataFormat = metadataFormat;
|
||||
}
|
||||
public List<String> cloneComments() {
|
||||
List<String> res = new ArrayList<>();
|
||||
res.addAll(getComments());
|
||||
return res;
|
||||
}
|
||||
public String tokenWithTrailingComment(String token) {
|
||||
int line = getCurrentLocation().getLine();
|
||||
token(token);
|
||||
if (getComments().size() > 0 && getCommentLocation().getLine() == line) {
|
||||
return getFirstComment();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public boolean isAllowDoubleQuotes() {
|
||||
return allowDoubleQuotes;
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
package org.hl7.fhir.r4b.utils;
|
||||
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
|
||||
public class FHIRPathConstant {
|
||||
|
||||
public static boolean isFHIRPathConstant(String string) {
|
||||
return !Utilities.noString(string) && ((string.charAt(0) == '\'' || string.charAt(0) == '"') || string.charAt(0) == '@' || string.charAt(0) == '%' ||
|
||||
string.charAt(0) == '-' || string.charAt(0) == '+' || (string.charAt(0) >= '0' && string.charAt(0) <= '9') ||
|
||||
string.equals("true") || string.equals("false") || string.equals("{}"));
|
||||
}
|
||||
|
||||
public static boolean isFHIRPathFixedName(String string) {
|
||||
return string != null && (string.charAt(0) == '`');
|
||||
}
|
||||
|
||||
public static boolean isFHIRPathStringConstant(String string) {
|
||||
return string.charAt(0) == '\'' || string.charAt(0) == '"' || string.charAt(0) == '`';
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,198 +0,0 @@
|
|||
package org.hl7.fhir.r4b.utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.r4b.model.Base;
|
||||
import org.hl7.fhir.r4b.model.Element;
|
||||
import org.hl7.fhir.r4b.model.ElementDefinition;
|
||||
import org.hl7.fhir.r4b.model.Property;
|
||||
import org.hl7.fhir.r4b.model.Resource;
|
||||
import org.hl7.fhir.r4b.model.StringType;
|
||||
import org.hl7.fhir.r4b.model.ElementDefinition.TypeRefComponent;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
|
||||
public class FHIRPathUtilityClasses {
|
||||
|
||||
public static class FHIRConstant extends Base {
|
||||
|
||||
private static final long serialVersionUID = -8933773658248269439L;
|
||||
private String value;
|
||||
|
||||
public FHIRConstant(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String fhirType() {
|
||||
return "%constant";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void listChildren(List<Property> result) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdBase() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIdBase(String value) {
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String primitiveValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Base copy() {
|
||||
throw new Error("Not Implemented");
|
||||
}
|
||||
}
|
||||
|
||||
public static class ClassTypeInfo extends Base {
|
||||
private static final long serialVersionUID = 4909223114071029317L;
|
||||
private Base instance;
|
||||
|
||||
public ClassTypeInfo(Base instance) {
|
||||
super();
|
||||
this.instance = instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String fhirType() {
|
||||
return "ClassInfo";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void listChildren(List<Property> result) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdBase() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIdBase(String value) {
|
||||
}
|
||||
|
||||
public Base[] getProperty(int hash, String name, boolean checkValid) throws FHIRException {
|
||||
if (name.equals("name")) {
|
||||
return new Base[] { new StringType(getName()) };
|
||||
} else if (name.equals("namespace")) {
|
||||
return new Base[] { new StringType(getNamespace()) };
|
||||
} else {
|
||||
return super.getProperty(hash, name, checkValid);
|
||||
}
|
||||
}
|
||||
|
||||
private String getNamespace() {
|
||||
if ((instance instanceof Resource)) {
|
||||
return "FHIR";
|
||||
} else if (!(instance instanceof Element) || ((Element) instance).isDisallowExtensions()) {
|
||||
return "System";
|
||||
} else {
|
||||
return "FHIR";
|
||||
}
|
||||
}
|
||||
|
||||
private String getName() {
|
||||
if ((instance instanceof Resource)) {
|
||||
return instance.fhirType();
|
||||
} else if (!(instance instanceof Element) || ((Element) instance).isDisallowExtensions()) {
|
||||
return Utilities.capitalize(instance.fhirType());
|
||||
} else {
|
||||
return instance.fhirType();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Base copy() {
|
||||
throw new Error("Not Implemented");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class TypedElementDefinition {
|
||||
private ElementDefinition element;
|
||||
private String type;
|
||||
|
||||
public TypedElementDefinition(ElementDefinition element, String type) {
|
||||
super();
|
||||
this.element = element;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public TypedElementDefinition(ElementDefinition element) {
|
||||
super();
|
||||
this.element = element;
|
||||
}
|
||||
|
||||
public ElementDefinition getElement() {
|
||||
return element;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public List<TypeRefComponent> getTypes() {
|
||||
List<TypeRefComponent> res = new ArrayList<ElementDefinition.TypeRefComponent>();
|
||||
for (TypeRefComponent tr : element.getType()) {
|
||||
if (type == null || type.equals(tr.getCode())) {
|
||||
res.add(tr);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public boolean hasType(String tn) {
|
||||
if (type != null) {
|
||||
return tn.equals(type);
|
||||
} else {
|
||||
for (TypeRefComponent t : element.getType()) {
|
||||
if (tn.equals(t.getCode())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class FunctionDetails {
|
||||
private String description;
|
||||
private int minParameters;
|
||||
private int maxParameters;
|
||||
|
||||
public FunctionDetails(String description, int minParameters, int maxParameters) {
|
||||
super();
|
||||
this.description = description;
|
||||
this.minParameters = minParameters;
|
||||
this.maxParameters = maxParameters;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public int getMinParameters() {
|
||||
return minParameters;
|
||||
}
|
||||
|
||||
public int getMaxParameters() {
|
||||
return maxParameters;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,739 +0,0 @@
|
|||
package org.hl7.fhir.r5.model;
|
||||
|
||||
/*
|
||||
Copyright (c) 2011+, HL7, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of HL7 nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.utilities.SourceLocation;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
|
||||
public class ExpressionNode {
|
||||
|
||||
public enum Kind {
|
||||
Name, Function, Constant, Group, Unary
|
||||
}
|
||||
|
||||
public enum Function {
|
||||
Custom,
|
||||
|
||||
Empty, Not, Exists, SubsetOf, SupersetOf, IsDistinct, Distinct, Count, Where, Select, All, Repeat, Aggregate, Item /*implicit from name[]*/, As, Is, Single,
|
||||
First, Last, Tail, Skip, Take, Union, Combine, Intersect, Exclude, Iif, Upper, Lower, ToChars, IndexOf, Substring, StartsWith, EndsWith, Matches, MatchesFull, ReplaceMatches, Contains, Replace, Length,
|
||||
Children, Descendants, MemberOf, Trace, Check, Today, Now, Resolve, Extension, AllFalse, AnyFalse, AllTrue, AnyTrue,
|
||||
HasValue, OfType, Type, ConvertsToBoolean, ConvertsToInteger, ConvertsToString, ConvertsToDecimal, ConvertsToQuantity, ConvertsToDateTime, ConvertsToDate, ConvertsToTime, ToBoolean, ToInteger, ToString, ToDecimal, ToQuantity, ToDateTime, ToTime, ConformsTo,
|
||||
Round, Sqrt, Abs, Ceiling, Exp, Floor, Ln, Log, Power, Truncate,
|
||||
|
||||
// R3 functions
|
||||
Encode, Decode, Escape, Unescape, Trim, Split, Join, LowBoundary, HighBoundary, Precision,
|
||||
|
||||
// Local extensions to FHIRPath
|
||||
HtmlChecks1, HtmlChecks2, AliasAs, Alias, Comparable, hasTemplateIdOf;
|
||||
|
||||
public static Function fromCode(String name) {
|
||||
if (name.equals("empty")) return Function.Empty;
|
||||
if (name.equals("not")) return Function.Not;
|
||||
if (name.equals("exists")) return Function.Exists;
|
||||
if (name.equals("subsetOf")) return Function.SubsetOf;
|
||||
if (name.equals("supersetOf")) return Function.SupersetOf;
|
||||
if (name.equals("isDistinct")) return Function.IsDistinct;
|
||||
if (name.equals("distinct")) return Function.Distinct;
|
||||
if (name.equals("count")) return Function.Count;
|
||||
if (name.equals("where")) return Function.Where;
|
||||
if (name.equals("select")) return Function.Select;
|
||||
if (name.equals("all")) return Function.All;
|
||||
if (name.equals("repeat")) return Function.Repeat;
|
||||
if (name.equals("aggregate")) return Function.Aggregate;
|
||||
if (name.equals("item")) return Function.Item;
|
||||
if (name.equals("as")) return Function.As;
|
||||
if (name.equals("is")) return Function.Is;
|
||||
if (name.equals("single")) return Function.Single;
|
||||
if (name.equals("first")) return Function.First;
|
||||
if (name.equals("last")) return Function.Last;
|
||||
if (name.equals("tail")) return Function.Tail;
|
||||
if (name.equals("skip")) return Function.Skip;
|
||||
if (name.equals("take")) return Function.Take;
|
||||
if (name.equals("union")) return Function.Union;
|
||||
if (name.equals("combine")) return Function.Combine;
|
||||
if (name.equals("intersect")) return Function.Intersect;
|
||||
if (name.equals("exclude")) return Function.Exclude;
|
||||
if (name.equals("iif")) return Function.Iif;
|
||||
if (name.equals("lower")) return Function.Lower;
|
||||
if (name.equals("upper")) return Function.Upper;
|
||||
if (name.equals("toChars")) return Function.ToChars;
|
||||
if (name.equals("indexOf")) return Function.IndexOf;
|
||||
if (name.equals("substring")) return Function.Substring;
|
||||
if (name.equals("startsWith")) return Function.StartsWith;
|
||||
if (name.equals("endsWith")) return Function.EndsWith;
|
||||
if (name.equals("matches")) return Function.Matches;
|
||||
if (name.equals("matchesFull")) return Function.MatchesFull;
|
||||
if (name.equals("replaceMatches")) return Function.ReplaceMatches;
|
||||
if (name.equals("contains")) return Function.Contains;
|
||||
if (name.equals("replace")) return Function.Replace;
|
||||
if (name.equals("length")) return Function.Length;
|
||||
if (name.equals("children")) return Function.Children;
|
||||
if (name.equals("descendants")) return Function.Descendants;
|
||||
if (name.equals("memberOf")) return Function.MemberOf;
|
||||
if (name.equals("trace")) return Function.Trace;
|
||||
if (name.equals("check")) return Function.Check;
|
||||
if (name.equals("today")) return Function.Today;
|
||||
if (name.equals("now")) return Function.Now;
|
||||
if (name.equals("resolve")) return Function.Resolve;
|
||||
if (name.equals("extension")) return Function.Extension;
|
||||
if (name.equals("allFalse")) return Function.AllFalse;
|
||||
if (name.equals("anyFalse")) return Function.AnyFalse;
|
||||
if (name.equals("allTrue")) return Function.AllTrue;
|
||||
if (name.equals("anyTrue")) return Function.AnyTrue;
|
||||
if (name.equals("hasValue")) return Function.HasValue;
|
||||
if (name.equals("alias")) return Function.Alias;
|
||||
if (name.equals("aliasAs")) return Function.AliasAs;
|
||||
if (name.equals("htmlChecks")) return Function.HtmlChecks1;
|
||||
if (name.equals("htmlchecks")) return Function.HtmlChecks1; // support change of care from R3
|
||||
if (name.equals("htmlChecks2")) return Function.HtmlChecks2;
|
||||
if (name.equals("comparable")) return Function.Comparable;
|
||||
if (name.equals("encode")) return Function.Encode;
|
||||
if (name.equals("decode")) return Function.Decode;
|
||||
if (name.equals("escape")) return Function.Escape;
|
||||
if (name.equals("unescape")) return Function.Unescape;
|
||||
if (name.equals("trim")) return Function.Trim;
|
||||
if (name.equals("split")) return Function.Split;
|
||||
if (name.equals("join")) return Function.Join;
|
||||
if (name.equals("ofType")) return Function.OfType;
|
||||
if (name.equals("type")) return Function.Type;
|
||||
if (name.equals("toInteger")) return Function.ToInteger;
|
||||
if (name.equals("toDecimal")) return Function.ToDecimal;
|
||||
if (name.equals("toString")) return Function.ToString;
|
||||
if (name.equals("toQuantity")) return Function.ToQuantity;
|
||||
if (name.equals("toBoolean")) return Function.ToBoolean;
|
||||
if (name.equals("toDateTime")) return Function.ToDateTime;
|
||||
if (name.equals("toTime")) return Function.ToTime;
|
||||
if (name.equals("convertsToInteger")) return Function.ConvertsToInteger;
|
||||
if (name.equals("convertsToDecimal")) return Function.ConvertsToDecimal;
|
||||
if (name.equals("convertsToString")) return Function.ConvertsToString;
|
||||
if (name.equals("convertsToQuantity")) return Function.ConvertsToQuantity;
|
||||
if (name.equals("convertsToBoolean")) return Function.ConvertsToBoolean;
|
||||
if (name.equals("convertsToDateTime")) return Function.ConvertsToDateTime;
|
||||
if (name.equals("convertsToDate")) return Function.ConvertsToDate;
|
||||
if (name.equals("convertsToTime")) return Function.ConvertsToTime;
|
||||
if (name.equals("conformsTo")) return Function.ConformsTo;
|
||||
if (name.equals("round")) return Function.Round;
|
||||
if (name.equals("sqrt")) return Function.Sqrt;
|
||||
if (name.equals("abs")) return Function.Abs;
|
||||
if (name.equals("ceiling")) return Function.Ceiling;
|
||||
if (name.equals("exp")) return Function.Exp;
|
||||
if (name.equals("floor")) return Function.Floor;
|
||||
if (name.equals("ln")) return Function.Ln;
|
||||
if (name.equals("log")) return Function.Log;
|
||||
if (name.equals("power")) return Function.Power;
|
||||
if (name.equals("truncate")) return Function.Truncate;
|
||||
if (name.equals("lowBoundary")) return Function.LowBoundary;
|
||||
if (name.equals("highBoundary")) return Function.HighBoundary;
|
||||
if (name.equals("precision")) return Function.Precision;
|
||||
if (name.equals("hasTemplateIdOf")) return Function.hasTemplateIdOf;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public String toCode() {
|
||||
switch (this) {
|
||||
case Empty : return "empty";
|
||||
case Not : return "not";
|
||||
case Exists : return "exists";
|
||||
case SubsetOf : return "subsetOf";
|
||||
case SupersetOf : return "supersetOf";
|
||||
case IsDistinct : return "isDistinct";
|
||||
case Distinct : return "distinct";
|
||||
case Count : return "count";
|
||||
case Where : return "where";
|
||||
case Select : return "select";
|
||||
case All : return "all";
|
||||
case Repeat : return "repeat";
|
||||
case Aggregate : return "aggregate";
|
||||
case Item : return "item";
|
||||
case As : return "as";
|
||||
case Is : return "is";
|
||||
case Single : return "single";
|
||||
case First : return "first";
|
||||
case Last : return "last";
|
||||
case Tail : return "tail";
|
||||
case Skip : return "skip";
|
||||
case Take : return "take";
|
||||
case Union : return "union";
|
||||
case Combine : return "combine";
|
||||
case Intersect : return "intersect";
|
||||
case Exclude : return "exclude";
|
||||
case Iif : return "iif";
|
||||
case ToChars : return "toChars";
|
||||
case Lower : return "lower";
|
||||
case Upper : return "upper";
|
||||
case IndexOf : return "indexOf";
|
||||
case Substring : return "substring";
|
||||
case StartsWith : return "startsWith";
|
||||
case EndsWith : return "endsWith";
|
||||
case Matches : return "matches";
|
||||
case MatchesFull : return "matchesFull";
|
||||
case ReplaceMatches : return "replaceMatches";
|
||||
case Contains : return "contains";
|
||||
case Replace : return "replace";
|
||||
case Length : return "length";
|
||||
case Children : return "children";
|
||||
case Descendants : return "descendants";
|
||||
case MemberOf : return "memberOf";
|
||||
case Trace : return "trace";
|
||||
case Check : return "check";
|
||||
case Today : return "today";
|
||||
case Now : return "now";
|
||||
case Resolve : return "resolve";
|
||||
case Extension : return "extension";
|
||||
case AllFalse : return "allFalse";
|
||||
case AnyFalse : return "anyFalse";
|
||||
case AllTrue : return "allTrue";
|
||||
case AnyTrue : return "anyTrue";
|
||||
case HasValue : return "hasValue";
|
||||
case Alias : return "alias";
|
||||
case AliasAs : return "aliasAs";
|
||||
case Encode : return "encode";
|
||||
case Decode : return "decode";
|
||||
case Escape : return "escape";
|
||||
case Unescape : return "unescape";
|
||||
case Trim : return "trim";
|
||||
case Split : return "split";
|
||||
case Join : return "join";
|
||||
case HtmlChecks1 : return "htmlChecks";
|
||||
case HtmlChecks2 : return "htmlChecks2";
|
||||
case Comparable : return "comparable";
|
||||
case OfType : return "ofType";
|
||||
case Type : return "type";
|
||||
case ToInteger : return "toInteger";
|
||||
case ToDecimal : return "toDecimal";
|
||||
case ToString : return "toString";
|
||||
case ToBoolean : return "toBoolean";
|
||||
case ToQuantity : return "toQuantity";
|
||||
case ToDateTime : return "toDateTime";
|
||||
case ToTime : return "toTime";
|
||||
case ConvertsToInteger : return "convertsToInteger";
|
||||
case ConvertsToDecimal : return "convertsToDecimal";
|
||||
case ConvertsToString : return "convertsToString";
|
||||
case ConvertsToBoolean : return "convertsToBoolean";
|
||||
case ConvertsToQuantity : return "convertsToQuantity";
|
||||
case ConvertsToDateTime : return "convertsToDateTime";
|
||||
case ConvertsToDate : return "convertsToDate";
|
||||
case ConvertsToTime : return "isTime";
|
||||
case ConformsTo : return "conformsTo";
|
||||
case Round : return "round";
|
||||
case Sqrt : return "sqrt";
|
||||
case Abs : return "abs";
|
||||
case Ceiling : return "ceiling";
|
||||
case Exp : return "exp";
|
||||
case Floor : return "floor";
|
||||
case Ln : return "ln";
|
||||
case Log : return "log";
|
||||
case Power : return "power";
|
||||
case Truncate: return "truncate";
|
||||
case LowBoundary: return "lowBoundary";
|
||||
case HighBoundary: return "highBoundary";
|
||||
case Precision: return "precision";
|
||||
case hasTemplateIdOf: return "hasTemplateIdOf";
|
||||
default: return "?custom?";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum Operation {
|
||||
Equals, Equivalent, NotEquals, NotEquivalent, LessThan, Greater, LessOrEqual, GreaterOrEqual, Is, As, Union, Or, And, Xor, Implies,
|
||||
Times, DivideBy, Plus, Minus, Concatenate, Div, Mod, In, Contains, MemberOf;
|
||||
|
||||
public static Operation fromCode(String name) {
|
||||
if (Utilities.noString(name))
|
||||
return null;
|
||||
if (name.equals("="))
|
||||
return Operation.Equals;
|
||||
if (name.equals("~"))
|
||||
return Operation.Equivalent;
|
||||
if (name.equals("!="))
|
||||
return Operation.NotEquals;
|
||||
if (name.equals("!~"))
|
||||
return Operation.NotEquivalent;
|
||||
if (name.equals(">"))
|
||||
return Operation.Greater;
|
||||
if (name.equals("<"))
|
||||
return Operation.LessThan;
|
||||
if (name.equals(">="))
|
||||
return Operation.GreaterOrEqual;
|
||||
if (name.equals("<="))
|
||||
return Operation.LessOrEqual;
|
||||
if (name.equals("|"))
|
||||
return Operation.Union;
|
||||
if (name.equals("or"))
|
||||
return Operation.Or;
|
||||
if (name.equals("and"))
|
||||
return Operation.And;
|
||||
if (name.equals("xor"))
|
||||
return Operation.Xor;
|
||||
if (name.equals("is"))
|
||||
return Operation.Is;
|
||||
if (name.equals("as"))
|
||||
return Operation.As;
|
||||
if (name.equals("*"))
|
||||
return Operation.Times;
|
||||
if (name.equals("/"))
|
||||
return Operation.DivideBy;
|
||||
if (name.equals("+"))
|
||||
return Operation.Plus;
|
||||
if (name.equals("-"))
|
||||
return Operation.Minus;
|
||||
if (name.equals("&"))
|
||||
return Operation.Concatenate;
|
||||
if (name.equals("implies"))
|
||||
return Operation.Implies;
|
||||
if (name.equals("div"))
|
||||
return Operation.Div;
|
||||
if (name.equals("mod"))
|
||||
return Operation.Mod;
|
||||
if (name.equals("in"))
|
||||
return Operation.In;
|
||||
if (name.equals("contains"))
|
||||
return Operation.Contains;
|
||||
if (name.equals("memberOf"))
|
||||
return Operation.MemberOf;
|
||||
return null;
|
||||
|
||||
}
|
||||
public String toCode() {
|
||||
switch (this) {
|
||||
case Equals : return "=";
|
||||
case Equivalent : return "~";
|
||||
case NotEquals : return "!=";
|
||||
case NotEquivalent : return "!~";
|
||||
case Greater : return ">";
|
||||
case LessThan : return "<";
|
||||
case GreaterOrEqual : return ">=";
|
||||
case LessOrEqual : return "<=";
|
||||
case Union : return "|";
|
||||
case Or : return "or";
|
||||
case And : return "and";
|
||||
case Xor : return "xor";
|
||||
case Times : return "*";
|
||||
case DivideBy : return "/";
|
||||
case Plus : return "+";
|
||||
case Minus : return "-";
|
||||
case Concatenate : return "&";
|
||||
case Implies : return "implies";
|
||||
case Is : return "is";
|
||||
case As : return "as";
|
||||
case Div : return "div";
|
||||
case Mod : return "mod";
|
||||
case In : return "in";
|
||||
case Contains : return "contains";
|
||||
case MemberOf : return "memberOf";
|
||||
default: return "?custom?";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum CollectionStatus {
|
||||
SINGLETON, ORDERED, UNORDERED;
|
||||
|
||||
boolean isList() {
|
||||
return this == ORDERED || this == UNORDERED;
|
||||
}
|
||||
}
|
||||
|
||||
//the expression will have one of either name or constant
|
||||
private String uniqueId;
|
||||
private Kind kind;
|
||||
private String name;
|
||||
private Base constant;
|
||||
private Function function;
|
||||
private List<ExpressionNode> parameters; // will be created if there is a function
|
||||
private ExpressionNode inner;
|
||||
private ExpressionNode group;
|
||||
private Operation operation;
|
||||
private boolean proximal; // a proximal operation is the first in the sequence of operations. This is significant when evaluating the outcomes
|
||||
private ExpressionNode opNext;
|
||||
private SourceLocation start;
|
||||
private SourceLocation end;
|
||||
private SourceLocation opStart;
|
||||
private SourceLocation opEnd;
|
||||
private TypeDetails types;
|
||||
private TypeDetails opTypes;
|
||||
|
||||
|
||||
public ExpressionNode(int uniqueId) {
|
||||
super();
|
||||
this.uniqueId = Integer.toString(uniqueId);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder b = new StringBuilder();
|
||||
switch (kind) {
|
||||
case Name:
|
||||
b.append(name);
|
||||
break;
|
||||
case Function:
|
||||
if (function == Function.Item)
|
||||
b.append("[");
|
||||
else {
|
||||
b.append(name);
|
||||
b.append("(");
|
||||
}
|
||||
boolean first = true;
|
||||
for (ExpressionNode n : parameters) {
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
b.append(", ");
|
||||
b.append(n.toString());
|
||||
}
|
||||
if (function == Function.Item) {
|
||||
b.append("]");
|
||||
} else {
|
||||
b.append(")");
|
||||
}
|
||||
break;
|
||||
case Constant:
|
||||
if (constant == null) {
|
||||
b.append("{}");
|
||||
} else if (constant instanceof StringType) {
|
||||
b.append("'" + Utilities.escapeJson(constant.primitiveValue()) + "'");
|
||||
} else if (constant instanceof Quantity) {
|
||||
Quantity q = (Quantity) constant;
|
||||
b.append(Utilities.escapeJson(q.getValue().toPlainString()));
|
||||
if (q.hasUnit() || q.hasCode()) {
|
||||
b.append(" '");
|
||||
if (q.hasUnit()) {
|
||||
b.append(Utilities.escapeJson(q.getUnit()));
|
||||
} else {
|
||||
b.append(Utilities.escapeJson(q.getCode()));
|
||||
}
|
||||
b.append("'");
|
||||
}
|
||||
} else if (constant.primitiveValue() != null) {
|
||||
b.append(Utilities.escapeJson(constant.primitiveValue()));
|
||||
} else {
|
||||
b.append(Utilities.escapeJson(constant.toString()));
|
||||
}
|
||||
break;
|
||||
case Group:
|
||||
b.append("(");
|
||||
b.append(group.toString());
|
||||
b.append(")");
|
||||
}
|
||||
if (inner != null) {
|
||||
if (!((ExpressionNode.Kind.Function == inner.getKind()) && (ExpressionNode.Function.Item == inner.getFunction()))) {
|
||||
b.append(".");
|
||||
}
|
||||
b.append(inner.toString());
|
||||
}
|
||||
if (operation != null) {
|
||||
b.append(" ");
|
||||
b.append(operation.toCode());
|
||||
b.append(" ");
|
||||
b.append(opNext.toString());
|
||||
}
|
||||
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
public Base getConstant() {
|
||||
return constant;
|
||||
}
|
||||
public void setConstant(Base constant) {
|
||||
this.constant = constant;
|
||||
}
|
||||
|
||||
public Function getFunction() {
|
||||
return function;
|
||||
}
|
||||
public void setFunction(Function function) {
|
||||
this.function = function;
|
||||
if (parameters == null)
|
||||
parameters = new ArrayList<ExpressionNode>();
|
||||
}
|
||||
|
||||
public boolean isProximal() {
|
||||
return proximal;
|
||||
}
|
||||
public void setProximal(boolean proximal) {
|
||||
this.proximal = proximal;
|
||||
}
|
||||
public Operation getOperation() {
|
||||
return operation;
|
||||
}
|
||||
public void setOperation(Operation operation) {
|
||||
this.operation = operation;
|
||||
}
|
||||
public ExpressionNode getInner() {
|
||||
return inner;
|
||||
}
|
||||
public void setInner(ExpressionNode value) {
|
||||
this.inner = value;
|
||||
}
|
||||
public ExpressionNode getOpNext() {
|
||||
return opNext;
|
||||
}
|
||||
public void setOpNext(ExpressionNode value) {
|
||||
this.opNext = value;
|
||||
}
|
||||
public List<ExpressionNode> getParameters() {
|
||||
return parameters;
|
||||
}
|
||||
public boolean checkName() {
|
||||
if (!name.startsWith("$"))
|
||||
return true;
|
||||
else
|
||||
return Utilities.existsInList(name, "$this", "$total", "$index");
|
||||
}
|
||||
|
||||
public Kind getKind() {
|
||||
return kind;
|
||||
}
|
||||
|
||||
public void setKind(Kind kind) {
|
||||
this.kind = kind;
|
||||
}
|
||||
|
||||
public ExpressionNode getGroup() {
|
||||
return group;
|
||||
}
|
||||
|
||||
public void setGroup(ExpressionNode group) {
|
||||
this.group = group;
|
||||
}
|
||||
|
||||
public SourceLocation getStart() {
|
||||
return start;
|
||||
}
|
||||
|
||||
public void setStart(SourceLocation start) {
|
||||
this.start = start;
|
||||
}
|
||||
|
||||
public SourceLocation getEnd() {
|
||||
return end;
|
||||
}
|
||||
|
||||
public void setEnd(SourceLocation end) {
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
public SourceLocation getOpStart() {
|
||||
return opStart;
|
||||
}
|
||||
|
||||
public void setOpStart(SourceLocation opStart) {
|
||||
this.opStart = opStart;
|
||||
}
|
||||
|
||||
public SourceLocation getOpEnd() {
|
||||
return opEnd;
|
||||
}
|
||||
|
||||
public void setOpEnd(SourceLocation opEnd) {
|
||||
this.opEnd = opEnd;
|
||||
}
|
||||
|
||||
public String getUniqueId() {
|
||||
return uniqueId;
|
||||
}
|
||||
|
||||
|
||||
public int parameterCount() {
|
||||
if (parameters == null)
|
||||
return 0;
|
||||
else
|
||||
return parameters.size();
|
||||
}
|
||||
|
||||
public String Canonical() {
|
||||
StringBuilder b = new StringBuilder();
|
||||
write(b);
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
public String summary() {
|
||||
switch (kind) {
|
||||
case Name: return uniqueId+": "+name;
|
||||
case Function: return uniqueId+": "+function.toString()+"()";
|
||||
case Constant: return uniqueId+": "+constant;
|
||||
case Group: return uniqueId+": (Group)";
|
||||
}
|
||||
return "?exp-kind?";
|
||||
}
|
||||
|
||||
private void write(StringBuilder b) {
|
||||
|
||||
switch (kind) {
|
||||
case Name:
|
||||
b.append(name);
|
||||
break;
|
||||
case Constant:
|
||||
b.append(constant);
|
||||
break;
|
||||
case Function:
|
||||
b.append(function.toCode());
|
||||
b.append('(');
|
||||
boolean f = true;
|
||||
for (ExpressionNode n : parameters) {
|
||||
if (f)
|
||||
f = false;
|
||||
else
|
||||
b.append(", ");
|
||||
n.write(b);
|
||||
}
|
||||
b.append(')');
|
||||
|
||||
break;
|
||||
case Group:
|
||||
b.append('(');
|
||||
group.write(b);
|
||||
b.append(')');
|
||||
}
|
||||
|
||||
if (inner != null) {
|
||||
b.append('.');
|
||||
inner.write(b);
|
||||
}
|
||||
if (operation != null) {
|
||||
b.append(' ');
|
||||
b.append(operation.toCode());
|
||||
b.append(' ');
|
||||
opNext.write(b);
|
||||
}
|
||||
}
|
||||
|
||||
public String check() {
|
||||
|
||||
if (kind == null) {
|
||||
return "Error in expression - node has no kind";
|
||||
}
|
||||
switch (kind) {
|
||||
case Name:
|
||||
if (Utilities.noString(name))
|
||||
return "No Name provided @ "+location();
|
||||
break;
|
||||
|
||||
case Function:
|
||||
if (function == null)
|
||||
return "No Function id provided @ "+location();
|
||||
for (ExpressionNode n : parameters) {
|
||||
String msg = n.check();
|
||||
if (msg != null)
|
||||
return msg;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Unary:
|
||||
break;
|
||||
case Constant:
|
||||
if (constant == null)
|
||||
return "No Constant provided @ "+location();
|
||||
break;
|
||||
|
||||
case Group:
|
||||
if (group == null)
|
||||
return "No Group provided @ "+location();
|
||||
else {
|
||||
String msg = group.check();
|
||||
if (msg != null)
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
if (inner != null) {
|
||||
String msg = inner.check();
|
||||
if (msg != null)
|
||||
return msg;
|
||||
}
|
||||
if (operation == null) {
|
||||
|
||||
if (opNext != null)
|
||||
return "Next provided when it shouldn't be @ "+location();
|
||||
}
|
||||
else {
|
||||
if (opNext == null)
|
||||
return "No Next provided @ "+location();
|
||||
else
|
||||
opNext.check();
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
private String location() {
|
||||
return Integer.toString(start.getLine())+", "+Integer.toString(start.getColumn());
|
||||
}
|
||||
|
||||
public TypeDetails getTypes() {
|
||||
return types;
|
||||
}
|
||||
|
||||
public void setTypes(TypeDetails types) {
|
||||
this.types = types;
|
||||
}
|
||||
|
||||
public TypeDetails getOpTypes() {
|
||||
return opTypes;
|
||||
}
|
||||
|
||||
public void setOpTypes(TypeDetails opTypes) {
|
||||
this.opTypes = opTypes;
|
||||
}
|
||||
|
||||
public List<String> getDistalNames() {
|
||||
List<String> names = new ArrayList<String>();
|
||||
if (operation != null) {
|
||||
names.add(null);
|
||||
} else if (inner != null) {
|
||||
names.addAll(inner.getDistalNames());
|
||||
} else if (group != null) {
|
||||
names.addAll(group.getDistalNames());
|
||||
} else if (function != null) {
|
||||
names.add(null);
|
||||
} else if (constant != null) {
|
||||
names.add(null);
|
||||
} else {
|
||||
names.add(name);
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
public boolean isNullSet() {
|
||||
return kind == Kind.Constant && constant == null;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,590 +0,0 @@
|
|||
package org.hl7.fhir.r5.model;
|
||||
|
||||
/*
|
||||
Copyright (c) 2011+, HL7, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of HL7 nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hl7.fhir.exceptions.DefinitionException;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionBindingComponent;
|
||||
import org.hl7.fhir.r5.model.ExpressionNode.CollectionStatus;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionKind;
|
||||
import org.hl7.fhir.r5.model.TypeDetails.ProfiledTypeSorter;
|
||||
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
|
||||
|
||||
public class TypeDetails {
|
||||
public class ProfiledTypeSorter implements Comparator<ProfiledType> {
|
||||
|
||||
@Override
|
||||
public int compare(ProfiledType o1, ProfiledType o2) {
|
||||
return o1.uri.compareTo(o2.uri);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static final String FHIR_NS = "http://hl7.org/fhir/StructureDefinition/";
|
||||
public static final String FP_NS = "http://hl7.org/fhirpath/";
|
||||
public static final String FP_String = "http://hl7.org/fhirpath/System.String";
|
||||
public static final String FP_Boolean = "http://hl7.org/fhirpath/System.Boolean";
|
||||
public static final String FP_Integer = "http://hl7.org/fhirpath/System.Integer";
|
||||
public static final String FP_Decimal = "http://hl7.org/fhirpath/System.Decimal";
|
||||
public static final String FP_Quantity = "http://hl7.org/fhirpath/System.Quantity";
|
||||
public static final String FP_DateTime = "http://hl7.org/fhirpath/System.DateTime";
|
||||
public static final String FP_Time = "http://hl7.org/fhirpath/System.Time";
|
||||
public static final String FP_SimpleTypeInfo = "http://hl7.org/fhirpath/System.SimpleTypeInfo";
|
||||
public static final String FP_ClassInfo = "http://hl7.org/fhirpath/System.ClassInfo";
|
||||
public static final Set<String> FP_NUMBERS = new HashSet<String>(Arrays.asList(FP_Integer, FP_Decimal));
|
||||
|
||||
public static class ProfiledType {
|
||||
@Override
|
||||
public String toString() {
|
||||
return uri;
|
||||
}
|
||||
|
||||
private String uri;
|
||||
private List<String> profiles; // or, not and
|
||||
private List<ElementDefinitionBindingComponent> bindings;
|
||||
|
||||
public ProfiledType(String n) {
|
||||
uri = ns(n);
|
||||
if (uri.equals("http://hl7.org/fhir/StructureDefinition/CDA")) {
|
||||
System.out.println("!"); // #FIXME
|
||||
}
|
||||
}
|
||||
|
||||
public String getUri() {
|
||||
return uri;
|
||||
}
|
||||
|
||||
public boolean hasProfiles() {
|
||||
return profiles != null && profiles.size() > 0;
|
||||
}
|
||||
public List<String> getProfiles() {
|
||||
return profiles;
|
||||
}
|
||||
|
||||
public boolean hasBindings() {
|
||||
return bindings != null && bindings.size() > 0;
|
||||
}
|
||||
public List<ElementDefinitionBindingComponent> getBindings() {
|
||||
return bindings;
|
||||
}
|
||||
|
||||
public static String ns(String n) {
|
||||
return Utilities.isAbsoluteUrl(n) ? n : FHIR_NS+n;
|
||||
}
|
||||
|
||||
public void addProfile(String profile) {
|
||||
if (profiles == null)
|
||||
profiles = new ArrayList<String>();
|
||||
profiles.add(profile);
|
||||
}
|
||||
|
||||
public void addBinding(ElementDefinitionBindingComponent binding) {
|
||||
bindings = new ArrayList<ElementDefinitionBindingComponent>();
|
||||
bindings.add(binding);
|
||||
}
|
||||
|
||||
public boolean hasBinding(ElementDefinitionBindingComponent b) {
|
||||
return false; // todo: do we need to do this?
|
||||
}
|
||||
|
||||
public void addProfiles(List<CanonicalType> list) {
|
||||
if (profiles == null)
|
||||
profiles = new ArrayList<String>();
|
||||
for (UriType u : list)
|
||||
profiles.add(u.getValue());
|
||||
}
|
||||
public boolean isSystemType() {
|
||||
return uri.startsWith(FP_NS);
|
||||
}
|
||||
|
||||
public String describeMin() {
|
||||
if (uri.startsWith(FP_NS)) {
|
||||
return "System."+uri.substring(FP_NS.length());
|
||||
}
|
||||
if (uri.startsWith("http://hl7.org/fhir/StructureDefinition/")) {
|
||||
return "FHIR."+uri.substring("http://hl7.org/fhir/StructureDefinition/".length());
|
||||
}
|
||||
return uri;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private List<ProfiledType> types = new ArrayList<ProfiledType>();
|
||||
private CollectionStatus collectionStatus;
|
||||
private Set<String> targets; // or, not and, canonical urls
|
||||
private boolean choice;
|
||||
|
||||
public TypeDetails(CollectionStatus collectionStatus, String... names) {
|
||||
super();
|
||||
this.collectionStatus = collectionStatus;
|
||||
for (String n : names) {
|
||||
this.types.add(new ProfiledType(n));
|
||||
}
|
||||
}
|
||||
public TypeDetails(CollectionStatus collectionStatus, Set<String> names) {
|
||||
super();
|
||||
this.collectionStatus = collectionStatus;
|
||||
for (String n : names) {
|
||||
addType(new ProfiledType(n));
|
||||
}
|
||||
}
|
||||
public TypeDetails(CollectionStatus collectionStatus, ProfiledType pt) {
|
||||
super();
|
||||
this.collectionStatus = collectionStatus;
|
||||
this.types.add(pt);
|
||||
}
|
||||
|
||||
private TypeDetails() {
|
||||
}
|
||||
|
||||
public String addType(String n) {
|
||||
ProfiledType pt = new ProfiledType(n);
|
||||
String res = pt.uri;
|
||||
addType(pt);
|
||||
return res;
|
||||
}
|
||||
public String addType(String n, String p) {
|
||||
ProfiledType pt = new ProfiledType(n);
|
||||
pt.addProfile(p);
|
||||
String res = pt.uri;
|
||||
addType(pt);
|
||||
return res;
|
||||
}
|
||||
|
||||
public void addType(ProfiledType pt) {
|
||||
for (ProfiledType et : types) {
|
||||
if (et.uri.equals(pt.uri)) {
|
||||
if (pt.profiles != null) {
|
||||
for (String p : pt.profiles) {
|
||||
if (et.profiles == null)
|
||||
et.profiles = new ArrayList<String>();
|
||||
if (!et.profiles.contains(p))
|
||||
et.profiles.add(p);
|
||||
}
|
||||
}
|
||||
if (pt.bindings != null) {
|
||||
for (ElementDefinitionBindingComponent b : pt.bindings) {
|
||||
if (et.bindings == null)
|
||||
et.bindings = new ArrayList<ElementDefinitionBindingComponent>();
|
||||
if (!et.hasBinding(b))
|
||||
et.bindings.add(b);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
types.add(pt);
|
||||
}
|
||||
|
||||
public void addType(CollectionStatus status, ProfiledType pt) {
|
||||
addType(pt);
|
||||
if (collectionStatus == null) {
|
||||
collectionStatus = status;
|
||||
} else {
|
||||
switch (status) {
|
||||
case ORDERED:
|
||||
if (collectionStatus == CollectionStatus.SINGLETON) {
|
||||
collectionStatus = status;
|
||||
}
|
||||
break;
|
||||
case SINGLETON:
|
||||
break;
|
||||
case UNORDERED:
|
||||
collectionStatus = status;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addTypes(Collection<String> names) {
|
||||
for (String n : names)
|
||||
addType(new ProfiledType(n));
|
||||
}
|
||||
|
||||
public boolean hasType(IWorkerContext context, String... tn) {
|
||||
for (String n: tn) {
|
||||
String t = ProfiledType.ns(n);
|
||||
if (typesContains(t))
|
||||
return true;
|
||||
if (Utilities.existsInList(n, "boolean", "string", "integer", "decimal", "Quantity", "dateTime", "time", "ClassInfo", "SimpleTypeInfo")) {
|
||||
t = FP_NS+"System."+Utilities.capitalize(n);
|
||||
if (typesContains(t)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
t = ProfiledType.ns(n);
|
||||
StructureDefinition sd = context.fetchTypeDefinition(t);
|
||||
if (sd != null && sd.getKind() != StructureDefinitionKind.LOGICAL && Utilities.existsInList(sd.getType(), "boolean", "string", "integer", "decimal", "Quantity", "dateTime", "time")) {
|
||||
t = FP_NS+"System."+Utilities.capitalize(sd.getType());
|
||||
if (typesContains(t)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (String n: tn) {
|
||||
String id = n.contains("#") ? n.substring(0, n.indexOf("#")) : n;
|
||||
String tail = null;
|
||||
if (n.contains("#")) {
|
||||
tail = n.substring( n.indexOf("#")+1);
|
||||
tail = tail.substring(tail.indexOf("."));
|
||||
}
|
||||
List<StructureDefinition> list = new ArrayList<>();
|
||||
if (!Utilities.isAbsoluteUrl(n)) {
|
||||
list.addAll(context.fetchTypeDefinitions(n));
|
||||
} else {
|
||||
String t = ProfiledType.ns(n);
|
||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, t);
|
||||
if (sd != null) {
|
||||
list.add(sd);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
StructureDefinition sd = list.get(i);
|
||||
while (sd != null) {
|
||||
if (tail == null && typesContains(sd.getUrl()))
|
||||
return true;
|
||||
if (tail == null && getSystemType(sd.getUrl()) != null && typesContains(getSystemType(sd.getUrl())))
|
||||
return true;
|
||||
if (tail != null && typesContains(sd.getUrl()+"#"+sd.getType()+tail))
|
||||
return true;
|
||||
if ("http://hl7.org/fhir/StructureDefinition/string".equals(sd.getUrl()) && typesContains(FP_String)) {
|
||||
return true; // this is work around for R3
|
||||
}
|
||||
if (sd.hasBaseDefinition()) {
|
||||
if (sd.getType().equals("uri"))
|
||||
sd = context.fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/string");
|
||||
else
|
||||
sd = context.fetchResource(StructureDefinition.class, sd.getBaseDefinition());
|
||||
} else {
|
||||
sd = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private String getSystemType(String url) {
|
||||
if (url.startsWith("http://hl7.org/fhir/StructureDefinition/")) {
|
||||
String code = url.substring(40);
|
||||
if (Utilities.existsInList(code, "string", "boolean", "integer", "decimal", "dateTime", "time", "Quantity"))
|
||||
return FP_NS+"System.."+Utilities.capitalize(code);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean typesContains(String t) {
|
||||
for (ProfiledType pt : types)
|
||||
if (pt.uri.equals(t))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public void update(TypeDetails source) {
|
||||
for (ProfiledType pt : source.types)
|
||||
addType(pt);
|
||||
if (collectionStatus == null || collectionStatus == CollectionStatus.SINGLETON)
|
||||
collectionStatus = source.collectionStatus;
|
||||
else if (source.collectionStatus == CollectionStatus.UNORDERED)
|
||||
collectionStatus = source.collectionStatus;
|
||||
else
|
||||
collectionStatus = CollectionStatus.ORDERED;
|
||||
if (source.targets != null) {
|
||||
if (targets == null) {
|
||||
targets = new HashSet<>();
|
||||
}
|
||||
targets.addAll(source.targets);
|
||||
}
|
||||
if (source.isChoice()) {
|
||||
choice = true;
|
||||
}
|
||||
}
|
||||
|
||||
public TypeDetails union(TypeDetails right) {
|
||||
TypeDetails result = new TypeDetails(null);
|
||||
if (right.collectionStatus == CollectionStatus.UNORDERED || collectionStatus == CollectionStatus.UNORDERED)
|
||||
result.collectionStatus = CollectionStatus.UNORDERED;
|
||||
else
|
||||
result.collectionStatus = CollectionStatus.ORDERED;
|
||||
for (ProfiledType pt : types)
|
||||
result.addType(pt);
|
||||
for (ProfiledType pt : right.types)
|
||||
result.addType(pt);
|
||||
if (targets != null || right.targets != null) {
|
||||
result.targets = new HashSet<>();
|
||||
if (targets != null) {
|
||||
result.targets.addAll(targets);
|
||||
}
|
||||
if (right.targets != null) {
|
||||
result.targets.addAll(right.targets);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public TypeDetails intersect(TypeDetails right) {
|
||||
TypeDetails result = new TypeDetails(null);
|
||||
if (right.collectionStatus == CollectionStatus.UNORDERED || collectionStatus == CollectionStatus.UNORDERED)
|
||||
result.collectionStatus = CollectionStatus.UNORDERED;
|
||||
else
|
||||
result.collectionStatus = CollectionStatus.ORDERED;
|
||||
for (ProfiledType pt : types) {
|
||||
boolean found = false;
|
||||
for (ProfiledType r : right.types)
|
||||
found = found || pt.uri.equals(r.uri);
|
||||
if (found)
|
||||
result.addType(pt);
|
||||
}
|
||||
for (ProfiledType pt : right.types)
|
||||
result.addType(pt);
|
||||
if (targets != null && right.targets != null) {
|
||||
result.targets = new HashSet<>();
|
||||
for (String s : targets) {
|
||||
if (right.targets.contains(s)) {
|
||||
result.targets.add(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean hasNoTypes() {
|
||||
return types.isEmpty();
|
||||
}
|
||||
public Set<String> getTypes() {
|
||||
Set<String> res = new HashSet<String>();
|
||||
for (ProfiledType pt : types)
|
||||
res.add(pt.uri);
|
||||
return res;
|
||||
}
|
||||
public TypeDetails toSingleton() {
|
||||
TypeDetails result = new TypeDetails(CollectionStatus.SINGLETON);
|
||||
result.types.addAll(types);
|
||||
return result;
|
||||
}
|
||||
public CollectionStatus getCollectionStatus() {
|
||||
return collectionStatus;
|
||||
}
|
||||
|
||||
private boolean hasType(ProfiledType pt) {
|
||||
return hasType(pt.uri);
|
||||
}
|
||||
|
||||
public boolean hasType(String n) {
|
||||
String t = ProfiledType.ns(n);
|
||||
if (typesContains(t))
|
||||
return true;
|
||||
if (Utilities.existsInList(n, "boolean", "string", "integer", "decimal", "Quantity", "date", "dateTime", "time", "ClassInfo", "SimpleTypeInfo")) {
|
||||
t = FP_NS+"System."+Utilities.capitalize(n);
|
||||
if (typesContains(t))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean hasType(Set<String> tn) {
|
||||
for (String n: tn) {
|
||||
String t = ProfiledType.ns(n);
|
||||
if (typesContains(t))
|
||||
return true;
|
||||
if (Utilities.existsInList(n, "boolean", "string", "integer", "decimal", "Quantity", "dateTime", "time", "ClassInfo", "SimpleTypeInfo")) {
|
||||
t = FP_NS+"System."+Utilities.capitalize(n);
|
||||
if (typesContains(t))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String describe() {
|
||||
return Utilities.sorted(getTypes()).toString();
|
||||
}
|
||||
|
||||
public String describeMin() {
|
||||
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder();
|
||||
for (ProfiledType pt : sortedTypes(types))
|
||||
b.append(pt.describeMin());
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
private List<ProfiledType> sortedTypes(List<ProfiledType> types2) {
|
||||
List<ProfiledType> list = new ArrayList<>();
|
||||
Collections.sort(list, new ProfiledTypeSorter());
|
||||
return list;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
for (ProfiledType pt : types)
|
||||
return pt.uri;
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return (collectionStatus == null ? collectionStatus.SINGLETON.toString() : collectionStatus.toString()) + getTypes().toString();
|
||||
}
|
||||
public String getTypeCode() throws DefinitionException {
|
||||
if (types.size() != 1)
|
||||
throw new DefinitionException("Multiple types? ("+types.toString()+")");
|
||||
for (ProfiledType pt : types)
|
||||
if (pt.uri.startsWith("http://hl7.org/fhir/StructureDefinition/"))
|
||||
return pt.uri.substring(40);
|
||||
else
|
||||
return pt.uri;
|
||||
return null;
|
||||
}
|
||||
public List<ProfiledType> getProfiledTypes() {
|
||||
return types;
|
||||
}
|
||||
public boolean hasBinding() {
|
||||
for (ProfiledType pt : types) {
|
||||
if (pt.hasBindings())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public ElementDefinitionBindingComponent getBinding() {
|
||||
for (ProfiledType pt : types) {
|
||||
for (ElementDefinitionBindingComponent b : pt.getBindings())
|
||||
return b;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public void addTarget(String url) {
|
||||
if (targets == null) {
|
||||
targets = new HashSet<>();
|
||||
}
|
||||
targets.add(url);
|
||||
}
|
||||
public Set<String> getTargets() {
|
||||
return targets;
|
||||
}
|
||||
public boolean typesHaveTargets() {
|
||||
for (ProfiledType pt : types) {
|
||||
if (Utilities.existsInList(pt.getUri(), "Reference", "CodeableReference", "canonical", "http://hl7.org/fhir/StructureDefinition/Reference", "http://hl7.org/fhir/StructureDefinition/CodeableReference", "http://hl7.org/fhir/StructureDefinition/canonical")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public void addTargets(Set<String> src) {
|
||||
if (src != null) {
|
||||
for (String s : src) {
|
||||
addTarget(s);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public TypeDetails copy() {
|
||||
TypeDetails td = new TypeDetails();
|
||||
td.types.addAll(types);
|
||||
td.collectionStatus = collectionStatus;
|
||||
if (targets != null ) {
|
||||
td.targets = new HashSet<>();
|
||||
td.targets.addAll(targets);
|
||||
}
|
||||
return td;
|
||||
}
|
||||
|
||||
public boolean matches(TypeDetails other) {
|
||||
boolean result = collectionStatus == other.collectionStatus && types.equals(other.types);
|
||||
if (targets == null) {
|
||||
return result && other.targets == null;
|
||||
} else {
|
||||
return result && targets.equals(other.targets);
|
||||
}
|
||||
|
||||
}
|
||||
public void addTypes(TypeDetails other) {
|
||||
if (other.collectionStatus != CollectionStatus.SINGLETON) {
|
||||
if (other.collectionStatus == CollectionStatus.UNORDERED || collectionStatus == CollectionStatus.UNORDERED) {
|
||||
collectionStatus = CollectionStatus.UNORDERED;
|
||||
} else {
|
||||
collectionStatus = CollectionStatus.ORDERED;
|
||||
}
|
||||
}
|
||||
for (ProfiledType pt : other.types) {
|
||||
addType(pt);
|
||||
}
|
||||
if (other.targets != null) {
|
||||
if (targets == null) {
|
||||
targets = new HashSet<>();
|
||||
}
|
||||
targets.addAll(other.targets);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean contains(TypeDetails other) {
|
||||
// TODO Auto-generated method stub
|
||||
if (other.collectionStatus != collectionStatus) {
|
||||
return false;
|
||||
}
|
||||
for (ProfiledType pt : other.types) {
|
||||
if (!hasType(pt)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public static TypeDetails empty() {
|
||||
return new TypeDetails(CollectionStatus.SINGLETON);
|
||||
}
|
||||
public boolean isList() {
|
||||
return collectionStatus != null && collectionStatus.isList();
|
||||
}
|
||||
|
||||
// for SQL-on-FHIR: warnings when .ofType() is not paired with a choice element
|
||||
public void setChoice(boolean b) {
|
||||
choice = true;
|
||||
}
|
||||
public boolean isChoice() {
|
||||
return choice;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,603 +0,0 @@
|
|||
package org.hl7.fhir.r5.utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
|
||||
/*
|
||||
Copyright (c) 2011+, HL7, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of HL7 nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
import org.hl7.fhir.r5.model.ExpressionNode;
|
||||
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
|
||||
import org.hl7.fhir.utilities.SourceLocation;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
|
||||
// shared lexer for concrete syntaxes
|
||||
// - FluentPath
|
||||
// - Mapping language
|
||||
|
||||
public class FHIRLexer {
|
||||
public class FHIRLexerException extends FHIRException {
|
||||
|
||||
private SourceLocation location;
|
||||
|
||||
// public FHIRLexerException() {
|
||||
// super();
|
||||
// }
|
||||
//
|
||||
// public FHIRLexerException(String message, Throwable cause) {
|
||||
// super(message, cause);
|
||||
// }
|
||||
//
|
||||
// public FHIRLexerException(String message) {
|
||||
// super(message);
|
||||
// }
|
||||
//
|
||||
// public FHIRLexerException(Throwable cause) {
|
||||
// super(cause);
|
||||
// }
|
||||
|
||||
public FHIRLexerException(String message, SourceLocation location) {
|
||||
super(message);
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
public SourceLocation getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
}
|
||||
private String source;
|
||||
private int cursor;
|
||||
private int currentStart;
|
||||
private String current;
|
||||
private List<String> comments = new ArrayList<>();
|
||||
private SourceLocation currentLocation;
|
||||
private SourceLocation currentStartLocation;
|
||||
private int id;
|
||||
private String name;
|
||||
private boolean liquidMode; // in liquid mode, || terminates the expression and hands the parser back to the host
|
||||
private SourceLocation commentLocation;
|
||||
private boolean metadataFormat;
|
||||
private boolean allowDoubleQuotes;
|
||||
|
||||
public FHIRLexer(String source, String name) throws FHIRLexerException {
|
||||
this.source = source == null ? "" : source;
|
||||
this.name = name == null ? "??" : name;
|
||||
currentLocation = new SourceLocation(1, 1);
|
||||
next();
|
||||
}
|
||||
public FHIRLexer(String source, int i) throws FHIRLexerException {
|
||||
this.source = source;
|
||||
this.cursor = i;
|
||||
currentLocation = new SourceLocation(1, 1);
|
||||
next();
|
||||
}
|
||||
public FHIRLexer(String source, int i, boolean allowDoubleQuotes) throws FHIRLexerException {
|
||||
this.source = source;
|
||||
this.cursor = i;
|
||||
this.allowDoubleQuotes = allowDoubleQuotes;
|
||||
currentLocation = new SourceLocation(1, 1);
|
||||
next();
|
||||
}
|
||||
public FHIRLexer(String source, String name, boolean metadataFormat, boolean allowDoubleQuotes) throws FHIRLexerException {
|
||||
this.source = source == null ? "" : source;
|
||||
this.name = name == null ? "??" : name;
|
||||
this.metadataFormat = metadataFormat;
|
||||
this.allowDoubleQuotes = allowDoubleQuotes;
|
||||
currentLocation = new SourceLocation(1, 1);
|
||||
next();
|
||||
}
|
||||
public String getCurrent() {
|
||||
return current;
|
||||
}
|
||||
public SourceLocation getCurrentLocation() {
|
||||
return currentLocation;
|
||||
}
|
||||
|
||||
public boolean isConstant() {
|
||||
return FHIRPathConstant.isFHIRPathConstant(current);
|
||||
}
|
||||
|
||||
public boolean isFixedName() {
|
||||
return FHIRPathConstant.isFHIRPathFixedName(current);
|
||||
}
|
||||
|
||||
public boolean isStringConstant() {
|
||||
return FHIRPathConstant.isFHIRPathStringConstant(current);
|
||||
}
|
||||
|
||||
public String take() throws FHIRLexerException {
|
||||
String s = current;
|
||||
next();
|
||||
return s;
|
||||
}
|
||||
|
||||
public int takeInt() throws FHIRLexerException {
|
||||
String s = current;
|
||||
if (!Utilities.isInteger(s))
|
||||
throw error("Found "+current+" expecting an integer");
|
||||
next();
|
||||
return Integer.parseInt(s);
|
||||
}
|
||||
|
||||
public boolean isToken() {
|
||||
if (Utilities.noString(current))
|
||||
return false;
|
||||
|
||||
if (current.startsWith("$"))
|
||||
return true;
|
||||
|
||||
if (current.equals("*") || current.equals("**"))
|
||||
return true;
|
||||
|
||||
if ((current.charAt(0) >= 'A' && current.charAt(0) <= 'Z') || (current.charAt(0) >= 'a' && current.charAt(0) <= 'z')) {
|
||||
for (int i = 1; i < current.length(); i++)
|
||||
if (!( (current.charAt(1) >= 'A' && current.charAt(1) <= 'Z') || (current.charAt(1) >= 'a' && current.charAt(1) <= 'z') ||
|
||||
(current.charAt(1) >= '0' && current.charAt(1) <= '9')))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public FHIRLexerException error(String msg) {
|
||||
return error(msg, currentLocation.toString(), currentLocation);
|
||||
}
|
||||
|
||||
public FHIRLexerException error(String msg, String location, SourceLocation loc) {
|
||||
return new FHIRLexerException("Error @"+location+": "+msg, loc);
|
||||
}
|
||||
|
||||
public void next() throws FHIRLexerException {
|
||||
skipWhitespaceAndComments();
|
||||
current = null;
|
||||
currentStart = cursor;
|
||||
currentStartLocation = currentLocation;
|
||||
if (cursor < source.length()) {
|
||||
char ch = source.charAt(cursor);
|
||||
if (ch == '!' || ch == '>' || ch == '<' || ch == ':' || ch == '-' || ch == '=') {
|
||||
cursor++;
|
||||
if (cursor < source.length() && (source.charAt(cursor) == '=' || source.charAt(cursor) == '~' || source.charAt(cursor) == '-') || (ch == '-' && source.charAt(cursor) == '>'))
|
||||
cursor++;
|
||||
current = source.substring(currentStart, cursor);
|
||||
} else if (ch == '.' ) {
|
||||
cursor++;
|
||||
if (cursor < source.length() && (source.charAt(cursor) == '.'))
|
||||
cursor++;
|
||||
current = source.substring(currentStart, cursor);
|
||||
} else if (ch >= '0' && ch <= '9') {
|
||||
cursor++;
|
||||
boolean dotted = false;
|
||||
while (cursor < source.length() && ((source.charAt(cursor) >= '0' && source.charAt(cursor) <= '9') || (source.charAt(cursor) == '.') && !dotted)) {
|
||||
if (source.charAt(cursor) == '.')
|
||||
dotted = true;
|
||||
cursor++;
|
||||
}
|
||||
if (source.charAt(cursor-1) == '.')
|
||||
cursor--;
|
||||
current = source.substring(currentStart, cursor);
|
||||
} else if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) {
|
||||
while (cursor < source.length() && ((source.charAt(cursor) >= 'A' && source.charAt(cursor) <= 'Z') || (source.charAt(cursor) >= 'a' && source.charAt(cursor) <= 'z') ||
|
||||
(source.charAt(cursor) >= '0' && source.charAt(cursor) <= '9') || source.charAt(cursor) == '_'))
|
||||
cursor++;
|
||||
current = source.substring(currentStart, cursor);
|
||||
} else if (ch == '%') {
|
||||
cursor++;
|
||||
if (cursor < source.length() && (source.charAt(cursor) == '`')) {
|
||||
cursor++;
|
||||
while (cursor < source.length() && (source.charAt(cursor) != '`'))
|
||||
cursor++;
|
||||
cursor++;
|
||||
} else
|
||||
while (cursor < source.length() && ((source.charAt(cursor) >= 'A' && source.charAt(cursor) <= 'Z') || (source.charAt(cursor) >= 'a' && source.charAt(cursor) <= 'z') ||
|
||||
(source.charAt(cursor) >= '0' && source.charAt(cursor) <= '9') || source.charAt(cursor) == ':' || source.charAt(cursor) == '-'))
|
||||
cursor++;
|
||||
current = source.substring(currentStart, cursor);
|
||||
} else if (ch == '/') {
|
||||
cursor++;
|
||||
if (cursor < source.length() && (source.charAt(cursor) == '/')) {
|
||||
// we've run into metadata
|
||||
cursor++;
|
||||
cursor++;
|
||||
current = source.substring(currentStart, cursor);
|
||||
} else {
|
||||
current = source.substring(currentStart, cursor);
|
||||
}
|
||||
} else if (ch == '$') {
|
||||
cursor++;
|
||||
while (cursor < source.length() && (source.charAt(cursor) >= 'a' && source.charAt(cursor) <= 'z'))
|
||||
cursor++;
|
||||
current = source.substring(currentStart, cursor);
|
||||
} else if (ch == '{') {
|
||||
cursor++;
|
||||
ch = source.charAt(cursor);
|
||||
if (ch == '}')
|
||||
cursor++;
|
||||
current = source.substring(currentStart, cursor);
|
||||
} else if (ch == '"' && allowDoubleQuotes) {
|
||||
cursor++;
|
||||
boolean escape = false;
|
||||
while (cursor < source.length() && (escape || source.charAt(cursor) != '"')) {
|
||||
if (escape)
|
||||
escape = false;
|
||||
else
|
||||
escape = (source.charAt(cursor) == '\\');
|
||||
cursor++;
|
||||
}
|
||||
if (cursor == source.length())
|
||||
throw error("Unterminated string");
|
||||
cursor++;
|
||||
current = "\""+source.substring(currentStart+1, cursor-1)+"\"";
|
||||
} else if (ch == '`') {
|
||||
cursor++;
|
||||
boolean escape = false;
|
||||
while (cursor < source.length() && (escape || source.charAt(cursor) != '`')) {
|
||||
if (escape)
|
||||
escape = false;
|
||||
else
|
||||
escape = (source.charAt(cursor) == '\\');
|
||||
cursor++;
|
||||
}
|
||||
if (cursor == source.length())
|
||||
throw error("Unterminated string");
|
||||
cursor++;
|
||||
current = "`"+source.substring(currentStart+1, cursor-1)+"`";
|
||||
} else if (ch == '\''){
|
||||
cursor++;
|
||||
char ech = ch;
|
||||
boolean escape = false;
|
||||
while (cursor < source.length() && (escape || source.charAt(cursor) != ech)) {
|
||||
if (escape)
|
||||
escape = false;
|
||||
else
|
||||
escape = (source.charAt(cursor) == '\\');
|
||||
cursor++;
|
||||
}
|
||||
if (cursor == source.length())
|
||||
throw error("Unterminated string");
|
||||
cursor++;
|
||||
current = source.substring(currentStart, cursor);
|
||||
if (ech == '\'')
|
||||
current = "\'"+current.substring(1, current.length() - 1)+"\'";
|
||||
} else if (ch == '`') {
|
||||
cursor++;
|
||||
boolean escape = false;
|
||||
while (cursor < source.length() && (escape || source.charAt(cursor) != '`')) {
|
||||
if (escape)
|
||||
escape = false;
|
||||
else
|
||||
escape = (source.charAt(cursor) == '\\');
|
||||
cursor++;
|
||||
}
|
||||
if (cursor == source.length())
|
||||
throw error("Unterminated string");
|
||||
cursor++;
|
||||
current = "`"+source.substring(currentStart+1, cursor-1)+"`";
|
||||
} else if (ch == '|' && liquidMode) {
|
||||
cursor++;
|
||||
ch = source.charAt(cursor);
|
||||
if (ch == '|')
|
||||
cursor++;
|
||||
current = source.substring(currentStart, cursor);
|
||||
} else if (ch == '@'){
|
||||
int start = cursor;
|
||||
cursor++;
|
||||
while (cursor < source.length() && isDateChar(source.charAt(cursor), start))
|
||||
cursor++;
|
||||
current = source.substring(currentStart, cursor);
|
||||
} else { // if CharInSet(ch, ['.', ',', '(', ')', '=', '$']) then
|
||||
cursor++;
|
||||
current = source.substring(currentStart, cursor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void skipWhitespaceAndComments() {
|
||||
comments.clear();
|
||||
commentLocation = null;
|
||||
boolean last13 = false;
|
||||
boolean done = false;
|
||||
while (cursor < source.length() && !done) {
|
||||
if (cursor < source.length() -1 && "//".equals(source.substring(cursor, cursor+2)) && !isMetadataStart()) {
|
||||
if (commentLocation == null) {
|
||||
commentLocation = currentLocation.copy();
|
||||
}
|
||||
int start = cursor+2;
|
||||
while (cursor < source.length() && !((source.charAt(cursor) == '\r') || source.charAt(cursor) == '\n')) {
|
||||
cursor++;
|
||||
}
|
||||
comments.add(source.substring(start, cursor).trim());
|
||||
} else if (cursor < source.length() - 1 && "/*".equals(source.substring(cursor, cursor+2))) {
|
||||
if (commentLocation == null) {
|
||||
commentLocation = currentLocation.copy();
|
||||
}
|
||||
int start = cursor+2;
|
||||
while (cursor < source.length() - 1 && !"*/".equals(source.substring(cursor, cursor+2))) {
|
||||
last13 = currentLocation.checkChar(source.charAt(cursor), last13);
|
||||
cursor++;
|
||||
}
|
||||
if (cursor >= source.length() -1) {
|
||||
error("Unfinished comment");
|
||||
} else {
|
||||
comments.add(source.substring(start, cursor).trim());
|
||||
cursor = cursor + 2;
|
||||
}
|
||||
} else if (Utilities.isWhitespace(source.charAt(cursor))) {
|
||||
last13 = currentLocation.checkChar(source.charAt(cursor), last13);
|
||||
cursor++;
|
||||
} else {
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isMetadataStart() {
|
||||
return metadataFormat && cursor < source.length() - 2 && "///".equals(source.substring(cursor, cursor+3));
|
||||
}
|
||||
|
||||
private boolean isDateChar(char ch,int start) {
|
||||
int eot = source.charAt(start+1) == 'T' ? 10 : 20;
|
||||
|
||||
return ch == '-' || ch == ':' || ch == 'T' || ch == '+' || ch == 'Z' || Character.isDigit(ch) || (cursor-start == eot && ch == '.' && cursor < source.length()-1&& Character.isDigit(source.charAt(cursor+1)));
|
||||
}
|
||||
public boolean isOp() {
|
||||
return ExpressionNode.Operation.fromCode(current) != null;
|
||||
}
|
||||
public boolean done() {
|
||||
return currentStart >= source.length();
|
||||
}
|
||||
public int nextId() {
|
||||
id++;
|
||||
return id;
|
||||
}
|
||||
public SourceLocation getCurrentStartLocation() {
|
||||
return currentStartLocation;
|
||||
}
|
||||
|
||||
// special case use
|
||||
public void setCurrent(String current) {
|
||||
this.current = current;
|
||||
}
|
||||
|
||||
public boolean hasComments() {
|
||||
return comments.size() > 0;
|
||||
}
|
||||
|
||||
public List<String> getComments() {
|
||||
return comments;
|
||||
}
|
||||
|
||||
public String getAllComments() {
|
||||
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder("\r\n");
|
||||
b.addAll(comments);
|
||||
comments.clear();
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
public String getFirstComment() {
|
||||
if (hasComments()) {
|
||||
String s = comments.get(0);
|
||||
comments.remove(0);
|
||||
return s;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasToken(String kw) {
|
||||
return !done() && kw.equals(current);
|
||||
}
|
||||
public boolean hasToken(String... names) {
|
||||
if (done())
|
||||
return false;
|
||||
for (String s : names)
|
||||
if (s.equals(current))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public void token(String kw) throws FHIRLexerException {
|
||||
if (!kw.equals(current))
|
||||
throw error("Found \""+current+"\" expecting \""+kw+"\"");
|
||||
next();
|
||||
}
|
||||
|
||||
public String readConstant(String desc) throws FHIRLexerException {
|
||||
if (!isStringConstant())
|
||||
throw error("Found "+current+" expecting \"["+desc+"]\"");
|
||||
|
||||
return processConstant(take());
|
||||
}
|
||||
|
||||
public String readFixedName(String desc) throws FHIRLexerException {
|
||||
if (!isFixedName())
|
||||
throw error("Found "+current+" expecting \"["+desc+"]\"");
|
||||
|
||||
return processFixedName(take());
|
||||
}
|
||||
|
||||
public String processConstant(String s) throws FHIRLexerException {
|
||||
StringBuilder b = new StringBuilder();
|
||||
int i = 1;
|
||||
while (i < s.length()-1) {
|
||||
char ch = s.charAt(i);
|
||||
if (ch == '\\') {
|
||||
i++;
|
||||
switch (s.charAt(i)) {
|
||||
case 't':
|
||||
b.append('\t');
|
||||
break;
|
||||
case 'r':
|
||||
b.append('\r');
|
||||
break;
|
||||
case 'n':
|
||||
b.append('\n');
|
||||
break;
|
||||
case 'f':
|
||||
b.append('\f');
|
||||
break;
|
||||
case '\'':
|
||||
b.append('\'');
|
||||
break;
|
||||
case '"':
|
||||
b.append('"');
|
||||
break;
|
||||
case '`':
|
||||
b.append('`');
|
||||
break;
|
||||
case '\\':
|
||||
b.append('\\');
|
||||
break;
|
||||
case '/':
|
||||
b.append('/');
|
||||
break;
|
||||
case 'u':
|
||||
i++;
|
||||
int uc = Integer.parseInt(s.substring(i, i+4), 16);
|
||||
b.append((char) uc);
|
||||
i = i + 4;
|
||||
break;
|
||||
default:
|
||||
throw new FHIRLexerException("Unknown FHIRPath character escape \\"+s.charAt(i), currentLocation);
|
||||
}
|
||||
} else {
|
||||
b.append(ch);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
public String processFixedName(String s) throws FHIRLexerException {
|
||||
StringBuilder b = new StringBuilder();
|
||||
int i = 1;
|
||||
while (i < s.length()-1) {
|
||||
char ch = s.charAt(i);
|
||||
if (ch == '\\') {
|
||||
i++;
|
||||
switch (s.charAt(i)) {
|
||||
case 't':
|
||||
b.append('\t');
|
||||
break;
|
||||
case 'r':
|
||||
b.append('\r');
|
||||
break;
|
||||
case 'n':
|
||||
b.append('\n');
|
||||
break;
|
||||
case 'f':
|
||||
b.append('\f');
|
||||
break;
|
||||
case '\'':
|
||||
b.append('\'');
|
||||
break;
|
||||
case '"':
|
||||
b.append('"');
|
||||
break;
|
||||
case '\\':
|
||||
b.append('\\');
|
||||
break;
|
||||
case '/':
|
||||
b.append('/');
|
||||
break;
|
||||
case 'u':
|
||||
i++;
|
||||
int uc = Integer.parseInt(s.substring(i, i+4), 16);
|
||||
b.append((char) uc);
|
||||
i = i + 4;
|
||||
break;
|
||||
default:
|
||||
throw new FHIRLexerException("Unknown FHIRPath character escape \\"+s.charAt(i), currentLocation);
|
||||
}
|
||||
} else {
|
||||
b.append(ch);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
public void skipToken(String token) throws FHIRLexerException {
|
||||
if (getCurrent().equals(token))
|
||||
next();
|
||||
|
||||
}
|
||||
public String takeDottedToken() throws FHIRLexerException {
|
||||
StringBuilder b = new StringBuilder();
|
||||
b.append(take());
|
||||
while (!done() && getCurrent().equals(".")) {
|
||||
b.append(take());
|
||||
b.append(take());
|
||||
}
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
public int getCurrentStart() {
|
||||
return currentStart;
|
||||
}
|
||||
public String getSource() {
|
||||
return source;
|
||||
}
|
||||
public boolean isLiquidMode() {
|
||||
return liquidMode;
|
||||
}
|
||||
public void setLiquidMode(boolean liquidMode) {
|
||||
this.liquidMode = liquidMode;
|
||||
}
|
||||
public SourceLocation getCommentLocation() {
|
||||
return this.commentLocation;
|
||||
}
|
||||
public boolean isMetadataFormat() {
|
||||
return metadataFormat;
|
||||
}
|
||||
public void setMetadataFormat(boolean metadataFormat) {
|
||||
this.metadataFormat = metadataFormat;
|
||||
}
|
||||
public List<String> cloneComments() {
|
||||
List<String> res = new ArrayList<>();
|
||||
res.addAll(getComments());
|
||||
return res;
|
||||
}
|
||||
public String tokenWithTrailingComment(String token) {
|
||||
int line = getCurrentLocation().getLine();
|
||||
token(token);
|
||||
if (getComments().size() > 0 && getCommentLocation().getLine() == line) {
|
||||
return getFirstComment();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public boolean isAllowDoubleQuotes() {
|
||||
return allowDoubleQuotes;
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
package org.hl7.fhir.r5.utils;
|
||||
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
|
||||
public class FHIRPathConstant {
|
||||
|
||||
public static boolean isFHIRPathConstant(String string) {
|
||||
return !Utilities.noString(string) && ((string.charAt(0) == '\'' || string.charAt(0) == '"') || string.charAt(0) == '@' || string.charAt(0) == '%' ||
|
||||
string.charAt(0) == '-' || string.charAt(0) == '+' || (string.charAt(0) >= '0' && string.charAt(0) <= '9') ||
|
||||
string.equals("true") || string.equals("false") || string.equals("{}"));
|
||||
}
|
||||
|
||||
public static boolean isFHIRPathFixedName(String string) {
|
||||
return string != null && (string.charAt(0) == '`');
|
||||
}
|
||||
|
||||
public static boolean isFHIRPathStringConstant(String string) {
|
||||
return string.charAt(0) == '\'' || string.charAt(0) == '"' || string.charAt(0) == '`';
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,201 +0,0 @@
|
|||
package org.hl7.fhir.r5.utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.r5.model.Base;
|
||||
import org.hl7.fhir.r5.model.Element;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition;
|
||||
import org.hl7.fhir.r5.model.Property;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.model.StringType;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent;
|
||||
import org.hl7.fhir.utilities.FhirPublication;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
|
||||
public class FHIRPathUtilityClasses {
|
||||
|
||||
public static class FHIRConstant extends Base {
|
||||
|
||||
private static final long serialVersionUID = -8933773658248269439L;
|
||||
private String value;
|
||||
|
||||
public FHIRConstant(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String fhirType() {
|
||||
return "%constant";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void listChildren(List<Property> result) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdBase() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIdBase(String value) {
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String primitiveValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Base copy() {
|
||||
throw new Error("Not Implemented");
|
||||
}
|
||||
|
||||
public FhirPublication getFHIRPublicationVersion() {
|
||||
return FhirPublication.R5;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ClassTypeInfo extends Base {
|
||||
private static final long serialVersionUID = 4909223114071029317L;
|
||||
private Base instance;
|
||||
|
||||
public ClassTypeInfo(Base instance) {
|
||||
super();
|
||||
this.instance = instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String fhirType() {
|
||||
return "ClassInfo";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void listChildren(List<Property> result) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdBase() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIdBase(String value) {
|
||||
}
|
||||
|
||||
public Base[] getProperty(int hash, String name, boolean checkValid) throws FHIRException {
|
||||
if (name.equals("name")) {
|
||||
return new Base[]{new StringType(getName())};
|
||||
} else if (name.equals("namespace")) {
|
||||
return new Base[]{new StringType(getNamespace())};
|
||||
} else {
|
||||
return super.getProperty(hash, name, checkValid);
|
||||
}
|
||||
}
|
||||
|
||||
private String getNamespace() {
|
||||
if ((instance instanceof Resource)) {
|
||||
return "FHIR";
|
||||
} else if (!(instance instanceof Element) || ((Element)instance).isDisallowExtensions()) {
|
||||
return "System";
|
||||
} else {
|
||||
return "FHIR";
|
||||
}
|
||||
}
|
||||
|
||||
private String getName() {
|
||||
if ((instance instanceof Resource)) {
|
||||
return instance.fhirType();
|
||||
} else if (!(instance instanceof Element) || ((Element)instance).isDisallowExtensions()) {
|
||||
return Utilities.capitalize(instance.fhirType());
|
||||
} else {
|
||||
return instance.fhirType();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Base copy() {
|
||||
throw new Error("Not Implemented");
|
||||
}
|
||||
|
||||
public FhirPublication getFHIRPublicationVersion() {
|
||||
return FhirPublication.R5;
|
||||
}
|
||||
}
|
||||
|
||||
public static class TypedElementDefinition {
|
||||
private ElementDefinition element;
|
||||
private String type;
|
||||
private StructureDefinition src;
|
||||
public TypedElementDefinition(StructureDefinition src, ElementDefinition element, String type) {
|
||||
super();
|
||||
this.element = element;
|
||||
this.type = type;
|
||||
this.src = src;
|
||||
}
|
||||
public TypedElementDefinition(ElementDefinition element) {
|
||||
super();
|
||||
this.element = element;
|
||||
}
|
||||
public ElementDefinition getElement() {
|
||||
return element;
|
||||
}
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
public List<TypeRefComponent> getTypes() {
|
||||
List<TypeRefComponent> res = new ArrayList<ElementDefinition.TypeRefComponent>();
|
||||
for (TypeRefComponent tr : element.getType()) {
|
||||
if (type == null || type.equals(tr.getCode())) {
|
||||
res.add(tr);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
public boolean hasType(String tn) {
|
||||
if (type != null) {
|
||||
return tn.equals(type);
|
||||
} else {
|
||||
for (TypeRefComponent t : element.getType()) {
|
||||
if (tn.equals(t.getCode())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public StructureDefinition getSrc() {
|
||||
return src;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class FunctionDetails {
|
||||
private String description;
|
||||
private int minParameters;
|
||||
private int maxParameters;
|
||||
public FunctionDetails(String description, int minParameters, int maxParameters) {
|
||||
super();
|
||||
this.description = description;
|
||||
this.minParameters = minParameters;
|
||||
this.maxParameters = maxParameters;
|
||||
}
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
public int getMinParameters() {
|
||||
return minParameters;
|
||||
}
|
||||
public int getMaxParameters() {
|
||||
return maxParameters;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue