Fixed collection rewrite regarding OR operation with other fields.

Change-Id: I89ff58eee9ee2378dfc4678491c713c8d23bc437
diff --git a/full/src/main/java/de/ids_mannheim/korap/rewrite/CollectionRewrite.java b/full/src/main/java/de/ids_mannheim/korap/rewrite/CollectionRewrite.java
index 7f7370a..1ab70a3 100644
--- a/full/src/main/java/de/ids_mannheim/korap/rewrite/CollectionRewrite.java
+++ b/full/src/main/java/de/ids_mannheim/korap/rewrite/CollectionRewrite.java
@@ -81,9 +81,20 @@
             }
             else {
                 for (int i = 0; i < operands.size(); i++) {
-                    updatedAvailabilities = checkAvailability(operands.get(i),
-                            originalAvailabilities, updatedAvailabilities,
-                            true);
+                    node = operands.get(i);
+                    if (node.has("key") && !node.at("/key").asText()
+                            .equals("availability")) {
+                        jlog.debug("RESET availabilities 1, key="
+                                + node.at("/key").asText());
+                        updatedAvailabilities.clear();
+                        updatedAvailabilities.addAll(originalAvailabilities);
+                        break;
+                    }
+                    else {
+                        updatedAvailabilities = checkAvailability(
+                                operands.get(i), originalAvailabilities,
+                                updatedAvailabilities, true);
+                    }
                 }
             }
         }
