that can support different implementations. git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@268202 13f79535-47bb-0310-9956-ffa450edef68master
@@ -69,7 +69,7 @@ import java.util.Stack; | |||||
* nested inside elements of the same type (i.e. <patternset> | * nested inside elements of the same type (i.e. <patternset> | ||||
* but not <path>).</p> | * but not <path>).</p> | ||||
* | * | ||||
* @author <a href="mailto:stefan.bodewig@megabit.net">Stefan Bodewig</a> | |||||
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | |||||
*/ | */ | ||||
public abstract class DataType { | public abstract class DataType { | ||||
/** | /** | ||||
@@ -0,0 +1,195 @@ | |||||
/* | |||||
* The Apache Software License, Version 1.1 | |||||
* | |||||
* Copyright (c) 2000 The Apache Software Foundation. All rights | |||||
* reserved. | |||||
* | |||||
* Redistribution and use in source and binary forms, with or without | |||||
* modification, are permitted provided that the following conditions | |||||
* are met: | |||||
* | |||||
* 1. Redistributions of source code must retain the above copyright | |||||
* notice, this list of conditions and the following disclaimer. | |||||
* | |||||
* 2. Redistributions in binary form must reproduce the above copyright | |||||
* notice, this list of conditions and the following disclaimer in | |||||
* the documentation and/or other materials provided with the | |||||
* distribution. | |||||
* | |||||
* 3. The end-user documentation included with the redistribution, if | |||||
* any, must include the following acknowlegement: | |||||
* "This product includes software developed by the | |||||
* Apache Software Foundation (http://www.apache.org/)." | |||||
* Alternately, this acknowlegement may appear in the software itself, | |||||
* if and wherever such third-party acknowlegements normally appear. | |||||
* | |||||
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software | |||||
* Foundation" must not be used to endorse or promote products derived | |||||
* from this software without prior written permission. For written | |||||
* permission, please contact apache@apache.org. | |||||
* | |||||
* 5. Products derived from this software may not be called "Apache" | |||||
* nor may "Apache" appear in their names without prior written | |||||
* permission of the Apache Group. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED | |||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |||||
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR | |||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | |||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
* SUCH DAMAGE. | |||||
* ==================================================================== | |||||
* | |||||
* This software consists of voluntary contributions made by many | |||||
* individuals on behalf of the Apache Software Foundation. For more | |||||
* information on the Apache Software Foundation, please see | |||||
* <http://www.apache.org/>. | |||||
*/ | |||||
package org.apache.tools.ant.types; | |||||
import org.apache.tools.ant.BuildException; | |||||
import org.apache.tools.ant.Project; | |||||
import org.apache.tools.ant.util.*; | |||||
import java.util.Properties; | |||||
import java.util.Stack; | |||||
/** | |||||
* Element to define a FileNameMapper. | |||||
* | |||||
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | |||||
*/ | |||||
public class Mapper extends DataType { | |||||
protected Project p; | |||||
protected MapperType type = null; | |||||
public Mapper(Project p) { | |||||
this.p = p; | |||||
} | |||||
/** | |||||
* Set the type of FileNameMapper to use. | |||||
*/ | |||||
public void setType(MapperType type) { | |||||
if (isReference()) { | |||||
throw tooManyAttributes(); | |||||
} | |||||
this.type = type; | |||||
} | |||||
protected String from = null; | |||||
/** | |||||
* Set the argument to FileNameMapper.setFrom | |||||
*/ | |||||
public void setFrom(String from) { | |||||
if (isReference()) { | |||||
throw tooManyAttributes(); | |||||
} | |||||
this.from = from; | |||||
} | |||||
protected String to = null; | |||||
/** | |||||
* Set the argument to FileNameMapper.setTo | |||||
*/ | |||||
public void setTo(String to) { | |||||
if (isReference()) { | |||||
throw tooManyAttributes(); | |||||
} | |||||
this.to = to; | |||||
} | |||||
/** | |||||
* Make this Mapper instance a reference to another Mapper. | |||||
* | |||||
* <p>You must not set any other attribute if you make it a | |||||
* reference.</p> | |||||
*/ | |||||
public void setRefid(Reference r) throws BuildException { | |||||
if (type != null || from != null || to != null) { | |||||
throw tooManyAttributes(); | |||||
} | |||||
super.setRefid(r); | |||||
} | |||||
/** | |||||
* Returns a fully configured FileNameMapper implementation. | |||||
*/ | |||||
public FileNameMapper getImplementation() throws BuildException { | |||||
if (isReference()) { | |||||
return getRef().getImplementation(); | |||||
} | |||||
if (type == null) { | |||||
throw new BuildException("type attribute is required"); | |||||
} | |||||
try { | |||||
Class c = Class.forName(type.getImplementation()); | |||||
FileNameMapper m = (FileNameMapper) c.newInstance(); | |||||
m.setFrom(from); | |||||
m.setTo(to); | |||||
return m; | |||||
} catch (Throwable t) { | |||||
throw new BuildException(t); | |||||
} | |||||
} | |||||
/** | |||||
* Performs the check for circular references and returns the | |||||
* referenced Mapper. | |||||
*/ | |||||
protected Mapper getRef() { | |||||
if (!checked) { | |||||
Stack stk = new Stack(); | |||||
stk.push(this); | |||||
dieOnCircularReference(stk, p); | |||||
} | |||||
Object o = ref.getReferencedObject(p); | |||||
if (!(o instanceof Mapper)) { | |||||
String msg = ref.getRefId()+" doesn\'t denote a mapper"; | |||||
throw new BuildException(msg); | |||||
} else { | |||||
return (Mapper) o; | |||||
} | |||||
} | |||||
/** | |||||
* Class as Argument to FileNameMapper.setType. | |||||
*/ | |||||
public static class MapperType extends EnumeratedAttribute { | |||||
private Properties implementations; | |||||
public MapperType() { | |||||
implementations = new Properties(); | |||||
implementations.put("identity", | |||||
"org.apache.tools.ant.util.IdentityMapper"); | |||||
implementations.put("flatten", | |||||
"org.apache.tools.ant.util.FlatFileNameMapper"); | |||||
implementations.put("glob", | |||||
"org.apache.tools.ant.util.GlobPatternMapper"); | |||||
implementations.put("merge", | |||||
"org.apache.tools.ant.util.MergingMapper"); | |||||
} | |||||
public String[] getValues() { | |||||
return new String[] {"identity", "flatten", "glob", "merge"}; | |||||
} | |||||
public String getImplementation() { | |||||
return implementations.getProperty(getValue()); | |||||
} | |||||
} | |||||
} |
@@ -1,3 +1,4 @@ | |||||
path=org.apache.tools.ant.types.Path | path=org.apache.tools.ant.types.Path | ||||
fileset=org.apache.tools.ant.types.FileSet | fileset=org.apache.tools.ant.types.FileSet | ||||
patternset=org.apache.tools.ant.types.PatternSet | patternset=org.apache.tools.ant.types.PatternSet | ||||
mapper=org.apache.tools.ant.types.Mapper |
@@ -0,0 +1,177 @@ | |||||
/* | |||||
* The Apache Software License, Version 1.1 | |||||
* | |||||
* Copyright (c) 2000 The Apache Software Foundation. All rights | |||||
* reserved. | |||||
* | |||||
* Redistribution and use in source and binary forms, with or without | |||||
* modification, are permitted provided that the following conditions | |||||
* are met: | |||||
* | |||||
* 1. Redistributions of source code must retain the above copyright | |||||
* notice, this list of conditions and the following disclaimer. | |||||
* | |||||
* 2. Redistributions in binary form must reproduce the above copyright | |||||
* notice, this list of conditions and the following disclaimer in | |||||
* the documentation and/or other materials provided with the | |||||
* distribution. | |||||
* | |||||
* 3. The end-user documentation included with the redistribution, if | |||||
* any, must include the following acknowlegement: | |||||
* "This product includes software developed by the | |||||
* Apache Software Foundation (http://www.apache.org/)." | |||||
* Alternately, this acknowlegement may appear in the software itself, | |||||
* if and wherever such third-party acknowlegements normally appear. | |||||
* | |||||
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software | |||||
* Foundation" must not be used to endorse or promote products derived | |||||
* from this software without prior written permission. For written | |||||
* permission, please contact apache@apache.org. | |||||
* | |||||
* 5. Products derived from this software may not be called "Apache" | |||||
* nor may "Apache" appear in their names without prior written | |||||
* permission of the Apache Group. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED | |||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |||||
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR | |||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | |||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
* SUCH DAMAGE. | |||||
* ==================================================================== | |||||
* | |||||
* This software consists of voluntary contributions made by many | |||||
* individuals on behalf of the Apache Software Foundation. For more | |||||
* information on the Apache Software Foundation, please see | |||||
* <http://www.apache.org/>. | |||||
*/ | |||||
package org.apache.tools.ant.types; | |||||
import org.apache.tools.ant.BuildException; | |||||
import org.apache.tools.ant.Project; | |||||
import org.apache.tools.ant.util.*; | |||||
import junit.framework.TestCase; | |||||
import junit.framework.AssertionFailedError; | |||||
import java.io.File; | |||||
/** | |||||
* JUnit 3 testcases for org.apache.tools.ant.types.Mapper. | |||||
* | |||||
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | |||||
*/ | |||||
public class MapperTest extends TestCase { | |||||
private Project project; | |||||
public MapperTest(String name) { | |||||
super(name); | |||||
} | |||||
public void setUp() { | |||||
project = new Project(); | |||||
project.setBasedir("."); | |||||
} | |||||
public void testEmptyElementIfIsReference() { | |||||
Mapper m = new Mapper(project); | |||||
m.setFrom("*.java"); | |||||
try { | |||||
m.setRefid(new Reference("dummyref")); | |||||
fail("Can add reference to Mapper with from attribute set"); | |||||
} catch (BuildException be) { | |||||
assertEquals("You must not specify more than one attribute when using refid", | |||||
be.getMessage()); | |||||
} | |||||
m = new Mapper(project); | |||||
m.setRefid(new Reference("dummyref")); | |||||
try { | |||||
m.setFrom("*.java"); | |||||
fail("Can set from in Mapper that is a reference."); | |||||
} catch (BuildException be) { | |||||
assertEquals("You must not specify more than one attribute when using refid", | |||||
be.getMessage()); | |||||
} | |||||
m = new Mapper(project); | |||||
m.setRefid(new Reference("dummyref")); | |||||
try { | |||||
m.setTo("*.java"); | |||||
fail("Can set to in Mapper that is a reference."); | |||||
} catch (BuildException be) { | |||||
assertEquals("You must not specify more than one attribute when using refid", | |||||
be.getMessage()); | |||||
} | |||||
try { | |||||
Mapper.MapperType mt = new Mapper.MapperType(); | |||||
mt.setValue("glob"); | |||||
m.setType(mt); | |||||
fail("Can set type in Mapper that is a reference."); | |||||
} catch (BuildException be) { | |||||
assertEquals("You must not specify more than one attribute when using refid", | |||||
be.getMessage()); | |||||
} | |||||
} | |||||
public void testCircularReferenceCheck() { | |||||
Mapper m = new Mapper(project); | |||||
project.addReference("dummy", m); | |||||
m.setRefid(new Reference("dummy")); | |||||
try { | |||||
m.getImplementation(); | |||||
fail("Can make Mapper a Reference to itself."); | |||||
} catch (BuildException be) { | |||||
assertEquals("This data type contains a circular reference.", | |||||
be.getMessage()); | |||||
} | |||||
// dummy1 --> dummy2 --> dummy3 --> dummy1 | |||||
Mapper m1 = new Mapper(project); | |||||
project.addReference("dummy1", m1); | |||||
m1.setRefid(new Reference("dummy2")); | |||||
Mapper m2 = new Mapper(project); | |||||
project.addReference("dummy2", m2); | |||||
m2.setRefid(new Reference("dummy3")); | |||||
Mapper m3 = new Mapper(project); | |||||
project.addReference("dummy3", m3); | |||||
m3.setRefid(new Reference("dummy1")); | |||||
try { | |||||
m1.getImplementation(); | |||||
fail("Can make circular reference."); | |||||
} catch (BuildException be) { | |||||
assertEquals("This data type contains a circular reference.", | |||||
be.getMessage()); | |||||
} | |||||
// dummy1 --> dummy2 --> dummy3 | |||||
// (which holds a glob mapper from "*.java" to "*.class" | |||||
m1 = new Mapper(project); | |||||
project.addReference("dummy1", m1); | |||||
m1.setRefid(new Reference("dummy2")); | |||||
m2 = new Mapper(project); | |||||
project.addReference("dummy2", m2); | |||||
m2.setRefid(new Reference("dummy3")); | |||||
m3 = new Mapper(project); | |||||
project.addReference("dummy3", m3); | |||||
Mapper.MapperType mt = new Mapper.MapperType(); | |||||
mt.setValue("glob"); | |||||
m3.setType(mt); | |||||
m3.setFrom("*.java"); | |||||
m3.setTo("*.class"); | |||||
FileNameMapper fmm = m1.getImplementation(); | |||||
assert("should be glob", fmm instanceof GlobPatternMapper); | |||||
String[] result = fmm.mapFileName("a.java"); | |||||
assertEquals("a.java should match", 1, result.length); | |||||
assertEquals("a.class", result[0]); | |||||
} | |||||
} |
@@ -65,9 +65,9 @@ import java.io.File; | |||||
/** | /** | ||||
* JUnit 3 testcases for org.apache.tools.ant.types.PatternSet. | * JUnit 3 testcases for org.apache.tools.ant.types.PatternSet. | ||||
* | * | ||||
* <p>This doesn't actually test much, mainly reference handling. | |||||
* <p>This doesn't actually test much, mainly reference handling.</p> | |||||
* | * | ||||
* @author <a href="mailto:stefan.bodewig@megabit.net">Stefan Bodewig</a> | |||||
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | |||||
*/ | */ | ||||
public class PatternSetTest extends TestCase { | public class PatternSetTest extends TestCase { | ||||