Implemented Timeout rewrite.

Change-Id: Icdbb54451e29b8978f7a5749486cb7adee23327f
diff --git a/src/main/java/de/ids_mannheim/korap/config/KustvaktConfiguration.java b/src/main/java/de/ids_mannheim/korap/config/KustvaktConfiguration.java
index e6d2fca..658208e 100644
--- a/src/main/java/de/ids_mannheim/korap/config/KustvaktConfiguration.java
+++ b/src/main/java/de/ids_mannheim/korap/config/KustvaktConfiguration.java
@@ -118,6 +118,9 @@
     // another variable might be needed to define which metadata fields are restricted 
     private boolean isMetadataRestricted = false;
     private boolean totalResultCacheEnabled;
+    
+    private int guestTimeout;
+    private int loginTimeout;
 
     // EM: Maybe needed when we support pipe registration
     @Deprecated
@@ -230,6 +233,13 @@
 
         maxTokenContext = Integer.parseInt(properties.getProperty(
                 "max.token.context.size", "0"));
+        
+        // Timeout validity in milis
+        guestTimeout = Integer.parseInt(properties.getProperty(
+                "timeout.guest", "10000"));
+        loginTimeout = Integer.parseInt(properties.getProperty(
+                "timeout.login", "90000"));
+        
     }
 
     @Deprecated
diff --git a/src/main/java/de/ids_mannheim/korap/core/service/SearchService.java b/src/main/java/de/ids_mannheim/korap/core/service/SearchService.java
index 8647962..eeddaba 100644
--- a/src/main/java/de/ids_mannheim/korap/core/service/SearchService.java
+++ b/src/main/java/de/ids_mannheim/korap/core/service/SearchService.java
@@ -418,10 +418,10 @@
         // meta.addEntry("itemsPerResource", 1);
 
         if (corpusAccess.equals(CorpusAccess.FREE)) {
-            meta.addEntry("timeout", 10000);
+            meta.addEntry("timeout", config.getGuestTimeout());
         }
         else {
-            meta.addEntry("timeout", 90000);
+            meta.addEntry("timeout", config.getLoginTimeout());
         }
 
         if (fieldList != null && !fieldList.isEmpty()) {
diff --git a/src/main/java/de/ids_mannheim/korap/rewrite/QueryContextRewrite.java b/src/main/java/de/ids_mannheim/korap/rewrite/QueryContextRewrite.java
index 0494fa4..e5f3bee 100644
--- a/src/main/java/de/ids_mannheim/korap/rewrite/QueryContextRewrite.java
+++ b/src/main/java/de/ids_mannheim/korap/rewrite/QueryContextRewrite.java
@@ -47,7 +47,7 @@
 				context.replace(position, arrayNode,
 						new RewriteIdentifier(position, sourceNode, position
 								+ " has been replaced. The original value is "
-								+ "described in the source property."));
+								+ "described in the original property."));
                 return true;
             }
         }
diff --git a/src/main/java/de/ids_mannheim/korap/rewrite/QueryReferenceRewrite.java b/src/main/java/de/ids_mannheim/korap/rewrite/QueryReferenceRewrite.java
index b70dbf1..e5f6a36 100644
--- a/src/main/java/de/ids_mannheim/korap/rewrite/QueryReferenceRewrite.java
+++ b/src/main/java/de/ids_mannheim/korap/rewrite/QueryReferenceRewrite.java
@@ -93,7 +93,7 @@
         JsonNode sourceNode = JsonUtils.readTree(source);
 		koralNode.replace(qref, new RewriteIdentifier(null, sourceNode,
 				"This node has been replaced. The original node is described in "
-				+ "the source property."));
+				+ "the original property."));
         
 //        koralNode.remove("@type",
 //                new RewriteIdentifier("@type", "", jsonNode.at("/@type").asText()));
