removal of date validation warning; validation for dateConstraint on date formats

Change-Id: I32155b44f79e0310008f6c01d99fe981c6e46bdf
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryProcessor.java b/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryProcessor.java
index 92f2b61..35bafa6 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryProcessor.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryProcessor.java
@@ -109,11 +109,12 @@
             term.putAll(parseValue(valueNode));
             String match = operatorNode.getText();
             term.put("match", "match:" + interpretMatchOperator(match));
-            if (checkOperatorValueConformance(term) == false) {
+
+            if (!checkOperatorValueConformance(term)) {
                 requestMap = new LinkedHashMap<String, Object>();
                 return;
             }
-            if (checkDateValidity(valueNode)) {
+            if (QueryUtils.checkDateValidity(valueNode.getText())) {
                 addWarning("The collection query contains a value that looks"
                         + " like a date ('" + valueNode.getText() + "') and an"
                         + " operator that is only defined for strings" + " ('"
@@ -121,6 +122,7 @@
                         + " a string. Use a date operator to ensure the value"
                         + " is treated as a date");
             }
+
             putIntoSuperObject(term);
         }
 
@@ -135,11 +137,19 @@
             term.putAll(parseValue(dateNode));
             String match = dateOpNode.getText();
             term.put("match", "match:" + interpretMatchOperator(match));
-            if (checkOperatorValueConformance(term) == false) {
+            if (!checkOperatorValueConformance(term)) {
                 requestMap = new LinkedHashMap<String, Object>();
                 return;
             }
+            if (!QueryUtils.checkDateValidity(dateNode.getText())) {
+                addError(StatusCodes.MALFORMED_QUERY,
+                        "The collection query contains elements "
+                                + "that could not be parsed as a date ('"
+                                + dateNode.getText() + "')");
+                return;
+            }
             putIntoSuperObject(term);
+
         }
 
         if (nodeCat.equals("token")) {
@@ -261,37 +271,17 @@
 
         if ("regex".equals(node_cat))
             map.put("type", "type:regex");
-
-        // deprecated code
-        //        if (getNodeCat(valueNode.getChild(0)).equals("regex")) {
-        //            String regex = valueNode.getChild(0).getChild(0)
-        //                    .toStringTree(parser);
-        //            map.put("value", regex.substring(1, regex.length() - 1));
-        //            map.put("type", "type:regex");
-        //        }else if (getNodeCat(valueNode.getChild(0)).equals("multiword")) {
-        //            TokenStream stream = parser.getTokenStream();
-        //            String stm = stream
-        //                    .getText(valueNode.getChild(0).getSourceInterval());
-        //
-        //            //            StringBuilder mw = new StringBuilder(); // multiword
-        //            //            for (int i = 1;
-        //            //                 i < valueNode.getChild(0).getChildCount() - 1; i++) {
-        //            //                mw.append(valueNode.getChild(0).getChild(i).getText());
-        //            //            }
-        //            map.put("value", stm.substring(1, stm.length() - 1));
-        //        }else {
-        //            map.put("value", valueNode.getChild(0).toStringTree(parser));
-        //        }
         return map;
     }
 
     /**
-     * Checks if a date
+     * Checks if value is a date
      *
      * @param valueNode
      * @return
      */
 
+    @Deprecated
     private boolean checkDateValidity(ParseTree valueNode) {
         Pattern p = Pattern.compile("[0-9]{4}(-([0-9]{2})(-([0-9]{2}))?)?");
         Matcher m = p.matcher(valueNode.getText());
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/QueryUtils.java b/src/main/java/de/ids_mannheim/korap/query/serialize/QueryUtils.java
index 7c3128a..6980b2e 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/QueryUtils.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/QueryUtils.java
@@ -1,27 +1,20 @@
 package de.ids_mannheim.korap.query.serialize;
 
 import java.util.AbstractMap.SimpleEntry;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.Stack;
+import java.util.*;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 /**
  * @author Joachim Bingel (bingel@ids-mannheim.de),
  *         Michael Hanl (hanl@ids-mannheim.de)
- * @date 10/12/2013
  * @version 0.3.0
+ * @date 10/12/2013
  * @since 0.1.0
  */
 public class QueryUtils {
 
-    public static SimpleEntry<String, Integer> checkUnbalancedPars (String q) {
+    public static SimpleEntry<String, Integer> checkUnbalancedPars(String q) {
         Map<Character, Character> brackets = new HashMap<Character, Character>();
         brackets.put('[', ']');
         brackets.put('{', '}');
@@ -38,9 +31,8 @@
             if (brackets.containsKey(q.charAt(i))) {
                 stack.push(q.charAt(i));
                 lastOpenBracket = i;
-            }
-            else if (stack.empty()
-                    || (q.charAt(i) != brackets.get(stack.pop()))) {
+            }else if (stack.empty() || (q.charAt(i) != brackets
+                    .get(stack.pop()))) {
                 return new SimpleEntry<String, Integer>(
                         "Parantheses/brackets unbalanced.", i);
             }
@@ -51,15 +43,13 @@
         return null;
     }
 
-
-    public static List<String> parseMorph (String stringTree) {
+    public static List<String> parseMorph(String stringTree) {
 
         ArrayList<String> morph = new ArrayList<String>();
         return morph;
     }
 
-
-    public static String buildCypherQuery (String cypher, String ctypel,
+    public static String buildCypherQuery(String cypher, String ctypel,
             String ctyper, int cl, int cr, int page, int limit) {
         // todo: implies that there is only one type allowed!
         String sctypel = "", sctyper = "";
@@ -110,8 +100,7 @@
         return buffer.toString();
     }
 
-
-    public static String buildDotQuery (long sid, String graphdb_id) {
+    public static String buildDotQuery(long sid, String graphdb_id) {
         StringBuffer b = new StringBuffer();
         b.append("<query>");
         b.append("<sentenceId>");
@@ -133,8 +122,7 @@
         return b.toString();
     }
 
-
-    public String buildaggreQuery (String query) {
+    public String buildaggreQuery(String query) {
         StringBuffer b = new StringBuffer();
         b.append("<query><cypher><![CDATA[");
         b.append(query);
@@ -163,10 +151,9 @@
         return b.toString();
     }
 
-
     @Deprecated
-    public static Map addParameters (Map request, int page, int num,
-            String cli, String cri, int cls, int crs, boolean cutoff) {
+    public static Map addParameters(Map request, int page, int num, String cli,
+            String cri, int cls, int crs, boolean cutoff) {
         Map ctx = new LinkedHashMap();
         List left = new ArrayList();
         left.add(cli);
@@ -185,8 +172,34 @@
         return request;
     }
 
+    /**
+     * Checks if value is a date
+     *
+     * @param value
+     * @return
+     */
 
-    public static String escapeRegexSpecialChars (String key) {
+    public static boolean checkDateValidity(String value) {
+        Pattern p = Pattern.compile("^[0-9]{4}(-([0-9]{2})(-([0-9]{2}))?)?$");
+        Matcher m = p.matcher(value);
+
+        if (!m.find())
+            return false;
+        String month = m.group(2);
+        String day = m.group(4);
+        if (month != null) {
+            if (Integer.parseInt(month) > 12) {
+                return false;
+            }else if (day != null) {
+                if (Integer.parseInt(day) > 31) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    public static String escapeRegexSpecialChars(String key) {
         key.replace("\\", "\\\\");
         Pattern p = Pattern
                 .compile("\\.|\\^|\\$|\\||\\?|\\*|\\+|\\(|\\)|\\[|\\]|\\{|\\}");
diff --git a/src/test/java/de/ids_mannheim/korap/query/serialize/CollectionQueryProcessorTest.java b/src/test/java/de/ids_mannheim/korap/query/serialize/CollectionQueryProcessorTest.java
index 61a2813..3725c83 100644
--- a/src/test/java/de/ids_mannheim/korap/query/serialize/CollectionQueryProcessorTest.java
+++ b/src/test/java/de/ids_mannheim/korap/query/serialize/CollectionQueryProcessorTest.java
@@ -54,7 +54,8 @@
     }
 
     @Test
-    public void testSpecialCharacters() throws JsonProcessingException, IOException {
+    public void testSpecialCharacters()
+            throws JsonProcessingException, IOException {
         collection = "[base/n=alt]";
         qs.setQuery(query, ql);
         qs.setCollection(collection);
@@ -66,7 +67,9 @@
         assertEquals("n", res.at("/collection/wrap/layer").asText());
         assertEquals("alt", res.at("/collection/wrap/key").asText());
         assertEquals("match:eq", res.at("/collection/wrap/match").asText());
-    };
+    }
+
+    ;
 
     @Test
     public void testContains() throws JsonProcessingException, IOException {
@@ -99,6 +102,20 @@
     }
 
     @Test
+    public void testNotDate() throws JsonProcessingException, IOException {
+        collection = "author=\"firefighter1974\"";
+        qs.setQuery(query, ql);
+        qs.setCollection(collection);
+        res = mapper.readTree(qs.toJSON());
+        assertEquals("koral:doc", res.at("/collection/@type").asText());
+        assertEquals("author", res.at("/collection/key").asText());
+        assertEquals("firefighter1974", res.at("/collection/value").asText());
+        assertEquals("match:eq", res.at("/collection/match").asText());
+        assertEquals("", res.at("/errors/0/0").asText());
+        assertEquals("", res.at("/warnings/0/0").asText());
+    }
+
+    @Test
     public void testTwoConjuncts() throws JsonProcessingException, IOException {
         collection = "textClass=Sport & pubDate in 2014";
         qs.setQuery(query, ql);
@@ -125,7 +142,11 @@
         collection = "textClass=Sport & pubDate=2014";
         qs.setQuery(query, ql);
         qs.setCollection(collection);
-        res = mapper.readTree(qs.toJSON());
+
+        String s = qs.toJSON();
+        System.out.println("________________________");
+        System.out.println(s);
+        res = mapper.readTree(s);
         assertEquals("koral:docGroup", res.at("/collection/@type").asText());
         assertEquals("operation:and", res.at("/collection/operation").asText());
         assertEquals("koral:doc",
@@ -514,4 +535,20 @@
         assertEquals("type:date", res.at("/collection/type").asText());
         assertEquals("match:leq", res.at("/collection/match").asText());
     }
+
+    @Test
+    public void testDateValidate() {
+        String fake_date = "fireStorm2014";
+        String fake_date_2 = "2014-12Date";
+        String date = "2015";
+        String date_1 = "2015-05";
+        String date_2 = "2015-05-13";
+        String date_3 = "2015-23-01";
+        assertEquals(false, QueryUtils.checkDateValidity(fake_date));
+        assertEquals(false, QueryUtils.checkDateValidity(fake_date_2));
+        assertEquals(true, QueryUtils.checkDateValidity(date));
+        assertEquals(true, QueryUtils.checkDateValidity(date_1));
+        assertEquals(true, QueryUtils.checkDateValidity(date_2));
+        assertEquals(false, QueryUtils.checkDateValidity(date_3));
+    }
 }