Author: mbenson
Date: Tue Oct 10 10:30:33 2006
New Revision: 454842

URL: http://svn.apache.org/viewvc?view=rev&rev=454842
Log:
Added <compare> resource selector to select resources based on the
results of their comparison to other resources. Inspired by userlist thread
http://marc.theaimsgroup.com/?t=115998761500004&r=1&w=2 .
Still lacks an example other than testcases. :(

Added:
    ant/core/trunk/src/main/org/apache/tools/ant/types/Quantifier.java   (with 
props)
    
ant/core/trunk/src/main/org/apache/tools/ant/types/resources/selectors/Compare.java
   (with props)
Modified:
    ant/core/trunk/WHATSNEW
    ant/core/trunk/docs/manual/CoreTypes/resources.html
    
ant/core/trunk/src/resources/org/apache/tools/ant/types/resources/selectors/antlib.xml
    ant/core/trunk/src/tests/antunit/types/resources/selectors/test.xml

Modified: ant/core/trunk/WHATSNEW
URL: 
http://svn.apache.org/viewvc/ant/core/trunk/WHATSNEW?view=diff&rev=454842&r1=454841&r2=454842
==============================================================================
--- ant/core/trunk/WHATSNEW (original)
+++ ant/core/trunk/WHATSNEW Tue Oct 10 10:30:33 2006
@@ -66,6 +66,9 @@
 * Added <tokens> resource collection for convenient creation of string
   resources from other resources' content. Inspired by Bugzilla 40504.
 
+* Added <compare> resource selector to select resources based on the
+  results of their comparison to other resources.
+
 Changes from Ant 1.7.0Beta1 to Ant 1.7.0Beta2
 =============================================
 

Modified: ant/core/trunk/docs/manual/CoreTypes/resources.html
URL: 
http://svn.apache.org/viewvc/ant/core/trunk/docs/manual/CoreTypes/resources.html?view=diff&rev=454842&r1=454841&r2=454842
==============================================================================
--- ant/core/trunk/docs/manual/CoreTypes/resources.html (original)
+++ ant/core/trunk/docs/manual/CoreTypes/resources.html Tue Oct 10 10:30:33 2006
@@ -463,6 +463,8 @@
       containing a particular text string.</li>
     <li><a href="selectors.html#regexpselect">containsregexp</a> - select
       resources whose contents match a particular regular expression.</li>
+    <li><a href="#rsel.compare">compare</a> - select resources
+      based on comparison to other resources.</li>
   </ul>
 
   <h4><a name="rsel.name">name</a></h4>
@@ -621,12 +623,40 @@
     </tr>
   </table>
 
+  <h4><a name="rsel.compare">compare</a></h4>
+  <p>Selects a resource based on its comparison to one or more "control"
+     resources using nested <a href="#rcmp">resource comparators</a>.</p>
+  <table border="1" cellpadding="2" cellspacing="0">
+    <tr>
+      <td valign="top"><b>Attribute</b></td>
+      <td valign="top"><b>Description</b></td>
+      <td align="center" valign="top"><b>Required</b></td>
+    </tr>
+    <tr>
+      <td valign="top">when</td>
+      <td valign="top">Comparison ("equal"/"eq", "greater"/"gt", "less"/"lt",
+        "le" (less or equal), "ge" (greater or equal), "ne" (not equal).</td>
+      <td valign="top">No, default "equal"</td>
+    </tr>
+    <tr>
+      <td valign="top">against</td>
+      <td valign="top">Quantifier ("all"/"each"/"every", "any"/"some",
+        (exactly) "one", "most"/"majority", "none".</td>
+      <td valign="top">No, default "all"</td>
+    </tr>
+  </table>
+  <h4>Parameters specified as nested elements</h4>
+  <p>The resources against which comparisons will be made must be specified
+    using the nested &lt;control&gt; element, which denotes a
+    <a href="#resources">resources</a> collection.</p>
+
 </blockquote>
 
 <h4><a name="sort">sort</a></h4>
 
 <p>Sorts another nested resource collection according to the resources'
-natural order, or by one or more nested resource comparators:</p>
+   natural order, or by one or more nested <a href="#rcmp">resource
+   comparators</a>:</p>
 <blockquote>
   <table border="1" cellpadding="2" cellspacing="0">
     <tr>
@@ -650,7 +680,7 @@
     are available in the internal <a href="antlib.html">antlib</a>
     <code>org.apache.tools.ant.types.resources.comparators</code>:
   </p>
-
+  <h4><a name="rcmp">Resource Comparators:</a></h4>
   <ul>
     <li><a href="#rcmp.name">name</a> - sort resources by name</li>
     <li><a href="#rcmp.exists">exists</a> - sort resources by existence</li>

Added: ant/core/trunk/src/main/org/apache/tools/ant/types/Quantifier.java
URL: 
http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/types/Quantifier.java?view=auto&rev=454842
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/types/Quantifier.java (added)
+++ ant/core/trunk/src/main/org/apache/tools/ant/types/Quantifier.java Tue Oct 
10 10:30:33 2006
@@ -0,0 +1,139 @@
+/*
+ *  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.tools.ant.types;
+
+import org.apache.tools.ant.BuildException;
+
+/**
+ * EnumeratedAttribute for quantifier comparisons. Evaluates a
+ * <code>boolean[]</code> or raw <code>true</code> and <code>false</code>
+ * counts. Accepts the following values:<ul>
+ * <li>"all"</li> - none <code>false</code>
+ * <li>"each"</li> - none <code>false</code>
+ * <li>"every"</li> - none <code>false</code>
+ * <li>"any"</li> - at least one <code>true</code>
+ * <li>"some"</li> - at least one <code>true</code>
+ * <li>"one"</li> - exactly one <code>true</code>
+ * <li>"majority"</li> - more <code>true</code> than <code>false</code>
+ * <li>"most"</li> - more <code>true</code> than <code>false</code>
+ * <li>"none"</li> - none <code>true</code>
+ * </ul>
+ * @since Ant 1.7
+ */
+public class Quantifier extends EnumeratedAttribute {
+    private static final String[] VALUES
+        = new String[] {"all", "each", "every", "any", "some", "one",
+                        "majority", "most", "none"};
+
+    public static final Quantifier ALL = new Quantifier("all");
+    public static final Quantifier ANY = new Quantifier("any");
+    public static final Quantifier ONE = new Quantifier("one");
+    public static final Quantifier MAJORITY = new Quantifier("majority");
+    public static final Quantifier NONE = new Quantifier("none");
+
+    private static abstract class Predicate {
+        abstract boolean eval(int t, int f);
+    }
+
+    private static final Predicate ALL_PRED = new Predicate() {
+        boolean eval(int t, int f) { return f == 0; }
+    };
+
+    private static final Predicate ANY_PRED = new Predicate() {
+        boolean eval(int t, int f) { return t > 0 ; }
+    };
+
+    private static final Predicate ONE_PRED = new Predicate() {
+        boolean eval(int t, int f) { return t == 1; }
+    };
+
+    private static final Predicate MAJORITY_PRED = new Predicate() {
+        boolean eval(int t, int f) { return t > f; }
+    };
+
+    private static final Predicate NONE_PRED = new Predicate() {
+        boolean eval(int t, int f) { return t == 0; }
+    };
+
+    private static final Predicate[] PREDS = new Predicate[VALUES.length];
+
+    static {
+        PREDS[0] = ALL_PRED;
+        PREDS[1] = ALL_PRED;
+        PREDS[2] = ALL_PRED;
+        PREDS[3] = ANY_PRED;
+        PREDS[4] = ANY_PRED;
+        PREDS[5] = ONE_PRED;
+        PREDS[6] = MAJORITY_PRED;
+        PREDS[7] = MAJORITY_PRED;
+        PREDS[8] = NONE_PRED;
+    }
+
+    /**
+     * Default constructor.
+     */
+    public Quantifier() {
+    }
+
+    /**
+     * Construct a new Quantifier with the specified value.
+     * @param value the EnumeratedAttribute value.
+     */
+    public Quantifier(String value) {
+        setValue(value);
+    }
+
+    /**
+     * Return the possible values.
+     * @return String[] of EnumeratedAttribute values.
+     */
+    public String[] getValues() {
+        return VALUES;
+    }
+
+    /**
+     * Evaluate a <code>boolean<code> array.
+     * @param b the <code>boolean[]</code> to evaluate.
+     * @return true if the argument fell within the parameters of this 
Quantifier.
+     */
+    public boolean evaluate(boolean[] b) {
+        int t = 0;
+        for (int i = 0; i < b.length; i++) {
+            if (b[i]) {
+                t++;
+            }
+        }
+        return evaluate(t, b.length - t);
+    }
+
+    /**
+     * Evaluate integer <code>true</code> vs. <code>false</code> counts.
+     * @param t the number of <code>true</code> values.
+     * @param f the number of <code>false</code> values.
+     * @return true if the arguments fell within the parameters of this 
Quantifier.
+     */
+    public boolean evaluate(int t, int f) {
+        int index = getIndex();
+        if (index == -1) {
+            throw new BuildException("Quantifier value not set.");
+        }
+        return PREDS[index].eval(t, f);
+    }
+
+}
+

Propchange: ant/core/trunk/src/main/org/apache/tools/ant/types/Quantifier.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ant/core/trunk/src/main/org/apache/tools/ant/types/Quantifier.java
------------------------------------------------------------------------------
    svn:executable = *

Added: 
ant/core/trunk/src/main/org/apache/tools/ant/types/resources/selectors/Compare.java
URL: 
http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/types/resources/selectors/Compare.java?view=auto&rev=454842
==============================================================================
--- 
ant/core/trunk/src/main/org/apache/tools/ant/types/resources/selectors/Compare.java
 (added)
+++ 
ant/core/trunk/src/main/org/apache/tools/ant/types/resources/selectors/Compare.java
 Tue Oct 10 10:30:33 2006
@@ -0,0 +1,153 @@
+/*
+ *  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.tools.ant.types.resources.selectors;
+
+import java.util.Stack;
+import java.util.Vector;
+import java.util.TreeMap;
+import java.util.Iterator;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Collections;
+import java.util.AbstractCollection;
+import java.util.NoSuchElementException;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Comparison;
+import org.apache.tools.ant.types.DataType;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.Quantifier;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.resources.Union;
+import org.apache.tools.ant.types.resources.comparators.ResourceComparator;
+import 
org.apache.tools.ant.types.resources.comparators.DelegatedResourceComparator;
+
+/**
+ * ResourceSelector that compares against "control" Resource(s)
+ * using ResourceComparators.
+ * @since Ant 1.7
+ */
+public class Compare extends DataType implements ResourceSelector {
+
+    private static final String ONE_CONTROL_MESSAGE
+        = " the <control> element should be specified exactly once.";
+
+    private DelegatedResourceComparator comp = new 
DelegatedResourceComparator();
+    private Quantifier against = Quantifier.ALL;
+
+    private Comparison when = Comparison.EQUAL;
+
+    private Union control;
+
+    /**
+     * Add a ResourceComparator to this Compare selector.
+     * If multiple ResourceComparators are added, they will be processed in 
LIFO order.
+     * @param c the ResourceComparator to add.
+     */
+    public synchronized void add(ResourceComparator c) {
+        if (isReference()) {
+            throw noChildrenAllowed();
+        }
+        comp.add(c);
+    }
+
+    /**
+     * Set the quantifier to be used. Default "all".
+     * @param against the Quantifier EnumeratedAttribute to use.
+     */
+    public synchronized void setAgainst(Quantifier against) {
+        if (isReference()) {
+            throw tooManyAttributes();
+        }
+        this.against = against;
+    }
+
+    /**
+     * Set the comparison to be used. Default "equal".
+     * @param when the Comparison EnumeratedAttribute to use.
+     */
+    public synchronized void setWhen(Comparison when) {
+        if (isReference()) {
+            throw tooManyAttributes();
+        }
+        this.when = when;
+    }
+
+    /**
+     * Create the nested control element. These are the
+     * resources to compare against.
+     * @return ResourceCollection.
+     */
+    public synchronized ResourceCollection createControl() {
+        if (isReference()) {
+            throw noChildrenAllowed();
+        }
+        if (control != null) {
+            throw oneControl();
+        }
+        control = new Union();
+        return control;
+    }
+
+    //implement ResourceSelector; inherit doc
+    public synchronized boolean isSelected(Resource r) {
+        if (isReference()) {
+            return ((ResourceSelector) getCheckedRef()).isSelected(r);
+        }
+        if (control == null) {
+            throw oneControl();
+        }
+        int t = 0, f = 0;
+        for (Iterator it = control.iterator(); it.hasNext();) {
+            if (when.evaluate(comp.compare(r, (Resource) it.next()))) {
+                t++;
+            } else {
+                f++;
+            }
+        }
+        return against.evaluate(t, f);
+    }
+
+    /**
+     * Overrides the version from DataType
+     * to recurse on nested ResourceComparators.
+     * @param stk the stack of data types to use (recursively).
+     * @param p   the project to use to dereference the references.
+     * @throws BuildException on error.
+     */
+    protected synchronized void dieOnCircularReference(Stack stk, Project p)
+        throws BuildException {
+        if (isChecked()) {
+            return;
+        }
+        if (isReference()) {
+            super.dieOnCircularReference(stk, p);
+        } else {
+            if (control != null) {
+                DataType.invokeCircularReferenceCheck(control, stk, p);
+            }
+            DataType.invokeCircularReferenceCheck(comp, stk, p);
+            setChecked(true);
+        }
+    }
+
+    private BuildException oneControl() {
+        return new BuildException(super.toString() + ONE_CONTROL_MESSAGE);
+    }
+}

Propchange: 
ant/core/trunk/src/main/org/apache/tools/ant/types/resources/selectors/Compare.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: 
ant/core/trunk/src/resources/org/apache/tools/ant/types/resources/selectors/antlib.xml
URL: 
http://svn.apache.org/viewvc/ant/core/trunk/src/resources/org/apache/tools/ant/types/resources/selectors/antlib.xml?view=diff&rev=454842&r1=454841&r2=454842
==============================================================================
--- 
ant/core/trunk/src/resources/org/apache/tools/ant/types/resources/selectors/antlib.xml
 (original)
+++ 
ant/core/trunk/src/resources/org/apache/tools/ant/types/resources/selectors/antlib.xml
 Tue Oct 10 10:30:33 2006
@@ -1,6 +1,8 @@
 <antlib>
   <typedef name="and"
     classname="org.apache.tools.ant.types.resources.selectors.And" />
+  <typedef name="compare"
+    classname="org.apache.tools.ant.types.resources.selectors.Compare" />
   <typedef name="contains"
     classname="org.apache.tools.ant.types.selectors.ContainsSelector" />
   <typedef name="containsregexp"

Modified: ant/core/trunk/src/tests/antunit/types/resources/selectors/test.xml
URL: 
http://svn.apache.org/viewvc/ant/core/trunk/src/tests/antunit/types/resources/selectors/test.xml?view=diff&rev=454842&r1=454841&r2=454842
==============================================================================
--- ant/core/trunk/src/tests/antunit/types/resources/selectors/test.xml 
(original)
+++ ant/core/trunk/src/tests/antunit/types/resources/selectors/test.xml Tue Oct 
10 10:30:33 2006
@@ -1,5 +1,6 @@
 <project default="all" xmlns:au="antlib:org.apache.ant.antunit"
-         xmlns:rsel="antlib:org.apache.tools.ant.types.resources.selectors">
+         xmlns:rsel="antlib:org.apache.tools.ant.types.resources.selectors"
+         xmlns:rcmp="antlib:org.apache.tools.ant.types.resources.comparators">
 
   <target name="testname1">
     <au:assertTrue>
@@ -99,7 +100,7 @@
     </au:assertTrue>
   </target>
 
-  <target name="testinstanceoftype"
+  <target name="instanceoftype"
     depends="testinstanceoftype1,testinstanceoftype2,testinstanceoftype3" />
 
   <target name="testinstanceofclass">
@@ -115,7 +116,7 @@
     </au:assertTrue>
   </target>
 
-  <target name="instanceof" depends="testinstanceoftype,testinstanceofclass" />
+  <target name="instanceof" depends="instanceoftype,testinstanceofclass" />
 
   <target name="testtype">
     <au:assertTrue>
@@ -358,6 +359,68 @@
     </au:assertTrue>
   </target>
 
+  <target name="testcompare">
+    <au:assertTrue>
+      <and>
+        <!-- basic test, natural ordering -->
+        <resourcecount count="3">
+          <restrict>
+            <rsel:compare when="greater" against="each">
+              <control><string value="b" /></control>
+            </rsel:compare>
+            <resources>
+              <string value="a" />
+              <string value="b" />
+              <string value="c" />
+              <string value="d" />
+              <string value="e" />
+            </resources>
+          </restrict>
+        </resourcecount>
+        <!-- one comparator, default when/against -->
+        <resourcecount count="5">
+          <restrict>
+            <rsel:compare>
+              <control><string value="." /></control>
+              <rcmp:size />
+            </rsel:compare>
+            <resources>
+              <string value="a" />
+              <string value="b" />
+              <string value="c" />
+              <string value="d" />
+              <string value="e" />
+            </resources>
+          </restrict>
+        </resourcecount>
+        <!-- multiple controls, comparators -->
+        <resourcecount count="3">
+          <restrict>
+            <rsel:compare when="greater" against="each">
+              <control>
+                <string value="a" />
+                <string value="b" />
+                <string value="bb" />
+                <string value="c" />
+                <string value="ccc" />
+              </control>
+              <rcmp:name />
+              <rcmp:size />
+            </rsel:compare>
+            <resources>
+              <string value="a" />
+              <string value="bbbb" />
+              <string value="ccc" />
+              <string value="cccc" />
+              <string value="d" />
+              <string value="e" />
+            </resources>
+          </restrict>
+        </resourcecount>
+      </and>
+    </au:assertTrue>
+  </target>
+
   <target name="majority"
           depends="testmajority1,testmajority2,testmajority3,testmajority4" />
 
@@ -365,7 +428,7 @@
           depends="testand,testor,testnone,testnot,majority" />
 
   <target name="all"
-    
depends="name,testexists,instanceof,testtype,testdate,testsize,testcontains,testcontainsregexp,logical"
 />
+    
depends="name,testexists,instanceof,testtype,testdate,testsize,testcontains,testcontainsregexp,logical,testcompare"
 />
 
   <!-- 
     The tests for oata.types.selectors.ModifiedSelectorTest as 



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to