aboutsummaryrefslogtreecommitdiff
path: root/src/uk/ac/ox/cs/pagoda/query
diff options
context:
space:
mode:
Diffstat (limited to 'src/uk/ac/ox/cs/pagoda/query')
-rw-r--r--src/uk/ac/ox/cs/pagoda/query/AnswerTuple.java65
-rw-r--r--src/uk/ac/ox/cs/pagoda/query/DeserializedQueryRecord.java9
-rw-r--r--src/uk/ac/ox/cs/pagoda/query/QueryRecord.java98
3 files changed, 115 insertions, 57 deletions
diff --git a/src/uk/ac/ox/cs/pagoda/query/AnswerTuple.java b/src/uk/ac/ox/cs/pagoda/query/AnswerTuple.java
index 183cbe1..cd86282 100644
--- a/src/uk/ac/ox/cs/pagoda/query/AnswerTuple.java
+++ b/src/uk/ac/ox/cs/pagoda/query/AnswerTuple.java
@@ -15,6 +15,9 @@ import uk.ac.ox.cs.pagoda.util.Namespace;
15import java.lang.reflect.Type; 15import java.lang.reflect.Type;
16import java.util.HashMap; 16import java.util.HashMap;
17import java.util.Map; 17import java.util.Map;
18import java.util.StringTokenizer;
19import java.util.regex.Matcher;
20import java.util.regex.Pattern;
18 21
19public class AnswerTuple { 22public class AnswerTuple {
20 23
@@ -42,31 +45,31 @@ public class AnswerTuple {
42 for (int i = 0; i < arity; ++i) m_tuple[i] = sup.m_tuple[i]; 45 for (int i = 0; i < arity; ++i) m_tuple[i] = sup.m_tuple[i];
43 } 46 }
44 47
45 private AnswerTuple(String m_str) { 48// private AnswerTuple(String m_str) {
46 this.m_str = m_str; 49// this.m_str = m_str;
47 } 50// }
48 51
49 public int getArity() { 52 public int getArity() {
50 return m_tuple.length; 53 return m_tuple.length;
51 } 54 }
52 55
53 public int hashCode() { 56 public int hashCode() {
54 return toString().hashCode(); 57// return toString().hashCode();
55// int code = 0; 58 int code = 0;
56// for (int i = 0; i < m_tuple.length; ++i) 59 for (int i = 0; i < m_tuple.length; ++i)
57// code = code * 1997 + m_tuple[i].hashCode(); 60 code = code * 1997 + m_tuple[i].hashCode();
58// return code; 61 return code;
59 } 62 }
60 63
61 public boolean equals(Object obj) { 64 public boolean equals(Object obj) {
62 if (!(obj instanceof AnswerTuple)) return false; 65 if (!(obj instanceof AnswerTuple)) return false;
63 AnswerTuple that = (AnswerTuple) obj; 66 AnswerTuple that = (AnswerTuple) obj;
64 if (m_tuple.length != that.m_tuple.length) return false; 67 if (m_tuple.length != that.m_tuple.length) return false;
65 for (int i = 0; i < m_tuple.length; ++i) 68 for (int i = 0; i < m_tuple.length; ++i)
66 if (!m_tuple[i].equals(that.m_tuple[i])) 69 if (!m_tuple[i].equals(that.m_tuple[i]))
67 return false; 70 return false;
68 return true; 71 return true;
69// return toString().equals(obj.toString()); 72// return toString().equals(obj.toString());
70 } 73 }
71 74
72 public String toString() { 75 public String toString() {
@@ -77,7 +80,7 @@ public class AnswerTuple {
77 if (m_tuple[i] instanceof uk.ac.ox.cs.JRDFox.model.Individual) 80 if (m_tuple[i] instanceof uk.ac.ox.cs.JRDFox.model.Individual)
78 sb.append("<").append(((uk.ac.ox.cs.JRDFox.model.Individual) m_tuple[i]).getIRI()).append(">"); 81 sb.append("<").append(((uk.ac.ox.cs.JRDFox.model.Individual) m_tuple[i]).getIRI()).append(">");
79 else if (m_tuple[i] instanceof uk.ac.ox.cs.JRDFox.model.BlankNode) { 82 else if (m_tuple[i] instanceof uk.ac.ox.cs.JRDFox.model.BlankNode) {
80 sb.append(((uk.ac.ox.cs.JRDFox.model.BlankNode) m_tuple[i]).toString()); 83 sb.append(m_tuple[i].toString());
81 } 84 }
82 else { 85 else {
83 Literal l = (Literal) m_tuple[i]; 86 Literal l = (Literal) m_tuple[i];
@@ -146,10 +149,40 @@ public class AnswerTuple {
146 149
147 } 150 }
148 151
149 public class AnswerTupleDeserializer implements JsonDeserializer<AnswerTuple> { 152 static final Pattern owlLiteralRegex = Pattern.compile("^\"(?<lexicalForm>[^@]+(@(?<langTag>.+))?)\"(^^<(?<dataType>.+)>)?$");
153
154 public static class AnswerTupleDeserializer implements JsonDeserializer<AnswerTuple> {
150 public AnswerTuple deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) 155 public AnswerTuple deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
151 throws JsonParseException { 156 throws JsonParseException {
152 return new AnswerTuple(json.getAsJsonPrimitive().getAsString()); 157 String tuplesString = json.getAsJsonPrimitive().getAsString();
158 StringTokenizer tokenizer = new StringTokenizer(SEPARATOR);
159 GroundTerm[] terms = new GroundTerm[tokenizer.countTokens()];
160
161 // TODO test parsing
162 for (int i = 0; i < tokenizer.countTokens(); i++) {
163 String token = tokenizer.nextToken();
164 if (token.charAt(0) == '<') {
165 terms[i] = uk.ac.ox.cs.JRDFox.model.Individual.create(token.substring(1,token.length()-1));
166 }
167 else if (token.charAt(0) == '"') {
168 Matcher matcher = owlLiteralRegex.matcher(token);
169 if(matcher.matches()) {
170 String lexicalForm = matcher.group("lexicalForm");
171 String dataTypeIRI = matcher.group("dataType");
172 Datatype dataType;
173 if (dataTypeIRI.isEmpty()) dataType = Datatype.RDF_PLAIN_LITERAL;
174 else dataType = uk.ac.ox.cs.JRDFox.model.Datatype.value(dataTypeIRI);
175 terms[i] = uk.ac.ox.cs.JRDFox.model.Literal.create(lexicalForm, dataType);
176 }
177 else {
178 throw new IllegalArgumentException("The given json does not represent a valid AnswerTuple");
179 }
180 }
181 else {
182 terms[i] = uk.ac.ox.cs.JRDFox.model.BlankNode.create(token);
183 }
184 }
185 return new AnswerTuple(terms);
153 } 186 }
154 } 187 }
155 188
diff --git a/src/uk/ac/ox/cs/pagoda/query/DeserializedQueryRecord.java b/src/uk/ac/ox/cs/pagoda/query/DeserializedQueryRecord.java
new file mode 100644
index 0000000..3d25eaf
--- /dev/null
+++ b/src/uk/ac/ox/cs/pagoda/query/DeserializedQueryRecord.java
@@ -0,0 +1,9 @@
1package uk.ac.ox.cs.pagoda.query;
2
3/*
4* A light version of QueryRecord,
5* which can be obtained easily from the Json serialization of QueryRecord.
6* */
7public class DeserializedQueryRecord {
8 // TODO implement
9}
diff --git a/src/uk/ac/ox/cs/pagoda/query/QueryRecord.java b/src/uk/ac/ox/cs/pagoda/query/QueryRecord.java
index 4b55046..6c87eb5 100644
--- a/src/uk/ac/ox/cs/pagoda/query/QueryRecord.java
+++ b/src/uk/ac/ox/cs/pagoda/query/QueryRecord.java
@@ -19,7 +19,7 @@ public class QueryRecord {
19 19
20 public static final String botQueryText = "SELECT ?X WHERE { ?X <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#Nothing> }"; 20 public static final String botQueryText = "SELECT ?X WHERE { ?X <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#Nothing> }";
21 21
22 private Step diffculty; 22 private Step difficulty;
23 23
24 private String queryText; 24 private String queryText;
25 private int queryID = -1; 25 private int queryID = -1;
@@ -90,7 +90,7 @@ public class QueryRecord {
90 } 90 }
91 91
92 public boolean updateUpperBoundAnswers(AnswerTuples answerTuples, boolean toCheckAux) { 92 public boolean updateUpperBoundAnswers(AnswerTuples answerTuples, boolean toCheckAux) {
93 RDFoxAnswerTuples rdfAnswerTuples; 93 RDFoxAnswerTuples rdfAnswerTuples;
94 if (answerTuples instanceof RDFoxAnswerTuples) 94 if (answerTuples instanceof RDFoxAnswerTuples)
95 rdfAnswerTuples = (RDFoxAnswerTuples) answerTuples; 95 rdfAnswerTuples = (RDFoxAnswerTuples) answerTuples;
96 else { 96 else {
@@ -125,7 +125,7 @@ public class QueryRecord {
125 if ((!toCheckAux || !tuple.hasAuxPredicate()) && !soundAnswerTuples.contains(tuple)) { 125 if ((!toCheckAux || !tuple.hasAuxPredicate()) && !soundAnswerTuples.contains(tuple)) {
126 if (!toCheckAux && justCheck) return false; 126 if (!toCheckAux && justCheck) return false;
127 tupleSet.add(extendedTuple); 127 tupleSet.add(extendedTuple);
128 } 128 }
129 } 129 }
130 } 130 }
131 131
@@ -146,7 +146,7 @@ public class QueryRecord {
146 } 146 }
147 147
148 Utility.logInfo("The number of answers in the upper bound: " + (soundAnswerTuples.size() + gapAnswerTuples.size())); 148 Utility.logInfo("The number of answers in the upper bound: " + (soundAnswerTuples.size() + gapAnswerTuples.size()));
149 149
150 return update; 150 return update;
151 } 151 }
152 152
@@ -292,11 +292,11 @@ public class QueryRecord {
292 } 292 }
293 293
294 public void setDifficulty(Step step) { 294 public void setDifficulty(Step step) {
295 this.diffculty = step; 295 this.difficulty = step;
296 } 296 }
297 297
298 public Step getDifficulty() { 298 public Step getDifficulty() {
299 return diffculty; 299 return difficulty;
300 } 300 }
301 301
302 OWLOntology relevantOntology = null; 302 OWLOntology relevantOntology = null;
@@ -567,14 +567,16 @@ public class QueryRecord {
567 return answerVariables[1].length > answerVariables[0].length; 567 return answerVariables[1].length > answerVariables[0].length;
568 } 568 }
569 569
570 /**
571 * A Json serializer, which considers the main attributes.
572 */
570 public static class QueryRecordSerializer implements JsonSerializer<QueryRecord> { 573 public static class QueryRecordSerializer implements JsonSerializer<QueryRecord> {
571
572 public JsonElement serialize(QueryRecord src, Type typeOfSrc, JsonSerializationContext context) { 574 public JsonElement serialize(QueryRecord src, Type typeOfSrc, JsonSerializationContext context) {
573 Gson gson = new GsonBuilder().setPrettyPrinting().create(); 575 Gson gson = new GsonBuilder().setPrettyPrinting().create();
574 JsonObject object = new JsonObject(); 576 JsonObject object = new JsonObject();
575 object.addProperty("queryID", src.queryID); 577 object.addProperty("queryID", src.queryID);
576 object.addProperty("queryText", src.queryText); 578 object.addProperty("queryText", src.queryText);
577 object.addProperty("difficulty", src.diffculty.toString()); 579 object.addProperty("difficulty", src.difficulty != null ? src.difficulty.toString() : "");
578 580
579 object.add("answerVariables", context.serialize(src.getAnswerVariables())); 581 object.add("answerVariables", context.serialize(src.getAnswerVariables()));
580 object.add("answers", context.serialize(src.soundAnswerTuples)); 582 object.add("answers", context.serialize(src.soundAnswerTuples));
@@ -586,8 +588,10 @@ public class QueryRecord {
586 588
587 private QueryRecord() { } 589 private QueryRecord() { }
588 590
589 public class QueryRecordDeserializer implements JsonDeserializer<QueryRecord> { 591 /**
590 592 * A Json deserializer, compliant to the output of the serializer defined above.
593 */
594 public static class QueryRecordDeserializer implements JsonDeserializer<QueryRecord> {
591 public QueryRecord deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) 595 public QueryRecord deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
592 throws JsonParseException { 596 throws JsonParseException {
593 597
@@ -595,6 +599,7 @@ public class QueryRecord {
595 JsonObject object = json.getAsJsonObject(); 599 JsonObject object = json.getAsJsonObject();
596 record.queryID = object.getAsJsonPrimitive("queryID").getAsInt(); 600 record.queryID = object.getAsJsonPrimitive("queryID").getAsInt();
597 record.queryText = object.getAsJsonPrimitive("queryText").getAsString(); 601 record.queryText = object.getAsJsonPrimitive("queryText").getAsString();
602 record.difficulty = Step.valueOf(object.getAsJsonPrimitive("difficulty").getAsString());
598 603
599 JsonArray answerVariablesJson = object.getAsJsonArray("answerVariables"); 604 JsonArray answerVariablesJson = object.getAsJsonArray("answerVariables");
600 record.answerVariables = new String[2][]; 605 record.answerVariables = new String[2][];
@@ -602,52 +607,63 @@ public class QueryRecord {
602 for(int i = 0; i < answerVariablesJson.size(); i++) 607 for(int i = 0; i < answerVariablesJson.size(); i++)
603 record.answerVariables[0][i] = answerVariablesJson.get(i).getAsString(); 608 record.answerVariables[0][i] = answerVariablesJson.get(i).getAsString();
604 609
605 record.soundAnswerTuples = context.deserialize(object.getAsJsonObject("answers"), 610 record.soundAnswerTuples = new HashSet<>();
606 new TypeToken<Set<AnswerTuple>>() {}.getType()); 611 record.gapAnswerTuples = new HashSet<>();
612 Type type = new TypeToken<AnswerTuple>() { }.getType();
613 for (JsonElement answer : object.getAsJsonArray("answers")) {
614 record.soundAnswerTuples.add(context.deserialize(answer, type));
615 }
616 for (JsonElement answer : object.getAsJsonArray("gapAnswers")) {
617 record.soundAnswerTuples.add(context.deserialize(answer, type));
618 }
607 619
608 record.gapAnswerTuples = context.deserialize(object.getAsJsonObject("gapAnswers"), 620 return record;
609 new TypeToken<Set<AnswerTuple>>() {}.getType());
610 return null;
611 } 621 }
612 } 622 }
613 623
614 /* 624 /**
615 * Two QueryRecords are equal iff 625 * Two <tt>QueryRecords</tt> are equal iff
616 * they have the same queryText and 626 * they have the same <tt>queryText</tt>,
617 * their AnswerTuples have the same string representation 627 * <tt>soundAnswerTuples</tt>
628 * and <tt>gapAnswerTuples</tt>.
618 * */ 629 * */
619 @Override 630 @Override
620 public boolean equals(Object o) { 631 public boolean equals(Object o) {
621 if(!o.getClass().equals(getClass())) return false; 632 if(!o.getClass().equals(getClass())) return false;
622 QueryRecord that = (QueryRecord) o; 633 QueryRecord that = (QueryRecord) o;
634 return this.queryText.equals(that.queryText)
635 && soundAnswerTuples.equals(that.soundAnswerTuples)
636 && gapAnswerTuples.equals(that.gapAnswerTuples);
637 }
623 638
624 if(!this.queryText.equals(that.queryText)) return false; 639 @Override
625 640 public int hashCode() {
626 if(soundAnswerTuples.size() != that.soundAnswerTuples.size()) return false; 641 return Objects.hash(queryText, soundAnswerTuples, gapAnswerTuples);
627 if(gapAnswerTuples.size() != that.gapAnswerTuples.size()) return false; 642 }
628
629 ArrayList<AnswerTuple> thisSoundAnswers = new ArrayList<>(soundAnswerTuples);
630 Collections.sort(thisSoundAnswers, (AnswerTuple t1, AnswerTuple t2) -> t1.m_str.compareTo(t2.m_str));
631 643
632 ArrayList<AnswerTuple> thatSoundAnswers = new ArrayList<>(that.soundAnswerTuples); 644 public static class GsonCreator {
633 Collections.sort(thatSoundAnswers, (AnswerTuple t1, AnswerTuple t2) -> t1.m_str.compareTo(t2.m_str));
634 645
635 Iterator<AnswerTuple> soundIt1 = this.soundAnswerTuples.iterator(); 646 private static Gson gson;
636 Iterator<AnswerTuple> soundIt2 = that.soundAnswerTuples.iterator();
637 while(soundIt1.hasNext() && soundIt2.hasNext())
638 if(!soundIt1.next().m_str.equals(soundIt2.next().m_str)) return false;
639 647
640 ArrayList<AnswerTuple> thisGapAnswers = new ArrayList<>(gapAnswerTuples); 648 private GsonCreator() {}
641 Collections.sort(thisGapAnswers, (AnswerTuple t1, AnswerTuple t2) -> t1.m_str.compareTo(t2.m_str));
642 649
643 ArrayList<AnswerTuple> thatGapAnswers = new ArrayList<>(that.gapAnswerTuples); 650 public static Gson getInstance() {
644 Collections.sort(thatGapAnswers, (AnswerTuple t1, AnswerTuple t2) -> t1.m_str.compareTo(t2.m_str)); 651 if(gson == null) {
652 gson = new GsonBuilder()
653 .registerTypeAdapter(AnswerTuple.class, new AnswerTuple.AnswerTupleSerializer())
654 .registerTypeAdapter(QueryRecord.class, new QueryRecord.QueryRecordSerializer())
655 .registerTypeAdapter(QueryRecord.class, new QueryRecord.QueryRecordDeserializer())
656 .registerTypeAdapter(AnswerTuple.class, new AnswerTuple.AnswerTupleDeserializer())
657 .disableHtmlEscaping()
658 .setPrettyPrinting()
659 .create();
660 }
661 return gson;
662 }
645 663
646 Iterator<AnswerTuple> gapIt1 = this.gapAnswerTuples.iterator(); 664// public static void dispose() {
647 Iterator<AnswerTuple> gapIt2 = that.gapAnswerTuples.iterator(); 665// gson = null;
648 while(gapIt1.hasNext() && gapIt2.hasNext()) 666// }
649 if(!gapIt1.next().m_str.equals(gapIt2.next().m_str)) return false;
650 667
651 return true;
652 } 668 }
653} 669}