Introduced query reference rewrite mechanism
Change-Id: If05c5d6b4a1071d72bc7e7293d6130393a00ca87
diff --git a/full/src/main/java/de/ids_mannheim/korap/rewrite/QueryReferenceRewrite.java b/full/src/main/java/de/ids_mannheim/korap/rewrite/QueryReferenceRewrite.java
new file mode 100644
index 0000000..aab0b77
--- /dev/null
+++ b/full/src/main/java/de/ids_mannheim/korap/rewrite/QueryReferenceRewrite.java
@@ -0,0 +1,110 @@
+package de.ids_mannheim.korap.rewrite;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+import de.ids_mannheim.korap.config.KustvaktConfiguration;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.rewrite.KoralNode.RewriteIdentifier;
+import de.ids_mannheim.korap.service.QueryReferenceService;
+import de.ids_mannheim.korap.user.User;
+import de.ids_mannheim.korap.util.StatusCodes;
+import de.ids_mannheim.korap.utils.JsonUtils;
+
+/**
+ * Rewrites query reference with the corresponding koral
+ * query describing the actual query fragment.
+ *
+ * Based on VirtualCorpusRewrite.
+ *
+ * @author diewald, margaretha
+ *
+ */
+@Component
+public class QueryReferenceRewrite implements RewriteTask.RewriteQuery {
+
+ @Autowired
+ private KustvaktConfiguration config;
+
+ @Autowired
+ private QueryReferenceService refService;
+
+ @Override
+ public KoralNode rewriteQuery (KoralNode node,
+ KustvaktConfiguration config,
+ User user) throws KustvaktException {
+ if (node.has("query")) {
+ node = node.at("/query");
+ findQueryRef(user.getUsername(), node);
+ }
+ return node;
+ }
+
+ private void findQueryRef (String username, KoralNode koralNode)
+ throws KustvaktException {
+ if (koralNode.has("@type")
+ && koralNode.get("@type").equals("koral:queryRef")) {
+ if (!koralNode.has("ref")) {
+ throw new KustvaktException(
+ StatusCodes.MISSING_QUERY_REFERENCE,
+ "ref is not found"
+ );
+ }
+ else {
+ String queryRefName = koralNode.get("ref");
+ String queryRefOwner = "system";
+ boolean ownerExist = false;
+ if (queryRefName.contains("/")) {
+ String[] names = queryRefName.split("/");
+ if (names.length == 2) {
+ queryRefOwner = names[0];
+ queryRefName = names[1];
+ ownerExist = true;
+ }
+ }
+
+ JsonNode qref = refService.searchQueryByName(
+ username,
+ queryRefName,
+ queryRefOwner);
+
+ rewriteQuery(qref,koralNode);
+ }
+ }
+
+ else if (koralNode.has("operands")) {
+ KoralNode operands = koralNode.at("/operands");
+
+ for (int i = 0; i < operands.size(); i++) {
+ KoralNode operand = operands.get(i);
+ this.findQueryRef(username, operand);
+ operand.buildRewrites();
+ }
+ }
+ }
+
+
+ private void removeOwner (String koralQuery,
+ String queryRefOwner,
+ KoralNode koralNode) throws KustvaktException {
+ JsonNode jsonNode = koralNode.rawNode();
+ String ref = jsonNode.at("/ref").asText();
+ koralNode.remove("ref", new RewriteIdentifier("ref", ref));
+
+ ref = ref.substring(queryRefOwner.length() + 1, ref.length());
+ koralNode.set("ref", ref, new RewriteIdentifier("ref", ref));
+ }
+
+ private void rewriteQuery (JsonNode qref, KoralNode koralNode)
+ throws KustvaktException {
+ JsonNode jsonNode = koralNode.rawNode();
+ koralNode.remove("@type",
+ new RewriteIdentifier("@type", jsonNode.at("/@type").asText()));
+ koralNode.remove("ref",
+ new RewriteIdentifier("ref", jsonNode.at("/ref").asText()));
+ koralNode.setAll((ObjectNode) qref);
+ }
+}
diff --git a/full/src/main/java/de/ids_mannheim/korap/service/QueryReferenceService.java b/full/src/main/java/de/ids_mannheim/korap/service/QueryReferenceService.java
new file mode 100644
index 0000000..eb99f68
--- /dev/null
+++ b/full/src/main/java/de/ids_mannheim/korap/service/QueryReferenceService.java
@@ -0,0 +1,34 @@
+package de.ids_mannheim.korap.service;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.exceptions.StatusCodes;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import de.ids_mannheim.korap.utils.JsonUtils;
+
+/**
+ * @author diewald
+ */
+@Service
+public class QueryReferenceService {
+
+
+ public JsonNode searchQueryByName (String username,
+ String refName,
+ String createdBy) throws KustvaktException {
+
+ String refCode = createdBy + "/" + refName;
+
+ if (refCode.equals("system/emptyToken")) {
+ return JsonUtils.readTree("{\"@type\":\"koral:token\"}");
+ };
+
+ throw new KustvaktException(
+ StatusCodes.NO_RESOURCE_FOUND,
+ "Query reference " + refCode + " is not found.",
+ String.valueOf(refCode));
+ }
+};
diff --git a/full/src/main/resources/default-config.xml b/full/src/main/resources/default-config.xml
index bd25718..c1da94b 100644
--- a/full/src/main/resources/default-config.xml
+++ b/full/src/main/resources/default-config.xml
@@ -220,12 +220,14 @@
<bean id="foundryRewrite" class="de.ids_mannheim.korap.rewrite.FoundryRewrite"/>
<bean id="collectionRewrite" class="de.ids_mannheim.korap.rewrite.CollectionRewrite"/>
<bean id="virtualCorpusRewrite" class="de.ids_mannheim.korap.rewrite.VirtualCorpusRewrite"/>
+ <bean id="queryReferenceRewrite" class="de.ids_mannheim.korap.rewrite.QueryReferenceRewrite"/>
<util:list id="rewriteTasks"
value-type="de.ids_mannheim.korap.rewrite.RewriteTask">
<ref bean="foundryRewrite" />
<ref bean="collectionRewrite" />
<ref bean="virtualCorpusRewrite" />
+ <ref bean="queryReferenceRewrite" />
</util:list>
<bean id="rewriteHandler" class="de.ids_mannheim.korap.rewrite.RewriteHandler">
@@ -389,4 +391,4 @@
</props>
</constructor-arg>
</bean>
-</beans>
\ No newline at end of file
+</beans>
diff --git a/full/src/test/java/de/ids_mannheim/korap/rewrite/QueryRewriteTest.java b/full/src/test/java/de/ids_mannheim/korap/rewrite/QueryRewriteTest.java
new file mode 100644
index 0000000..5cae6bc
--- /dev/null
+++ b/full/src/test/java/de/ids_mannheim/korap/rewrite/QueryRewriteTest.java
@@ -0,0 +1,55 @@
+package de.ids_mannheim.korap.rewrite;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+
+import org.junit.Test;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.google.common.net.HttpHeaders;
+import com.sun.jersey.api.client.ClientResponse;
+
+import de.ids_mannheim.korap.authentication.http.HttpAuthorizationHandler;
+import de.ids_mannheim.korap.config.Attributes;
+import de.ids_mannheim.korap.config.SpringJerseyTest;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.util.QueryException;
+import de.ids_mannheim.korap.utils.JsonUtils;
+
+/**
+ * @author diewald
+ *
+ */
+public class QueryRewriteTest extends SpringJerseyTest {
+
+ @Test
+ public void testRewriteRefNotFound ()
+ throws KustvaktException, Exception {
+
+ ClientResponse response = resource().path(API_VERSION).path("search")
+ .queryParam("q", "[orth=der]{%23examplequery} Baum")
+ .queryParam("ql", "poliqarp")
+ .get(ClientResponse.class);
+
+ String ent = response.getEntity(String.class);
+ JsonNode node = JsonUtils.readTree(ent);
+ assertEquals(node.at("/errors/0/1").asText(), "Query reference system/examplequery is not found.");
+ }
+
+ @Test
+ public void testRewriteRefRewrite ()
+ throws KustvaktException, Exception {
+
+ ClientResponse response = resource().path(API_VERSION).path("search")
+ .queryParam("q", "[orth=der]{%23system/emptyToken} Baum")
+ .queryParam("ql", "poliqarp")
+ .get(ClientResponse.class);
+
+ String ent = response.getEntity(String.class);
+ JsonNode node = JsonUtils.readTree(ent);
+ assertEquals("koral:token", node.at("/query/operands/1/@type").asText());
+ assertEquals("@type(koral:queryRef)", node.at("/query/operands/1/rewrites/0/scope").asText());
+ }
+}
diff --git a/full/src/test/resources/test-config.xml b/full/src/test/resources/test-config.xml
index 82b314e..b9f5e07 100644
--- a/full/src/test/resources/test-config.xml
+++ b/full/src/test/resources/test-config.xml
@@ -203,6 +203,7 @@
<bean id="collectionCleanRewrite" class="de.ids_mannheim.korap.rewrite.CollectionCleanRewrite"/>
<bean id="virtualCorpusRewrite" class="de.ids_mannheim.korap.rewrite.VirtualCorpusRewrite"/>
<bean id="collectionConstraint" class="de.ids_mannheim.korap.rewrite.CollectionConstraint"/>
+ <bean id="queryReferenceRewrite" class="de.ids_mannheim.korap.rewrite.QueryReferenceRewrite"/>
<util:list id="rewriteTasks"
value-type="de.ids_mannheim.korap.rewrite.RewriteTask">
@@ -211,6 +212,7 @@
<ref bean="foundryRewrite" />
<ref bean="collectionRewrite" />
<ref bean="virtualCorpusRewrite" />
+ <ref bean="queryReferenceRewrite" />
</util:list>
<bean id="rewriteHandler" class="de.ids_mannheim.korap.rewrite.RewriteHandler">
@@ -375,4 +377,4 @@
</props>
</constructor-arg>
</bean>
-</beans>
\ No newline at end of file
+</beans>