jhm 2004/07/12 08:04:13 Modified: . build.xml src/main/org/apache/tools/ant/types/selectors/modifiedselector ModifiedSelector.java src/testcases/org/apache/tools/ant/types/selectors ModifiedSelectorTest.java src/etc/testcases/types selectors.xml docs/manual/CoreTypes selectors.html Log: No more -lib needed. Revision Changes Path 1.424 +6 -2 ant/build.xml Index: build.xml =================================================================== RCS file: /home/cvs/ant/build.xml,v retrieving revision 1.423 retrieving revision 1.424 diff -u -r1.423 -r1.424 --- build.xml 25 Jun 2004 13:42:08 -0000 1.423 +++ build.xml 12 Jul 2004 15:04:13 -0000 1.424 @@ -85,6 +85,8 @@ <property name="build.tests" value="${build.dir}/testcases"/> <property name="build.tests.javadocs" value="${build.dir}/javadocs.test/"/> <property name="manifest.tmp" value="${build.dir}/optional.manifest"/> + <!-- the absolute path --> + <property name="build.tests.value" location="${build.tests}"/> <!-- =================================================================== @@ -365,7 +367,7 @@ the java version =================================================================== --> - + <target name="javac.preset" depends="javac.preset.1.5+,javac.preset.1.5-"/> <target name="javac.preset.1.5+" depends="check_for_optional_packages" if="jdk1.5+"> @@ -1455,6 +1457,7 @@ <sysproperty key="ant.home" value="${ant.home}"/> <sysproperty key="build.tests" value="${build.tests}"/> + <sysproperty key="build.tests.value" value="${build.tests.value}"/> <sysproperty key="tests-classpath.value" value="${tests-classpath.value}"/> @@ -1604,6 +1607,7 @@ <!-- <jvmarg value="-classic"/> --> <sysproperty key="ant.home" value="${ant.home}"/> <sysproperty key="build.tests" value="${build.tests}"/> + <sysproperty key="build.tests.value" value="${build.tests.value}"/> <sysproperty key="tests-classpath.value" value="${tests-classpath.value}"/> <classpath refid="tests-classpath"/> @@ -1629,4 +1633,4 @@ description="--> creates a minimum distribution in ./dist" depends="dist-lite"/> -</project> +</project> \ No newline at end of file 1.8 +64 -17 ant/src/main/org/apache/tools/ant/types/selectors/modifiedselector/ModifiedSelector.java Index: ModifiedSelector.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/types/selectors/modifiedselector/ModifiedSelector.java,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- ModifiedSelector.java 10 Jul 2004 17:15:37 -0000 1.7 +++ ModifiedSelector.java 12 Jul 2004 15:04:13 -0000 1.8 @@ -32,6 +32,7 @@ import org.apache.tools.ant.BuildEvent; import org.apache.tools.ant.types.EnumeratedAttribute; import org.apache.tools.ant.types.Parameter; +import org.apache.tools.ant.types.Path; import org.apache.tools.ant.types.selectors.BaseExtendSelector; @@ -82,6 +83,17 @@ * </copy> * </pre></p> * + * <p>If you want to provide your own interface implementation you can do + * that via the *classname attributes. If the classes are not on Antīs core + * classpath, you will have to provide the path via nested <classpath> + * element, so that the selector can find the classes. <pre> + * <modified cacheclassname="com.mycompany.MyCache"> + * <classpath> + * <pathelement location="lib/mycompony-antutil.jar"/> + * </classpath> + * </modified> + * </p> + * * <p>All these three examples copy the files from <i>src</i> to <i>dest</i> * using the ModifiedSelector. The ModifiedSelector uses the <i>PropertyfileCache * </i>, the <i>DigestAlgorithm</i> and the <i>EqualComparator</i> for its @@ -205,6 +217,8 @@ * </table> * If another name is used a BuildException "Invalid parameter" is thrown. </p> * + * <p>Additionally this selector supports a nested <classpath>. </p> + * * <p>This selector uses reflection for setting the values of its three interfaces * (using org.apache.tools.ant.IntrospectionHelper) therefore no special * 'configuration interfaces' has to be implemented by new caches, algorithms or @@ -214,7 +228,7 @@ * a nested <i><param name="algorithm.provider" value="MyProvider"/></i>. * * - * @version 2004-07-09 + * @version 2004-07-12 * @since Ant 1.6 */ public class ModifiedSelector extends BaseExtendSelector implements BuildListener { @@ -283,6 +297,12 @@ */ private Vector specialParameter = new Vector(); + /** The classloader of this class. */ + private ClassLoader myClassLoader = null; + + /** provided classpath for the classloader */ + private Path classpath = null; + // ----- constructors ----- @@ -467,22 +487,8 @@ protected Object loadClass(String classname, String msg, Class type) { try { // load the specified class + Object rv = getClassLoader().loadClass(classname).newInstance(); - /* TODO: the selector cant find the specified class if the - * selector is loaded from a different classloader. - * See ModifiedSelectorTest.testCustom<Algorithm|Cache|Comparator|Classes>(). - * To be able to run these tests you have to ensure that <junit> can find - * the classes by adding the test package to the core: - * - by placing the ant-testutils.jar in %ANT_HOME/lib - * - by adding '-lib build/testcases' while invocation - * - * IMO this is not only a problem for the Mock-Classes inside the - * tests. The *classname attributes are designed for the user to - * provide his own implementations. Therefore they should be - * found ... Workaround again: -lib, ~/.ant/lib, ant.home/lib - * JHM - */ - Object rv = Class.forName(classname).newInstance(); if (!type.isInstance(rv)) { throw new BuildException("Specified class (" + classname + ") " + msg); } @@ -495,7 +501,6 @@ } - // ----- the selection work ----- @@ -626,6 +631,48 @@ */ public void setDelayUpdate(boolean delayUpdate) { this.delayUpdate = delayUpdate; + } + + + /** + * Add the classpath. + * @param path the classpath + */ + public void addClasspath(Path path) { + if (classpath != null) { + throw new BuildException("<classpath> can be set only once."); + } + classpath = path; + } + + + /** + * Returns and initializes the classloader for this class. + * @return the classloader + */ + public ClassLoader getClassLoader() { + if (myClassLoader == null) { + myClassLoader = (classpath == null) + // the usual classloader + ? getClass().getClassLoader() + // additional use the provided classpath + : new org.apache.tools.ant.AntClassLoader(getProject(), classpath); + } + return myClassLoader; + } + + + /** + * Set the used ClassLoader. + * If you invoke this selector by API (e.g. inside some testcases) the selector + * will use a different classloader for loading the interface implementations than + * the caller. Therefore you will get a ClassCastException if you get the + * implementations from the selector and cast them. + * @param loader the ClassLoader to use + * @see ModifiedSelectorTest#doDelayUpdateTest(int key) + */ + public void setClassLoader(ClassLoader loader) { + myClassLoader = loader; } 1.9 +26 -50 ant/src/testcases/org/apache/tools/ant/types/selectors/ModifiedSelectorTest.java Index: ModifiedSelectorTest.java =================================================================== RCS file: /home/cvs/ant/src/testcases/org/apache/tools/ant/types/selectors/ModifiedSelectorTest.java,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- ModifiedSelectorTest.java 10 Jul 2004 17:15:37 -0000 1.8 +++ ModifiedSelectorTest.java 12 Jul 2004 15:04:13 -0000 1.9 @@ -28,6 +28,7 @@ // Ant import org.apache.tools.ant.BuildException; import org.apache.tools.ant.types.Parameter; +import org.apache.tools.ant.types.Path; // inside MockProject import org.apache.tools.ant.Project; @@ -42,7 +43,7 @@ /** * Unit tests for ModifiedSelector. * - * @version 2004-07-07 + * @version 2004-07-12 * @since Ant 1.6 */ public class ModifiedSelectorTest extends BaseSelectorTest { @@ -54,6 +55,9 @@ /** Package of the CacheSelector classes. */ private static String pkg = "org.apache.tools.ant.types.selectors.modifiedselector"; + /** Path where the testclasses are. */ + private Path testclasses = null; + // ===================== constructors, factories ===================== @@ -75,57 +79,22 @@ // ===================== JUnit stuff ===================== + public void setUp() { + // project reference is set in super.setUp() + super.setUp(); + // init the testclasses path object + Project prj = getProject(); + if (prj != null) { + testclasses = new Path(prj, prj.getProperty("build.tests.value")); + } + } - /* There are two tests which cannot run until the test package is added - * to the core classloader. See comment in ModifiedSelelector.loadClass(). - * The tests should pass then - but because the usual build wont add - * these classes I exclude them from being executed: - * - classloaderProblem_testCustomAlgorithm2 - * - classloaderProblem_testCustomClasses - * - * For activating decomment the suite method. - * - * the addTest-part can be generated via grep and sed: - * grep "void test" ModifiedSelectorTest.java - * | sed -e 's/() {/"));/' - * -e 's/public void / suite.addTest(new ModifiedSelectorTest("/' - */ /* * / // for test only - ignore tests where we arent work at the moment public static junit.framework.Test suite() { junit.framework.TestSuite suite= new junit.framework.TestSuite(); suite.addTest(new ModifiedSelectorTest("testValidateWrongCache")); - suite.addTest(new ModifiedSelectorTest("testValidateWrongAlgorithm")); - suite.addTest(new ModifiedSelectorTest("testValidateWrongComparator")); - suite.addTest(new ModifiedSelectorTest("testIllegalCustomAlgorithm")); - suite.addTest(new ModifiedSelectorTest("testNonExistentCustomAlgorithm")); - suite.addTest(new ModifiedSelectorTest("testCustomAlgorithm")); - suite.addTest(new ModifiedSelectorTest("testPropcacheInvalid")); - suite.addTest(new ModifiedSelectorTest("testPropertyfileCache")); - suite.addTest(new ModifiedSelectorTest("testCreatePropertiesCacheDirect")); - suite.addTest(new ModifiedSelectorTest("testCreatePropertiesCacheViaModifiedSelector")); - suite.addTest(new ModifiedSelectorTest("testCreatePropertiesCacheViaCustomSelector")); - suite.addTest(new ModifiedSelectorTest("testHashvalueAlgorithm")); - suite.addTest(new ModifiedSelectorTest("testDigestAlgorithmMD5")); - suite.addTest(new ModifiedSelectorTest("testDigestAlgorithmSHA")); - suite.addTest(new ModifiedSelectorTest("testChecksumAlgorithm")); - suite.addTest(new ModifiedSelectorTest("testChecksumAlgorithmCRC")); - suite.addTest(new ModifiedSelectorTest("testChecksumAlgorithmAdler")); - suite.addTest(new ModifiedSelectorTest("testEqualComparator")); - suite.addTest(new ModifiedSelectorTest("testRuleComparator")); - suite.addTest(new ModifiedSelectorTest("testEqualComparatorViaSelector")); - suite.addTest(new ModifiedSelectorTest("testSeldirs")); - suite.addTest(new ModifiedSelectorTest("testScenario1")); - suite.addTest(new ModifiedSelectorTest("testScenarioCoreSelectorDefaults")); - suite.addTest(new ModifiedSelectorTest("testScenarioCoreSelectorSettings")); - suite.addTest(new ModifiedSelectorTest("testScenarioCustomSelectorSettings")); - - suite.addTest(new ModifiedSelectorTest("classloaderProblem_testDelayUpdateTaskFinished")); - suite.addTest(new ModifiedSelectorTest("classloaderProblem_testDelayUpdateTargetFinished")); - suite.addTest(new ModifiedSelectorTest("classloaderProblem_testDelayUpdateBuildFinished")); - suite.addTest(new ModifiedSelectorTest("classloaderProblem_testCustomAlgorithm2")); - suite.addTest(new ModifiedSelectorTest("classloaderProblem_testCustomClasses")); return suite; } /* */ @@ -216,13 +185,13 @@ } - public void classloaderProblem_testCustomAlgorithm2() { + public void testCustomAlgorithm2() { String algo = getAlgoName("org.apache.tools.ant.types.selectors.MockAlgorithm"); assertTrue("Wrong algorithm used: "+algo, algo.startsWith("MockAlgorithm")); } - public void classloaderProblem_testCustomClasses() { + public void testCustomClasses() { BFT bft = new BFT(); bft.setUp(); try { @@ -248,17 +217,17 @@ } - public void classloaderProblem_testDelayUpdateTaskFinished() { + public void testDelayUpdateTaskFinished() { doDelayUpdateTest(1); } - public void classloaderProblem_testDelayUpdateTargetFinished() { + public void testDelayUpdateTargetFinished() { doDelayUpdateTest(2); } - public void classloaderProblem_testDelayUpdateBuildFinished() { + public void testDelayUpdateBuildFinished() { doDelayUpdateTest(3); } @@ -281,6 +250,11 @@ sel.setProject(project); sel.setUpdate(true); sel.setDelayUpdate(true); + // sorry - otherwise we will get a ClassCastException because the MockCache + // is loaded by two different classloader ... + sel.setClassLoader(this.getClass().getClassLoader()); + sel.addClasspath(testclasses); + sel.setAlgorithmClass("org.apache.tools.ant.types.selectors.MockAlgorithm"); sel.setCacheClass("org.apache.tools.ant.types.selectors.MockCache"); sel.configure(); @@ -313,6 +287,8 @@ */ private String getAlgoName(String classname) { ModifiedSelector sel = new ModifiedSelector(); + // add the test classes to its classpath + sel.addClasspath(testclasses); sel.setAlgorithmClass(classname); // let the selector do its checks sel.validate(); 1.9 +5 -1 ant/src/etc/testcases/types/selectors.xml Index: selectors.xml =================================================================== RCS file: /home/cvs/ant/src/etc/testcases/types/selectors.xml,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- selectors.xml 10 Jul 2004 17:15:37 -0000 1.8 +++ selectors.xml 12 Jul 2004 15:04:13 -0000 1.9 @@ -250,7 +250,11 @@ algorithmclass="${pkg.test}.MockAlgorithm" cacheclass="${pkg.test}.MockCache" comparatorclass="${pkg.test}.MockComparator" - /> + > + <classpath> + <pathelement location="${build.tests.value}"/> + </classpath> + </modified> </fileset> <fileset id="fs.full" dir="${test.dir}/src"/> <property name="fs.mod.value" refid="fs.mod"/> 1.24 +16 -16 ant/docs/manual/CoreTypes/selectors.html Index: selectors.html =================================================================== RCS file: /home/cvs/ant/docs/manual/CoreTypes/selectors.html,v retrieving revision 1.23 retrieving revision 1.24 diff -u -r1.23 -r1.24 --- selectors.html 10 Jul 2004 17:15:37 -0000 1.23 +++ selectors.html 12 Jul 2004 15:04:13 -0000 1.24 @@ -684,22 +684,19 @@ <tr> <td valign="top"> algorithmclass </td> <td valign="top"> Classname of custom algorithm implementation. Lower - priority than <i>algorithm</i>. - <!-- NOTE --> (see <a href="#ModSelNote">note</a> for restrictions) </td> + priority than <i>algorithm</i>. </td> <td valign="top" align="center"> No </td> </tr> <tr> <td valign="top"> cacheclass </td> <td valign="top"> Classname of custom cache implementation. Lower - priority than <i>cache</i>. - <!-- NOTE --> (see <a href="#ModSelNote">note</a> for restrictions) </td> + priority than <i>cache</i>. </td> <td valign="top" align="center"> No </td> </tr> <tr> <td valign="top"> comparatorclass </td> <td valign="top"> Classname of custom comparator implementation. Lower - priority than <i>comparator</i>. - <!-- NOTE --> (see <a href="#ModSelNote">note</a> for restrictions) </td> + priority than <i>comparator</i>. </td> <td valign="top" align="center"> No </td> </tr> <tr> @@ -803,6 +800,10 @@ </tr> </table> + <p>The <code><modified></code> selector supports a nested + <code><classpath></code> element that represents a <a href="../using.html#path"> + PATH like structure</a> for finding custom interface implementations. </p> + <p>Here are some examples of how to use the Modified Selector:</p> <blockquote><pre> @@ -868,23 +869,22 @@ Apache Forrest</a>). Here all <b>changed</b> files are uploaded to the server. The CacheSelector saves therefore much upload time.</p> + <blockquote><pre> + <modified cacheclassname="com.mycompany.MyCache"> + <classpath> + <pathelement location="lib/mycompony-antutil.jar"/> + </classpath> + </modified> + </pre></blockquote> + <p>Uses <tt>com.mycompany.MyCache</tt> from a jar outside of Ants own classpath + as cache implementation</p> - <!-- NOTE --> - <i>(see <a href="#ModSelNote">note</a> for restrictions)</i> <a name="ModSelNote"></a> <h4>Note on RuleBasedCollator</h4> <p>The RuleBasedCollator needs a format for its work, but its needed while instantiation. There is a problem in the initialization algorithm for this case. Therefore you should not use this (or tell me the workaround :-).</p> - <p>The selector can not find the specified algorithm-, cache- or comparator- - class if the selector is loaded from a different classloader. - To be able to use your own classes you have to ensure that the selector - can find the classes by adding the your package to the core: <ul> - <li> by placing your JAR in %ANT_HOME/lib </li> - <li> by adding '-lib myclasses/' while invocation </li> - <li> by placing your JAR in ${ant.home}/.ant/lib </li> - </ul></p> <a name="selectcontainers"></a>
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]