You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by rd...@apache.org on 2009/08/04 14:17:36 UTC

svn commit: r800745 - in /james/jsieve/trunk/main/src/main/java/org/apache/jsieve: ./ comparators/

Author: rdonkin
Date: Tue Aug  4 12:17:36 2009
New Revision: 800745

URL: http://svn.apache.org/viewvc?rev=800745&view=rev
Log:
JSIEVE-72 Validate comparators that must be explicitly be declared https://issues.apache.org/jira/browse/JSIEVE-72

Added:
    james/jsieve/trunk/main/src/main/java/org/apache/jsieve/Constants.java   (with props)
Modified:
    james/jsieve/trunk/main/src/main/java/org/apache/jsieve/BaseSieveContext.java
    james/jsieve/trunk/main/src/main/java/org/apache/jsieve/ComparatorManager.java
    james/jsieve/trunk/main/src/main/java/org/apache/jsieve/ComparatorManagerImpl.java
    james/jsieve/trunk/main/src/main/java/org/apache/jsieve/SieveContext.java
    james/jsieve/trunk/main/src/main/java/org/apache/jsieve/SieveFactory.java
    james/jsieve/trunk/main/src/main/java/org/apache/jsieve/SieveValidationVisitor.java
    james/jsieve/trunk/main/src/main/java/org/apache/jsieve/TagArgument.java
    james/jsieve/trunk/main/src/main/java/org/apache/jsieve/comparators/ComparatorUtils.java

Modified: james/jsieve/trunk/main/src/main/java/org/apache/jsieve/BaseSieveContext.java
URL: http://svn.apache.org/viewvc/james/jsieve/trunk/main/src/main/java/org/apache/jsieve/BaseSieveContext.java?rev=800745&r1=800744&r2=800745&view=diff
==============================================================================
--- james/jsieve/trunk/main/src/main/java/org/apache/jsieve/BaseSieveContext.java (original)
+++ james/jsieve/trunk/main/src/main/java/org/apache/jsieve/BaseSieveContext.java Tue Aug  4 12:17:36 2009
@@ -20,7 +20,6 @@
 package org.apache.jsieve;
 
 import org.apache.commons.logging.Log;
-import org.apache.jsieve.comparators.Comparator;
 import org.apache.jsieve.exception.LookupException;
 import org.apache.jsieve.tests.ExecutableTest;
 
@@ -93,10 +92,6 @@
         return commandManager.getCommand(name);
     }
 
-    public Comparator getComparator(String name) throws LookupException {
-        return comparatorManager.getComparator(name);
-    }
-
     public ExecutableTest getTest(String name) throws LookupException {
         return testManager.getTest(name);
     }
@@ -104,4 +99,12 @@
     public Log getLog() {
         return log;
     }
+
+    /**
+     * @see SieveContext#getComparatorManager()
+     */
+    @Override
+    public ComparatorManager getComparatorManager() {
+        return comparatorManager;
+    }
 }

Modified: james/jsieve/trunk/main/src/main/java/org/apache/jsieve/ComparatorManager.java
URL: http://svn.apache.org/viewvc/james/jsieve/trunk/main/src/main/java/org/apache/jsieve/ComparatorManager.java?rev=800745&r1=800744&r2=800745&view=diff
==============================================================================
--- james/jsieve/trunk/main/src/main/java/org/apache/jsieve/ComparatorManager.java (original)
+++ james/jsieve/trunk/main/src/main/java/org/apache/jsieve/ComparatorManager.java Tue Aug  4 12:17:36 2009
@@ -40,4 +40,13 @@
      * @throws LookupException
      */
     public Comparator getComparator(String name) throws LookupException;
+    
+    /**
+     * Is an explicit declaration in a <code>require</code> statement
+     * unnecessary for this comparator?
+     * @param comparatorName not null
+     * @return true when this comparator need not be declared by <core>require</code>,
+     * false when any usage of this comparator must be declared in a <code>require</code> statement
+     */
+    public boolean isImplicitlyDeclared(final String comparatorName);
 }

Modified: james/jsieve/trunk/main/src/main/java/org/apache/jsieve/ComparatorManagerImpl.java
URL: http://svn.apache.org/viewvc/james/jsieve/trunk/main/src/main/java/org/apache/jsieve/ComparatorManagerImpl.java?rev=800745&r1=800744&r2=800745&view=diff
==============================================================================
--- james/jsieve/trunk/main/src/main/java/org/apache/jsieve/ComparatorManagerImpl.java (original)
+++ james/jsieve/trunk/main/src/main/java/org/apache/jsieve/ComparatorManagerImpl.java Tue Aug  4 12:17:36 2009
@@ -19,7 +19,11 @@
 
 package org.apache.jsieve;
 
