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 { | ||||