currently implemented data types are <path>, <fileset> and <patternset>. git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@267959 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -46,6 +46,8 @@ specified. | |||
| all files if the stylesheet changes. | |||
| * New data types fileset and patternset - expected to get a broader use. | |||
| They as well as PATH like structures can now be defined on a global | |||
| level and later be referenced by their id attribute. | |||
| * You can specify environment variables to <exec>. | |||
| @@ -34,6 +34,15 @@ | |||
| <property name="build.compiler" value="classic"/> | |||
| <property name="build.compiler.emacs" value="on"/> | |||
| <!-- =================================================================== --> | |||
| <!-- Define a global set of patterns that can be referenced by --> | |||
| <!-- its id attribute --> | |||
| <!-- =================================================================== --> | |||
| <patternset id="chmod.patterns"> | |||
| <include name="**/ant" /> | |||
| <include name="**/antRun" /> | |||
| </patternset> | |||
| <!-- =================================================================== --> | |||
| <!-- Check to see what optional dependencies are available --> | |||
| <!-- =================================================================== --> | |||
| @@ -125,10 +134,7 @@ | |||
| <copydir src="${src.bin.dir}" dest="${bin.dir}"/> | |||
| <chmod perm="+x"> | |||
| <fileset dir="${bin.dir}"> | |||
| <patternset id="chmod.patterns"> | |||
| <include name="**/ant" /> | |||
| <include name="**/antRun" /> | |||
| </patternset> | |||
| <patternsetref refid="chmod.patterns"/> | |||
| </fileset> | |||
| </chmod> | |||
| <fixcrlf srcdir="${bin.dir}" includes="ant,antRun" cr="remove"/> | |||
| @@ -460,6 +460,11 @@ defined.</p> | |||
| <p>Builds a PATH which holds the value of <code>${classpath}</code> | |||
| followed by all JAR files in the <code>lib</code> directory, followed | |||
| by the <code>classes</code> directory.</p> | |||
| <p>If you want to use the same PATH like structure for several tasks, | |||
| you can define them with a <code><path></code> element at the | |||
| same level as <em>target</em>s and reference them via their | |||
| <em>id</em> attribute - see <a href="#references">References</a> for an | |||
| example.</p> | |||
| <h3><a name="arg">Command line arguments</a></h3> | |||
| <p>Several tasks take arguments that shall be passed to another | |||
| @@ -518,33 +523,49 @@ the same snippet of XML over and over again - using a | |||
| example.</p> | |||
| <p>The following example</p> | |||
| <blockquote><pre> | |||
| <rmic ...> | |||
| <classpath> | |||
| <pathelement location="lib/" /> | |||
| <pathelement path="${java.class.path}/" /> | |||
| <pathelement path="${additional.path}" /> | |||
| </classpath> | |||
| </rmic> | |||
| <javac ...> | |||
| <classpath> | |||
| <pathelement location="lib/" /> | |||
| <pathelement path="${java.class.path}/" /> | |||
| <pathelement path="${additional.path}" /> | |||
| </classpath> | |||
| </javac> | |||
| <project ... > | |||
| <target ... > | |||
| <rmic ...> | |||
| <classpath> | |||
| <pathelement location="lib/" /> | |||
| <pathelement path="${java.class.path}/" /> | |||
| <pathelement path="${additional.path}" /> | |||
| </classpath> | |||
| </rmic> | |||
| </target> | |||
| <target ... > | |||
| <javac ...> | |||
| <classpath> | |||
| <pathelement location="lib/" /> | |||
| <pathelement path="${java.class.path}/" /> | |||
| <pathelement path="${additional.path}" /> | |||
| </classpath> | |||
| </javac> | |||
| </target> | |||
| </project> | |||
| </pre></blockquote> | |||
| <p>could be rewritten as</p> | |||
| <blockquote><pre> | |||
| <rmic ...> | |||
| <classpath id="project.class.path"> | |||
| <project ... > | |||
| <path id="project.class.path"> | |||
| <pathelement location="lib/" /> | |||
| <pathelement path="${java.class.path}/" /> | |||
| <pathelement path="${additional.path}" /> | |||
| </classpath> | |||
| </rmic> | |||
| <javac ...> | |||
| <classpathref refid="project.class.path" /> | |||
| </javac> | |||
| </path> | |||
| <target ... > | |||
| <rmic ...> | |||
| <classpathref refid="project.class.path" /> | |||
| </rmic> | |||
| </target> | |||
| <target ... > | |||
| <javac ...> | |||
| <classpathref refid="project.class.path" /> | |||
| </javac> | |||
| </target> | |||
| </project> | |||
| </pre></blockquote> | |||
| <p>All tasks that use nested elements for <a | |||
| href="#patternset">PatternSet</a>s, <a href="#fileset">FileSet</a>s or | |||
| @@ -666,9 +687,10 @@ If you do not want these default excludes applied, you may disable them with the | |||
| <h3><a name="patternset">PatternSets</a></h3> | |||
| <p>Patterns can be grouped to sets and later be referenced by their id | |||
| attribute. They are defined via a <code>patternset</code> element - | |||
| which can currently only appear nested into a <a | |||
| href="#fileset">FileSet</a> or a directory based task that constitutes | |||
| an implicit FileSet.</p> | |||
| which can appear nested into a <a href="#fileset">FileSet</a> or a | |||
| directory based task that constitutes an implicit FileSet. In addition | |||
| <code>patternset</code>s can be defined at the same level as | |||
| <code>target</code> - i.e. as children of <code>project</code></p> | |||
| <p>Patterns can be specified by nested <code><include></code> or | |||
| <code><exclude></code> elements or the following attributes.</p> | |||
| <table border="1" cellpadding="2" cellspacing="0"> | |||
| @@ -713,8 +735,9 @@ can be <a href="#references">referred</a> to via | |||
| <p>FileSets are groups of files. These files can be found in a | |||
| directory tree starting in a base directory and are matched by | |||
| patterns taken from a number of <a | |||
| href="#patternset">PatternSets</a>. Currently FileSets can only appear | |||
| inside task that support this feature.</p> | |||
| href="#patternset">PatternSets</a>. FileSets can appear inside task | |||
| that support this feature or at the same level as <code>target</code> | |||
| - i.e. as children of <code>project</code>.</p> | |||
| <p>PatternSets can be specified as nested | |||
| <code><patternset></code> or <code><patternsetref></code> | |||
| elements. In addition FileSet holds an implicit PatternSet and | |||
| @@ -250,6 +250,8 @@ public class ProjectHelper { | |||
| handleProperty(name, attrs); | |||
| } else if (name.equals("target")) { | |||
| handleTarget(name, attrs); | |||
| } else if (project.getDataTypeDefinitions().get(name) != null) { | |||
| handleDataType(name, attrs); | |||
| } else { | |||
| throw new SAXParseException("Unexpected element \"" + name + "\"", locator); | |||
| } | |||
| @@ -266,6 +268,10 @@ public class ProjectHelper { | |||
| private void handleTarget(String tag, AttributeList attrs) throws SAXParseException { | |||
| new TargetHandler(this).init(tag, attrs); | |||
| } | |||
| private void handleDataType(String name, AttributeList attrs) throws SAXParseException { | |||
| new DataTypeHandler(this).init(name, attrs); | |||
| } | |||
| } | |||
| /** | |||
| @@ -388,8 +394,6 @@ public class ProjectHelper { | |||
| * Handler for all nested properties. | |||
| */ | |||
| private class NestedElementHandler extends AbstractHandler { | |||
| private DocumentHandler parentHandler; | |||
| private Object target; | |||
| private Object child; | |||
| @@ -431,6 +435,48 @@ public class ProjectHelper { | |||
| } | |||
| } | |||
| /** | |||
| * Handler for all data types at global level. | |||
| */ | |||
| private class DataTypeHandler extends AbstractHandler { | |||
| private Object element; | |||
| public DataTypeHandler(DocumentHandler parentHandler) { | |||
| super(parentHandler); | |||
| } | |||
| public void init(String propType, AttributeList attrs) throws SAXParseException { | |||
| try { | |||
| element = project.createDataType(propType); | |||
| if (element == null) { | |||
| throw new BuildException("Unknown data type "+propType); | |||
| } | |||
| configure(element, attrs); | |||
| } catch (BuildException exc) { | |||
| throw new SAXParseException(exc.getMessage(), locator, exc); | |||
| } | |||
| } | |||
| public void characters(char[] buf, int start, int end) throws SAXParseException { | |||
| String text = new String(buf, start, end).trim(); | |||
| if (text.length() == 0) return; | |||
| IntrospectionHelper ih = | |||
| IntrospectionHelper.getHelper(element.getClass()); | |||
| try { | |||
| ih.addText(element, text); | |||
| } catch (BuildException exc) { | |||
| throw new SAXParseException(exc.getMessage(), locator, exc); | |||
| } | |||
| } | |||
| public void startElement(String name, AttributeList attrs) throws SAXParseException { | |||
| new NestedElementHandler(this, element).init(name, attrs); | |||
| } | |||
| } | |||
| private void configure(Object target, AttributeList attrs) throws BuildException { | |||
| if( target instanceof TaskAdapter ) | |||
| target=((TaskAdapter)target).getProxy(); | |||
| @@ -106,7 +106,8 @@ public class AntStructure extends Task { | |||
| out = new PrintWriter(new FileWriter(output)); | |||
| } | |||
| printHead(out); | |||
| Enumeration dataTypes = project.getDataTypeDefinitions().keys(); | |||
| printHead(out, dataTypes); | |||
| Vector tasks = new Vector(); | |||
| Enumeration enum = project.getTaskDefinitions().keys(); | |||
| @@ -116,6 +117,13 @@ public class AntStructure extends Task { | |||
| } | |||
| printTargetDecl(out, tasks); | |||
| dataTypes = project.getDataTypeDefinitions().keys(); | |||
| while (dataTypes.hasMoreElements()) { | |||
| String typeName = (String) dataTypes.nextElement(); | |||
| printElementDecl(out, typeName, | |||
| (Class) project.getDataTypeDefinitions().get(typeName)); | |||
| } | |||
| for (int i=0; i<tasks.size(); i++) { | |||
| String taskName = (String) tasks.elementAt(i); | |||
| printElementDecl(out, taskName, | |||
| @@ -134,12 +142,18 @@ public class AntStructure extends Task { | |||
| } | |||
| } | |||
| private void printHead(PrintWriter out) { | |||
| private void printHead(PrintWriter out, Enumeration enum) { | |||
| out.println("<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>"); | |||
| out.println("<!ENTITY % boolean \"(true|false|on|off|yes|no)\">"); | |||
| out.println(""); | |||
| out.println("<!ELEMENT project (target | property | taskdef)*>"); | |||
| out.print("<!ELEMENT project (target | property | taskdef"); | |||
| while (enum.hasMoreElements()) { | |||
| String typeName = (String) enum.nextElement(); | |||
| out.print(" | "+typeName); | |||
| } | |||
| out.println(")*>"); | |||
| out.println("<!ATTLIST project"); | |||
| out.println(" name CDATA #REQUIRED"); | |||
| out.println(" default CDATA #REQUIRED"); | |||