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> | |||
| * 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 { | |||
| /** | |||
| @@ -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 | |||
| fileset=org.apache.tools.ant.types.FileSet | |||
| 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. | |||
| * | |||
| * <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 { | |||