Fixed redundancy in collection rewrite.

Change-Id: Ieb861be5a0a264d2d4bd4b1c2e38c7e8debf4f0c
diff --git a/src/main/java/de/ids_mannheim/korap/resource/rewrite/CollectionRewrite.java b/src/main/java/de/ids_mannheim/korap/resource/rewrite/CollectionRewrite.java
index 1de7d2f..54b5457 100644
--- a/src/main/java/de/ids_mannheim/korap/resource/rewrite/CollectionRewrite.java
+++ b/src/main/java/de/ids_mannheim/korap/resource/rewrite/CollectionRewrite.java
@@ -1,64 +1,103 @@
 package de.ids_mannheim.korap.resource.rewrite;
 
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.fasterxml.jackson.databind.JsonNode;
+import com.google.common.collect.Lists;
 
 import de.ids_mannheim.korap.config.Attributes;
 import de.ids_mannheim.korap.config.KustvaktConfiguration;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.query.object.KoralMatchOperator;
 import de.ids_mannheim.korap.resource.rewrite.KoralNode.RewriteIdentifier;
 import de.ids_mannheim.korap.user.User;
+import de.ids_mannheim.korap.user.User.CorpusAccess;
 import de.ids_mannheim.korap.utils.JsonUtils;
 import de.ids_mannheim.korap.utils.KoralCollectionQueryBuilder;
 
 /**
  * @author margaretha
- * @date 30 May 2017
+ * @date 2 June 2017
  */
 public class CollectionRewrite implements RewriteTask.RewriteQuery {
 
     private static Logger jlog = LoggerFactory
             .getLogger(CollectionRewrite.class);
-    public static String AVAILABILITY = "availability";
-
 
     public CollectionRewrite () {
         super();
     }
 
+    
+    private List<String> checkAvailability (JsonNode node, List<String> userAvailabilities) {
+
+        if (node.has("operands")) {
+            ArrayList<JsonNode> operands = Lists
+                    .newArrayList(node.at("/operands").elements());
+            for (int i = 0; i < operands.size(); i++) {
+                userAvailabilities = checkAvailability(operands.get(i), userAvailabilities);
+            }
+        }
+        else if (node.has("key")
+                && node.at("/key").asText().equals("availability")) {
+            String queryAvailability = node.at("/value").asText();
+            String matchOp = node.at("/match").asText();
+            if (userAvailabilities.contains(queryAvailability) && matchOp.
+                    equals(KoralMatchOperator.EQUALS.toString())){
+                userAvailabilities.remove(queryAvailability);
+            }
+        }
+
+        return userAvailabilities;
+    }
 
     @Override
     public JsonNode rewriteQuery (KoralNode node, KustvaktConfiguration config,
             User user) throws KustvaktException {
         JsonNode jsonNode = node.rawNode();
-        KoralCollectionQueryBuilder builder = new KoralCollectionQueryBuilder();
+        
+        List<String> userAvailabilities = new ArrayList<String>();
         switch (user.getCorpusAccess()) {
             case PUB:
-                builder.with(
-                        "availability = /CC-BY.*/ | availability = /ACA.*/");
+                userAvailabilities.add("CC-BY.*");
+                userAvailabilities.add("ACA.*");
+//                builder.with(
+//                        "availability = /CC-BY.*/ | availability = /ACA.*/");
                 break;
             case ALL:
-                builder.with("availability = /QAO.*/ | availability = /ACA.*/ |"
-                        + "  availability = /CC-BY.*/");
+                userAvailabilities.add("CC-BY.*");
+                userAvailabilities.add("ACA.*");
+                userAvailabilities.add("QAO.*");
+
+//                builder.with("availability = /QAO.*/ | availability = /ACA.*/ |"
+//                        + "  availability = /CC-BY.*/");
                 break;
             case FREE:
-                builder.with("availability   = /CC-BY.*/");
+                userAvailabilities.add("CC-BY.*");
+//                builder.with("availability   = /CC-BY.*/");
                 break;
         }
 
+        KoralCollectionQueryBuilder builder = new KoralCollectionQueryBuilder();
         RewriteIdentifier identifier = new KoralNode.RewriteIdentifier(
                 Attributes.AVAILABILITY, user.getCorpusAccess());
         JsonNode rewrittesNode;
 
         if (jsonNode.has("collection")) {
+            userAvailabilities = checkAvailability(jsonNode.at("/collection"), userAvailabilities);
+            builder.with(buildAvailability(userAvailabilities));
             builder.setBaseQuery(builder.toJSON());
             rewrittesNode = builder.mergeWith(jsonNode).at("/collection");
             node.set("collection", rewrittesNode, identifier);
         }
         else {
+            builder.with(buildAvailability(userAvailabilities));
             rewrittesNode = JsonUtils.readTree(builder.toJSON())
                     .at("/collection");
             node.set("collection", rewrittesNode, identifier);
@@ -67,4 +106,19 @@
         jlog.info("REWRITES: " + node.at("/collection").toString());
         return node.rawNode();
     }
+    
+    
+    private String buildAvailability (List<String> userAvailabilities) {
+        StringBuilder sb = new StringBuilder();
+        for (int i=0; i < userAvailabilities.size()-1; i++){
+            sb.append("availability=/");
+            sb.append(userAvailabilities.get(i));
+            sb.append("/ | ");
+        }
+        sb.append("availability=/");
+        sb.append(userAvailabilities.get(userAvailabilities.size()-1));
+        sb.append("/");
+        return sb.toString();
+    }
 }
+
diff --git a/src/test/java/de/ids_mannheim/korap/web/service/full/SearchWithAvailabilityTest.java b/src/test/java/de/ids_mannheim/korap/web/service/full/SearchWithAvailabilityTest.java
index b2f46b0..407dcf0 100644
--- a/src/test/java/de/ids_mannheim/korap/web/service/full/SearchWithAvailabilityTest.java
+++ b/src/test/java/de/ids_mannheim/korap/web/service/full/SearchWithAvailabilityTest.java
@@ -67,6 +67,35 @@
                 node.at("/collection/rewrites/0/scope").asText());
     }
     
