All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.hl7.fhir.dstu3.model.ExpressionNode Maven / Gradle / Ivy

There is a newer version: 7.4.0
Show newest version
package org.hl7.fhir.dstu3.model;

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 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();
	}

	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 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.line)+", "+Integer.toString(start.column);
	}

	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;
	}
		
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy