Handling requests with unauthorized availability values.

Change-Id: Ifd66aa2158b93c267de5410b97426ccd84afeb7d
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 6fcae2f..9d70e36 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,63 +1,141 @@
 package de.ids_mannheim.korap.resource.rewrite;
 
+import java.util.ArrayList;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
 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 22 May 2017
+ * @date 30 May 2017
  */
 public class CollectionRewrite implements RewriteTask.RewriteQuery {
 
-	private static Logger jlog = LoggerFactory.getLogger(CollectionRewrite.class);
+    private static Logger jlog = LoggerFactory
+            .getLogger(CollectionRewrite.class);
+    public static String AVAILABILITY = "availability";
 
-	public CollectionRewrite() {
-		super();
-	}
+    public static Pattern notFreeLicense = Pattern.compile("ACA|QAO");
+    public static Pattern notPublicLicense = Pattern.compile("QAO");
 
-	@Override
-	public JsonNode rewriteQuery(KoralNode node, KustvaktConfiguration config, User user) throws KustvaktException {
-		JsonNode subnode = node.rawNode();
-		KoralCollectionQueryBuilder builder = new KoralCollectionQueryBuilder();
-		if (subnode.at("/collection").isMissingNode()) {
-			if (subnode.has("collection")) {
-				builder.setBaseQuery(JsonUtils.toJSON(subnode));
-			}
 
-			switch (user.getCorpusAccess()) {
-			case PUB:
-				builder = new KoralCollectionQueryBuilder();
-				builder.with("availability = /CC-BY.*/ | availablity = /ACA.*/");
-				break;
+    public CollectionRewrite () {
+        super();
+    }
 
-			case ALL:
-				builder = new KoralCollectionQueryBuilder();
-				builder.with("availability = /QAO.*/ | availablity = /ACA.*/ |  availablity = /CC-BY.*/");
-				break;
 
-			default: // FREE
-				builder = new KoralCollectionQueryBuilder();
-				builder.with("availability	 = /CC-BY.*/");
-				break;
-			}
+    private String verifyAvailability (JsonNode node, CorpusAccess access,
+            KustvaktConfiguration config) {
 
-			JsonNode rewritten = JsonUtils.readTree(builder.toJSON()).at("/collection");
-			RewriteIdentifier identifier = new KoralNode.RewriteIdentifier(Attributes.AVAILABILITY,
-					rewritten.at("/value"));
-			node.set("collection", rewritten, identifier);
-			jlog.debug(node.at("/collection").toString());
-		}
+        if (node.has("operands")) {
+            ArrayList<JsonNode> operands = Lists
+                    .newArrayList(node.at("/operands").elements());
+            for (int i = 0; i < operands.size(); i++) {
+                String path = verifyAvailability(operands.get(i), access,
+                        config);
+                if (!path.isEmpty()) { return "/operands/" + i; }
+            }
+        }
+        else if (node.has("key")
+                && node.at("/key").asText().equals(AVAILABILITY)) {
+            Matcher m;
+            String queryAvailability = node.at("/value").asText();
+            if (node.at("/match").asText()
+                    .equals(KoralMatchOperator.EQUALS.toString())) {
 
-		return node.rawNode();
-	}
+                if (access.equals(CorpusAccess.FREE)) {
+                    m = notFreeLicense.matcher(queryAvailability);
+                    if (m.find()) return "/value";
+                }
+                else if (access.equals(CorpusAccess.PUB)) {
+                    m = notPublicLicense.matcher(queryAvailability);
+                    if (m.find()) return "/value";
+                }
+            }
+            // match:ne
+            else {
+                if (access.equals(CorpusAccess.FREE)) {
+                    m = config.getFreeLicensePattern()
+                            .matcher(queryAvailability);
+                    if (m.find()) return "/value";
+                }
+                else if (access.equals(CorpusAccess.PUB)) {
+                    m = config.getPublicLicensePattern()
+                            .matcher(queryAvailability);
+                    if (m.find()) return "/value";
+                }
+            }
+        }
+
+        return "";
+    }
+
+
+    @Override
+    public JsonNode rewriteQuery (KoralNode node, KustvaktConfiguration config,
+            User user) throws KustvaktException {
+        JsonNode jsonNode = node.rawNode();
+        KoralCollectionQueryBuilder builder = new KoralCollectionQueryBuilder();
+        switch (user.getCorpusAccess()) {
+            case PUB:
+                builder.with(
+                        "availability = /CC-BY.*/ | availability = /ACA.*/");
+                break;
+            case ALL:
+                builder.with("availability = /QAO.*/ | availability = /ACA.*/ |"
+                        + "  availability = /CC-BY.*/");
+                break;
+            case FREE:
+                builder.with("availability   = /CC-BY.*/");
+                break;
+        }
+
+        RewriteIdentifier identifier = new KoralNode.RewriteIdentifier(
+                Attributes.AVAILABILITY, user.getCorpusAccess());
+        JsonNode rewrittesNode;
+
+        if (jsonNode.has("collection")) {
+            String path = verifyAvailability(jsonNode.at("/collection"),
+                    user.getCorpusAccess(), config);
+            if (!path.isEmpty()) {
+                rewrittesNode = JsonUtils.readTree(builder.toJSON())
+                        .at("/collection");
+                if (path.equals("/value")) {
+                    node.replace("collection", rewrittesNode, identifier);
+                }
+                else {
+                    node.replaceAt("/collection" + path, rewrittesNode,
+                            identifier);
+                }
+            }
+            else {
+                builder.setBaseQuery(builder.toJSON());
+                rewrittesNode = builder.mergeWith(jsonNode).at("/collection");
+                node.set("collection", rewrittesNode, identifier);
+            }
+        }
+        else {
+            rewrittesNode = JsonUtils.readTree(builder.toJSON())
+                    .at("/collection");
+            node.set("collection", rewrittesNode, identifier);
+        }
+
+        jlog.debug("REWRITES: " + node.at("/collection").toString());
+        return node.rawNode();
+    }
 }
diff --git a/src/main/java/de/ids_mannheim/korap/resource/rewrite/KoralNode.java b/src/main/java/de/ids_mannheim/korap/resource/rewrite/KoralNode.java
index 6de5552..0614f91 100644
--- a/src/main/java/de/ids_mannheim/korap/resource/rewrite/KoralNode.java
+++ b/src/main/java/de/ids_mannheim/korap/resource/rewrite/KoralNode.java
@@ -100,7 +100,20 @@
             this.rewrites.add("override", name);
         }
     }
+    
+    public void replaceAt (String path, Object value, RewriteIdentifier ident) {
+        if (this.node.isObject() && !this.node.at(path).isMissingNode()) {
+            ObjectNode n = (ObjectNode) this.node.at(path);
+            n.removeAll();
+            n.putAll((ObjectNode)value);
 
+            String name = path;
+            if (ident != null)
+                name = ident.toString();
+
+            this.rewrites.add("override", name);
+        }
+    }
 
     public void set (String name, Object value, RewriteIdentifier ident) {
         if (this.node.isObject()) {