From b91a25c851c38c44462c4a025b41cf631bc658bb Mon Sep 17 00:00:00 2001 From: Peter Donald Date: Fri, 29 Jun 2001 02:40:11 +0000 Subject: [PATCH] Updated to allow PIs to specify template and parameters to template. git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@269247 13f79535-47bb-0310-9956-ffa450edef68 --- proposal/myrmidon/build.sh | 4 +- .../builder/DefaultProjectBuilder.java | 24 +-- .../components/builder/ReactorPIHandler.java | 59 ++++++ .../builder/StopParsingException.java | 24 +++ .../components/builder/XSLProjectBuilder.java | 189 ++++++++++++++++-- .../apache/myrmidon/framework/Condition.java | 12 ++ .../apache/myrmidon/framework/Pattern.java | 4 +- proposal/myrmidon/src/make/sample.ant | 1 + proposal/myrmidon/src/make/sample.ati | 120 +++++++++++ .../src/manifest/ant1-ant-descriptor.xml | 4 - .../src/manifest/myrmidon-manifest.mf | 2 +- .../src/manifest/runtime-ant-descriptor.xml | 4 +- .../src/manifest/selftest-ant-descriptor.xml | 6 +- 13 files changed, 406 insertions(+), 47 deletions(-) create mode 100644 proposal/myrmidon/src/java/org/apache/myrmidon/components/builder/ReactorPIHandler.java create mode 100644 proposal/myrmidon/src/java/org/apache/myrmidon/components/builder/StopParsingException.java create mode 100644 proposal/myrmidon/src/make/sample.ati diff --git a/proposal/myrmidon/build.sh b/proposal/myrmidon/build.sh index 5a791b734..aff1fe211 100644 --- a/proposal/myrmidon/build.sh +++ b/proposal/myrmidon/build.sh @@ -1,8 +1,8 @@ #!/bin/sh echo -echo "Ant Build System" -echo "----------------" +echo "Myrmidon Build System" +echo "---------------------" export MYRMIDON_HOME=tools diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/components/builder/DefaultProjectBuilder.java b/proposal/myrmidon/src/java/org/apache/myrmidon/components/builder/DefaultProjectBuilder.java index 3a18517f2..2464b106f 100644 --- a/proposal/myrmidon/src/java/org/apache/myrmidon/components/builder/DefaultProjectBuilder.java +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/components/builder/DefaultProjectBuilder.java @@ -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() ); } /** diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/components/builder/ReactorPIHandler.java b/proposal/myrmidon/src/java/org/apache/myrmidon/components/builder/ReactorPIHandler.java new file mode 100644 index 000000000..b75b5243c --- /dev/null +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/components/builder/ReactorPIHandler.java @@ -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 Peter Donald + */ +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(); + } +} diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/components/builder/StopParsingException.java b/proposal/myrmidon/src/java/org/apache/myrmidon/components/builder/StopParsingException.java new file mode 100644 index 000000000..d81bb8fa7 --- /dev/null +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/components/builder/StopParsingException.java @@ -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 Peter Donald + */ +class StopParsingException + extends SAXException +{ + public StopParsingException() + { + super( "" ); + } +} diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/components/builder/XSLProjectBuilder.java b/proposal/myrmidon/src/java/org/apache/myrmidon/components/builder/XSLProjectBuilder.java index 8ea0c5615..b3f4d064e 100644 --- a/proposal/myrmidon/src/java/org/apache/myrmidon/components/builder/XSLProjectBuilder.java +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/components/builder/XSLProjectBuilder.java @@ -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 "; + + private final static String PARAMS_EXCEPTION = + "Malformed PI: expected "; + + private final static String STYLE_EXCEPTION = + "Malformed PI: expected "; + + 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; } } diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/framework/Condition.java b/proposal/myrmidon/src/java/org/apache/myrmidon/framework/Condition.java index eb3480e77..985ef512d 100644 --- a/proposal/myrmidon/src/java/org/apache/myrmidon/framework/Condition.java +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/framework/Condition.java @@ -76,6 +76,18 @@ public class Condition return result; } + + public String toString() + { + if( isIfCondition() ) + { + return "if='" + getCondition() + "'"; + } + else + { + return "unless='" + getCondition() + "'"; + } + } } diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/framework/Pattern.java b/proposal/myrmidon/src/java/org/apache/myrmidon/framework/Pattern.java index 998e86853..0b63a1733 100644 --- a/proposal/myrmidon/src/java/org/apache/myrmidon/framework/Pattern.java +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/framework/Pattern.java @@ -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 + "]"; } /** diff --git a/proposal/myrmidon/src/make/sample.ant b/proposal/myrmidon/src/make/sample.ant index f721d28ee..da2c7eaf2 100644 --- a/proposal/myrmidon/src/make/sample.ant +++ b/proposal/myrmidon/src/make/sample.ant @@ -54,6 +54,7 @@ Legal: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Test case for aspects + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/proposal/myrmidon/src/manifest/ant1-ant-descriptor.xml b/proposal/myrmidon/src/manifest/ant1-ant-descriptor.xml index 5a22a1676..bddae2cdc 100644 --- a/proposal/myrmidon/src/manifest/ant1-ant-descriptor.xml +++ b/proposal/myrmidon/src/manifest/ant1-ant-descriptor.xml @@ -1,9 +1,5 @@ - - - - \ No newline at end of file diff --git a/proposal/myrmidon/src/manifest/myrmidon-manifest.mf b/proposal/myrmidon/src/manifest/myrmidon-manifest.mf index 78fbb354d..82a5fbf3a 100644 --- a/proposal/myrmidon/src/manifest/myrmidon-manifest.mf +++ b/proposal/myrmidon/src/manifest/myrmidon-manifest.mf @@ -1,3 +1,3 @@ Manifest-Version: 1.0 Main-Class: org.apache.myrmidon.frontends.CLIMain -Created-By: Apache Ant Project \ No newline at end of file +Created-By: Apache Ant Project diff --git a/proposal/myrmidon/src/manifest/runtime-ant-descriptor.xml b/proposal/myrmidon/src/manifest/runtime-ant-descriptor.xml index 8ba083b82..3d9f5d4a7 100644 --- a/proposal/myrmidon/src/manifest/runtime-ant-descriptor.xml +++ b/proposal/myrmidon/src/manifest/runtime-ant-descriptor.xml @@ -1,14 +1,12 @@ - - - + \ No newline at end of file diff --git a/proposal/myrmidon/src/manifest/selftest-ant-descriptor.xml b/proposal/myrmidon/src/manifest/selftest-ant-descriptor.xml index 528051c59..d82b87031 100644 --- a/proposal/myrmidon/src/manifest/selftest-ant-descriptor.xml +++ b/proposal/myrmidon/src/manifest/selftest-ant-descriptor.xml @@ -1,13 +1,9 @@ - - + - - - \ No newline at end of file