Commit 20bd21e2 authored by Georg Fette's avatar Georg Fette
Browse files

refactored a lot of the abstract graph model

test cases do not succeed at the moment, just an intermediate checkin
parent 26a729b8
......@@ -2,7 +2,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>QueryMapper</groupId>
<version>0.0.2-SNAPSHOT</version>
<version>0.0.3-SNAPSHOT</version>
<name>QueryMapper</name>
<artifactId>QueryMapper</artifactId>
<properties>
......
......@@ -8,12 +8,12 @@ import org.antlr.v4.runtime.tree.ParseTreeListener;
*/
public interface AqlListener extends ParseTreeListener {
/**
* Enter a parse tree produced by {@link AqlParser#query}.
* Enter a parse tree produced by {@link AqlParser#root}.
* @param ctx the parse tree
*/
void enterQuery(AqlParser.QueryContext ctx);
/**
* Exit a parse tree produced by {@link AqlParser#query}.
* Exit a parse tree produced by {@link AqlParser#root}.
* @param ctx the parse tree
*/
void exitQuery(AqlParser.QueryContext ctx);
......
......@@ -11,7 +11,7 @@ import org.antlr.v4.runtime.tree.ParseTreeVisitor;
*/
public interface AqlVisitor<T> extends ParseTreeVisitor<T> {
/**
* Visit a parse tree produced by {@link AqlParser#query}.
* Visit a parse tree produced by {@link AqlParser#root}.
* @param ctx the parse tree
* @return the visitor result
*/
......
package de.uniwue.query.CQL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import de.uniwue.query.PrimitiveDateTime;
public class CQLDateTimeParser {
private SimpleDateFormat onlyYearsIn, dateTimeWithSecondsIn, onlyTimeWithSecondsIn, yearsOut,
monthsOut, daysOut, hoursOut, minutesOut, secondsOut, milliSecsOut;
private String onlyYearsInRegex, dateTimeWithSecondsInRegex, onlyTimeWithSecondsInRegex;
private static CQLDateTimeParser singleton;
public static CQLDateTimeParser getSingleTon() {
if (singleton == null) {
singleton = new CQLDateTimeParser();
singleton.initDateFormats();
}
return singleton;
}
private void initDateFormats() {
onlyYearsIn = new SimpleDateFormat("@yyyy");
onlyYearsInRegex = "^@\\d{4}$";
dateTimeWithSecondsIn = new SimpleDateFormat("@yyyy-MM-DD'T'HH:mm:ss");
dateTimeWithSecondsInRegex = "^@\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$";
onlyTimeWithSecondsIn = new SimpleDateFormat("@'T'HH:mm:ss");
onlyTimeWithSecondsInRegex = "^@T\\d{2}:\\d{2}:\\d{2}$";
yearsOut = new SimpleDateFormat("yyyy");
monthsOut = new SimpleDateFormat("MM");
daysOut = new SimpleDateFormat("DD");
hoursOut = new SimpleDateFormat("HH");
minutesOut = new SimpleDateFormat("mm");
secondsOut = new SimpleDateFormat("ss");
milliSecsOut = new SimpleDateFormat("SSS");
}
private boolean checkFormat(String format, String aDateString) {
return aDateString.matches(format);
}
public PrimitiveDateTime parseDateTime(String dateTimeStringIn) {
boolean hasYears = false, hasMonths = false, hasDays = false, hasHours = false,
hasMinutes = false, hasSeconds = false, hasMillis = false;
Date parse = null;
try {
if (checkFormat(onlyYearsInRegex, dateTimeStringIn)) {
parse = onlyYearsIn.parse(dateTimeStringIn);
hasYears = true;
} else if (checkFormat(dateTimeWithSecondsInRegex, dateTimeStringIn)) {
parse = dateTimeWithSecondsIn.parse(dateTimeStringIn);
hasYears = true;
hasMonths = true;
hasDays = true;
hasHours = true;
hasMinutes = true;
hasSeconds = true;
} else if (checkFormat(onlyTimeWithSecondsInRegex, dateTimeStringIn)) {
parse = onlyTimeWithSecondsIn.parse(dateTimeStringIn);
hasHours = true;
hasMinutes = true;
hasSeconds = true;
} else {
throw new RuntimeException("unknown format");
}
} catch (ParseException e) {
throw new RuntimeException(e);
}
String yearValue = null, monthValue = null, dayValue = null, hourValue = null,
minuteValue = null, secondValue = null, millisecValue = null;
Integer yearValueInt = null, monthValueInt = null, dayValueInt = null, hourValueInt = null,
minuteValueInt = null, secondValueInt = null, millisecValueInt = null;
String dateTimeStringLow = "", dateTimeStringHigh = "";
if (hasMillis) {
millisecValue = milliSecsOut.format(parse);
millisecValueInt = Integer.valueOf(millisecValue);
if (millisecValue.length() == 1) {
millisecValue = "0" + millisecValue;
}
if (millisecValue.length() == 2) {
millisecValue = "0" + millisecValue;
}
} else {
dateTimeStringLow = "000";
dateTimeStringHigh = "999";
}
if (hasSeconds) {
secondValue = secondsOut.format(parse);
secondValueInt = Integer.valueOf(secondValue);
if (secondValue.length() == 1) {
secondValue = "0" + secondValue;
}
dateTimeStringLow = secondValue + ":" + dateTimeStringLow;
dateTimeStringHigh = secondValue + ":" + dateTimeStringHigh;
} else {
dateTimeStringLow = "00:" + dateTimeStringLow;
dateTimeStringHigh = "59:" + dateTimeStringHigh;
}
if (hasMinutes) {
minuteValue = minutesOut.format(parse);
minuteValueInt = Integer.valueOf(minuteValue);
if (minuteValue.length() == 1) {
minuteValue = "0" + minuteValue;
}
dateTimeStringLow = minuteValue + ":" + dateTimeStringLow;
dateTimeStringHigh = minuteValue + ":" + dateTimeStringHigh;
} else {
dateTimeStringLow = "00:" + dateTimeStringLow;
dateTimeStringHigh = "59:" + dateTimeStringHigh;
}
if (hasHours) {
hourValue = hoursOut.format(parse);
hourValueInt = Integer.valueOf(hourValue);
if (hourValue.length() == 1) {
hourValue = "0" + hourValue;
}
dateTimeStringLow = hourValue + ":" + dateTimeStringLow;
dateTimeStringHigh = hourValue + ":" + dateTimeStringHigh;
} else {
dateTimeStringLow = "00:" + dateTimeStringLow;
dateTimeStringHigh = "23:" + dateTimeStringHigh;
}
if (hasDays) {
dayValue = daysOut.format(parse);
dayValueInt = Integer.valueOf(dayValue);
if (dayValue.length() == 1) {
dayValue = "0" + dayValue;
}
dateTimeStringLow = dayValue + "T" + dateTimeStringLow;
dateTimeStringHigh = dayValue + "T" + dateTimeStringHigh;
} else {
dateTimeStringLow = "01T" + dateTimeStringLow;
dateTimeStringHigh = "31T" + dateTimeStringHigh;
// TODO: hm, what about months with another amount of days than 31 ?
}
if (hasMonths) {
monthValue = monthsOut.format(parse);
monthValueInt = Integer.valueOf(monthValue);
if (monthValue.length() == 1) {
monthValue = "0" + monthValue;
}
dateTimeStringLow = monthValue + "-" + dateTimeStringLow;
dateTimeStringHigh = monthValue + "-" + dateTimeStringHigh;
} else {
dateTimeStringLow = "01-" + dateTimeStringLow;
dateTimeStringHigh = "12-" + dateTimeStringHigh;
// TODO: hm, what about months with another amount of days than 31 ?
}
yearValue = yearsOut.format(parse);
yearValueInt = Integer.valueOf(yearValue);
dateTimeStringLow = "@" + yearValue + "-" + dateTimeStringLow;
dateTimeStringHigh = "@" + yearValue + "-" + dateTimeStringHigh;
PrimitiveDateTime newParam = new PrimitiveDateTime(yearValueInt, monthValueInt, dayValueInt,
hourValueInt, minuteValueInt, secondValueInt, millisecValueInt, dateTimeStringIn);
return newParam;
}
}
......@@ -6,12 +6,15 @@ import de.uniwue.query.OperatorType;
public class CQLOperatorMapper {
public static void initializeOpMappings(OperatorMap aMap) {
aMap.addOp("is", OperatorType.IS);
aMap.addOp("sort by", OperatorType.SORT);
aMap.addOp("", OperatorType.SORT_ITEM);
aMap.addOp("exists", OperatorType.EXISTS);
aMap.addOp("", OperatorType.OPERATOR_RESULT_PROPERTY);
aMap.addOp("", OperatorType.QUERY);
aMap.addOp("", OperatorType.FIELD);
aMap.addOp("", OperatorType.ITERATE);
aMap.addOp("", OperatorType.ALIAS_REF);
aMap.addOp("", OperatorType.FILTER);
aMap.addOp("", OperatorType.QUANTITY);
aMap.addOp("", OperatorType.INTERVAL);
aMap.addOp("", OperatorType.LIST);
......@@ -30,9 +33,11 @@ public class CQLOperatorMapper {
aMap.addOp("in", OperatorType.IN_VALUE_SET);
aMap.addOp("Now()", OperatorType.NOW);
aMap.addOp("Today()", OperatorType.TODAY);
aMap.addOp("TimeOfDay()", OperatorType.TIME_OF_DAY);
aMap.addOp("Now", OperatorType.NOW);
aMap.addOp("Today", OperatorType.TODAY);
aMap.addOp("TimeOfDay", OperatorType.TIMEOFDAY);
aMap.addOp("Time", OperatorType.TIME);
aMap.addOp("Datetime", OperatorType.DATETIME);
aMap.addOp("Interval", OperatorType.INTERVAL);
aMap.addOp("during", OperatorType.DURING);
......
package de.uniwue.query;
import java.util.Set;
import java.util.ArrayList;
import java.util.List;
public abstract class Expression {
public boolean isConcept() {
return this instanceof QueryConcept;
}
// an identifier with which the expression can be identified inside the returned results
public String outputName;
public boolean isInResult;
public boolean optional;
public String alias;
public List<QueryOperator> parents = new ArrayList<QueryOperator>();
public boolean isPrimitive() {
return this instanceof Primitive;
......@@ -16,8 +24,16 @@ public abstract class Expression {
return this instanceof QueryOperator;
}
public QueryConcept asConcept() {
return (QueryConcept) this;
public boolean isConcept() {
boolean result;
if (isOperator()) {
QueryOperator thisAsOp = asOperator();
if ((thisAsOp.type == OperatorType.ITERATE) || (thisAsOp.type == OperatorType.FIELD)
|| (thisAsOp.type == OperatorType.REVERSE_FIELD)) {
return true;
}
}
return false;
}
public Primitive asPrimitive() {
......@@ -28,8 +44,8 @@ public abstract class Expression {
return (QueryOperator) this;
}
public abstract void getReturnedExpressions(Set<Expression> results);
public boolean includeInResult;
public QueryOperator asConcept() {
return (QueryOperator) this;
}
}
package de.uniwue.query.FHIRRest;
import java.io.IOException;
import org.jdom.JDOMException;
import de.uniwue.query.GraphQuery;
import de.uniwue.query.Mapper;
import de.uniwue.query.QueryConcept;
public class FHIRRest_2_Graph_Mapper extends Mapper {
public FHIRRest_2_Graph_Mapper() {
}
public String getSystem() {
return Graph_2_FHIRRest_Mapper.system;
}
private void clear() {
query = new GraphQuery();
}
public GraphQuery parse(String queryString) throws JDOMException, IOException {
clear();
String rootReturnConc = queryString.replaceAll("\\?.*", "");
QueryConcept rootConcept = new QueryConcept(rootReturnConc);
rootConcept.includeInResult = true;
query.rootConcepts.add(rootConcept);
return query;
}
}
package de.uniwue.query.FHIRRest;
import de.uniwue.query.Graph_2_System_Mapper;
public class Graph_2_FHIRRest_Mapper extends Graph_2_System_Mapper {
protected static String system = "FHIRRest";
public Graph_2_FHIRRest_Mapper() {
super(system);
// initializeOpMappings(opMap);
}
public String getSystem() {
return system;
}
/*
@Override
protected void initialize(GraphQuery aQuery) {
super.initialize(aQuery);
}
@Override
protected void checkErrors() {
super.checkErrors();
checkForSingleReturnConcept();
checkForSingleRootConcept();
checkOnlyLeftSideConceptsAllowed();
}
private void checkForSingleRootConcept() {
if (query.rootConcepts.size() > 1) {
throw new RuntimeException("only one root concept allowed");
}
}
private void checkForSingleReturnConcept() {
List<QueryConcept> returnConcs = query.getReturnedConcepts();
if (returnConcs.size() > 1) {
throw new RuntimeException("only one result concept allowed");
}
}
private void checkOnlyLeftSideConceptsAllowed() {
for (QueryOperator anOp : query.rootClause.getOperatorsRecursive()) {
boolean isFirst = true;
for (Expression anExp : anOp.getParameters()) {
if (isFirst) {
isFirst = false;
continue;
}
if (anExp.isConcept()) {
throw new RuntimeException("only operators with concepts on the left side are allowed");
}
}
}
}
private String getPath(QueryConcept aConc) {
QueryConcept currentConc = aConc;
String chain = "";
while (currentConc.parentConcept != null) {
if (!chain.isEmpty()) {
chain = "." + chain;
}
chain = currentConc.code + chain;
currentConc = currentConc.parentConcept;
}
return chain;
}
public String visit(GraphQuery aQuery) {
initialize(aQuery);
String result = "";
QueryConcept returnConc = query.getReturnedConcepts().get(0);
result = returnConc.code;
String constrains = "";
for (Expression anExp : query.rootClause.getParameters()) {
if (constrains.isEmpty()) {
constrains += "?";
} else {
constrains += "&";
}
if (anExp.isConcept()) {
// TODO: something with "exists"
String chain = getPath(anExp.asConcept());
constrains += chain;
} else if (anExp.isOperator()) {
QueryOperator anOp = anExp.asOperator();
String anOpString = opMap.graph_2_system_operatorMap.get(anOp.type);
List<Expression> params = anOp.getParameters();
QueryConcept asConcept = params.get(0).asConcept();
String chain = getPath(asConcept);
String value = params.get(1).asPrimitive().value;
constrains += chain + anOpString + value;
}
}
result += constrains;
return result;
}
public static void initializeOpMappings(OperatorMap opMap) {
opMap.addOp("=", OperatorType.EQUALS);
opMap.addOp("=gt", OperatorType.MORE);
opMap.addOp("=ge", OperatorType.MORE_OR_EQUAL);
opMap.addOp("=lt", OperatorType.LESS);
opMap.addOp("=le", OperatorType.LESS_OR_EQUAL);
}
*/
}
package de.uniwue.query;
import java.util.HashMap;
import java.util.Map;
public class GraphLibrary {
public Map<String, GraphQuery> queries = new HashMap<String, GraphQuery>();
}
......@@ -6,59 +6,64 @@ import java.util.List;
public class GraphPath {
private List<QueryConcept> nodes = new ArrayList<QueryConcept>();
private List<QueryOperator> iterators = new ArrayList<QueryOperator>();
public GraphPath() {
}
public GraphPath(GraphPath aPath) {
nodes.addAll(aPath.nodes);
iterators.addAll(aPath.iterators);
}
public GraphPath(QueryConcept aPathElem) {
nodes.add(aPathElem);
public GraphPath(QueryOperator aPathElem) {
iterators.add(aPathElem);
}
public void addElement(QueryConcept aConcept) {
nodes.add(aConcept);
public void addElement(QueryOperator aConcept) {
iterators.add(aConcept);
}
public void addElement(QueryConcept aConcept, int index) {
nodes.add(index, aConcept);
public void addElement(QueryOperator aConcept, int index) {
iterators.add(index, aConcept);
}
public void removeLastElement() {
if (nodes.size() > 0) {
nodes.remove(nodes.size() - 1);
if (iterators.size() > 0) {
iterators.remove(iterators.size() - 1);
}
}
public QueryConcept getLastElement() {
return nodes.get(nodes.size() - 1);
public QueryOperator getLastElement() {
return iterators.get(iterators.size() - 1);
}
public QueryConcept getElementAt(int i) {
return nodes.get(i);
public QueryOperator getElementAt(int i) {
return iterators.get(i);
}
public int size() {
return nodes.size();
return iterators.size();
}
public void clear() {
nodes.clear();
iterators.clear();
}
@Override
public String toString() {
String result = "";
boolean first = true;
for (int i = 0; i < nodes.size(); i++) {
for (int i = 0; i < iterators.size(); i++) {
if (!first) {
result += "/";
}
if (first) {
result += iterators.get(i).getParameters().get(0).asPrimitive().value;
} else {
result += iterators.get(i).getParameters().get(1).asPrimitive().value;
}
first = false;
result += nodes.get(i).code;
}
return result;
}
......@@ -68,15 +73,15 @@ public class GraphPath {
boolean anotherRound = true;
while (anotherRound) {
anotherRound = false;
for (int i = 0; i < result.nodes.size(); i++) {
QueryConcept anElem = result.nodes.get(i);
if (aliases.containsKey(anElem.code)) {
for (int i = 0; i < result.iterators.size(); i++) {
QueryOperator anElem = result.iterators.get(i);
if (aliases.containsKey(anElem.getParameters().get(0).asPrimitive().value)) {
anotherRound = true;
GraphPath conceptPath = aliases.get(anElem.code);
result.nodes.remove(i);
for (int j = 0; j < conceptPath.nodes.size(); j++) {
QueryConcept aSubstitute = conceptPath.nodes.get(j);
result.nodes.add(i + j, aSubstitute);
GraphPath conceptPath = aliases.get(anElem.getParameters().get(0).asPrimitive().value);
result.iterators.remove(i);
for (int j = 0; j < conceptPath.iterators.size(); j++) {
QueryOperator aSubstitute = conceptPath.iterators.get(j);
result.iterators.add(i + j, aSubstitute);
}
}
}
......@@ -98,10 +103,10 @@ public class GraphPath {
if (getClass() != obj.getClass())
return false;
GraphPath other = (GraphPath) obj;
if (nodes == null) {
if (other.nodes != null)
if (iterators == null) {
if (other.iterators != null)
return false;
} else if (!nodes.equals(other.nodes))
} else if (!iterators.equals(other.iterators))
return false;
return true;
}
......
package de.uniwue.query;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;