+import static org.apache.jsieve.Constants.COMPARATOR_ASCII_CASEMAP_NAME;
+import static org.apache.jsieve.Constants.COMPARATOR_OCTET_NAME;
+
 import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.CopyOnWriteArraySet;
 
 import org.apache.jsieve.comparators.Comparator;
 import org.apache.jsieve.exception.LookupException;
@@ -33,14 +37,53 @@
  */
 public class ComparatorManagerImpl implements ComparatorManager {
 
+    /** 
+     * Constructs a set containing the names of those comparisons for which <code>require</code> 
+     * is not necessary before usage, according to RFC5228.
+     * See <a href='http://tools.ietf.org/html/rfc5228#section-2.7.3'>RFC5228, 2.7.3 Comparators</a>. 
+     */
+    public static CopyOnWriteArraySet<String> standardDefinedComparators() {
+        final CopyOnWriteArraySet<String> results = new CopyOnWriteArraySet<String>();
+        results.add(COMPARATOR_OCTET_NAME);
+        results.add(COMPARATOR_ASCII_CASEMAP_NAME);
+        return results;
+    }
+    
     private final ConcurrentMap<String, String> classNameMap;
+    /** 
+     * The names of those comparisons for which <code>require</code> is not necessary before usage.
+     * See <a href='http://tools.ietf.org/html/rfc5228#section-2.7.3'>RFC5228, 2.7.3 Comparators</a>. 
+     */
+    private final CopyOnWriteArraySet<String> implicitlyDeclared;
 
     /**
-     * Constructor for ComparatorManager.
+     * Constructs a manager with the standard comparators implicitly defined.
+     * @param classNameMap not null
      */
     public ComparatorManagerImpl(final ConcurrentMap<String, String> classNameMap) {
+        this(classNameMap, standardDefinedComparators());
+    }
+    
+    /**
+     * Constructor for ComparatorManager.
+     * @param classNameMap indexes names of implementation classes against logical names, not null
+     * @param implicitlyDeclared names of those comparisons for which <code>require</code> is not necessary before usage
+     */
+    public ComparatorManagerImpl(final ConcurrentMap<String, String> classNameMap, final CopyOnWriteArraySet<String> implicitlyDeclared) {
         super();
         this.classNameMap = classNameMap;
+        this.implicitlyDeclared = implicitlyDeclared;
+    }
+    
+    /**
+     * Is an explicit declaration in a <code>require</code> statement
+     * unnecessary for this comparator?
+     * @param comparatorName not null
+     * @return true when this comparator need not be declared by <core>require</code>,
+     * false when any usage of this comparator must be declared in a <code>require</code> statement
+     */
+    public boolean isImplicitlyDeclared(final String comparatorName) {
+        return implicitlyDeclared.contains(comparatorName);
     }
 
     /**
@@ -103,7 +146,7 @@
     private String getClassName(String name) throws LookupException {
         String className = classNameMap.get(name.toLowerCase());
         if (null == className)
-            throw new LookupException("Command named '" + name
+            throw new LookupException("Comparator named '" + name
                     + "' not mapped.");
         return className;
     }

Added: james/jsieve/trunk/main/src/main/java/org/apache/jsieve/Constants.java
URL: http://svn.apache.org/viewvc/james/jsieve/trunk/main/src/main/java/org/apache/jsieve/Constants.java?rev=800745&view=auto
==============================================================================
--- james/jsieve/trunk/main/src/main/java/org/apache/jsieve/Constants.java (added)
+++ james/jsieve/trunk/main/src/main/java/org/apache/jsieve/Constants.java Tue Aug  4 12:17:36 2009
@@ -0,0 +1,30 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+package org.apache.jsieve;
+
+public class Constants {
+
+    public static final String TAG_COMPARATOR = ":comparator";
+    
+    /** Name of the standard ascii casemap comparator. See <a href='http://tools.ietf.org/html/rfc4790'>RFC4790</a>. */
+    public static final String COMPARATOR_ASCII_CASEMAP_NAME = "i;ascii-casemap";
+    /** Name of the standard octet comparator. See <a href='http://tools.ietf.org/html/rfc4790'>RFC4790</a>. */
+    public static final String COMPARATOR_OCTET_NAME = "i;octet";
+
+}

Propchange: james/jsieve/trunk/main/src/main/java/org/apache/jsieve/Constants.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: james/jsieve/trunk/main/src/main/java/org/apache/jsieve/SieveContext.java
URL: http://svn.apache.org/viewvc/james/jsieve/trunk/main/src/main/java/org/apache/jsieve/SieveContext.java?rev=800745&r1=800744&r2=800745&view=diff
==============================================================================
--- james/jsieve/trunk/main/src/main/java/org/apache/jsieve/SieveContext.java (original)
+++ james/jsieve/trunk/main/src/main/java/org/apache/jsieve/SieveContext.java Tue Aug  4 12:17:36 2009
@@ -20,7 +20,6 @@
 package org.apache.jsieve;
 
 import org.apache.commons.logging.Log;
