Browse Source

No more -lib needed.

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@276691 13f79535-47bb-0310-9956-ffa450edef68
master
Jan Materne 21 years ago
parent
commit
04d73d1565
5 changed files with 117 additions and 86 deletions
  1. +6
    -2
      build.xml
  2. +16
    -16
      docs/manual/CoreTypes/selectors.html
  3. +5
    -1
      src/etc/testcases/types/selectors.xml
  4. +64
    -17
      src/main/org/apache/tools/ant/types/selectors/modifiedselector/ModifiedSelector.java
  5. +26
    -50
      src/testcases/org/apache/tools/ant/types/selectors/ModifiedSelectorTest.java

+ 6
- 2
build.xml View File

@@ -85,6 +85,8 @@
<property name="build.tests" value="${build.dir}/testcases"/> <property name="build.tests" value="${build.dir}/testcases"/>
<property name="build.tests.javadocs" value="${build.dir}/javadocs.test/"/> <property name="build.tests.javadocs" value="${build.dir}/javadocs.test/"/>
<property name="manifest.tmp" value="${build.dir}/optional.manifest"/> <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 the java version
=================================================================== ===================================================================
--> -->
<target name="javac.preset" depends="javac.preset.1.5+,javac.preset.1.5-"/> <target name="javac.preset" depends="javac.preset.1.5+,javac.preset.1.5-"/>
<target name="javac.preset.1.5+" depends="check_for_optional_packages" <target name="javac.preset.1.5+" depends="check_for_optional_packages"
if="jdk1.5+"> if="jdk1.5+">
@@ -1455,6 +1457,7 @@


<sysproperty key="ant.home" value="${ant.home}"/> <sysproperty key="ant.home" value="${ant.home}"/>
<sysproperty key="build.tests" value="${build.tests}"/> <sysproperty key="build.tests" value="${build.tests}"/>
<sysproperty key="build.tests.value" value="${build.tests.value}"/>
<sysproperty key="tests-classpath.value" <sysproperty key="tests-classpath.value"
value="${tests-classpath.value}"/> value="${tests-classpath.value}"/>


@@ -1604,6 +1607,7 @@
<!-- <jvmarg value="-classic"/> --> <!-- <jvmarg value="-classic"/> -->
<sysproperty key="ant.home" value="${ant.home}"/> <sysproperty key="ant.home" value="${ant.home}"/>
<sysproperty key="build.tests" value="${build.tests}"/> <sysproperty key="build.tests" value="${build.tests}"/>
<sysproperty key="build.tests.value" value="${build.tests.value}"/>
<sysproperty key="tests-classpath.value" <sysproperty key="tests-classpath.value"
value="${tests-classpath.value}"/> value="${tests-classpath.value}"/>
<classpath refid="tests-classpath"/> <classpath refid="tests-classpath"/>
@@ -1629,4 +1633,4 @@
description="--> creates a minimum distribution in ./dist" description="--> creates a minimum distribution in ./dist"
depends="dist-lite"/> depends="dist-lite"/>


</project>
</project>

+ 16
- 16
docs/manual/CoreTypes/selectors.html View File

@@ -684,22 +684,19 @@
<tr> <tr>
<td valign="top"> algorithmclass </td> <td valign="top"> algorithmclass </td>
<td valign="top"> Classname of custom algorithm implementation. Lower <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> <td valign="top" align="center"> No </td>
</tr> </tr>
<tr> <tr>
<td valign="top"> cacheclass </td> <td valign="top"> cacheclass </td>
<td valign="top"> Classname of custom cache implementation. Lower <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> <td valign="top" align="center"> No </td>
</tr> </tr>
<tr> <tr>
<td valign="top"> comparatorclass </td> <td valign="top"> comparatorclass </td>
<td valign="top"> Classname of custom comparator implementation. Lower <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> <td valign="top" align="center"> No </td>
</tr> </tr>
<tr> <tr>
@@ -803,6 +800,10 @@
</tr> </tr>
</table> </table>


<p>The <code>&lt;modified&gt;</code> selector supports a nested
<code>&lt;classpath&gt;</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> <p>Here are some examples of how to use the Modified Selector:</p>


<blockquote><pre> <blockquote><pre>
@@ -868,23 +869,22 @@
Apache Forrest</a>). Here all <b>changed</b> files are uploaded to the server. The Apache Forrest</a>). Here all <b>changed</b> files are uploaded to the server. The
CacheSelector saves therefore much upload time.</p> CacheSelector saves therefore much upload time.</p>