diff --git a/src/main/java/de/ids_mannheim/korap/rewrite/RewriteIdentifier.java b/src/main/java/de/ids_mannheim/korap/rewrite/RewriteIdentifier.java
index 583c9ec..44fadd4 100644
--- a/src/main/java/de/ids_mannheim/korap/rewrite/RewriteIdentifier.java
+++ b/src/main/java/de/ids_mannheim/korap/rewrite/RewriteIdentifier.java
@@ -5,15 +5,15 @@
     private String scope,comment = "";
     private Object original;
 
-    public RewriteIdentifier (String scope, String value, String comment) {
+    public RewriteIdentifier (String scope, String original, String comment) {
         this.scope = scope;
-        this.original = value;
+        this.original = original;
         this.comment = comment;
     }
     
-	public RewriteIdentifier (String scope, Object source, String comment) {
+	public RewriteIdentifier (String scope, Object original, String comment) {
 		this.scope = scope;
-		this.original = source;
+		this.original = original;
 		this.comment = comment;
 	}
     
diff --git a/src/main/java/de/ids_mannheim/korap/rewrite/TimeoutRewrite.java b/src/main/java/de/ids_mannheim/korap/rewrite/TimeoutRewrite.java
new file mode 100644
index 0000000..a467ce5
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/rewrite/TimeoutRewrite.java
@@ -0,0 +1,35 @@
+package de.ids_mannheim.korap.rewrite;
+
+import de.ids_mannheim.korap.config.KustvaktConfiguration;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.user.User;
+import de.ids_mannheim.korap.user.User.CorpusAccess;
+
+public class TimeoutRewrite implements RewriteTask.RewriteQuery {
+
+	@Override
+	public KoralNode rewriteQuery (KoralNode node, KustvaktConfiguration config,
+			User user) throws KustvaktException {
+		CorpusAccess access = user.getCorpusAccess();
+		if (node.has("meta")) {
+            node = node.at("/meta");
+            int timeout = (access.equals(CorpusAccess.FREE)) ?
+				config.getGuestTimeout() : config.getLoginTimeout();
+            
+			if (node.has("timeout")) {
+				RewriteIdentifier id = new RewriteIdentifier("timeout",
+						node.get("timeout"), "Timeout has been replaced. "
+						+ "The original value is described in the original "
+						+ "property.");
+				node.replace("timeout", timeout, id);
+			}
+            else {
+            	RewriteIdentifier id = new RewriteIdentifier("timeout", null, 
+            			"Timeout has been added.");
+            	node.set("timeout", timeout, id);
+            }
+        }
+		return node;
+	}
+
+}
diff --git a/src/main/java/de/ids_mannheim/korap/rewrite/VirtualCorpusRewrite.java b/src/main/java/de/ids_mannheim/korap/rewrite/VirtualCorpusRewrite.java
index 7dc4219..ca8673e 100644
--- a/src/main/java/de/ids_mannheim/korap/rewrite/VirtualCorpusRewrite.java
+++ b/src/main/java/de/ids_mannheim/korap/rewrite/VirtualCorpusRewrite.java
@@ -100,7 +100,7 @@
         String newRef = ref.substring(vcOwner.length() + 1, ref.length());
         koralNode.replace("ref", newRef, new RewriteIdentifier("ref", ref, 
         		"Ref has been replaced. The original value is described at "
-        		+ "the source property."));
+        		+ "the original property."));
     }
 
     protected void rewriteVC (QueryDO vc, KoralNode koralNode)
@@ -113,7 +113,7 @@
         
 		koralNode.replace(newKoralQuery, new RewriteIdentifier(null, sourceNode,
 				"This node has been replaced. The original node is described at "
-						+ "the source property."));
+						+ "the original property."));
         
         // rewrite
 //        koralNode.remove("@type", new RewriteIdentifier("@type", "",