+    private void checkAndPublicWithoutACA (String json) {
+        JsonNode node = JsonUtils.readTree(json);
+        assertNotNull(node);
+        assertEquals("operation:and",
+                node.at("/collection/operation").asText());
+        assertEquals("match:eq",
+                node.at("/collection/operands/0/match").asText());
+        assertEquals("type:regex",
+                node.at("/collection/operands/0/type").asText());
+        assertEquals("availability",
+                node.at("/collection/operands/0/key").asText());
+        assertEquals("CC-BY.*",
+                node.at("/collection/operands/0/value").asText());
+        
+        assertEquals("match:eq",
+                node.at("/collection/operands/1/match").asText());
+        assertEquals("type:regex",
+                node.at("/collection/operands/1/type").asText());
+        assertEquals("availability",
+                node.at("/collection/operands/1/key").asText());
+        assertEquals("ACA.*",
+                node.at("/collection/operands/1/value").asText());
+        
+        assertEquals("operation:insertion",
+                node.at("/collection/rewrites/0/operation").asText());
+        assertEquals("availability(PUB)",
+                node.at("/collection/rewrites/0/scope").asText());
+    }
+    
     private void checkAndAll (String json) {
         JsonNode node = JsonUtils.readTree(json);
         assertNotNull(node);
@@ -90,7 +119,7 @@
                 node.at("/operands/0/type").asText());
         assertEquals("availability",
                 node.at("/operands/0/key").asText());
-        assertEquals("QAO.*",
+        assertEquals("CC-BY.*",
                 node.at("/operands/0/value").asText());
         
         node = node.at("/operands/1");
@@ -102,11 +131,35 @@
                 node.at("/operands/0/value").asText());
         assertEquals("match:eq",
                 node.at("/operands/1/match").asText());
-        assertEquals("CC-BY.*",
+        assertEquals("QAO.*",
                 node.at("/operands/1/value").asText());
         
     }
 
+    private void checkAndAllWithoutACA (String json) {
+        JsonNode node = JsonUtils.readTree(json);
+        assertNotNull(node);
+        assertEquals("operation:and",
+                node.at("/collection/operation").asText());
+        assertEquals("match:eq",
+                node.at("/collection/operands/0/operands/0/match").asText());
+        assertEquals("type:regex",
+                node.at("/collection/operands/0/operands/0/type").asText());
+        assertEquals("availability",
+                node.at("/collection/operands/0/operands/0/key").asText());
+        assertEquals("CC-BY.*",
+                node.at("/collection/operands/0/operands/0/value").asText());
+        assertEquals("match:eq",
+                node.at("/collection/operands/0/operands/1/match").asText());
+        assertEquals("QAO.*",
+                node.at("/collection/operands/0/operands/1/value").asText());
+        assertEquals("operation:insertion",
+                node.at("/collection/rewrites/0/operation").asText());
+        assertEquals("availability(ALL)",
+                node.at("/collection/rewrites/0/scope").asText());
+    }
+    
+    
 
     private ClientResponse builtSimpleClientResponse (String collectionQuery) {
         return resource().path(getAPIVersion()).path("search")
@@ -269,7 +322,7 @@
         assertEquals(ClientResponse.Status.OK.getStatusCode(),
                 response.getStatus());
 
-        checkAndPublic(response.getEntity(String.class));
+        checkAndPublicWithoutACA(response.getEntity(String.class));
     }
 
 
@@ -327,7 +380,7 @@
         assertEquals(ClientResponse.Status.OK.getStatusCode(),
                 response.getStatus());
 
-        checkAndAll(response.getEntity(String.class));
+        checkAndAllWithoutACA(response.getEntity(String.class));
     }
     
 }