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