<blockquote><pre>
&lt;modified cacheclassname="com.mycompany.MyCache"&gt;
&lt;classpath&gt;
&lt;pathelement location="lib/mycompony-antutil.jar"/&gt;
&lt;/classpath&gt;
&lt;/modified&gt;
</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> <a name="ModSelNote"></a>
<h4>Note on RuleBasedCollator</h4> <h4>Note on RuleBasedCollator</h4>
<p>The RuleBasedCollator needs a format for its work, but its needed while <p>The RuleBasedCollator needs a format for its work, but its needed while
instantiation. There is a problem in the initialization algorithm for this instantiation. There is a problem in the initialization algorithm for this
case. Therefore you should not use this (or tell me the workaround :-).</p> 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> <a name="selectcontainers"></a>


+ 5
- 1
src/etc/testcases/types/selectors.xml View File

@@ -250,7 +250,11 @@
algorithmclass="${pkg.test}.MockAlgorithm" algorithmclass="${pkg.test}.MockAlgorithm"
cacheclass="${pkg.test}.MockCache" cacheclass="${pkg.test}.MockCache"
comparatorclass="${pkg.test}.MockComparator" comparatorclass="${pkg.test}.MockComparator"
/>
>
<classpath>
<pathelement location="${build.tests.value}"/>
</classpath>
</modified>
</fileset> </fileset>
<fileset id="fs.full" dir="${test.dir}/src"/> <fileset id="fs.full" dir="${test.dir}/src"/>
<property name="fs.mod.value" refid="fs.mod"/> <property name="fs.mod.value" refid="fs.mod"/>


+ 64
- 17
src/main/org/apache/tools/ant/types/selectors/modifiedselector/ModifiedSelector.java View File

@@ -32,6 +32,7 @@ import org.apache.tools.ant.BuildListener;
import org.apache.tools.ant.BuildEvent; import org.apache.tools.ant.BuildEvent;
import org.apache.tools.ant.types.EnumeratedAttribute; import org.apache.tools.ant.types.EnumeratedAttribute;
import org.apache.tools.ant.types.Parameter; import org.apache.tools.ant.types.Parameter;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.selectors.BaseExtendSelector; import org.apache.tools.ant.types.selectors.BaseExtendSelector;




@@ -82,6 +83,17 @@ import org.apache.tools.ant.types.selectors.BaseExtendSelector;
* </copy> * </copy>
* </pre></p> * </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 &lt;classpath&gt;
* 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> * <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 * using the ModifiedSelector. The ModifiedSelector uses the <i>PropertyfileCache
* </i>, the <i>DigestAlgorithm</i> and the <i>EqualComparator</i> for its * </i>, the <i>DigestAlgorithm</i> and the <i>EqualComparator</i> for its
@@ -205,6 +217,8 @@ import org.apache.tools.ant.types.selectors.BaseExtendSelector;
* </table> * </table>
* If another name is used a BuildException "Invalid parameter" is thrown. </p> * If another name is used a BuildException "Invalid parameter" is thrown. </p>
* *
* <p>Additionally this selector supports a nested &lt;classpath&gt;. </p>
*
* <p>This selector uses reflection for setting the values of its three interfaces * <p>This selector uses reflection for setting the values of its three interfaces
* (using org.apache.tools.ant.IntrospectionHelper) therefore no special * (using org.apache.tools.ant.IntrospectionHelper) therefore no special
* 'configuration interfaces' has to be implemented by new caches, algorithms or * 'configuration interfaces' has to be implemented by new caches, algorithms or
@@ -214,7 +228,7 @@ import org.apache.tools.ant.types.selectors.BaseExtendSelector;
* a nested <i><param name="algorithm.provider" value="MyProvider"/></i>. * a nested <i><param name="algorithm.provider" value="MyProvider"/></i>.
* *
* *
* @version 2004-07-09
* @version 2004-07-12
* @since Ant 1.6 * @since Ant 1.6
*/ */
public class ModifiedSelector extends BaseExtendSelector implements BuildListener { public class ModifiedSelector extends BaseExtendSelector implements BuildListener {
@@ -283,6 +297,12 @@ public class ModifiedSelector extends BaseExtendSelector implements BuildListene
*/ */
private Vector specialParameter = new Vector(); private Vector specialParameter = new Vector();


/** The classloader of this class. */
private ClassLoader myClassLoader = null;

/** provided classpath for the classloader */
private Path classpath = null;



// ----- constructors ----- // ----- constructors -----


@@ -467,22 +487,8 @@ public class ModifiedSelector extends BaseExtendSelector implements BuildListene
protected Object loadClass(String classname, String msg, Class type) { protected Object loadClass(String classname, String msg, Class type) {
try { try {
// load the specified class // 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)) { if (!type.isInstance(rv)) {
throw new BuildException("Specified class (" + classname + ") " + msg); throw new BuildException("Specified class (" + classname + ") " + msg);
} }
@@ -495,7 +501,6 @@ public class ModifiedSelector extends BaseExtendSelector implements BuildListene
} }





// ----- the selection work ----- // ----- the selection work -----




@@ -629,6 +634,48 @@ public class ModifiedSelector extends BaseExtendSelector implements BuildListene
} }




