git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@269247 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -1,8 +1,8 @@ | |||
| #!/bin/sh | |||
| echo | |||
| echo "Ant Build System" | |||
| echo "----------------" | |||
| echo "Myrmidon Build System" | |||
| echo "---------------------" | |||
| export MYRMIDON_HOME=tools | |||
| @@ -7,6 +7,7 @@ | |||
| */ | |||
| package org.apache.myrmidon.components.builder; | |||
| import java.net.URL; | |||
| import java.io.File; | |||
| import java.io.IOException; | |||
| import java.util.ArrayList; | |||
| @@ -61,8 +62,8 @@ public class DefaultProjectBuilder | |||
| private Project build( final File file, final HashMap projects ) | |||
| throws Exception | |||
| { | |||
| final String systemID = file.toURL().toString(); | |||
| final Project result = (Project)projects.get( systemID ); | |||
| final URL systemID = file.toURL(); | |||
| final Project result = (Project)projects.get( systemID.toString() ); | |||
| if( null != result ) | |||
| { | |||
| return result; | |||
| @@ -73,9 +74,10 @@ public class DefaultProjectBuilder | |||
| process( systemID, handler ); | |||
| final Configuration configuration = handler.getConfiguration(); | |||
| final DefaultProject project = buildProject( file, configuration ); | |||
| projects.put( systemID, project ); | |||
| projects.put( systemID.toString(), project ); | |||
| //build using all top-level attributes | |||
| buildTopLevelProject( project, configuration, projects ); | |||
| @@ -83,7 +85,7 @@ public class DefaultProjectBuilder | |||
| return project; | |||
| } | |||
| protected void process( final String systemID, | |||
| protected void process( final URL systemID, | |||
| final SAXConfigurationHandler handler ) | |||
| throws Exception | |||
| { | |||
| @@ -96,19 +98,7 @@ public class DefaultProjectBuilder | |||
| parser.setContentHandler( handler ); | |||
| parser.setErrorHandler( handler ); | |||
| parser.parse( systemID ); | |||
| /* | |||
| // Create a transform factory instance. | |||
| final TransformerFactory factory = TransformerFactory.newInstance(); | |||
| // Create a transformer for the stylesheet. | |||
| final Transformer transformer = factory.newTransformer( new StreamSource(xslID) ); | |||
| final Result result = new SAXResult( handler ); | |||
| // Transform the source XML to System.out. | |||
| transformer.transform( new StreamSource(sourceID), result ); | |||
| */ | |||
| parser.parse( systemID.toString() ); | |||
| } | |||
| /** | |||
| @@ -0,0 +1,59 @@ | |||
| /* | |||
| * Copyright (C) The Apache Software Foundation. All rights reserved. | |||
| * | |||
| * This software is published under the terms of the Apache Software License | |||
| * version 1.1, a copy of which has been included with this distribution in | |||
| * the LICENSE file. | |||
| */ | |||
| package org.apache.myrmidon.components.builder; | |||
| import java.util.ArrayList; | |||
| import org.xml.sax.Attributes; | |||
| import org.xml.sax.SAXException; | |||
| import org.xml.sax.helpers.DefaultHandler; | |||
| /** | |||
| * Handler that reacts to PIs before first element. | |||
| * Have to do it this way as there doesn't seem to be a *safe* way | |||
| * of redirecting content handlers at runtime while using transformers. | |||
| * | |||
| * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||
| */ | |||
| public class ReactorPIHandler | |||
| extends DefaultHandler | |||
| { | |||
| private ArrayList m_targets = new ArrayList(); | |||
| private ArrayList m_data = new ArrayList(); | |||
| public int getPICount() | |||
| { | |||
| return m_targets.size(); | |||
| } | |||
| public String getTarget( final int index ) | |||
| { | |||
| return (String)m_targets.get( index ); | |||
| } | |||
| public String getData( final int index ) | |||
| { | |||
| return (String)m_data.get( index ); | |||
| } | |||
| public void processingInstruction( final String target, final String data ) | |||
| throws SAXException | |||
| { | |||
| m_targets.add( target ); | |||
| m_data.add( data ); | |||
| } | |||
| public void startElement( final String uri, | |||
| final String localName, | |||
| final String qName, | |||
| final Attributes atts ) | |||
| throws SAXException | |||
| { | |||
| //Workaround to stop SAX pipeline | |||
| throw new StopParsingException(); | |||
| } | |||
| } | |||
| @@ -0,0 +1,24 @@ | |||
| /* | |||
| * Copyright (C) The Apache Software Foundation. All rights reserved. | |||
| * | |||
| * This software is published under the terms of the Apache Software License | |||
| * version 1.1, a copy of which has been included with this distribution in | |||
| * the LICENSE file. | |||
| */ | |||
| package org.apache.myrmidon.components.builder; | |||
| import org.xml.sax.SAXException; | |||
| /** | |||
| * Dummy exception to stop parsing "safely". | |||
| * | |||
| * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> | |||
| */ | |||
| class StopParsingException | |||
| extends SAXException | |||
| { | |||
| public StopParsingException() | |||
| { | |||
| super( "" ); | |||
| } | |||
| } | |||
| @@ -7,13 +7,25 @@ | |||
| */ | |||
| package org.apache.myrmidon.components.builder; | |||
| import javax.xml.transform.Transformer; | |||
| import java.net.URL; | |||
| import java.io.InputStream; | |||
| import java.util.Properties; | |||
| import javax.xml.parsers.SAXParser; | |||
| import javax.xml.parsers.SAXParserFactory; | |||
| import org.apache.avalon.framework.configuration.SAXConfigurationHandler; | |||
| import org.apache.avalon.framework.parameters.Parameterizable; | |||
| import org.apache.avalon.framework.parameters.Parameters; | |||
| import org.xml.sax.SAXException; | |||
| import org.xml.sax.XMLReader; | |||
| import javax.xml.transform.TransformerFactory; | |||
| import javax.xml.transform.Transformer; | |||
| import javax.xml.transform.TransformerConfigurationException; | |||
| import javax.xml.transform.sax.SAXResult; | |||
| import javax.xml.transform.stream.StreamResult; | |||
| import javax.xml.transform.sax.SAXSource; | |||
| import javax.xml.transform.sax.SAXTransformerFactory; | |||
| import javax.xml.transform.sax.TransformerHandler; | |||
| import javax.xml.transform.stream.StreamSource; | |||
| import org.apache.avalon.framework.configuration.SAXConfigurationHandler; | |||
| import org.apache.avalon.excalibur.io.FileUtil; | |||
| import javax.xml.transform.stream.StreamResult; | |||
| /** | |||
| * Default implementation to construct project from a build file. | |||
| @@ -22,24 +34,173 @@ import org.apache.avalon.excalibur.io.FileUtil; | |||
| */ | |||
| public class XSLProjectBuilder | |||
| extends DefaultProjectBuilder | |||
| implements Parameterizable | |||
| { | |||
| protected void process( final String sourceID, | |||
| private final static String PARAM_EXCEPTION = | |||
| "Malformed PI: expected <?xsl-param name=\"foo\" value=\"bar\"?>"; | |||
| private final static String PARAMS_EXCEPTION = | |||
| "Malformed PI: expected <?xsl-params location=\"myparams.properties\"?>"; | |||
| private final static String STYLE_EXCEPTION = | |||
| "Malformed PI: expected <?xsl-params href=\"mystylesheet.xsl\"?>"; | |||
| private Parameters m_parameters; | |||
| private URL m_systemID; | |||
| public void parameterize( final Parameters parameters ) | |||
| { | |||
| m_parameters = parameters; | |||
| } | |||
| protected void process( final URL sourceID, | |||
| final SAXConfigurationHandler handler ) | |||
| throws Exception | |||
| { | |||
| final String xslSheet = FileUtil.removeExtension( sourceID ) + ".xsl"; | |||
| final SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); | |||
| final SAXParser saxParser = saxParserFactory.newSAXParser(); | |||
| final XMLReader reader = saxParser.getXMLReader(); | |||
| reader.setFeature( "http://xml.org/sax/features/validation", false ); | |||
| reader.setErrorHandler( handler ); | |||
| final ReactorPIHandler reactorHandler = new ReactorPIHandler(); | |||
| reader.setContentHandler( reactorHandler ); | |||
| try { reader.parse( sourceID.toString() ); } | |||
| catch( final StopParsingException spe ) | |||
| { | |||
| //Ignore me | |||
| } | |||
| Transformer transformer = null; | |||
| final int size = reactorHandler.getPICount(); | |||
| for( int i = 0; i < size; i++ ) | |||
| { | |||
| final String target = reactorHandler.getTarget( i ); | |||
| final String data = reactorHandler.getData( i ); | |||
| if( target.equals( "xsl-param" ) ) handleParameter( data ); | |||
| else if( target.equals( "xsl-params" ) ) handleParameters( data, sourceID ); | |||
| else if( target.equals( "xsl-stylesheet" ) ) | |||
| { | |||
| if( null != transformer ) | |||
| { | |||
| throw new SAXException( "Build file can not contain " + | |||
| "two xsl-stylesheet PIs" ); | |||
| } | |||
| final TransformerFactory factory = TransformerFactory.newInstance(); | |||
| final String stylesheet = getStylesheet( data, sourceID ); | |||
| transformer = factory.newTransformer( new StreamSource( stylesheet ) ); | |||
| } | |||
| } | |||
| if( null == transformer ) | |||
| { | |||
| reader.setContentHandler( handler ); | |||
| reader.parse( sourceID.toString() ); | |||
| } | |||
| else | |||
| { | |||
| final SAXResult result = new SAXResult( handler ); | |||
| transformer.transform( new StreamSource( sourceID.toString() ), result ); | |||
| } | |||
| } | |||
| private void handleParameter( final String data ) | |||
| throws SAXException | |||
| { | |||
| int index = data.indexOf( '\"' ); | |||
| if( -1 == index ) | |||
| { | |||
| throw new SAXException( PARAM_EXCEPTION ); | |||
| } | |||
| index = data.indexOf( '\"', index + 1 ); | |||
| if( -1 == index ) | |||
| { | |||
| throw new SAXException( PARAM_EXCEPTION ); | |||
| } | |||
| // Create a transform factory instance. | |||
| final TransformerFactory factory = TransformerFactory.newInstance(); | |||
| //split between two "attributes" occurs on index | |||
| final String[] name = parseAttribute( data.substring( 0, index + 1 ) ); | |||
| final String[] value = parseAttribute( data.substring( index + 1 ).trim() ); | |||
| if( !name[ 0 ].equals( "name" ) || !value[ 0 ].equals( "value" ) ) | |||
| { | |||
| throw new SAXException( PARAM_EXCEPTION ); | |||
| } | |||
| // Create a transformer for the stylesheet. | |||
| final Transformer transformer = factory.newTransformer( new StreamSource( xslSheet ) ); | |||
| m_parameters.setParameter( name[ 1 ], value[ 1 ] ); | |||
| } | |||
| final SAXResult result = new SAXResult( handler ); | |||
| private void handleParameters( final String data, final URL baseSource ) | |||
| throws SAXException | |||
| { | |||
| final String[] params = parseAttribute( data ); | |||
| if( !params[ 0 ].equals( "location" ) ) | |||
| { | |||
| throw new SAXException( PARAMS_EXCEPTION ); | |||
| } | |||
| try | |||
| { | |||
| final Properties properties = new Properties(); | |||
| final URL url = new URL( baseSource, params[ 1 ] ); | |||
| final InputStream input = url.openStream(); | |||
| properties.load( input ); | |||
| final Parameters parameters = Parameters.fromProperties( properties ); | |||
| m_parameters.merge( parameters ); | |||
| } | |||
| catch( final Exception e ) | |||
| { | |||
| throw new SAXException( "Error loading parameters: " + e ); | |||
| } | |||
| } | |||
| private String getStylesheet( final String data, final URL baseSource ) | |||
| throws SAXException | |||
| { | |||
| final String[] stylesheet = parseAttribute( data ); | |||
| if( !stylesheet[ 0 ].equals( "href" ) ) | |||
| { | |||
| throw new SAXException( STYLE_EXCEPTION ); | |||
| } | |||
| try { return new URL( baseSource, stylesheet[ 1 ] ).toString(); } | |||
| catch( final Exception e ) | |||
| { | |||
| throw new SAXException( "Error locating stylesheet '" + stylesheet[ 1 ] + | |||
| "' due to " + e ); | |||
| } | |||
| } | |||
| private String[] parseAttribute( final String data ) | |||
| throws SAXException | |||
| { | |||
| //name="value" | |||
| int index = data.indexOf( '=' ); | |||
| if( -1 == index ) | |||
| { | |||
| throw new SAXException( "Expecting an attribute but received '" + | |||
| data + "'" ); | |||
| } | |||
| //Make a debug option for this | |||
| //transformer.transform( new StreamSource( sourceID ), new StreamResult( System.out ) ); | |||
| final int size = data.length(); | |||
| if( '\"' != data.charAt( index + 1 ) || | |||
| '\"' != data.charAt( size - 1 ) || | |||
| size - 1 == index ) | |||
| { | |||
| throw new SAXException( "Expecting the value of attribute " + | |||
| data.substring( 0, index ) + | |||
| " to be enclosed in quotes" ); | |||
| } | |||
| final String[] result = new String[ 2 ]; | |||
| result[ 0 ] = data.substring( 0, index ); | |||
| result[ 1 ] = data.substring( index + 2, size - 1 ); | |||
| transformer.transform( new StreamSource( sourceID ), result ); | |||
| return result; | |||
| } | |||
| } | |||
| @@ -76,6 +76,18 @@ public class Condition | |||
| return result; | |||
| } | |||
| public String toString() | |||
| { | |||
| if( isIfCondition() ) | |||
| { | |||
| return "if='" + getCondition() + "'"; | |||
| } | |||
| else | |||
| { | |||
| return "unless='" + getCondition() + "'"; | |||
| } | |||
| } | |||
| } | |||
| @@ -80,7 +80,9 @@ public class Pattern | |||
| public String toString() | |||
| { | |||
| return "Pattern['" + m_name + "'," + m_condition + "]" ; | |||
| String result = "Pattern['" + m_name + "',"; | |||
| if( null != m_condition ) result = result + m_condition; | |||
| return result + "]"; | |||
| } | |||
| /** | |||
| @@ -54,6 +54,7 @@ Legal: | |||
| <target name="ant-call-test"> | |||
| <!-- test elided until we decide scope and necessity of ant-call --> | |||
| <echo message="AntCall test elided until we decide scope and necessity of ant-call"/> | |||
| <!-- | |||
| <ant-call target="ant-call-test-target"> | |||
| <param name="blah" value="blah-value" /> | |||
| @@ -0,0 +1,120 @@ | |||
| <?xml version="1.0"?> | |||
| <?xsl-param name="foo" value="bar"?> | |||
| <?xsl-stylesheet href="template-simple.xsl"?> | |||
| <!-- next is ignored --> | |||
| <?xsl-params-old location="foo.properties"?> | |||
| <!-- | |||
| ============================================================================== | |||
| Sample build file | |||
| Authors: | |||
| Peter Donald <donaldp@apache.org> | |||
| Legal: | |||
| Copyright (c) 2000 The Apache Software Foundation. All Rights Reserved. | |||
| ============================================================================== | |||
| --> | |||
| <project name="MySample" default="main" basedir="." | |||
| xmlns:ant="http://jakarta.apache.org/2001/Ant/ant" | |||
| xmlns:doc="http://jakarta.apache.org/2001/Ant/doc" | |||
| xmlns:blee="http://jakarta.apache.org/2001/Ant/blee" > | |||
| <?xsl-params ignored="true"?> | |||
| <projectref name="prim" location="primitive-tests.ant" /> | |||
| <import library="core.atl" /> | |||
| <property name="year" value="2000"/> | |||
| <target name="main" depends="typedef-test, converterdef-test, datatype-test, namespace-test, ant1-tasklib-test" /> | |||
| <target name="all" depends="property-test, typedef-test, converterdef-test, ant-call-test, datatype-test, namespace-test, ant1-tasklib-test, prim->main" /> | |||
| <!-- | |||
| <register-tasklib lib="../../dist/lib/core.atl" /> | |||
| --> | |||
| <target name="property-test"> | |||
| <property name="blah" value="fred" /> | |||
| <property name="${blah}" value="barney" /> | |||
| <echo message="Doing the funky Echo with ${blah} ${fred} Year=${year}!"/> | |||
| </target> | |||
| <target name="typedef-test"> | |||
| <typedef name="echo2" | |||
| type="task" | |||
| classname="org.apache.myrmidon.libs.core.Echo" | |||
| lib="../../dist/lib/core.atl" /> | |||
| <echo2 message="Luke to Echo base. Can you hear me?"/> | |||
| </target> | |||
| <target name="converterdef-test"> | |||
| <converterdef classname="org.apache.myrmidon.libs.core.StringToClassConverter" | |||
| source-type="java.lang.String" | |||
| destination-type="java.lang.Class" | |||
| lib="../../dist/lib/core.atl" /> | |||
| </target> | |||
| <target name="ant-call-test"> | |||
| <!-- test elided until we decide scope and necessity of ant-call --> | |||
| <echo message="AntCall test elided until we decide scope and necessity of ant-call"/> | |||
| <!-- | |||
| <ant-call target="ant-call-test-target"> | |||
| <param name="blah" value="blah-value" /> | |||
| </ant-call> | |||
| --> | |||
| </target> | |||
| <target name="ant-call-test-target"> | |||
| <echo message="This should fail ...."/> | |||
| <echo message="${blah}"/> | |||
| <echo message="Whoa - it no fail. You used ant-call to call me and set param blah!"/> | |||
| </target> | |||
| <target name="datatype-test"> | |||
| <property name="foo"> | |||
| <pattern name="*.java"/> | |||
| </property> | |||
| <pattern id="foo2" name="*.java" if="..." /> | |||
| <echo message="foo=${foo}" /> | |||
| <echo message="foo2=${foo2}" /> | |||
| </target> | |||
| <target name="namespace-test"> | |||
| <!-- ant and doc are built in namespaces --> | |||
| <echo ant:fail-on-error="true" message="Some random message"> | |||
| <doc:description> | |||
| Test case for aspects | |||
| </doc:description> | |||
| <ant:some-element some-attribute="blah"/> | |||
| </echo> | |||
| <!-- load facility for blee: namespace --> | |||
| <facility namespace="blee"> | |||
| <noop/> | |||
| </facility> | |||
| <echo blee:some-param="blah" message="Blee namespace test successful!"/> | |||
| </target> | |||
| <target name="ant1-tasklib-test"> | |||
| <ant1-tasklib prefix="a1-" lib="../../dist/lib/ant1-compat.jar"/> | |||
| <a1-echo message="Boo!" /> | |||
| <a1-mkdir dir="../../dist/test"/> | |||
| <a1-copy file="../../tools/lib/ant.jar" tofile="../../dist/test/ant1-compat.jar" /> | |||
| </target> | |||
| </project> | |||
| @@ -1,9 +1,5 @@ | |||
| <ant-lib> | |||
| <types> | |||
| <task name="ant1-tasklib" classname="org.apache.myrmidon.libs.ant1.Ant1Tasklib" /> | |||
| </types> | |||
| </ant-lib> | |||
| @@ -1,3 +1,3 @@ | |||
| Manifest-Version: 1.0 | |||
| Main-Class: org.apache.myrmidon.frontends.CLIMain | |||
| Created-By: Apache Ant Project | |||
| Created-By: Apache Ant Project | |||
| @@ -1,14 +1,12 @@ | |||
| <ant-lib> | |||
| <types> | |||
| <!-- core tasks for operation --> | |||
| <task name="facility" classname="org.apache.myrmidon.libs.runtime.Facility" /> | |||
| <task name="typedef" classname="org.apache.myrmidon.libs.runtime.TypeDef" /> | |||
| <task name="converterdef" classname="org.apache.myrmidon.libs.runtime.ConverterDef" /> | |||
| <task name="import" classname="org.apache.myrmidon.libs.runtime.Import" /> | |||
| <task name="ant-call" classname="org.apache.myrmidon.libs.runtime.AntCall" /> | |||
| <!--<task name="ant-call" classname="org.apache.myrmidon.libs.runtime.AntCall" />--> | |||
| </types> | |||
| </ant-lib> | |||
| @@ -1,13 +1,9 @@ | |||
| <ant-lib> | |||
| <ant-lib> | |||
| <types> | |||
| <!-- tasks to test operation of engine --> | |||
| <task name="prim-test" classname="org.apache.myrmidon.libs.selftest.PrimitiveTypesTest" /> | |||
| <task name="sub-elements-test" classname="org.apache.myrmidon.libs.selftest.SubElementTest" /> | |||
| <task name="conf-test" classname="org.apache.myrmidon.libs.selftest.ConfigurationTest" /> | |||
| <task name="content-test" classname="org.apache.myrmidon.libs.selftest.ContentTest" /> | |||
| </types> | |||
| </ant-lib> | |||