-import org.apache.jsieve.comparators.Comparator;
 import org.apache.jsieve.exception.LookupException;
 import org.apache.jsieve.tests.ExecutableTest;
 
@@ -55,13 +54,14 @@
     public abstract void setConditionManager(final ConditionManager manager);
 
     // TODO: consider whether API can be consolidated
-    public abstract ExecutableCommand getCommand(String name)
-            throws LookupException;
-
-    // TODO: consider whether API can be consolidated
-    public abstract Comparator getComparator(String name)
-            throws LookupException;
+    public abstract ExecutableCommand getCommand(String name) throws LookupException;
 
+    /**
+     * Gets the comparator manager.
+     * @return not null
+     */
+    public abstract ComparatorManager getComparatorManager();
+    
     // TODO: consider whether API can be consolidated
     public abstract ExecutableTest getTest(String name) throws LookupException;
 

Modified: james/jsieve/trunk/main/src/main/java/org/apache/jsieve/SieveFactory.java
URL: http://svn.apache.org/viewvc/james/jsieve/trunk/main/src/main/java/org/apache/jsieve/SieveFactory.java?rev=800745&r1=800744&r2=800745&view=diff
==============================================================================
--- james/jsieve/trunk/main/src/main/java/org/apache/jsieve/SieveFactory.java (original)
+++ james/jsieve/trunk/main/src/main/java/org/apache/jsieve/SieveFactory.java Tue Aug  4 12:17:36 2009
@@ -101,7 +101,7 @@
             final SimpleNode node = new SieveParser(inputStream, "UTF-8")
                     .start();
             SieveValidationVisitor visitor = new SieveValidationVisitor(
-                    commandManager, testManager);
+                    commandManager, testManager, comparatorManager);
             node.jjtAccept(visitor, null);
             return node;
         } catch (ParseException ex) {

Modified: james/jsieve/trunk/main/src/main/java/org/apache/jsieve/SieveValidationVisitor.java
URL: http://svn.apache.org/viewvc/james/jsieve/trunk/main/src/main/java/org/apache/jsieve/SieveValidationVisitor.java?rev=800745&r1=800744&r2=800745&view=diff
==============================================================================
--- james/jsieve/trunk/main/src/main/java/org/apache/jsieve/SieveValidationVisitor.java (original)
+++ james/jsieve/trunk/main/src/main/java/org/apache/jsieve/SieveValidationVisitor.java Tue Aug  4 12:17:36 2009
@@ -44,18 +44,23 @@
 public class SieveValidationVisitor implements SieveParserVisitor {
 
     private final CommandManager commandManager;
-
     private final TestManager testManager;
+    private final ComparatorManager comparatorManager;
 
     private boolean requireAllowed = true;
-
+    /** Is the visitor within a <code>require</code>? */
     private boolean isInRequire = false;
-
+    /** Is the next argument expected to be a comparator name? */
+    private boolean nextArgumentIsComparatorName = false;
+    /** Is the visitor within a comparator name argument? */
+    private boolean isInComparatorNameArgument = false;
+    
     protected SieveValidationVisitor(final CommandManager commandManager,
-            final TestManager testManager) {
+            final TestManager testManager, final ComparatorManager comparatorManager) {
         super();
         this.commandManager = commandManager;
         this.testManager = testManager;
+        this.comparatorManager = comparatorManager;
     }
 
     public Object visit(SimpleNode node, Object data) throws SieveException {
@@ -99,12 +104,30 @@
     }
 
     public Object visit(ASTarguments node, Object data) throws SieveException {
-
+        // Reset test for explicitly required comparator types
+        nextArgumentIsComparatorName = false;
         return visitNode(node, data);
     }
 
     public Object visit(ASTargument node, Object data) throws SieveException {
-        return visitNode(node, data);
+        final Object value = node.getValue();
+        if (value == null) { 
+            if (nextArgumentIsComparatorName) {
+                // Mark enclosed string for check against required list
+                isInComparatorNameArgument = true;
+            }
+            nextArgumentIsComparatorName = false;
+        } else {
+            if (value instanceof TagArgument) {
+                final TagArgument tag = (TagArgument) value;
+                nextArgumentIsComparatorName = tag.isComparator();
+            } else {
+                nextArgumentIsComparatorName = false;
+            }
+        }
+        final Object result = visitNode(node, data);
+        isInComparatorNameArgument = false;
+        return result;
     }
 
     public Object visit(ASTtest node, Object data) throws SieveException {
@@ -117,20 +140,38 @@
 
     public Object visit(ASTstring node, Object data) throws SieveException {
         if (isInRequire) {
-            final Object value = node.getValue();
-            if (value != null && value instanceof String) {
-                final String name = (String) value;
-                try {
-                    commandManager.getCommand(name);
-                } catch (LookupException e) {
-                    // TODO: catching is inefficient, should just check
-                    testManager.getTest(name);
-                }
-            }
+            requirements(node);
+        }
+        if (isInComparatorNameArgument) {
+            comparatorNameArgument(node);
         }
         return visitNode(node, data);
     }
 
+    private void comparatorNameArgument(ASTstring node) throws SieveException {
+        final Object value = node.getValue();
+        if (value != null && value instanceof String) {
+            final String name = (String) value;
+            if (!comparatorManager.isImplicitlyDeclared(name)) {
+                // TODO: replace with better exception
+                throw new SieveException("Comparator must be explicitly declared in a require statement.");
+            }
+        }
+    }
+
+    private void requirements(ASTstring node) throws LookupException {
+        final Object value = node.getValue();
+        if (value != null && value instanceof String) {
+            final String name = (String) value;
+            try {
+                commandManager.getCommand(name);
+            } catch (LookupException e) {
+                // TODO: catching is inefficient, should just check
+                testManager.getTest(name);
+            }
+        }
+    }
+
     public Object visit(ASTstring_list node, Object data) throws SieveException {
         return visitNode(node, data);
     }

Modified: james/jsieve/trunk/main/src/main/java/org/apache/jsieve/TagArgument.java
URL: http://svn.apache.org/viewvc/james/jsieve/trunk/main/src/main/java/org/apache/jsieve/TagArgument.java?rev=800745&r1=800744&r2=800745&view=diff
==============================================================================
--- james/jsieve/trunk/main/src/main/java/org/apache/jsieve/TagArgument.java (original)
+++ james/jsieve/trunk/main/src/main/java/org/apache/jsieve/TagArgument.java Tue Aug  4 12:17:36 2009
@@ -19,6 +19,8 @@
 
 package org.apache.jsieve;
 
+import static org.apache.jsieve.Constants.TAG_COMPARATOR;
+
 import org.apache.jsieve.parser.generated.Token;
 
 /**
@@ -71,6 +73,25 @@
     }
 
     /**
+     * Does this argument match the given tag?
+     * @param tag not null
+     * @return true when the tag identifier equals that given,
+     * false otherwise
+     */
+    public boolean is(String tag) {
+       return tag.equals(fieldTag); 
+    }
+    
+    /**
+     * Is this a comparator tag?
+     * @return true when identifier matches {@link Constants#TAG_COMPARATOR},
+     * false otherwise
+     */
+    public boolean isComparator() {
+        return this.is(TAG_COMPARATOR);
+    }
+    
+    /**
      * Sets the tag.
      * 
      * @param tag

Modified: james/jsieve/trunk/main/src/main/java/org/apache/jsieve/comparators/ComparatorUtils.java
URL: http://svn.apache.org/viewvc/james/jsieve/trunk/main/src/main/java/org/apache/jsieve/comparators/ComparatorUtils.java?rev=800745&r1=800744&r2=800745&view=diff
==============================================================================
--- james/jsieve/trunk/main/src/main/java/org/apache/jsieve/comparators/ComparatorUtils.java (original)
+++ james/jsieve/trunk/main/src/main/java/org/apache/jsieve/comparators/ComparatorUtils.java Tue Aug  4 12:17:36 2009
@@ -193,7 +193,7 @@
      */
     public static boolean contains(String comparatorName, String container,
             String contents, SieveContext context) throws LookupException {
-        Contains comparatorObj = context.getComparator(comparatorName);
+        Contains comparatorObj = context.getComparatorManager().getComparator(comparatorName);
         return comparatorObj.contains(container, contents);
     }
 
@@ -209,7 +209,7 @@
      */
     public static boolean is(String comparatorName, String string1,
             String string2, SieveContext context) throws LookupException {
-        Equals comparatorObj = context.getComparator(comparatorName);
+        Equals comparatorObj = context.getComparatorManager().getComparator(comparatorName);
         return comparatorObj.equals(string1, string2);
     }
 
@@ -226,7 +226,7 @@
      */
     public static boolean matches(String comparatorName, String string,
             String glob, SieveContext context) throws SieveException {
-        Matches comparatorObj = context.getComparator(comparatorName);
+        Matches comparatorObj = context.getComparatorManager().getComparator(comparatorName);
         return comparatorObj.matches(string, glob);
     }
 



---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org