/**
* 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;
}


/** /**
* Support for nested &lt;param&gt; tags. * Support for nested &lt;param&gt; tags.
* @param key the key of the parameter * @param key the key of the parameter


+ 26
- 50
src/testcases/org/apache/tools/ant/types/selectors/ModifiedSelectorTest.java View File

@@ -28,6 +28,7 @@ import java.text.RuleBasedCollator;
// Ant // Ant
import org.apache.tools.ant.BuildException; import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.types.Parameter; import org.apache.tools.ant.types.Parameter;
import org.apache.tools.ant.types.Path;


// inside MockProject // inside MockProject
import org.apache.tools.ant.Project; import org.apache.tools.ant.Project;
@@ -42,7 +43,7 @@ import org.apache.tools.ant.types.selectors.modifiedselector.*;
/** /**
* Unit tests for ModifiedSelector. * Unit tests for ModifiedSelector.
* *
* @version 2004-07-07
* @version 2004-07-12
* @since Ant 1.6 * @since Ant 1.6
*/ */
public class ModifiedSelectorTest extends BaseSelectorTest { public class ModifiedSelectorTest extends BaseSelectorTest {
@@ -54,6 +55,9 @@ public class ModifiedSelectorTest extends BaseSelectorTest {
/** Package of the CacheSelector classes. */ /** Package of the CacheSelector classes. */
private static String pkg = "org.apache.tools.ant.types.selectors.modifiedselector"; private static String pkg = "org.apache.tools.ant.types.selectors.modifiedselector";


/** Path where the testclasses are. */
private Path testclasses = null;



// ===================== constructors, factories ===================== // ===================== constructors, factories =====================


@@ -75,57 +79,22 @@ public class ModifiedSelectorTest extends BaseSelectorTest {
// ===================== JUnit stuff ===================== // ===================== 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 // for test only - ignore tests where we arent work at the moment
public static junit.framework.Test suite() { public static junit.framework.Test suite() {
junit.framework.TestSuite suite= new junit.framework.TestSuite(); junit.framework.TestSuite suite= new junit.framework.TestSuite();
suite.addTest(new ModifiedSelectorTest("testValidateWrongCache")); 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; return suite;
} }
/* */ /* */
@@ -216,13 +185,13 @@ public class ModifiedSelectorTest extends BaseSelectorTest {
} }




public void classloaderProblem_testCustomAlgorithm2() {
public void testCustomAlgorithm2() {
String algo = getAlgoName("org.apache.tools.ant.types.selectors.MockAlgorithm"); String algo = getAlgoName("org.apache.tools.ant.types.selectors.MockAlgorithm");
assertTrue("Wrong algorithm used: "+algo, algo.startsWith("MockAlgorithm")); assertTrue("Wrong algorithm used: "+algo, algo.startsWith("MockAlgorithm"));
} }




public void classloaderProblem_testCustomClasses() {
public void testCustomClasses() {
BFT bft = new BFT(); BFT bft = new BFT();
bft.setUp(); bft.setUp();
try { try {
@@ -248,17 +217,17 @@ public class ModifiedSelectorTest extends BaseSelectorTest {
} }




public void classloaderProblem_testDelayUpdateTaskFinished() {
public void testDelayUpdateTaskFinished() {
doDelayUpdateTest(1); doDelayUpdateTest(1);
} }




public void classloaderProblem_testDelayUpdateTargetFinished() {
public void testDelayUpdateTargetFinished() {
doDelayUpdateTest(2); doDelayUpdateTest(2);
} }




public void classloaderProblem_testDelayUpdateBuildFinished() {
public void testDelayUpdateBuildFinished() {
doDelayUpdateTest(3); doDelayUpdateTest(3);
} }


@@ -281,6 +250,11 @@ public class ModifiedSelectorTest extends BaseSelectorTest {
sel.setProject(project); sel.setProject(project);
sel.setUpdate(true); sel.setUpdate(true);
sel.setDelayUpdate(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.setAlgorithmClass("org.apache.tools.ant.types.selectors.MockAlgorithm");
sel.setCacheClass("org.apache.tools.ant.types.selectors.MockCache"); sel.setCacheClass("org.apache.tools.ant.types.selectors.MockCache");
sel.configure(); sel.configure();
@@ -313,6 +287,8 @@ public class ModifiedSelectorTest extends BaseSelectorTest {
*/ */
private String getAlgoName(String classname) { private String getAlgoName(String classname) {
ModifiedSelector sel = new ModifiedSelector(); ModifiedSelector sel = new ModifiedSelector();
// add the test classes to its classpath
sel.addClasspath(testclasses);
sel.setAlgorithmClass(classname); sel.setAlgorithmClass(classname);
// let the selector do its checks // let the selector do its checks
sel.validate(); sel.validate();


Loading…
Cancel
Save