@@ -91,13 +102,14 @@
                 && node.at("/key").asText().equals("availability")) {
             String queryAvailability = node.at("/value").asText();
             String matchOp = node.at("/match").asText();
+
             if (originalAvailabilities.contains(queryAvailability)
                     && matchOp.equals(KoralMatchOperator.EQUALS.toString())) {
                 jlog.debug("REMOVE " + queryAvailability);
                 updatedAvailabilities.remove(queryAvailability);
             }
             else if (isOperationOr) {
-                jlog.debug("RESET availabilities");
+                jlog.debug("RESET availabilities 2");
                 updatedAvailabilities.clear();
                 updatedAvailabilities.addAll(originalAvailabilities);
                 return updatedAvailabilities;
@@ -110,7 +122,7 @@
     public JsonNode rewriteQuery (KoralNode node, KustvaktConfiguration config,
             User user) throws KustvaktException {
         JsonNode jsonNode = node.rawNode();
-        
+
         FullConfiguration fullConfig = (FullConfiguration) config;
 
         List<String> userAvailabilities = new ArrayList<String>();
@@ -145,7 +157,7 @@
                     avalabilityCopy, userAvailabilities, false);
             if (!userAvailabilities.isEmpty()) {
                 builder.with(buildAvailability(avalabilityCopy));
-                jlog.debug("corpus query: " +builder.toString());
+                jlog.debug("corpus query: " + builder.toString());
                 builder.setBaseQuery(builder.toJSON());
                 rewrittesNode = builder.mergeWith(jsonNode).at("/collection");
                 node.set("collection", rewrittesNode, identifier);
@@ -153,7 +165,7 @@
         }
         else {
             builder.with(buildAvailability(userAvailabilities));
-            jlog.debug("corpus query: " +builder.toString());
+            jlog.debug("corpus query: " + builder.toString());
             rewrittesNode =
                     JsonUtils.readTree(builder.toJSON()).at("/collection");
             node.set("collection", rewrittesNode, identifier);
@@ -169,27 +181,28 @@
         for (int i = 0; i < userAvailabilities.size(); i++) {
             parseAvailability(sb, userAvailabilities.get(i), "|");
         }
-        String availabilities = sb.toString(); 
-        return availabilities.substring(0, availabilities.length()-3);
+        String availabilities = sb.toString();
+        return availabilities.substring(0, availabilities.length() - 3);
     }
-    
-    private void parseAvailability (StringBuilder sb, String availability, String operator) {
+
+    private void parseAvailability (StringBuilder sb, String availability,
+            String operator) {
         String uaArr[] = null;
-        if (availability.contains("|")){
+        if (availability.contains("|")) {
             uaArr = availability.split("\\|");
-            for (int j=0; j < uaArr.length; j++){
+            for (int j = 0; j < uaArr.length; j++) {
                 parseAvailability(sb, uaArr[j].trim(), "|");
             }
         }
         // EM: not supported
-//        else if (availability.contains("&")){
-//            uaArr = availability.split("&");
-//            for (int j=0; j < uaArr.length -1; j++){
-//                parseAvailability(sb, uaArr[j], "&");
-//            }
-//            parseAvailability(sb, uaArr[uaArr.length-1], "|");
-//        } 
-        else{
+        //        else if (availability.contains("&")){
+        //            uaArr = availability.split("&");
+        //            for (int j=0; j < uaArr.length -1; j++){
+        //                parseAvailability(sb, uaArr[j], "&");
+        //            }
+        //            parseAvailability(sb, uaArr[uaArr.length-1], "|");
+        //        } 
+        else {
             sb.append("availability=/");
             sb.append(availability);
             sb.append("/ ");
@@ -198,6 +211,6 @@
         }
 
     }
-    
+
 }
 
diff --git a/full/src/main/resources/properties/log4j.properties b/full/src/main/resources/log4j.properties
similarity index 100%
rename from full/src/main/resources/properties/log4j.properties
rename to full/src/main/resources/log4j.properties
diff --git a/full/src/main/resources/templates/invitationNotification.vm b/full/src/main/resources/templates/invitationNotification.vm
deleted file mode 100644
index 02cf5c6..0000000
--- a/full/src/main/resources/templates/invitationNotification.vm
+++ /dev/null
@@ -1,13 +0,0 @@
-<html>
-	<body>
-		<h3>Hi ${username}, you are invited to group {$group} by ${inviter}!</h3>
-		<p>
-			Login to KorAP to accept or reject the invitation.
-			<br /> 
-			The invitation is valid for 30 minutes.
-		</p>
-		<p>
-			Do not reply! This is an automated generated email.
-		</p>
-	</body>
-</html>
\ No newline at end of file
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/SearchWithAvailabilityTest.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/AvailabilityTest.java
similarity index 83%
rename from full/src/test/java/de/ids_mannheim/korap/web/controller/SearchWithAvailabilityTest.java
rename to full/src/test/java/de/ids_mannheim/korap/web/controller/AvailabilityTest.java
index 00cdd97..927e3f0 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/controller/SearchWithAvailabilityTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/AvailabilityTest.java
@@ -1,6 +1,7 @@
 package de.ids_mannheim.korap.web.controller;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.assertNotNull;
 
 import org.junit.Test;
@@ -18,10 +19,10 @@
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.utils.JsonUtils;
 
-public class SearchWithAvailabilityTest extends SpringJerseyTest {
+public class AvailabilityTest extends SpringJerseyTest {
     @Autowired
     private HttpAuthorizationHandler handler;
-    
+
     private void checkAndFree (String json) throws KustvaktException {
         JsonNode node = JsonUtils.readTree(json);
         assertEquals("availability",
@@ -38,6 +39,7 @@
     private void checkAndPublic (String json) throws KustvaktException {
         JsonNode node = JsonUtils.readTree(json);
         assertNotNull(node);
+
         assertEquals("operation:and",
                 node.at("/collection/operation").asText());
         assertEquals("match:eq",
@@ -49,21 +51,24 @@
         assertEquals("CC-BY.*",
                 node.at("/collection/operands/0/operands/0/value").asText());
         assertEquals("match:eq",
-                node.at("/collection/operands/0/operands/1/operands/0/match").asText());
+                node.at("/collection/operands/0/operands/1/operands/0/match")
+                        .asText());
         assertEquals("ACA.*",
-                node.at("/collection/operands/0/operands/1/operands/0/value").asText());
+                node.at("/collection/operands/0/operands/1/operands/0/value")
+                        .asText());
         assertEquals("match:eq",
-                node.at("/collection/operands/0/operands/1/operands/1/match").asText());
+                node.at("/collection/operands/0/operands/1/operands/1/match")
+                        .asText());
         assertEquals("QAO-NC",
-                node.at("/collection/operands/0/operands/1/operands/1/value").asText());
+                node.at("/collection/operands/0/operands/1/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 checkAndPublicWithACA (String json)
-            throws KustvaktException {
+    private void checkAndPublicWithACA (String json) throws KustvaktException {
         JsonNode node = JsonUtils.readTree(json);
         assertNotNull(node);
         assertEquals("operation:and",
@@ -72,7 +77,7 @@
                 node.at("/collection/rewrites/0/operation").asText());
         assertEquals("availability(PUB)",
                 node.at("/collection/rewrites/0/scope").asText());
-        
+
         assertEquals("match:eq",
                 node.at("/collection/operands/1/match").asText());
         assertEquals("type:regex",
@@ -80,16 +85,12 @@
         assertEquals("availability",
                 node.at("/collection/operands/1/key").asText());
         assertEquals("ACA.*", node.at("/collection/operands/1/value").asText());
-        
+
         node = node.at("/collection/operands/0");
-        assertEquals("match:eq",
-                node.at("/operands/0/match").asText());
-        assertEquals("type:regex",
-                node.at("/operands/0/type").asText());
-        assertEquals("availability",
-                node.at("/operands/0/key").asText());
-        assertEquals("CC-BY.*",
-                node.at("/operands/0/value").asText());
+        assertEquals("match:eq", node.at("/operands/0/match").asText());
+        assertEquals("type:regex", node.at("/operands/0/type").asText());
+        assertEquals("availability", node.at("/operands/0/key").asText());
+        assertEquals("CC-BY.*", node.at("/operands/0/value").asText());
 
         assertEquals("match:eq",
                 node.at("/operands/1/operands/0/match").asText());
@@ -99,7 +100,7 @@
                 node.at("/operands/1/operands/0/key").asText());
         assertEquals("ACA.*", node.at("/operands/1/operands/0/value").asText());
 
-        
+
     }
 
     private void checkAndAll (String json) throws KustvaktException {
@@ -140,7 +141,7 @@
                 node.at("/collection/rewrites/0/operation").asText());
         assertEquals("availability(ALL)",
                 node.at("/collection/rewrites/0/scope").asText());
-        
+
         assertEquals("match:eq",
                 node.at("/collection/operands/1/match").asText());
         assertEquals("type:regex",
@@ -148,17 +149,13 @@
         assertEquals("availability",
                 node.at("/collection/operands/1/key").asText());
         assertEquals("ACA.*", node.at("/collection/operands/1/value").asText());
-        
+
         node = node.at("/collection/operands/0");
-        
-        assertEquals("match:eq",
-                node.at("/operands/0/match").asText());
-        assertEquals("type:regex",
-                node.at("/operands/0/type").asText());
-        assertEquals("availability",
-                node.at("/operands/0/key").asText());
-        assertEquals("CC-BY.*",
-                node.at("/operands/0/value").asText());
+
+        assertEquals("match:eq", node.at("/operands/0/match").asText());
+        assertEquals("type:regex", node.at("/operands/0/type").asText());
+        assertEquals("availability", node.at("/operands/0/key").asText());
+        assertEquals("CC-BY.*", node.at("/operands/0/value").asText());
         assertEquals("match:eq",
                 node.at("/operands/1/operands/1/operands/0/match").asText());
         assertEquals("QAO-NC",
@@ -167,7 +164,7 @@
                 node.at("/operands/1/operands/1/operands/1/match").asText());
         assertEquals("QAO.*",
                 node.at("/operands/1/operands/1/operands/1/value").asText());
-        
+
     }
 
 
@@ -180,11 +177,13 @@
 
 
     private ClientResponse builtClientResponseWithIP (String collectionQuery,
-            String ip) throws UniformInterfaceException, ClientHandlerException, KustvaktException {
+            String ip) throws UniformInterfaceException, ClientHandlerException,
+            KustvaktException {
         return resource().path("search").queryParam("q", "[orth=das]")
                 .queryParam("ql", "poliqarp").queryParam("cq", collectionQuery)
                 .header(Attributes.AUTHORIZATION,
-                        handler.createBasicAuthorizationHeaderValue("kustvakt", "kustvakt2015"))
+                        handler.createBasicAuthorizationHeaderValue("kustvakt",
+                                "kustvakt2015"))
                 .header(HttpHeaders.X_FORWARDED_FOR, ip)
                 .get(ClientResponse.class);
     }
@@ -244,7 +243,7 @@
                 response.getStatus());
 
         String json = response.getEntity(String.class);
-        
+
         JsonNode node = JsonUtils.readTree(json);
         assertEquals("operation:and",
                 node.at("/collection/operation").asText());
@@ -440,4 +439,61 @@
         checkAndAllWithACA(response.getEntity(String.class));
     }
 
+    @Test
+    public void testAvailabilityOr () throws KustvaktException {
+        ClientResponse response = builtSimpleClientResponse(
+                "availability=/CC-BY.*/ | availability=/ACA.*/");
+
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatus());
+
+        checkAndFree(response.getEntity(String.class));
+    }
+
+    @Test
+    public void testRedundancyOrPub () throws KustvaktException {
+        ClientResponse response = builtClientResponseWithIP(
+                "availability=/CC-BY.*/ | availability=/ACA.*/ | availability=/QAO-NC/",
+                "149.27.0.32");
+
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatus());
+
+        String json = response.getEntity(String.class);
+        JsonNode node = JsonUtils.readTree(json);
+        assertTrue(node.at("/collection/rewrites").isMissingNode());
+        assertEquals("operation:or", node.at("/collection/operation").asText());
+    }
+
+    @Test
+    public void testAvailabilityOrCorpusSigle () throws KustvaktException {
+        ClientResponse response = builtSimpleClientResponse(
+                "availability=/CC-BY.*/ | corpusSigle=GOE");
+
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatus());
+
+        checkAndFree(response.getEntity(String.class));
+    }
+
+    @Test
+    public void testOrWithoutAvailability () throws KustvaktException {
+        ClientResponse response = builtSimpleClientResponse(
+                "corpusSigle=GOE | textClass=politik");
+
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatus());
+
+        checkAndFree(response.getEntity(String.class));
+    }
+
+    @Test
+    public void testWithoutAvailability () throws KustvaktException {
+        ClientResponse response = builtSimpleClientResponse("corpusSigle=GOE");
+
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatus());
+
+        checkAndFree(response.getEntity(String.class));
+    }
 }