diff --git a/src/test/java/de/ids_mannheim/korap/rewrite/TimeoutRewriteTest.java b/src/test/java/de/ids_mannheim/korap/rewrite/TimeoutRewriteTest.java
new file mode 100644
index 0000000..43146ed
--- /dev/null
+++ b/src/test/java/de/ids_mannheim/korap/rewrite/TimeoutRewriteTest.java
@@ -0,0 +1,63 @@
+package de.ids_mannheim.korap.rewrite;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+import de.ids_mannheim.korap.config.KustvaktConfiguration;
+import de.ids_mannheim.korap.config.SpringJerseyTest;
+import de.ids_mannheim.korap.config.TestVariables;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.query.serialize.QuerySerializer;
+import de.ids_mannheim.korap.user.User;
+import de.ids_mannheim.korap.utils.JsonUtils;
+
+public class TimeoutRewriteTest extends SpringJerseyTest {
+
+	@Autowired
+	public KustvaktConfiguration config;
+
+	@Test
+	public void testReplaceTimeout () throws KustvaktException {
+		RewriteHandler handler = new RewriteHandler(config);
+        handler.add(TimeoutRewrite.class);
+        
+        Map<String, Object> map = new HashMap<String,Object>();
+        map.put("count", 25);
+        map.put("timeout", 50000);
+        QuerySerializer s = new QuerySerializer();
+        s.setQuery(TestVariables.SIMPLE_ADD_QUERY, "poliqarp");
+        s.setMeta(map);
+        String result = s.toJSON();
+        JsonNode node = JsonUtils.readTree(handler.processQuery(result,
+                User.UserFactory.getUser("test_user")));
+        
+        node = node.at("/meta"); 
+        assertEquals(10000, node.at("/timeout").asInt());
+        assertEquals(50000, node.at("/rewrites/0/original").asInt());
+	}
+	
+	@Test
+	public void testAddTimeout () throws KustvaktException {
+		RewriteHandler handler = new RewriteHandler(config);
+        handler.add(TimeoutRewrite.class);
+        
+        Map<String, Object> map = new HashMap<String,Object>();
+        map.put("count", 25);
+        QuerySerializer s = new QuerySerializer();
+        s.setQuery(TestVariables.SIMPLE_ADD_QUERY, "poliqarp");
+        s.setMeta(map);
+        String result = s.toJSON();
+        JsonNode node = JsonUtils.readTree(handler.processQuery(result,
+                User.UserFactory.getUser("test_user")));
+        
+        node = node.at("/meta"); 
+        assertEquals(10000, node.at("/timeout").asInt());
+	}
+}
diff --git a/src/test/resources/test-config.xml b/src/test/resources/test-config.xml
index 7a95588..5fd5ff2 100644
--- a/src/test/resources/test-config.xml
+++ b/src/test/resources/test-config.xml
@@ -214,6 +214,8 @@
 	<!-- Rewrite -->
 	<bean id="foundryRewrite"
 		class="de.ids_mannheim.korap.rewrite.FoundryRewrite" />
+	<bean id="timeoutRewrite"
+	class="de.ids_mannheim.korap.rewrite.TimeoutRewrite" />	
 	<bean id="availabilityRewrite"
 		class="de.ids_mannheim.korap.rewrite.AvailabilityRewrite" />
 	<bean id="virtualCorpusRewrite"
@@ -227,6 +229,7 @@
 	<util:list id="rewriteTasks"
 		value-type="de.ids_mannheim.korap.rewrite.RewriteTask">
 		<ref bean="foundryRewrite" />
+		<ref bean="timeoutRewrite" />
 		<ref bean="availabilityRewrite" />
 		<ref bean="virtualCorpusRewrite" />
 		<ref bean="queryReferenceRewrite" />
@@ -241,6 +244,7 @@
 	<util:list id="statisticsRewriteTasks"
 		value-type="de.ids_mannheim.korap.rewrite.RewriteTask">
 		<ref bean="foundryRewrite" />
+		<ref bean="timeoutRewrite" />
 		<ref bean="virtualCorpusRewrite" />
 		<ref bean="queryReferenceRewrite" />
 	</util:list>