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 <control> 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]