git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@272461 13f79535-47bb-0310-9956-ffa450edef68master
@@ -1,314 +0,0 @@ | |||
<ant-lib version="1.0"> | |||
<types> | |||
<!-- Type instance tasks --> | |||
<task name="ant1.path" | |||
classname="org.apache.tools.ant.Ant1CompatTypeInstanceTask" /> | |||
<task name="ant1.patternset" | |||
classname="org.apache.tools.ant.Ant1CompatTypeInstanceTask" /> | |||
<task name="ant1.filterset" | |||
classname="org.apache.tools.ant.Ant1CompatTypeInstanceTask" /> | |||
<!-- TaskAdapter tasks --> | |||
<task name="ant1.condition" | |||
classname="org.apache.tools.ant.Ant1CompatTaskAdapter" /> | |||
<!-- Tasks specialised for myrmidon --> | |||
<task name="ant1.ant" | |||
classname="org.apache.tools.ant.taskdefs.Ant" /> | |||
<task name="ant1.antcall" | |||
classname="org.apache.tools.ant.taskdefs.CallTarget" /> | |||
<!-- standard ant tasks --> | |||
<task name="ant1.mkdir" | |||
classname="org.apache.tools.ant.taskdefs.Mkdir" /> | |||
<task name="ant1.javac" | |||
classname="org.apache.tools.ant.taskdefs.Javac" /> | |||
<task name="ant1.chmod" | |||
classname="org.apache.tools.ant.taskdefs.Chmod" /> | |||
<task name="ant1.delete" | |||
classname="org.apache.tools.ant.taskdefs.Delete" /> | |||
<task name="ant1.copy" | |||
classname="org.apache.tools.ant.taskdefs.Copy" /> | |||
<task name="ant1.move" | |||
classname="org.apache.tools.ant.taskdefs.Move" /> | |||
<task name="ant1.jar" | |||
classname="org.apache.tools.ant.taskdefs.Jar" /> | |||
<task name="ant1.rmic" | |||
classname="org.apache.tools.ant.taskdefs.Rmic" /> | |||
<task name="ant1.cvs" | |||
classname="org.apache.tools.ant.taskdefs.Cvs" /> | |||
<task name="ant1.get" | |||
classname="org.apache.tools.ant.taskdefs.Get" /> | |||
<task name="ant1.unzip" | |||
classname="org.apache.tools.ant.taskdefs.Expand" /> | |||
<task name="ant1.unjar" | |||
classname="org.apache.tools.ant.taskdefs.Expand" /> | |||
<task name="ant1.unwar" | |||
classname="org.apache.tools.ant.taskdefs.Expand" /> | |||
<task name="ant1.echo" | |||
classname="org.apache.tools.ant.taskdefs.Echo" /> | |||
<task name="ant1.javadoc" | |||
classname="org.apache.tools.ant.taskdefs.Javadoc" /> | |||
<task name="ant1.zip" | |||
classname="org.apache.tools.ant.taskdefs.Zip" /> | |||
<task name="ant1.gzip" | |||
classname="org.apache.tools.ant.taskdefs.GZip" /> | |||
<task name="ant1.gunzip" | |||
classname="org.apache.tools.ant.taskdefs.GUnzip" /> | |||
<task name="ant1.replace" | |||
classname="org.apache.tools.ant.taskdefs.Replace" /> | |||
<task name="ant1.java" | |||
classname="org.apache.tools.ant.taskdefs.Java" /> | |||
<task name="ant1.tstamp" | |||
classname="org.apache.tools.ant.taskdefs.Tstamp" /> | |||
<task name="ant1.property" | |||
classname="org.apache.tools.ant.taskdefs.Property" /> | |||
<task name="ant1.taskdef" | |||
classname="org.apache.tools.ant.taskdefs.Taskdef" /> | |||
<task name="ant1.exec" | |||
classname="org.apache.tools.ant.taskdefs.ExecTask" /> | |||
<task name="ant1.tar" | |||
classname="org.apache.tools.ant.taskdefs.Tar" /> | |||
<task name="ant1.untar" | |||
classname="org.apache.tools.ant.taskdefs.Untar" /> | |||
<task name="ant1.available" | |||
classname="org.apache.tools.ant.taskdefs.Available" /> | |||
<task name="ant1.filter" | |||
classname="org.apache.tools.ant.taskdefs.Filter" /> | |||
<task name="ant1.fixcrlf" | |||
classname="org.apache.tools.ant.taskdefs.FixCRLF" /> | |||
<task name="ant1.patch" | |||
classname="org.apache.tools.ant.taskdefs.Patch" /> | |||
<task name="ant1.style" | |||
classname="org.apache.tools.ant.taskdefs.XSLTProcess" /> | |||
<task name="ant1.touch" | |||
classname="org.apache.tools.ant.taskdefs.Touch" /> | |||
<task name="ant1.signjar" | |||
classname="org.apache.tools.ant.taskdefs.SignJar" /> | |||
<task name="ant1.genkey" | |||
classname="org.apache.tools.ant.taskdefs.GenerateKey" /> | |||
<task name="ant1.antstructure" | |||
classname="org.apache.tools.ant.taskdefs.AntStructure" /> | |||
<task name="ant1.execon" | |||
classname="org.apache.tools.ant.taskdefs.ExecuteOn" /> | |||
<task name="ant1.sql" | |||
classname="org.apache.tools.ant.taskdefs.SQLExec" /> | |||
<task name="ant1.mail" | |||
classname="org.apache.tools.ant.taskdefs.email.EmailTask" /> | |||
<task name="ant1.fail" | |||
classname="org.apache.tools.ant.taskdefs.Exit" /> | |||
<task name="ant1.war" | |||
classname="org.apache.tools.ant.taskdefs.War" /> | |||
<task name="ant1.uptodate" | |||
classname="org.apache.tools.ant.taskdefs.UpToDate" /> | |||
<task name="ant1.apply" | |||
classname="org.apache.tools.ant.taskdefs.Transform" /> | |||
<task name="ant1.record" | |||
classname="org.apache.tools.ant.taskdefs.Recorder" /> | |||
<task name="ant1.cvspass" | |||
classname="org.apache.tools.ant.taskdefs.CVSPass" /> | |||
<task name="ant1.typedef" | |||
classname="org.apache.tools.ant.taskdefs.Typedef" /> | |||
<task name="ant1.sleep" | |||
classname="org.apache.tools.ant.taskdefs.Sleep" /> | |||
<task name="ant1.pathconvert" | |||
classname="org.apache.tools.ant.taskdefs.PathConvert" /> | |||
<task name="ant1.ear" | |||
classname="org.apache.tools.ant.taskdefs.Ear" /> | |||
<task name="ant1.parallel" | |||
classname="org.apache.tools.ant.taskdefs.Parallel" /> | |||
<task name="ant1.sequential" | |||
classname="org.apache.tools.ant.taskdefs.Sequential" /> | |||
<task name="ant1.dependset" | |||
classname="org.apache.tools.ant.taskdefs.DependSet" /> | |||
<task name="ant1.bzip2" | |||
classname="org.apache.tools.ant.taskdefs.BZip2" /> | |||
<task name="ant1.bunzip2" | |||
classname="org.apache.tools.ant.taskdefs.BUnzip2" /> | |||
<task name="ant1.checksum" | |||
classname="org.apache.tools.ant.taskdefs.Checksum" /> | |||
<task name="ant1.waitfor" | |||
classname="org.apache.tools.ant.taskdefs.WaitFor" /> | |||
<task name="ant1.input" | |||
classname="org.apache.tools.ant.taskdefs.Input" /> | |||
<task name="ant1.loadfile" | |||
classname="org.apache.tools.ant.taskdefs.LoadFile" /> | |||
<task name="ant1.manifest" | |||
classname="org.apache.tools.ant.taskdefs.Manifest" /> | |||
<task name="ant1.loadproperties" | |||
classname="org.apache.tools.ant.taskdefs.LoadProperties" /> | |||
<!-- optional tasks --> | |||
<task name="ant1.script" | |||
classname="org.apache.tools.ant.taskdefs.optional.Script" /> | |||
<task name="ant1.netrexxc" | |||
classname="org.apache.tools.ant.taskdefs.optional.NetRexxC" /> | |||
<task name="ant1.renameext" | |||
classname="org.apache.tools.ant.taskdefs.optional.RenameExtensions" /> | |||
<task name="ant1.ejbc" | |||
classname="org.apache.tools.ant.taskdefs.optional.ejb.Ejbc" /> | |||
<task name="ant1.ddcreator" | |||
classname="org.apache.tools.ant.taskdefs.optional.ejb.DDCreator" /> | |||
<task name="ant1.wlrun" | |||
classname="org.apache.tools.ant.taskdefs.optional.ejb.WLRun" /> | |||
<task name="ant1.wlstop" | |||
classname="org.apache.tools.ant.taskdefs.optional.ejb.WLStop" /> | |||
<task name="ant1.vssget" | |||
classname="org.apache.tools.ant.taskdefs.optional.vss.MSVSSGET" /> | |||
<task name="ant1.ejbjar" | |||
classname="org.apache.tools.ant.taskdefs.optional.ejb.EjbJar" /> | |||
<task name="ant1.mparse" | |||
classname="org.apache.tools.ant.taskdefs.optional.metamata.MParse" /> | |||
<task name="ant1.mmetrics" | |||
classname="org.apache.tools.ant.taskdefs.optional.metamata.MMetrics" /> | |||
<task name="ant1.maudit" | |||
classname="org.apache.tools.ant.taskdefs.optional.metamata.MAudit" /> | |||
<task name="ant1.junit" | |||
classname="org.apache.tools.ant.taskdefs.optional.junit.JUnitTask" /> | |||
<task name="ant1.cab" | |||
classname="org.apache.tools.ant.taskdefs.optional.Cab" /> | |||
<task name="ant1.ftp" | |||
classname="org.apache.tools.ant.taskdefs.optional.net.FTP" /> | |||
<task name="ant1.icontract" | |||
classname="org.apache.tools.ant.taskdefs.optional.IContract" /> | |||
<task name="ant1.javacc" | |||
classname="org.apache.tools.ant.taskdefs.optional.javacc.JavaCC" /> | |||
<task name="ant1.jjtree" | |||
classname="org.apache.tools.ant.taskdefs.optional.javacc.JJTree" /> | |||
<task name="ant1.stcheckout" | |||
classname="org.apache.tools.ant.taskdefs.optional.starteam.StarTeamCheckout" /> | |||
<task name="ant1.stcheckin" | |||
classname="org.apache.tools.ant.taskdefs.optional.starteam.StarTeamCheckin" /> | |||
<task name="ant1.stlabel" | |||
classname="org.apache.tools.ant.taskdefs.optional.starteam.StarTeamLabel" /> | |||
<task name="ant1.stlist" | |||
classname="org.apache.tools.ant.taskdefs.optional.starteam.StarTeamList" /> | |||
<task name="ant1.wljspc" | |||
classname="org.apache.tools.ant.taskdefs.optional.jsp.WLJspc" /> | |||
<task name="ant1.jlink" | |||
classname="org.apache.tools.ant.taskdefs.optional.jlink.JlinkTask" /> | |||
<task name="ant1.native2ascii" | |||
classname="org.apache.tools.ant.taskdefs.optional.Native2Ascii" /> | |||
<task name="ant1.propertyfile" | |||
classname="org.apache.tools.ant.taskdefs.optional.PropertyFile" /> | |||
<task name="ant1.depend" | |||
classname="org.apache.tools.ant.taskdefs.optional.depend.Depend" /> | |||
<task name="ant1.antlr" | |||
classname="org.apache.tools.ant.taskdefs.optional.ANTLR" /> | |||
<task name="ant1.vajload" | |||
classname="org.apache.tools.ant.taskdefs.optional.ide.VAJLoadProjects" /> | |||
<task name="ant1.vajexport" | |||
classname="org.apache.tools.ant.taskdefs.optional.ide.VAJExport" /> | |||
<task name="ant1.vajimport" | |||
classname="org.apache.tools.ant.taskdefs.optional.ide.VAJImport" /> | |||
<task name="ant1.telnet" | |||
classname="org.apache.tools.ant.taskdefs.optional.net.TelnetTask" /> | |||
<task name="ant1.csc" | |||
classname="org.apache.tools.ant.taskdefs.optional.dotnet.CSharp" /> | |||
<task name="ant1.ilasm" | |||
classname="org.apache.tools.ant.taskdefs.optional.dotnet.Ilasm" /> | |||
<task name="ant1.stylebook" | |||
classname="org.apache.tools.ant.taskdefs.optional.StyleBook" /> | |||
<task name="ant1.test" | |||
classname="org.apache.tools.ant.taskdefs.optional.Test" /> | |||
<task name="ant1.pvcs" | |||
classname="org.apache.tools.ant.taskdefs.optional.pvcs.Pvcs" /> | |||
<task name="ant1.p4change" | |||
classname="org.apache.tools.ant.taskdefs.optional.perforce.P4Change" /> | |||
<task name="ant1.p4label" | |||
classname="org.apache.tools.ant.taskdefs.optional.perforce.P4Label" /> | |||
<task name="ant1.p4have" | |||
classname="org.apache.tools.ant.taskdefs.optional.perforce.P4Have" /> | |||
<task name="ant1.p4sync" | |||
classname="org.apache.tools.ant.taskdefs.optional.perforce.P4Sync" /> | |||
<task name="ant1.p4edit" | |||
classname="org.apache.tools.ant.taskdefs.optional.perforce.P4Edit" /> | |||
<task name="ant1.p4submit" | |||
classname="org.apache.tools.ant.taskdefs.optional.perforce.P4Submit" /> | |||
<task name="ant1.p4counter" | |||
classname="org.apache.tools.ant.taskdefs.optional.perforce.P4Counter" /> | |||
<task name="ant1.javah" | |||
classname="org.apache.tools.ant.taskdefs.optional.Javah" /> | |||
<task name="ant1.ccupdate" | |||
classname="org.apache.tools.ant.taskdefs.optional.clearcase.CCUpdate" /> | |||
<task name="ant1.cccheckout" | |||
classname="org.apache.tools.ant.taskdefs.optional.clearcase.CCCheckout" /> | |||
<task name="ant1.cccheckin" | |||
classname="org.apache.tools.ant.taskdefs.optional.clearcase.CCCheckin" /> | |||
<task name="ant1.ccuncheckout" | |||
classname="org.apache.tools.ant.taskdefs.optional.clearcase.CCUnCheckout" /> | |||
<task name="ant1.sound" | |||
classname="org.apache.tools.ant.taskdefs.optional.sound.SoundTask" /> | |||
<task name="ant1.junitreport" | |||
classname="org.apache.tools.ant.taskdefs.optional.junit.XMLResultAggregator" /> | |||
<task name="ant1.vsslabel" | |||
classname="org.apache.tools.ant.taskdefs.optional.vss.MSVSSLABEL" /> | |||
<task name="ant1.vsshistory" | |||
classname="org.apache.tools.ant.taskdefs.optional.vss.MSVSSHISTORY" /> | |||
<task name="ant1.blgenclient" | |||
classname="org.apache.tools.ant.taskdefs.optional.ejb.BorlandGenerateClient" /> | |||
<task name="ant1.rpm" | |||
classname="org.apache.tools.ant.taskdefs.optional.Rpm" /> | |||
<task name="ant1.xmlvalidate" | |||
classname="org.apache.tools.ant.taskdefs.optional.XMLValidateTask" /> | |||
<task name="ant1.vsscheckin" | |||
classname="org.apache.tools.ant.taskdefs.optional.vss.MSVSSCHECKIN" /> | |||
<task name="ant1.vsscheckout" | |||
classname="org.apache.tools.ant.taskdefs.optional.vss.MSVSSCHECKOUT" /> | |||
<task name="ant1.iplanet-ejbc" | |||
classname="org.apache.tools.ant.taskdefs.optional.ejb.IPlanetEjbcTask" /> | |||
<task name="ant1.jdepend" | |||
classname="org.apache.tools.ant.taskdefs.optional.jdepend.JDependTask" /> | |||
<task name="ant1.mimemail" | |||
classname="org.apache.tools.ant.taskdefs.optional.net.MimeMail" /> | |||
<task name="ant1.ccmcheckin" | |||
classname="org.apache.tools.ant.taskdefs.optional.ccm.CCMCheckin" /> | |||
<task name="ant1.ccmcheckout" | |||
classname="org.apache.tools.ant.taskdefs.optional.ccm.CCMCheckout" /> | |||
<task name="ant1.ccmcheckintask" | |||
classname="org.apache.tools.ant.taskdefs.optional.ccm.CCMCheckinDefault" /> | |||
<task name="ant1.ccmreconfigure" | |||
classname="org.apache.tools.ant.taskdefs.optional.ccm.CCMReconfigure" /> | |||
<task name="ant1.ccmcreatetask" | |||
classname="org.apache.tools.ant.taskdefs.optional.ccm.CCMCreateTask" /> | |||
<task name="ant1.jpcoverage" | |||
classname="org.apache.tools.ant.taskdefs.optional.sitraka.Coverage" /> | |||
<task name="ant1.jpcovmerge" | |||
classname="org.apache.tools.ant.taskdefs.optional.sitraka.CovMerge" /> | |||
<task name="ant1.jpcovreport" | |||
classname="org.apache.tools.ant.taskdefs.optional.sitraka.CovReport" /> | |||
<task name="ant1.p4add" | |||
classname="org.apache.tools.ant.taskdefs.optional.perforce.P4Add" /> | |||
<task name="ant1.jspc" | |||
classname="org.apache.tools.ant.taskdefs.optional.jsp.JspC" /> | |||
<task name="ant1.replaceregexp" | |||
classname="org.apache.tools.ant.taskdefs.optional.ReplaceRegExp" /> | |||
<task name="ant1.translate" | |||
classname="org.apache.tools.ant.taskdefs.optional.i18n.Translate" /> | |||
<task name="ant1.sosget" | |||
classname="org.apache.tools.ant.taskdefs.optional.sos.SOSGet" /> | |||
<task name="ant1.soscheckin" | |||
classname="org.apache.tools.ant.taskdefs.optional.sos.SOSCheckin" /> | |||
<task name="ant1.soscheckout" | |||
classname="org.apache.tools.ant.taskdefs.optional.sos.SOSCheckout" /> | |||
<task name="ant1.soslabel" | |||
classname="org.apache.tools.ant.taskdefs.optional.sos.SOSLabel" /> | |||
<task name="ant1.echoproperties" | |||
classname="org.apache.tools.ant.taskdefs.optional.EchoProperties" /> | |||
<!-- deprecated ant tasks (kept for back compatibility) --> | |||
<task name="ant1.starteam" | |||
classname="org.apache.tools.ant.taskdefs.optional.scm.AntStarTeamCheckOut" /> | |||
<task name="ant1.javadoc2" | |||
classname="org.apache.tools.ant.taskdefs.Javadoc" /> | |||
<task name="ant1.copydir" | |||
classname="org.apache.tools.ant.taskdefs.Copydir" /> | |||
<task name="ant1.copyfile" | |||
classname="org.apache.tools.ant.taskdefs.Copyfile" /> | |||
<task name="ant1.deltree" | |||
classname="org.apache.tools.ant.taskdefs.Deltree" /> | |||
<task name="ant1.rename" | |||
classname="org.apache.tools.ant.taskdefs.Rename" /> | |||
</types> | |||
</ant-lib> |
@@ -1,12 +0,0 @@ | |||
Manifest-Version: 1.0 | |||
Created-By: Apache Ant Project | |||
Extension-Name: ant1.compat | |||
Specification-Title: Myrmidon Ant1 Compatibility Layer | |||
Specification-Version: 0.01 | |||
Specification-Vendor: Jakarta Apache | |||
Implementation-Vendor-Id: org.apache.jakarta | |||
Implementation-Vendor: Jakarta Apache Project | |||
Implementation-Version: 0.01 | |||
Extension-List: tools | |||
tools-Extension-Name: com.sun.tools | |||
tools-Specification-Version: 1.0 |
@@ -1,125 +0,0 @@ | |||
/* | |||
* 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.txt file. | |||
*/ | |||
package org.apache.tools.ant; | |||
import java.util.Locale; | |||
import org.apache.avalon.framework.configuration.Configuration; | |||
import org.apache.avalon.framework.configuration.ConfigurationException; | |||
/** | |||
* A helper class which uses reflection to configure any Object, | |||
* with the help of the Ant1 IntrospectionHelper. | |||
* This aims to mimic (to some extent) the Ant1-style configuration rules | |||
* implemented by ProjectHelperImpl. | |||
* | |||
* @author <a href="mailto:darrell@apache.org">Darrell DeBoer</a> | |||
* @version $Revision$ $Date$ | |||
*/ | |||
class Ant1CompatConfigurer | |||
{ | |||
private final Object m_configuredObject; | |||
private Configuration m_configuration; | |||
private final Project m_project; | |||
private final IntrospectionHelper m_helper; | |||
private Object[] m_childObjects; | |||
private Ant1CompatConfigurer[] m_childConfigurers; | |||
private String[] m_childNames; | |||
Ant1CompatConfigurer( Object configuredObject, | |||
Configuration config, | |||
Project project ) | |||
{ | |||
m_configuredObject = configuredObject; | |||
m_configuration = config; | |||
m_project = project; | |||
m_helper = IntrospectionHelper.getHelper( m_configuredObject.getClass() ); | |||
} | |||
/** | |||
* Create all child elements, recursively. | |||
*/ | |||
void createChildren() throws ConfigurationException | |||
{ | |||
Configuration[] childConfigs = m_configuration.getChildren(); | |||
m_childObjects = new Object[ childConfigs.length ]; | |||
m_childConfigurers = new Ant1CompatConfigurer[ childConfigs.length ]; | |||
m_childNames = new String[ childConfigs.length ]; | |||
for( int i = 0; i < childConfigs.length; i++ ) | |||
{ | |||
Configuration childConfig = childConfigs[ i ]; | |||
String name = childConfig.getName(); | |||
Object childObject = | |||
m_helper.createElement( m_project, m_configuredObject, name ); | |||
Ant1CompatConfigurer childConfigurer = | |||
new Ant1CompatConfigurer( childObject, childConfig, m_project ); | |||
m_childObjects[ i ] = childObject; | |||
m_childNames[ i ] = name; | |||
m_childConfigurers[ i ] = childConfigurer; | |||
// Recursively create children | |||
childConfigurer.createChildren(); | |||
} | |||
} | |||
/** | |||
* Configure attributes and text, recursively. | |||
*/ | |||
void configure() throws ConfigurationException | |||
{ | |||
// Configure the attributes. | |||
final String[] attribs = m_configuration.getAttributeNames(); | |||
for( int i = 0; i < attribs.length; i++ ) | |||
{ | |||
final String name = attribs[ i ]; | |||
final String value = | |||
m_project.replaceProperties( m_configuration.getAttribute( name ) ); | |||
try | |||
{ | |||
m_helper.setAttribute( m_project, m_configuredObject, | |||
name.toLowerCase( Locale.US ), value ); | |||
} | |||
catch( BuildException be ) | |||
{ | |||
// id attribute must be set externally | |||
if( !name.equals( "id" ) ) | |||
{ | |||
throw be; | |||
} | |||
} | |||
} | |||
// Configure the text content. | |||
String text = m_configuration.getValue( null ); | |||
if( text != null ) | |||
{ | |||
m_helper.addText( m_project, m_configuredObject, text ); | |||
} | |||
// Configure and add all children | |||
for( int i = 0; i < m_childConfigurers.length; i++ ) | |||
{ | |||
m_childConfigurers[ i ].configure(); | |||
// Store child if neccessary (addConfigured) | |||
m_helper.storeElement( m_project, m_configuredObject, | |||
m_childObjects[ i ], m_childNames[ i ] ); | |||
} | |||
// Set the reference, if id was specified. | |||
String id = m_configuration.getAttribute( "id", null ); | |||
if( id != null ) | |||
{ | |||
m_project.addReference( id, m_configuredObject ); | |||
} | |||
} | |||
} |
@@ -1,549 +0,0 @@ | |||
/* | |||
* 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.txt file. | |||
*/ | |||
package org.apache.tools.ant; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.util.Enumeration; | |||
import java.util.HashSet; | |||
import java.util.Hashtable; | |||
import java.util.Iterator; | |||
import java.util.Map; | |||
import java.util.Properties; | |||
import java.util.Set; | |||
import org.apache.aut.converter.Converter; | |||
import org.apache.aut.converter.ConverterException; | |||
import org.apache.myrmidon.api.TaskContext; | |||
import org.apache.myrmidon.api.TaskException; | |||
import org.apache.myrmidon.interfaces.type.DefaultTypeFactory; | |||
import org.apache.myrmidon.interfaces.type.TypeManager; | |||
import org.apache.tools.ant.types.Path; | |||
/** | |||
* Ant1 Project proxy for Myrmidon. Provides hooks between Myrmidon TaskContext | |||
* and Ant1 project. | |||
* Note that there is no logical separation between Ant1Project and this extension - | |||
* they could easily be flattened. Ant1Project is barely modified from the | |||
* Ant1 original, this class contains the extensions. | |||
* | |||
* @author <a href="mailto:darrell@apache.org">Darrell DeBoer</a> | |||
* @version $Revision$ $Date$ | |||
*/ | |||
public class Ant1CompatProject extends Project | |||
{ | |||
public static final String ANT1_TASK_PREFIX = "ant1."; | |||
public static final String MYRMIDON_PROJECT_PROP = | |||
org.apache.myrmidon.interfaces.model.Project.PROJECT; | |||
public static final String ANT1_PROJECT_PROP = "ant1.project"; | |||
// Add everything in the current classloader to the | |||
// java.class.path property. | |||
private static String javaclasspath = Path.systemClasspath.toString(); | |||
private final Converter m_converter; | |||
private Set m_userProperties = new HashSet(); | |||
private TaskContext m_context; | |||
private TaskContext m_underlyingContext; | |||
/** | |||
* Create an Ant1 project. | |||
* @param context The context for the first Ant1 Task loaded. | |||
*/ | |||
public Ant1CompatProject( TaskContext context ) | |||
throws TaskException | |||
{ | |||
super(); | |||
recontextulize( context ); | |||
setBaseDir( m_context.getBaseDirectory() ); | |||
String projectName = | |||
(String)m_context.getProperty( MYRMIDON_PROJECT_PROP ); | |||
if( projectName != null ) | |||
{ | |||
setName( projectName ); | |||
} | |||
m_converter = (Converter)m_context.getService( Converter.class ); | |||
} | |||
/** | |||
* Update the TaskContext for the current task. | |||
* @param context The TaskContext for the currently executing Task. | |||
*/ | |||
void recontextulize( TaskContext context ) | |||
throws TaskException | |||
{ | |||
// Only reset the context if it is a different instance. | |||
if( m_underlyingContext == context ) | |||
{ | |||
return; | |||
} | |||
// Need the underlying context for setting properties which | |||
// should be propogated to other Tasks. | |||
m_underlyingContext = context; | |||
// The main context allows Ant1 specific property overrides. | |||
m_context = context.createSubContext( "ant1-overrides" ); | |||
m_context.setProperty( "java.class.path", javaclasspath ); | |||
} | |||
/** | |||
* Writes a project level message to the log with the given log level. | |||
* @param msg The text to log. Should not be <code>null</code>. | |||
* @param msgLevel The priority level to log at. | |||
*/ | |||
public void log( String msg, int msgLevel ) | |||
{ | |||
doLog( msg, msgLevel ); | |||
super.log( msg, msgLevel ); | |||
} | |||
/** | |||
* Writes a task level message to the log with the given log level. | |||
* @param task The task to use in the log. Must not be <code>null</code>. | |||
* @param msg The text to log. Should not be <code>null</code>. | |||
* @param msgLevel The priority level to log at. | |||
*/ | |||
public void log( Task task, String msg, int msgLevel ) | |||
{ | |||
doLog( msg, msgLevel ); | |||
super.log( task, msg, msgLevel ); | |||
} | |||
/** | |||
* Writes a target level message to the log with the given log level. | |||
* @param target The target to use in the log. | |||
* Must not be <code>null</code>. | |||
* @param msg The text to log. Should not be <code>null</code>. | |||
* @param msgLevel The priority level to log at. | |||
*/ | |||
public void log( Target target, String msg, int msgLevel ) | |||
{ | |||
doLog( msg, msgLevel ); | |||
super.log( target, msg, msgLevel ); | |||
} | |||
private void doLog( String msg, int msgLevel ) | |||
{ | |||
switch( msgLevel ) | |||
{ | |||
case Ant1CompatProject.MSG_ERR: | |||
m_context.error( msg ); | |||
break; | |||
case Ant1CompatProject.MSG_WARN: | |||
m_context.warn( msg ); | |||
break; | |||
case Ant1CompatProject.MSG_INFO: | |||
m_context.info( msg ); | |||
break; | |||
case Ant1CompatProject.MSG_VERBOSE: | |||
m_context.verbose( msg ); | |||
break; | |||
case Ant1CompatProject.MSG_DEBUG: | |||
m_context.debug( msg ); | |||
} | |||
} | |||
/** | |||
* This is a copy of init() from the Ant1 Project, which adds Ant1 tasks and | |||
* DataTypes to the underlying Ant1 Project, but calling add methods on the | |||
* superclass to avoid adding everything to the TypeManager. | |||
* | |||
* @exception BuildException if the default task list cannot be loaded | |||
*/ | |||
public void init() throws BuildException | |||
{ | |||
setJavaVersionProperty(); | |||
String defs = "/org/apache/tools/ant/taskdefs/defaults.properties"; | |||
try | |||
{ | |||
Properties props = new Properties(); | |||
InputStream in = this.getClass().getResourceAsStream( defs ); | |||
if( in == null ) | |||
{ | |||
throw new BuildException( "Can't load default task list" ); | |||
} | |||
props.load( in ); | |||
in.close(); | |||
Enumeration enum = props.propertyNames(); | |||
while( enum.hasMoreElements() ) | |||
{ | |||
String key = (String)enum.nextElement(); | |||
String value = props.getProperty( key ); | |||
try | |||
{ | |||
Class taskClass = Class.forName( value ); | |||
// NOTE: Line modified from Ant1 Project. | |||
super.addTaskDefinition( key, taskClass ); | |||
} | |||
catch( NoClassDefFoundError ncdfe ) | |||
{ | |||
log( "Could not load a dependent class (" | |||
+ ncdfe.getMessage() + ") for task " + key, MSG_DEBUG ); | |||
} | |||
catch( ClassNotFoundException cnfe ) | |||
{ | |||
log( "Could not load class (" + value | |||
+ ") for task " + key, MSG_DEBUG ); | |||
} | |||
} | |||
} | |||
catch( IOException ioe ) | |||
{ | |||
throw new BuildException( "Can't load default task list" ); | |||
} | |||
String dataDefs = "/org/apache/tools/ant/types/defaults.properties"; | |||
try | |||
{ | |||
Properties props = new Properties(); | |||
InputStream in = this.getClass().getResourceAsStream( dataDefs ); | |||
if( in == null ) | |||
{ | |||
throw new BuildException( "Can't load default datatype list" ); | |||
} | |||
props.load( in ); | |||
in.close(); | |||
Enumeration enum = props.propertyNames(); | |||
while( enum.hasMoreElements() ) | |||
{ | |||
String key = (String)enum.nextElement(); | |||
String value = props.getProperty( key ); | |||
try | |||
{ | |||
Class dataClass = Class.forName( value ); | |||
// NOTE: Line modified from Ant1 Project. | |||
super.addDataTypeDefinition( key, dataClass ); | |||
} | |||
catch( NoClassDefFoundError ncdfe ) | |||
{ | |||
// ignore... | |||
} | |||
catch( ClassNotFoundException cnfe ) | |||
{ | |||
// ignore... | |||
} | |||
} | |||
} | |||
catch( IOException ioe ) | |||
{ | |||
throw new BuildException( "Can't load default datatype list" ); | |||
} | |||
setSystemProperties(); | |||
} | |||
/** | |||
* Adds a new task definition to the project, registering it with the | |||
* TypeManager, as well as the underlying Ant1 Project. | |||
* | |||
* @param taskName The name of the task to add. | |||
* Must not be <code>null</code>. | |||
* @param taskClass The full name of the class implementing the task. | |||
* Must not be <code>null</code>. | |||
* | |||
* @exception BuildException if the class is unsuitable for being an Ant | |||
* task. An error level message is logged before | |||
* this exception is thrown. | |||
* | |||
* @see #checkTaskClass(Class) | |||
*/ | |||
public void addTaskDefinition( String taskName, Class taskClass ) | |||
throws BuildException | |||
{ | |||
String ant2name = ANT1_TASK_PREFIX + taskName; | |||
try | |||
{ | |||
registerType( org.apache.myrmidon.api.Task.ROLE, ant2name, taskClass ); | |||
} | |||
catch( Exception e ) | |||
{ | |||
throw new BuildException( e ); | |||
} | |||
super.addTaskDefinition( taskName, taskClass ); | |||
} | |||
/** | |||
* Utility method to register a type. | |||
*/ | |||
protected void registerType( final String roleType, | |||
final String typeName, | |||
final Class type ) | |||
throws Exception | |||
{ | |||
final ClassLoader loader = type.getClassLoader(); | |||
final DefaultTypeFactory factory = new DefaultTypeFactory( loader ); | |||
factory.addNameClassMapping( typeName, type.getName() ); | |||
TypeManager typeManager = (TypeManager)m_context.getService( TypeManager.class ); | |||
typeManager.registerType( roleType, typeName, factory ); | |||
} | |||
/** | |||
* Sets a property. Any existing property of the same name | |||
* is overwritten, unless it is a user property. | |||
* @param name The name of property to set. | |||
* Must not be <code>null</code>. | |||
* @param value The new value of the property. | |||
* Must not be <code>null</code>. | |||
*/ | |||
public void setProperty( String name, String value ) | |||
{ | |||
if( m_userProperties.contains( name ) ) | |||
{ | |||
log( "Override ignored for user property " + name, MSG_VERBOSE ); | |||
return; | |||
} | |||
if( null != m_context.getProperty( name ) ) | |||
{ | |||
log( "Overriding previous definition of property " + name, | |||
MSG_VERBOSE ); | |||
} | |||
log( "Setting project property: " + name + " -> " + | |||
value, MSG_DEBUG ); | |||
doSetProperty( name, value ); | |||
} | |||
/** | |||
* Sets a property if no value currently exists. If the property | |||
* exists already, a message is logged and the method returns with | |||
* no other effect. | |||
* | |||
* @param name The name of property to set. | |||
* Must not be <code>null</code>. | |||
* @param value The new value of the property. | |||
* Must not be <code>null</code>. | |||
* @since 1.5 | |||
*/ | |||
public void setNewProperty( String name, String value ) | |||
{ | |||
if( null != m_context.getProperty( name ) ) | |||
{ | |||
log( "Override ignored for property " + name, MSG_VERBOSE ); | |||
return; | |||
} | |||
log( "Setting project property: " + name + " -> " + | |||
value, MSG_DEBUG ); | |||
doSetProperty( name, value ); | |||
} | |||
/** | |||
* Sets a user property, which cannot be overwritten by | |||
* set/unset property calls. Any previous value is overwritten. | |||
* @param name The name of property to set. | |||
* Must not be <code>null</code>. | |||
* @param value The new value of the property. | |||
* Must not be <code>null</code>. | |||
* @see #setProperty(String,String) | |||
*/ | |||
public void setUserProperty( String name, String value ) | |||
{ | |||
log( "Setting ro project property: " + name + " -> " + | |||
value, MSG_DEBUG ); | |||
m_userProperties.add( name ); | |||
doSetProperty( name, value ); | |||
} | |||
/** | |||
* Sets a property value in the underlying context, wrapping exceptions as | |||
* Ant1 BuildExceptions. | |||
* @param name property name | |||
* @param value property value | |||
*/ | |||
private void doSetProperty( String name, String value ) | |||
{ | |||
try | |||
{ | |||
m_underlyingContext.setProperty( name, value ); | |||
} | |||
catch( TaskException e ) | |||
{ | |||
throw new BuildException( "Could not set property: " + name, e ); | |||
} | |||
} | |||
/** | |||
* Returns the value of a property, if it is set. | |||
* | |||
* @param name The name of the property. | |||
* May be <code>null</code>, in which case | |||
* the return value is also <code>null</code>. | |||
* @return the property value, or <code>null</code> for no match | |||
* or if a <code>null</code> name is provided. | |||
*/ | |||
public String getProperty( String name ) | |||
{ | |||
Object value = m_context.getProperty( name ); | |||
if( value == null ) | |||
{ | |||
return null; | |||
} | |||
else if( value instanceof String ) | |||
{ | |||
return (String)value; | |||
} | |||
else | |||
{ | |||
try | |||
{ | |||
return (String)m_converter.convert( String.class, value, m_context ); | |||
} | |||
catch( ConverterException e ) | |||
{ | |||
throw new BuildException( e ); | |||
} | |||
} | |||
} | |||
/** | |||
* Returns the value of a user property, if it is set. | |||
* | |||
* @param name The name of the property. | |||
* May be <code>null</code>, in which case | |||
* the return value is also <code>null</code>. | |||
* @return the property value, or <code>null</code> for no match | |||
* or if a <code>null</code> name is provided. | |||
*/ | |||
public String getUserProperty( String name ) | |||
{ | |||
if( m_userProperties.contains( name ) ) | |||
{ | |||
return getProperty( name ); | |||
} | |||
else | |||
{ | |||
return null; | |||
} | |||
} | |||
/** | |||
* Returns a copy of the properties table. | |||
* @return a hashtable containing all properties | |||
* (including user properties). | |||
*/ | |||
public Hashtable getProperties() | |||
{ | |||
final Hashtable propsCopy = new Hashtable(); | |||
final Map contextProps; | |||
try | |||
{ | |||
contextProps = m_context.getProperties(); | |||
} | |||
catch( final TaskException e ) | |||
{ | |||
throw new BuildException( e ); | |||
} | |||
final Iterator propNames = contextProps.keySet().iterator(); | |||
while( propNames.hasNext() ) | |||
{ | |||
final String name = (String)propNames.next(); | |||
final String value = getProperty( name ); | |||
if( value != null ) | |||
{ | |||
propsCopy.put( name, value ); | |||
} | |||
} | |||
return propsCopy; | |||
} | |||
/** | |||
* Returns a copy of the user property hashtable | |||
* @return a hashtable containing just the user properties | |||
*/ | |||
public Hashtable getUserProperties() | |||
{ | |||
Hashtable propsCopy = new Hashtable(); | |||
Iterator userPropNames = m_userProperties.iterator(); | |||
while( userPropNames.hasNext() ) | |||
{ | |||
String name = (String)userPropNames.next(); | |||
String value = getProperty( name ); | |||
propsCopy.put( name, value ); | |||
} | |||
return propsCopy; | |||
} | |||
/** | |||
* Replaces ${} style constructions in the given value with the | |||
* string value of the corresponding data types. | |||
* | |||
* @param value The string to be scanned for property references. | |||
* May be <code>null</code>. | |||
* | |||
* @return the given string with embedded property names replaced | |||
* by values, or <code>null</code> if the given string is | |||
* <code>null</code>. | |||
* | |||
* @exception BuildException if the given value has an unclosed | |||
* property name, e.g. <code>${xxx</code> | |||
*/ | |||
public String replaceProperties( String value ) | |||
throws BuildException | |||
{ | |||
return ProjectHelper.replaceProperties( this, value, | |||
this.getProperties() ); | |||
} | |||
/** | |||
* Make the Ant1 project set the java version property, and then | |||
* copy it into the context properties. | |||
* | |||
* @exception BuildException if this Java version is not supported | |||
* | |||
* @see #getJavaVersion() | |||
*/ | |||
public void setJavaVersionProperty() throws BuildException | |||
{ | |||
String javaVersion = getJavaVersion(); | |||
doSetProperty( "ant.java.version", javaVersion ); | |||
log( "Detected Java version: " + javaVersion + " in: " | |||
+ System.getProperty( "java.home" ), MSG_VERBOSE ); | |||
log( "Detected OS: " + System.getProperty( "os.name" ), MSG_VERBOSE ); | |||
} | |||
/** | |||
* Sets the base directory for the project, checking that | |||
* the given filename exists and is a directory. | |||
* | |||
* @param baseD The project base directory. | |||
* Must not be <code>null</code>. | |||
* | |||
* @exception BuildException if the directory if invalid | |||
*/ | |||
public void setBaseDir( File baseD ) throws BuildException | |||
{ | |||
super.setBaseDir( baseD ); | |||
doSetProperty( "basedir", super.getProperty( "basedir" ) ); | |||
} | |||
} |
@@ -1,66 +0,0 @@ | |||
/* | |||
* 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.txt file. | |||
*/ | |||
package org.apache.tools.ant; | |||
import org.apache.avalon.framework.configuration.Configuration; | |||
import org.apache.avalon.framework.configuration.ConfigurationException; | |||
import org.apache.avalon.excalibur.i18n.Resources; | |||
import org.apache.avalon.excalibur.i18n.ResourceManager; | |||
/** | |||
* An adapter for running (in Myrmidon) Ant1 tasks which do not extend Task | |||
* | |||
* @author <a href="mailto:darrell@apache.org">Darrell DeBoer</a> | |||
* @version $Revision$ $Date$ | |||
*/ | |||
public class Ant1CompatTaskAdapter | |||
extends TaskAdapter | |||
{ | |||
private static final Resources REZ = | |||
ResourceManager.getPackageResources( Ant1CompatTaskAdapter.class ); | |||
/** | |||
* Gets the adapted task name from the configuration, and looks up the | |||
* Class for the adapted task. The adapted task is then instantiated and | |||
* configured. | |||
* @param configuration The Task Model | |||
* @throws ConfigurationException If the configuration is invalid. | |||
*/ | |||
public void configure( Configuration configuration ) | |||
throws ConfigurationException | |||
{ | |||
// Create a new instance of the proxy object, | |||
// and configure it. | |||
String taskName = getAnt1Name( configuration.getName() ); | |||
Class taskClass = (Class)project.getTaskDefinitions().get( taskName ); | |||
if( taskClass == null ) | |||
{ | |||
String message = | |||
REZ.getString( "taskadapter.invalid-task-name.error", taskName ); | |||
throw new ConfigurationException( message ); | |||
} | |||
Object adaptedTask = null; | |||
try | |||
{ | |||
adaptedTask = taskClass.newInstance(); | |||
} | |||
catch( Exception e ) | |||
{ | |||
String message = | |||
REZ.getString( "taskadapter.no-create.error", taskClass.getName() ); | |||
throw new ConfigurationException( message ); | |||
} | |||
configure( adaptedTask, configuration ); | |||
setProxy( adaptedTask ); | |||
} | |||
} |
@@ -1,50 +0,0 @@ | |||
/* | |||
* 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.txt file. | |||
*/ | |||
package org.apache.tools.ant; | |||
import org.apache.avalon.framework.configuration.Configuration; | |||
import org.apache.avalon.framework.configuration.ConfigurationException; | |||
import org.apache.avalon.excalibur.i18n.ResourceManager; | |||
import org.apache.avalon.excalibur.i18n.Resources; | |||
/** | |||
* A task for instantiating Ant1 datatypes. | |||
* | |||
* @author <a href="mailto:darrell@apache.org">Darrell DeBoer</a> | |||
* @version $Revision$ $Date$ | |||
*/ | |||
public class Ant1CompatTypeInstanceTask | |||
extends Task | |||
{ | |||
private static final Resources REZ = | |||
ResourceManager.getPackageResources( Ant1CompatTypeInstanceTask.class ); | |||
public void configure( Configuration configuration ) throws ConfigurationException | |||
{ | |||
if( configuration.getAttribute( "id", null ) == null ) | |||
{ | |||
final String message = REZ.getString( "type.no-id.error" ); | |||
throw new ConfigurationException( message ); | |||
} | |||
String typeName = configuration.getName(); | |||
Object datatype = project.createDataType( getAnt1Name( typeName ) ); | |||
// Configure the datatype. The type is added to the project | |||
// as a reference during configuration. | |||
configure( datatype, configuration ); | |||
} | |||
/** | |||
* Execute task. Don't do anything. | |||
*/ | |||
public void execute() | |||
{ | |||
// Everything is done during configuration. | |||
} | |||
} |
@@ -1,253 +0,0 @@ | |||
/* | |||
* The Apache Software License, Version 1.1 | |||
* | |||
* Copyright (c) 2000-2002 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", "Ant", 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; | |||
import java.io.PrintWriter; | |||
import java.io.PrintStream; | |||
import org.apache.tools.ant.Location; | |||
/** | |||
*----------------------------------------------------------------- | |||
* Ant1Compatability layer version of BuildException, modified slightly | |||
* from original Ant1 BuildException, to provide a Myrmidon-friendly | |||
* getCause(), so that cascading exceptions are followed. | |||
* ----------------------------------------------------------------- | |||
* | |||
* Signals an error condition during a build | |||
* | |||
* @author James Duncan Davidson | |||
*/ | |||
public class BuildException extends RuntimeException { | |||
/** Exception that might have caused this one. */ | |||
private Throwable m_cause; | |||
/** Location in the build file where the exception occured */ | |||
private Location m_location = Location.UNKNOWN_LOCATION; | |||
/** | |||
* Constructs a build exception with no descriptive information. | |||
*/ | |||
public BuildException() { | |||
} | |||
/** | |||
* Constructs an exception with the given descriptive message. | |||
* | |||
* @param msg A description of or information about the exception. | |||
* Should not be <code>null</code>. | |||
*/ | |||
public BuildException(final String msg) { | |||
super(msg); | |||
} | |||
/** | |||
* Constructs an exception with the given message and exception as | |||
* a root cause. | |||
* | |||
* @param msg A description of or information about the exception. | |||
* Should not be <code>null</code> unless a cause is specified. | |||
* @param cause The exception that might have caused this one. | |||
* May be <code>null</code>. | |||
*/ | |||
public BuildException(final String msg, final Throwable cause) { | |||
super(msg); | |||
m_cause = cause; | |||
} | |||
/** | |||
* Constructs an exception with the given message and exception as | |||
* a root cause and a location in a file. | |||
* | |||
* @param msg A description of or information about the exception. | |||
* Should not be <code>null</code> unless a cause is specified. | |||
* @param cause The exception that might have caused this one. | |||
* May be <code>null</code>. | |||
* @param location The location in the project file where the error | |||
* occurred. Must not be <code>null</code>. | |||
*/ | |||
public BuildException( final String msg, | |||
final Throwable cause, | |||
final Location location) { | |||
this(msg, cause); | |||
m_location = location; | |||
} | |||
/** | |||
* Constructs an exception with the given exception as a root cause. | |||
* | |||
* @param cause The exception that might have caused this one. | |||
* Should not be <code>null</code>. | |||
*/ | |||
public BuildException(final Throwable cause ) { | |||
this(cause.getMessage(), cause); | |||
} | |||
/** | |||
* Constructs an exception with the given descriptive message and a | |||
* location in a file. | |||
* | |||
* @param msg A description of or information about the exception. | |||
* Should not be <code>null</code>. | |||
* @param location The location in the project file where the error | |||
* occurred. Must not be <code>null</code>. | |||
*/ | |||
public BuildException(final String msg, final Location location) { | |||
super(msg); | |||
m_location = location; | |||
} | |||
/** | |||
* Constructs an exception with the given exception as | |||
* a root cause and a location in a file. | |||
* | |||
* @param cause The exception that might have caused this one. | |||
* Should not be <code>null</code>. | |||
* @param location The location in the project file where the error | |||
* occurred. Must not be <code>null</code>. | |||
*/ | |||
public BuildException(final Throwable cause, final Location location) { | |||
this(cause); | |||
m_location = location; | |||
} | |||
/** | |||
* Returns the nested exception, if any. | |||
* | |||
* @return the nested exception, or <code>null</code> if no | |||
* exception is associated with this one | |||
*/ | |||
public Throwable getException() { | |||
return m_cause; | |||
} | |||
/** | |||
* Returns the location of the error and the error message. | |||
* | |||
* @return the location of the error and the error message | |||
*/ | |||
public String toString() { | |||
return m_location.toString() + getMessage(); | |||
} | |||
/** | |||
* Sets the file location where the error occurred. | |||
* | |||
* @param location The file location where the error occurred. | |||
* Must not be <code>null</code>. | |||
*/ | |||
public void setLocation(final Location location) { | |||
m_location = location; | |||
} | |||
/** | |||
* Returns the file location where the error occurred. | |||
* | |||
* @return the file location where the error occurred. | |||
*/ | |||
public Location getLocation() { | |||
return m_location; | |||
} | |||
/** | |||
* Prints the stack trace for this exception and any | |||
* nested exception to <code>System.err</code>. | |||
*/ | |||
public void printStackTrace() { | |||
printStackTrace(System.err); | |||
} | |||
/** | |||
* Prints the stack trace of this exception and any nested | |||
* exception to the specified PrintStream. | |||
* | |||
* @param ps The PrintStream to print the stack trace to. | |||
* Must not be <code>null</code>. | |||
*/ | |||
public void printStackTrace(PrintStream ps) { | |||
synchronized (ps) { | |||
super.printStackTrace(ps); | |||
if (m_cause != null) { | |||
ps.println("--- Nested Exception ---"); | |||
m_cause.printStackTrace(ps); | |||
} | |||
} | |||
} | |||
/** | |||
* Prints the stack trace of this exception and any nested | |||
* exception to the specified PrintWriter. | |||
* | |||
* @param pw The PrintWriter to print the stack trace to. | |||
* Must not be <code>null</code>. | |||
*/ | |||
public void printStackTrace(PrintWriter pw) { | |||
synchronized (pw) { | |||
super.printStackTrace(pw); | |||
if (m_cause != null) { | |||
pw.println("--- Nested Exception ---"); | |||
m_cause.printStackTrace(pw); | |||
} | |||
} | |||
} | |||
/** | |||
* Myrmidon-friendly cascading exception method. | |||
* @return the cascading cause of this exception. | |||
*/ | |||
public Throwable getCause() | |||
{ | |||
return m_cause; | |||
} | |||
} |
@@ -1,286 +0,0 @@ | |||
/* | |||
* The Apache Software License, Version 1.1 | |||
* | |||
* Copyright (c) 2002 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", "Ant", 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; | |||
import java.io.BufferedReader; | |||
import java.io.File; | |||
import java.io.FilenameFilter; | |||
import java.io.IOException; | |||
import java.io.InputStreamReader; | |||
import java.io.PrintStream; | |||
import java.net.MalformedURLException; | |||
import java.net.URL; | |||
import java.net.URLClassLoader; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
/** | |||
* LoaderUtils is a utility class with methods for configuring a class | |||
* loader from a URL. | |||
* | |||
* @author Conor MacNeill | |||
* @created 9 January 2002 | |||
*/ | |||
public class LoaderUtils { | |||
/** | |||
* This is the file that is consulted on remote systems to specify | |||
* available jars | |||
*/ | |||
public static final String LIST_FILE = "file.list"; | |||
/** | |||
* Get the URLs of a set of libraries in the given location | |||
* | |||
* @param location the location to be searched | |||
* @param defaultFile default file if none can be found | |||
* @return an array of URLs for the relevant jars | |||
* @exception MalformedURLException the URLs cannot be created | |||
*/ | |||
public static URL[] getLocationURLs(URL location, String defaultFile) | |||
throws MalformedURLException { | |||
return getLocationURLs(location, defaultFile, new String[]{".jar"}); | |||
} | |||
/** | |||
* Get the URLs of a set of libraries in the given location | |||
* | |||
* @param location the location to be searched | |||
* @param extensions array of allowable file extensions | |||
* @param defaultFile default file if none can be found | |||
* @return an array of URLs for the relevant jars | |||
* @exception MalformedURLException if the URL to the jars could not be | |||
* formed | |||
*/ | |||
public static URL[] getLocationURLs(URL location, String defaultFile, | |||
String[] extensions) | |||
throws MalformedURLException { | |||
URL[] urls = null; | |||
if (location.getProtocol().equals("file")) { | |||
// URL is local filesystem. | |||
urls = getLocalURLs(new File(location.getFile()), extensions); | |||
} else { | |||
// URL is remote - try to read a file with the list of jars | |||
URL jarListURL = new URL(location, LIST_FILE); | |||
BufferedReader reader = null; | |||
List jarList = new ArrayList(); | |||
try { | |||
InputStreamReader isr | |||
= new InputStreamReader(jarListURL.openStream()); | |||
reader = new BufferedReader(isr); | |||
String line = null; | |||
while ((line = reader.readLine().trim()) != null) { | |||
for (int i = 0; i < extensions.length; ++i) { | |||
if (line.endsWith(extensions[i])) { | |||
jarList.add(new URL(location, line)); | |||
break; | |||
} | |||
} | |||
} | |||
urls = (URL[])jarList.toArray(new URL[0]); | |||
} catch (IOException e) { | |||
// use the default location | |||
if (defaultFile != null) { | |||
urls = new URL[]{new URL(location, defaultFile)}; | |||
} | |||
} finally { | |||
if (reader != null) { | |||
try { | |||
reader.close(); | |||
} catch (IOException e) { | |||
} | |||
} | |||
} | |||
} | |||
return urls; | |||
} | |||
/** | |||
* Get the classpath from a classloader. This can only extract path | |||
* components from the loaders which are instances of URLClassLoaders | |||
* | |||
* @param loader the loader whose path is required | |||
* @return the loader's configuration expressed as a classpath | |||
*/ | |||
public static String getClasspath(ClassLoader loader) { | |||
StringBuffer pathBuffer = null; | |||
if (loader instanceof URLClassLoader) { | |||
URLClassLoader urlLoader = (URLClassLoader)loader; | |||
URL[] urls = urlLoader.getURLs(); | |||
for (int i = 0; i < urls.length; ++i) { | |||
if (!urls[i].getProtocol().equals("file")) { | |||
continue; | |||
} | |||
String pathElement = urls[i].getFile(); | |||
if (pathBuffer == null) { | |||
pathBuffer = new StringBuffer(pathElement); | |||
} else { | |||
pathBuffer.append(File.pathSeparatorChar); | |||
pathBuffer.append(pathElement); | |||
} | |||
} | |||
} | |||
String path = pathBuffer == null ? "" : pathBuffer.toString(); | |||
ClassLoader parentLoader = loader.getParent(); | |||
if (parentLoader != null) { | |||
String parentPath = getClasspath(parentLoader); | |||
if (parentPath.length() != 0) { | |||
path = parentPath + File.pathSeparator + path; | |||
} | |||
} | |||
return path; | |||
} | |||
/** | |||
* Debug method to dump a class loader hierarchy to a PrintStream | |||
* URLClassLoaders dump their URLs | |||
* | |||
* @param loader the class loaders whose configuration is dumped | |||
* @param ps PrintStream to which info is sent | |||
*/ | |||
public static void dumpLoader(PrintStream ps, ClassLoader loader) { | |||
if (loader instanceof URLClassLoader) { | |||
URLClassLoader urlLoader = (URLClassLoader)loader; | |||
URL[] urls = urlLoader.getURLs(); | |||
if (urls.length == 0) { | |||
ps.println(" No URLs"); | |||
} else { | |||
for (int i = 0; i < urls.length; ++i) { | |||
ps.println(" URL: " + urls[i]); | |||
} | |||
} | |||
} else { | |||
ps.println("Class Loader: " + loader.getClass().getName()); | |||
} | |||
ps.println(); | |||
ClassLoader parentLoader = loader.getParent(); | |||
if (parentLoader != null) { | |||
ps.println("Parent Loader:"); | |||
dumpLoader(ps, parentLoader); | |||
} | |||
} | |||
/** | |||
* Get an array of URLs for each file in the filesystem. If the given | |||
* location is a directory, it is searched for files of the given | |||
* extension. If it is a file, it is returned as a URL if it matches the | |||
* given extension list. | |||
* | |||
* @param location the location within the local filesystem to be | |||
* searched | |||
* @param extensions an array of file extensions to be considered in the | |||
* search | |||
* @return an array of URLs for the file found in the directory. | |||
* @exception MalformedURLException if the URLs to the jars cannot be | |||
* formed | |||
*/ | |||
private static URL[] getLocalURLs(File location, | |||
final String[] extensions) | |||
throws MalformedURLException { | |||
URL[] urls = new URL[0]; | |||
if (!location.exists()) { | |||
return urls; | |||
} | |||
if (!location.isDirectory()) { | |||
String path = location.getPath(); | |||
for (int i = 0; i < extensions.length; ++i) { | |||
if (path.endsWith(extensions[i])) { | |||
urls[0] = location.toURL(); | |||
break; | |||
} | |||
} | |||
return urls; | |||
} | |||
File[] jars = location.listFiles( | |||
new FilenameFilter() { | |||
public boolean accept(File dir, String name) { | |||
for (int i = 0; i < extensions.length; ++i) { | |||
if (name.endsWith(extensions[i])) { | |||
return true; | |||
} | |||
} | |||
return false; | |||
} | |||
}); | |||
urls = new URL[jars.length]; | |||
for (int i = 0; i < jars.length; ++i) { | |||
urls[i] = jars[i].toURL(); | |||
} | |||
return urls; | |||
} | |||
/** | |||
* Set the context loader of the current thread and returns the existing | |||
* classloader | |||
* | |||
* @param newLoader the new context loader | |||
* @return the old context loader | |||
*/ | |||
public static ClassLoader setContextLoader(ClassLoader newLoader) { | |||
Thread thread = Thread.currentThread(); | |||
ClassLoader currentLoader = thread.getContextClassLoader(); | |||
thread.setContextClassLoader(newLoader); | |||
return currentLoader; | |||
} | |||
} | |||
@@ -1,374 +0,0 @@ | |||
/* | |||
* The Apache Software License, Version 1.1 | |||
* | |||
* Copyright (c) 2000-2002 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", "Ant", 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; | |||
/** | |||
* Base class for all tasks. | |||
* | |||
* Use Project.createTask to create a new task instance rather than | |||
* using this class directly for construction. | |||
* | |||
* @see Project#createTask | |||
*/ | |||
public abstract class OriginalAnt1Task extends ProjectComponent { | |||
/** Target this task belongs to, if any. */ | |||
protected Target target = null; | |||
/** Description of this task, if any. */ | |||
protected String description = null; | |||
/** Location within the build file of this task definition. */ | |||
protected Location location = Location.UNKNOWN_LOCATION; | |||
/** | |||
* Name of this task to be used for logging purposes. | |||
* This defaults to the same as the type, but may be | |||
* overridden by the user. For instance, the name "java" | |||
* isn't terribly descriptive for a task used within | |||
* another task - the outer task code can probably | |||
* provide a better one. | |||
*/ | |||
protected String taskName = null; | |||
/** Type of this task. */ | |||
protected String taskType = null; | |||
/** Wrapper for this object, used to configure it at runtime. */ | |||
protected RuntimeConfigurable wrapper; | |||
/** | |||
* Whether or not this task is invalid. A task becomes invalid | |||
* if a conflicting class is specified as the implementation for | |||
* its type. | |||
*/ | |||
private boolean invalid = false; | |||
/** Sole constructor. */ | |||
public OriginalAnt1Task() { | |||
} | |||
/** | |||
* Sets the target container of this task. | |||
* | |||
* @param target Target in whose scope this task belongs. | |||
* May be <code>null</code>, indicating a top-level task. | |||
*/ | |||
public void setOwningTarget(Target target) { | |||
this.target = target; | |||
} | |||
/** | |||
* Returns the container target of this task. | |||
* | |||
* @return The target containing this task, or <code>null</code> if | |||
* this task is a top-level task. | |||
*/ | |||
public Target getOwningTarget() { | |||
return target; | |||
} | |||
/** | |||
* Sets the name to use in logging messages. | |||
* | |||
* @param name The name to use in logging messages. | |||
* Should not be <code>null</code>. | |||
*/ | |||
public void setTaskName(String name) { | |||
this.taskName = name; | |||
} | |||
/** | |||
* Returns the name to use in logging messages. | |||
* | |||
* @return the name to use in logging messages. | |||
*/ | |||
public String getTaskName() { | |||
return taskName; | |||
} | |||
/** | |||
* Sets the name with which the task has been invoked. | |||
* | |||
* @param type The name the task has been invoked as. | |||
* Should not be <code>null</code>. | |||
*/ | |||
void setTaskType(String type) { | |||
this.taskType = type; | |||
} | |||
/** | |||
* Sets a description of the current action. This may be used for logging | |||
* purposes. | |||
* | |||
* @param desc Description of the current action. | |||
* May be <code>null</code>, indicating that no description is | |||
* available. | |||
* | |||
*/ | |||
public void setDescription( String desc ) { | |||
description = desc; | |||
} | |||
/** | |||
* Returns the description of the current action. | |||
* | |||
* @return the description of the current action, or <code>null</code> if | |||
* no description is available. | |||
*/ | |||
public String getDescription() { | |||
return description; | |||
} | |||
/** | |||
* Called by the project to let the task initialize properly. | |||
* The default implementation is a no-op. | |||
* | |||
* @exception BuildException if someting goes wrong with the build | |||
*/ | |||
public void init() throws BuildException {} | |||
/** | |||
* Called by the project to let the task do its work. This method may be | |||
* called more than once, if the task is invoked more than once. | |||
* For example, | |||
* if target1 and target2 both depend on target3, then running | |||
* "ant target1 target2" will run all tasks in target3 twice. | |||
* | |||
* @exception BuildException if something goes wrong with the build | |||
*/ | |||
public void execute() throws BuildException {} | |||
/** | |||
* Returns the file/location where this task was defined. | |||
* | |||
* @return the file/location where this task was defined. | |||
* Should not return <code>null</code>. Location.UNKNOWN_LOCATION | |||
* is used for unknown locations. | |||
* | |||
* @see Location#UNKNOWN_LOCATION | |||
*/ | |||
public Location getLocation() { | |||
return location; | |||
} | |||
/** | |||
* Sets the file/location where this task was defined. | |||
* | |||
* @param location The file/location where this task was defined. | |||
* Should not be <code>null</code> - use | |||
* Location.UNKNOWN_LOCATION if the location isn't known. | |||
* | |||
* @see Location#UNKNOWN_LOCATION | |||
*/ | |||
public void setLocation(Location location) { | |||
this.location = location; | |||
} | |||
/** | |||
* Returns the wrapper used for runtime configuration. | |||
* | |||
* @return the wrapper used for runtime configuration. This | |||
* method will generate a new wrapper (and cache it) | |||
* if one isn't set already. | |||
*/ | |||
public RuntimeConfigurable getRuntimeConfigurableWrapper() { | |||
if (wrapper == null) { | |||
wrapper = new RuntimeConfigurable(this, getTaskName()); | |||
} | |||
return wrapper; | |||
} | |||
/** | |||
* Sets the wrapper to be used for runtime configuration. | |||
* | |||
* @param wrapper The wrapper to be used for runtime configuration. | |||
* May be <code>null</code>, in which case the next call | |||
* to getRuntimeConfigurableWrapper will generate a new | |||
* wrapper. | |||
*/ | |||
protected void setRuntimeConfigurableWrapper(RuntimeConfigurable wrapper) { | |||
this.wrapper = wrapper; | |||
} | |||
// XXX: (Jon Skeet) The comment "if it hasn't been done already" may | |||
// not be strictly true. wrapper.maybeConfigure() won't configure the same | |||
// attributes/text more than once, but it may well add the children again, | |||
// unless I've missed something. | |||
/** | |||
* Configures this task - if it hasn't been done already. | |||
* If the task has been invalidated, it is replaced with an | |||
* UnknownElement task which uses the new definition in the project. | |||
* | |||
* @exception BuildException if the task cannot be configured. | |||
*/ | |||
public void maybeConfigure() throws BuildException { | |||
if (!invalid) { | |||
if (wrapper != null) { | |||
wrapper.maybeConfigure(project); | |||
} | |||
} else { | |||
getReplacement(); | |||
} | |||
} | |||
/** | |||
* Handles a line of output by logging it with the INFO priority. | |||
* | |||
* @param line The line of output to log. Should not be <code>null</code>. | |||
*/ | |||
protected void handleOutput(String line) { | |||
log(line, Project.MSG_INFO); | |||
} | |||
/** | |||
* Handles an error line by logging it with the INFO priority. | |||
* | |||
* @param line The error line to log. Should not be <code>null</code>. | |||
*/ | |||
protected void handleErrorOutput(String line) { | |||
log(line, Project.MSG_ERR); | |||
} | |||
/** | |||
* Logs a message with the default (INFO) priority. | |||
* | |||
* @param msg The message to be logged. Should not be <code>null</code>. | |||
*/ | |||
public void log(String msg) { | |||
log(msg, Project.MSG_INFO); | |||
} | |||
/** | |||
* Logs a mesage with the given priority. This delegates | |||
* the actual logging to the project. | |||
* | |||
* @param msg The message to be logged. Should not be <code>null</code>. | |||
* @param msgLevel The message priority at which this message is to | |||
* be logged. | |||
*/ | |||
public void log(String msg, int msgLevel) { | |||
project.log(getThis(), msg, msgLevel); | |||
} | |||
/** | |||
* Performs this task if it's still valid, or gets a replacement | |||
* version and performs that otherwise. | |||
* | |||
* Performing a task consists of firing a task started event, | |||
* configuring the task, executing it, and then firing task finished | |||
* event. If a runtime exception is thrown, the task finished event | |||
* is still fired, but with the exception as the cause. | |||
*/ | |||
public final void perform() { | |||
if (!invalid) { | |||
try { | |||
project.fireTaskStarted(getThis()); | |||
maybeConfigure(); | |||
execute(); | |||
project.fireTaskFinished(getThis(), null); | |||
} | |||
catch (RuntimeException exc) { | |||
if (exc instanceof BuildException) { | |||
BuildException be = (BuildException) exc; | |||
if (be.getLocation() == Location.UNKNOWN_LOCATION) { | |||
be.setLocation(getLocation()); | |||
} | |||
} | |||
project.fireTaskFinished(getThis(), exc); | |||
throw exc; | |||
} | |||
} else { | |||
UnknownElement ue = getReplacement(); | |||
Task task = ue.getTask(); | |||
task.perform(); | |||
} | |||
} | |||
/** | |||
* Marks this task as invalid. Any further use of this task | |||
* will go through a replacement with the updated definition. | |||
*/ | |||
final void markInvalid() { | |||
invalid = true; | |||
} | |||
/** | |||
* Replacement element used if this task is invalidated. | |||
*/ | |||
private UnknownElement replacement; | |||
/** | |||
* Creates an UnknownElement that can be used to replace this task. | |||
* Once this has been created once, it is cached and returned by | |||
* future calls. | |||
* | |||
* @return the UnknownElement instance for the new definition of this task. | |||
*/ | |||
private UnknownElement getReplacement() { | |||
if (replacement == null) { | |||
replacement = new UnknownElement(taskType); | |||
replacement.setProject(project); | |||
replacement.setTaskType(taskType); | |||
replacement.setTaskName(taskName); | |||
replacement.setLocation(location); | |||
replacement.setOwningTarget(target); | |||
replacement.setRuntimeConfigurableWrapper(wrapper); | |||
wrapper.setProxy(replacement); | |||
target.replaceChild(getThis(), replacement); | |||
replacement.maybeConfigure(); | |||
} | |||
return replacement; | |||
} | |||
private Task getThis() | |||
{ | |||
return (Task) this; | |||
} | |||
} |
@@ -1,4 +0,0 @@ | |||
type.no-id.error=Id must be specified. | |||
taskadapter.invalid-task-name.error=Invalid task name for TaskAdapter: {0}. | |||
taskadapter.no-create.error=Could not instantiate adapted task: {0}. |
@@ -1,117 +0,0 @@ | |||
/* | |||
* 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.txt file. | |||
*/ | |||
package org.apache.tools.ant; | |||
import java.util.Locale; | |||
import org.apache.avalon.framework.configuration.Configurable; | |||
import org.apache.avalon.framework.configuration.Configuration; | |||
import org.apache.avalon.framework.configuration.ConfigurationException; | |||
import org.apache.myrmidon.api.TaskContext; | |||
import org.apache.myrmidon.api.TaskException; | |||
/** | |||
* Ant1 Task proxy for Myrmidon. | |||
* Note that this class and OriginalAnt1Task (superclass) comprise a single logical | |||
* class, but the code is kept separate for ease of development. OriginalAnt1Task | |||
* is barely modified from the Ant1 original, whereas this class contains | |||
* all of the Myrmidon-specific adaptations. | |||
* | |||
* @author <a href="mailto:darrell@apache.org">Darrell DeBoer</a> | |||
* @version $Revision$ $Date$ | |||
*/ | |||
public class Task extends OriginalAnt1Task | |||
implements org.apache.myrmidon.api.Task, Configurable | |||
{ | |||
protected TaskContext m_context; | |||
/** | |||
* Specify the context in which the task operates in. | |||
* The Task will use the TaskContext to receive information | |||
* about it's environment. | |||
*/ | |||
public void contextualize( TaskContext context ) | |||
throws TaskException | |||
{ | |||
m_context = context; | |||
this.setTaskType( context.getName() ); | |||
this.setTaskName( context.getName() ); | |||
// Create/recontextualise the Ant1 Project. | |||
Ant1CompatProject project = | |||
(Ant1CompatProject)context.getProperty( Ant1CompatProject.ANT1_PROJECT_PROP ); | |||
if( project == null ) | |||
{ | |||
project = createProject(); | |||
m_context.setProperty( Ant1CompatProject.ANT1_PROJECT_PROP, project ); | |||
} | |||
else | |||
{ | |||
project.recontextulize( context ); | |||
} | |||
this.setProject( project ); | |||
} | |||
/** | |||
* Create and initialise an Ant1CompatProject | |||
*/ | |||
private Ant1CompatProject createProject() | |||
throws TaskException | |||
{ | |||
Ant1CompatProject project = new Ant1CompatProject( m_context ); | |||
project.init(); | |||
return project; | |||
} | |||
/** | |||
* Uses the task Configuration to perform Ant1-style configuration | |||
* on the Ant1 task. This method configures *all* tasks the way Ant1 | |||
* configures tasks inside a target. | |||
* | |||
* @param configuration The TaskModel for this Ant1 Task. | |||
* @throws ConfigurationException if the Configuration supplied is not valid | |||
*/ | |||
public void configure( Configuration configuration ) throws ConfigurationException | |||
{ | |||
configure( this, configuration ); | |||
} | |||
/** | |||
* Uses reflection to configure any Object, with the help of the Ant1 | |||
* IntrospectionHelper. using . This aims to mimic (to some extent) the | |||
* Ant1-style configuration rules implemented by ProjectHelperImpl. | |||
* @param target | |||
* The object to be configured. | |||
* @param configuration | |||
* The data to configure the object with. | |||
* @throws ConfigurationException | |||
* If the Configuration is not valid for the configured object | |||
*/ | |||
protected void configure( Object target, Configuration configuration ) throws ConfigurationException | |||
{ | |||
//TODO Maybe provide different configuration order for tasks not in a target, | |||
// elements in a TaskContainer etc... | |||
Ant1CompatConfigurer configurer = | |||
new Ant1CompatConfigurer( target, configuration, project ); | |||
configurer.createChildren(); | |||
configurer.configure(); | |||
this.init(); | |||
} | |||
/** | |||
* Returns the name of a Task/Datatype as referred to by Ant1 code, without | |||
* the "ant1." prefix. | |||
* @param fullName The full name as known by Myrmidon. | |||
* @return the name without the Ant1 prefix. | |||
*/ | |||
protected String getAnt1Name( String fullName ) | |||
{ | |||
return fullName.substring( Ant1CompatProject.ANT1_TASK_PREFIX.length() ); | |||
} | |||
} |
@@ -1,238 +0,0 @@ | |||
/* | |||
* 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.txt file. | |||
*/ | |||
package org.apache.tools.ant.taskdefs; | |||
import java.util.Iterator; | |||
import java.util.Vector; | |||
import org.apache.avalon.framework.configuration.Configuration; | |||
import org.apache.avalon.framework.configuration.DefaultConfiguration; | |||
import org.apache.myrmidon.api.TaskException; | |||
import org.apache.myrmidon.interfaces.executor.ExecutionFrame; | |||
import org.apache.myrmidon.interfaces.executor.Executor; | |||
import org.apache.tools.ant.Ant1CompatProject; | |||
import org.apache.tools.ant.BuildException; | |||
import org.apache.tools.ant.Task; | |||
/** | |||
* A base class for Ant1 versions of <ant> and <antcall> tasks, | |||
* which delegate to the Myrmidon versions of these tasks. | |||
* | |||
* @author <a href="mailto:darrell@apache.org">Darrell DeBoer</a> | |||
* @version $Revision$ $Date$ | |||
*/ | |||
public abstract class AbstractAnt1AntTask | |||
extends Task | |||
{ | |||
/** the target to call if any */ | |||
private String target = null; | |||
/** should we inherit properties from the parent ? */ | |||
private boolean inheritAll = true; | |||
/** the properties to pass to the new project */ | |||
private Vector properties = new Vector(); | |||
/** the references to pass to the new project */ | |||
private Vector references = new Vector(); | |||
/** | |||
* If true, inherit all properties from parent Project | |||
* If false, inherit only userProperties and those defined | |||
* inside the ant call itself | |||
*/ | |||
public void setInheritAll( boolean value ) | |||
{ | |||
inheritAll = value; | |||
} | |||
/** | |||
* set the target to execute. If none is defined it will | |||
* execute the default target of the build file | |||
*/ | |||
public void setTarget( String s ) | |||
{ | |||
this.target = s; | |||
} | |||
/** | |||
* Create a nested property (ant) or param (antcall) element. | |||
*/ | |||
protected Property doCreateProperty() | |||
{ | |||
Property p = new Property( true ); | |||
properties.addElement( p ); | |||
return p; | |||
} | |||
/** | |||
* create a reference element that identifies a data type that | |||
* should be carried over to the new project. | |||
*/ | |||
public void addReference( Reference r ) | |||
{ | |||
references.addElement( r ); | |||
} | |||
/** | |||
* Helper class that implements the nested <reference> | |||
* element of <ant> and <antcall>. | |||
*/ | |||
public static class Reference | |||
extends org.apache.tools.ant.types.Reference | |||
{ | |||
public Reference() | |||
{ | |||
super(); | |||
} | |||
private String targetid = null; | |||
public void setToRefid( String targetid ) | |||
{ | |||
this.targetid = targetid; | |||
} | |||
public String getToRefid() | |||
{ | |||
return targetid; | |||
} | |||
} | |||
/** | |||
* Removes the Ant1CompatProject from the properties, builds a TaskModel for | |||
* executing the Myrmidon task, and executes that TaskModel. | |||
* @throws BuildException on error | |||
*/ | |||
public void execute() throws BuildException | |||
{ | |||
Object ant1project = unsetAnt1Project(); | |||
try | |||
{ | |||
Configuration antConfig = constructTaskModel(); | |||
executeTask( antConfig ); | |||
} | |||
finally | |||
{ | |||
resetAnt1Project( ant1project ); | |||
} | |||
} | |||
/** | |||
* Executes the Myrmidon task detailed in the TaskModel provided. | |||
* @param taskModel the TaskModel for the task to execute. | |||
*/ | |||
private void executeTask( Configuration taskModel ) | |||
{ | |||
try | |||
{ | |||
Executor executor = (Executor)m_context.getService( Executor.class ); | |||
ExecutionFrame frame = | |||
(ExecutionFrame)m_context.getService( ExecutionFrame.class ); | |||
executor.execute( taskModel, frame ); | |||
} | |||
catch( TaskException e ) | |||
{ | |||
throw new BuildException( e ); | |||
} | |||
} | |||
/** | |||
* Removes the Ant1CompatProject from the TaskContext properties. | |||
* @return the removed project | |||
* @throws BuildException | |||
*/ | |||
private Object unsetAnt1Project() throws BuildException | |||
{ | |||
Object ant1project = null; | |||
try | |||
{ | |||
ant1project = | |||
m_context.getProperty( Ant1CompatProject.ANT1_PROJECT_PROP ); | |||
m_context.setProperty( Ant1CompatProject.ANT1_PROJECT_PROP, null ); | |||
} | |||
catch( TaskException e ) | |||
{ | |||
throw new BuildException( e ); | |||
} | |||
return ant1project; | |||
} | |||
/** | |||
* Adds the Ant1CompatProject back into the TaskContext properties. | |||
* @param ant1project the project to add. | |||
* @throws BuildException | |||
*/ | |||
private void resetAnt1Project( Object ant1project ) throws BuildException | |||
{ | |||
try | |||
{ | |||
m_context.setProperty( Ant1CompatProject.ANT1_PROJECT_PROP, | |||
ant1project ); | |||
} | |||
catch( TaskException e ) | |||
{ | |||
throw new BuildException( e ); | |||
} | |||
} | |||
/** | |||
* Builds the TaskModel for executing the Myrmidon version of a task. | |||
* @return a Configuration containing the TaskModel | |||
*/ | |||
protected Configuration constructTaskModel() | |||
{ | |||
DefaultConfiguration antConfig = buildTaskModel(); | |||
antConfig.setAttribute( "inherit-all", String.valueOf( inheritAll ) ); | |||
// Ignore inheritRefs for now ( inheritAll == inheritRefs ) | |||
if( target != null ) | |||
{ | |||
antConfig.setAttribute( "target", target ); | |||
} | |||
addProperties( antConfig ); | |||
addReferences( antConfig ); | |||
return antConfig; | |||
} | |||
/** | |||
* Create the Myrmidon TaskModel, and configure with subclass-specific config. | |||
*/ | |||
protected abstract DefaultConfiguration buildTaskModel(); | |||
/** | |||
* Adds all defined properties to the supplied Task model. | |||
* @param taskModel | |||
*/ | |||
protected void addProperties( DefaultConfiguration taskModel ) | |||
{ | |||
// Add all of the properties. | |||
Iterator iter = properties.iterator(); | |||
while( iter.hasNext() ) | |||
{ | |||
DefaultConfiguration param = new DefaultConfiguration( "param", "" ); | |||
Property property = (Property)iter.next(); | |||
param.setAttribute( "name", property.getName() ); | |||
param.setAttribute( "value", property.getValue() ); | |||
taskModel.addChild( param ); | |||
} | |||
} | |||
/** | |||
* Adds all defined references to the supplied Task model. | |||
* @param taskModel | |||
*/ | |||
protected void addReferences( DefaultConfiguration taskModel ) | |||
{ | |||
// TODO: Handle references. | |||
} | |||
} |
@@ -1,152 +0,0 @@ | |||
/* | |||
* The Apache Software License, Version 1.1 | |||
* | |||
* Copyright (c) 2000-2002 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", "Ant", 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.taskdefs; | |||
import java.io.File; | |||
import org.apache.avalon.framework.configuration.DefaultConfiguration; | |||
import org.apache.tools.ant.util.FileUtils; | |||
/** | |||
* Ant1Compat version of <ant>, which delegates to the Myrmidon version. | |||
* | |||
* @author costin@dnt.ro | |||
* @author <a href="mailto:darrell@apache.org">Darrell DeBoer</a> | |||
*/ | |||
public class Ant | |||
extends AbstractAnt1AntTask | |||
{ | |||
/** the basedir where is executed the build file */ | |||
private File dir = null; | |||
/** the build.xml file (can be absolute) in this case dir will be ignored */ | |||
private String antFile = null; | |||
/** the output */ | |||
private String output = null; | |||
/** should we inherit references from the parent ? */ | |||
private boolean inheritRefs = false; | |||
/** | |||
* If true, inherit all references from parent Project | |||
* If false, inherit only those defined | |||
* inside the ant call itself | |||
*/ | |||
public void setInheritRefs( boolean value ) | |||
{ | |||
inheritRefs = value; | |||
} | |||
/** | |||
* ... | |||
*/ | |||
public void setDir( File d ) | |||
{ | |||
this.dir = d; | |||
} | |||
/** | |||
* set the build file, it can be either absolute or relative. | |||
* If it is absolute, <tt>dir</tt> will be ignored, if it is | |||
* relative it will be resolved relative to <tt>dir</tt>. | |||
*/ | |||
public void setAntfile( String s ) | |||
{ | |||
// @note: it is a string and not a file to handle relative/absolute | |||
// otherwise a relative file will be resolved based on the current | |||
// basedir. | |||
this.antFile = s; | |||
} | |||
public void setOutput( String s ) | |||
{ | |||
this.output = s; | |||
} | |||
/** create a property to pass to the new project as a 'user property' */ | |||
public Property createProperty() | |||
{ | |||
return doCreateProperty(); | |||
} | |||
/** | |||
* Construct a TaskModel for the Myrmidon <ant> task, and configure it | |||
* with sub-class specific values (antfile). | |||
* @return the TaskModel | |||
*/ | |||
protected DefaultConfiguration buildTaskModel() | |||
{ | |||
DefaultConfiguration antConfig = new DefaultConfiguration( "ant", "" ); | |||
// Get the "file" value. | |||
if( antFile == null ) | |||
{ | |||
antFile = "build.xml"; | |||
} | |||
if( dir == null ) | |||
{ | |||
dir = project.getBaseDir(); | |||
} | |||
File file = FileUtils.newFileUtils().resolveFile( dir, antFile ); | |||
antFile = file.getAbsolutePath(); | |||
antConfig.setAttribute( "file", antFile ); | |||
return antConfig; | |||
} | |||
} |
@@ -1,36 +0,0 @@ | |||
/* | |||
* 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.txt file. | |||
*/ | |||
package org.apache.tools.ant.taskdefs; | |||
import org.apache.avalon.framework.configuration.DefaultConfiguration; | |||
/** | |||
* The Ant1Compat version of the <antcall> task, which delegates to the | |||
* Myrmidon version. | |||
* | |||
* @author <a href="mailto:darrell@apache.org">Darrell DeBoer</a> | |||
* @version $Revision$ $Date$ | |||
*/ | |||
public class CallTarget extends AbstractAnt1AntTask | |||
{ | |||
/** | |||
* Properties are referred to as Parameters in <antcall> | |||
*/ | |||
public Property createParam() | |||
{ | |||
return doCreateProperty(); | |||
} | |||
/** | |||
* The only configuration not done by base class is the task name. | |||
*/ | |||
protected DefaultConfiguration buildTaskModel() | |||
{ | |||
return new DefaultConfiguration( "ant-call", "" ); | |||
} | |||
} |
@@ -1,626 +0,0 @@ | |||
/* | |||
* The Apache Software License, Version 1.1 | |||
* | |||
* Copyright (c) 2000-2002 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", "Ant", 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.DirectoryScanner; | |||
import org.apache.tools.ant.Project; | |||
import org.apache.tools.ant.PathTokenizer; | |||
import org.apache.tools.ant.LoaderUtils; | |||
import java.io.File; | |||
import java.util.Enumeration; | |||
import java.util.Locale; | |||
import java.util.Stack; | |||
import java.util.Vector; | |||
/** | |||
* *********************************************************************** | |||
* Ant1Compatibility Layer version of Path, hacked to provide Ant1 runtime | |||
* files in System Classpath. | |||
* *********************************************************************** | |||
* | |||
* This object represents a path as used by CLASSPATH or PATH | |||
* environment variable. | |||
* <p> | |||
* <code> | |||
* <sometask><br> | |||
* <somepath><br> | |||
* <pathelement location="/path/to/file.jar" /><br> | |||
* <pathelement path="/path/to/file2.jar:/path/to/class2;/path/to/class3" /><br> | |||
* <pathelement location="/path/to/file3.jar" /><br> | |||
* <pathelement location="/path/to/file4.jar" /><br> | |||
* </somepath><br> | |||
* </sometask><br> | |||
* </code> | |||
* <p> | |||
* The object implemention <code>sometask</code> must provide a method called | |||
* <code>createSomepath</code> which returns an instance of <code>Path</code>. | |||
* Nested path definitions are handled by the Path object and must be labeled | |||
* <code>pathelement</code>.<p> | |||
* | |||
* The path element takes a parameter <code>path</code> which will be parsed | |||
* and split into single elements. It will usually be used | |||
* to define a path from an environment variable. | |||
* | |||
* @author Thomas.Haas@softwired-inc.com | |||
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | |||
*/ | |||
public class Path extends DataType implements Cloneable { | |||
private Vector elements; | |||
public static Path systemClasspath = | |||
new Path(null, System.getProperty("java.class.path")); | |||
//Modified from original source. | |||
//Append Ant1Compat classpath to systemclasspath. | |||
// ------------------Modified-------------------------------- | |||
static | |||
{ | |||
// Add Ant1Compat.atl to system classpath. | |||
String classpath = LoaderUtils.getClasspath( Path.class.getClassLoader() ); | |||
systemClasspath.append( new Path( null, classpath ) ); | |||
} | |||
//-----------------End Modified------------------------------ | |||
/** | |||
* Helper class, holds the nested <code><pathelement></code> values. | |||
*/ | |||
public class PathElement { | |||
private String[] parts; | |||
public void setLocation(File loc) { | |||
parts = new String[] {translateFile(loc.getAbsolutePath())}; | |||
} | |||
public void setPath(String path) { | |||
parts = Path.translatePath(getProject(), path); | |||
} | |||
public String[] getParts() { | |||
return parts; | |||
} | |||
} | |||
/** | |||
* Invoked by IntrospectionHelper for <code>setXXX(Path p)</code> | |||
* attribute setters. | |||
*/ | |||
public Path(Project p, String path) { | |||
this(p); | |||
createPathElement().setPath(path); | |||
} | |||
public Path(Project project) { | |||
setProject(project); | |||
elements = new Vector(); | |||
} | |||
/** | |||
* Adds a element definition to the path. | |||
* @param location the location of the element to add (must not be | |||
* <code>null</code> nor empty. | |||
*/ | |||
public void setLocation(File location) throws BuildException { | |||
if (isReference()) { | |||
throw tooManyAttributes(); | |||
} | |||
createPathElement().setLocation(location); | |||
} | |||
/** | |||
* Parses a path definition and creates single PathElements. | |||
* @param path the path definition. | |||
*/ | |||
public void setPath(String path) throws BuildException { | |||
if (isReference()) { | |||
throw tooManyAttributes(); | |||
} | |||
createPathElement().setPath(path); | |||
} | |||
/** | |||
* Makes this instance in effect a reference to another Path instance. | |||
* | |||
* <p>You must not set another attribute or nest elements inside | |||
* this element if you make it a reference.</p> | |||
*/ | |||
public void setRefid(Reference r) throws BuildException { | |||
if (!elements.isEmpty()) { | |||
throw tooManyAttributes(); | |||
} | |||
elements.addElement(r); | |||
super.setRefid(r); | |||
} | |||
/** | |||
* Creates the nested <code><pathelement></code> element. | |||
*/ | |||
public PathElement createPathElement() throws BuildException { | |||
if (isReference()) { | |||
throw noChildrenAllowed(); | |||
} | |||
PathElement pe = new PathElement(); | |||
elements.addElement(pe); | |||
return pe; | |||
} | |||
/** | |||
* Adds a nested <code><fileset></code> element. | |||
*/ | |||
public void addFileset(FileSet fs) throws BuildException { | |||
if (isReference()) { | |||
throw noChildrenAllowed(); | |||
} | |||
elements.addElement(fs); | |||
checked = false; | |||
} | |||
/** | |||
* Creates a nested <code><path></code> element. | |||
*/ | |||
public Path createPath() throws BuildException { | |||
if (isReference()) { | |||
throw noChildrenAllowed(); | |||
} | |||
Path p = new Path(getProject()); | |||
elements.addElement(p); | |||
checked = false; | |||
return p; | |||
} | |||
/** | |||
* Append the contents of the other Path instance to this. | |||
*/ | |||
public void append(Path other) { | |||
if (other == null) { | |||
return; | |||
} | |||
String[] l = other.list(); | |||
for (int i=0; i<l.length; i++) { | |||
if (elements.indexOf(l[i]) == -1) { | |||
elements.addElement(l[i]); | |||
} | |||
} | |||
} | |||
/** | |||
* Adds the components on the given path which exist to this | |||
* Path. Components that don't exist, aren't added. | |||
* | |||
* @param source - source path whose components are examined for existence | |||
*/ | |||
public void addExisting(Path source) { | |||
String[] list = source.list(); | |||
for (int i=0; i<list.length; i++) { | |||
File f = null; | |||
if (getProject() != null) { | |||
f = getProject().resolveFile(list[i]); | |||
} | |||
else { | |||
f = new File(list[i]); | |||
} | |||
if (f.exists()) { | |||
setLocation(f); | |||
} else { | |||
log("dropping " + f + " from path as it doesn't exist", | |||
Project.MSG_VERBOSE); | |||
} | |||
} | |||
} | |||
/** | |||
* Returns all path elements defined by this and nested path objects. | |||
* @return list of path elements. | |||
*/ | |||
public String[] list() { | |||
if (!checked) { | |||
// make sure we don't have a circular reference here | |||
Stack stk = new Stack(); | |||
stk.push(this); | |||
dieOnCircularReference(stk, getProject()); | |||
} | |||
Vector result = new Vector(2*elements.size()); | |||
for (int i=0; i<elements.size(); i++) { | |||
Object o = elements.elementAt(i); | |||
if (o instanceof Reference) { | |||
Reference r = (Reference) o; | |||
o = r.getReferencedObject(getProject()); | |||
// we only support references to paths right now | |||
if (!(o instanceof Path)) { | |||
String msg = r.getRefId()+" doesn\'t denote a path"; | |||
throw new BuildException(msg); | |||
} | |||
} | |||
if (o instanceof String) { | |||
// obtained via append | |||
addUnlessPresent(result, (String) o); | |||
} else if (o instanceof PathElement) { | |||
String[] parts = ((PathElement) o).getParts(); | |||
if (parts == null) { | |||
throw new BuildException("You must either set location or path on <pathelement>"); | |||
} | |||
for (int j=0; j<parts.length; j++) { | |||
addUnlessPresent(result, parts[j]); | |||
} | |||
} else if (o instanceof Path) { | |||
Path p = (Path) o; | |||
if (p.getProject() == null) { | |||
p.setProject(getProject()); | |||
} | |||
String[] parts = p.list(); | |||
for (int j=0; j<parts.length; j++) { | |||
addUnlessPresent(result, parts[j]); | |||
} | |||
} else if (o instanceof FileSet) { | |||
FileSet fs = (FileSet) o; | |||
DirectoryScanner ds = fs.getDirectoryScanner(getProject()); | |||
String[] s = ds.getIncludedFiles(); | |||
File dir = fs.getDir(getProject()); | |||
for (int j=0; j<s.length; j++) { | |||
File f = new File(dir, s[j]); | |||
String absolutePath = f.getAbsolutePath(); | |||
addUnlessPresent(result, translateFile(absolutePath)); | |||
} | |||
} | |||
} | |||
String[] res = new String[result.size()]; | |||
result.copyInto(res); | |||
return res; | |||
} | |||
/** | |||
* Returns a textual representation of the path, which can be used as | |||
* CLASSPATH or PATH environment variable definition. | |||
* @return a textual representation of the path. | |||
*/ | |||
public String toString() { | |||
final String[] list = list(); | |||
// empty path return empty string | |||
if (list.length == 0) { | |||
return ""; | |||
} | |||
// path containing one or more elements | |||
final StringBuffer result = new StringBuffer(list[0].toString()); | |||
for (int i=1; i < list.length; i++) { | |||
result.append(File.pathSeparatorChar); | |||
result.append(list[i]); | |||
} | |||
return result.toString(); | |||
} | |||
/** | |||
* Splits a PATH (with : or ; as separators) into its parts. | |||
*/ | |||
public static String[] translatePath(Project project, String source) { | |||
final Vector result = new Vector(); | |||
if (source == null) { | |||
return new String[0]; | |||
} | |||
PathTokenizer tok = new PathTokenizer(source); | |||
StringBuffer element = new StringBuffer(); | |||
while (tok.hasMoreTokens()) { | |||
element.setLength(0); | |||
String pathElement = tok.nextToken(); | |||
try { | |||
element.append(resolveFile(project, pathElement)); | |||
} | |||
catch (BuildException e) { | |||
project.log("Dropping path element " + pathElement + " as it is not valid relative to the project", | |||
Project.MSG_VERBOSE); | |||
} | |||
for (int i=0; i<element.length(); i++) { | |||
translateFileSep(element, i); | |||
} | |||
result.addElement(element.toString()); | |||
} | |||
String[] res = new String[result.size()]; | |||
result.copyInto(res); | |||
return res; | |||
} | |||
/** | |||
* Returns its argument with all file separator characters | |||
* replaced so that they match the local OS conventions. | |||
*/ | |||
public static String translateFile(String source) { | |||
if (source == null) { | |||
return ""; | |||
} | |||
final StringBuffer result = new StringBuffer(source); | |||
for (int i=0; i < result.length(); i++) { | |||
translateFileSep(result, i); | |||
} | |||
return result.toString(); | |||
} | |||
/** | |||
* Translates all occurrences of / or \ to correct separator of the | |||
* current platform and returns whether it had to do any | |||
* replacements. | |||
*/ | |||
protected static boolean translateFileSep(StringBuffer buffer, int pos) { | |||
if (buffer.charAt(pos) == '/' || buffer.charAt(pos) == '\\') { | |||
buffer.setCharAt(pos, File.separatorChar); | |||
return true; | |||
} | |||
return false; | |||
} | |||
/** | |||
* How many parts does this Path instance consist of. | |||
*/ | |||
public int size() { | |||
return list().length; | |||
} | |||
/** | |||
* Return a Path that holds the same elements as this instance. | |||
*/ | |||
public Object clone() { | |||
Path p = new Path(getProject()); | |||
p.append(this); | |||
return p; | |||
} | |||
/** | |||
* Overrides the version of DataType to recurse on all DataType | |||
* child elements that may have been added. | |||
*/ | |||
protected void dieOnCircularReference(Stack stk, Project p) | |||
throws BuildException { | |||
if (checked) { | |||
return; | |||
} | |||
Enumeration enum = elements.elements(); | |||
while (enum.hasMoreElements()) { | |||
Object o = enum.nextElement(); | |||
if (o instanceof Reference) { | |||
o = ((Reference) o).getReferencedObject(p); | |||
} | |||
if (o instanceof DataType) { | |||
if (stk.contains(o)) { | |||
throw circularReference(); | |||
} else { | |||
stk.push(o); | |||
((DataType) o).dieOnCircularReference(stk, p); | |||
stk.pop(); | |||
} | |||
} | |||
} | |||
checked = true; | |||
} | |||
/** | |||
* Resolve a filename with Project's help - if we know one that is. | |||
* | |||
* <p>Assume the filename is absolute if project is null.</p> | |||
*/ | |||
private static String resolveFile(Project project, String relativeName) { | |||
if (project != null) { | |||
File f = project.resolveFile(relativeName); | |||
return f.getAbsolutePath(); | |||
} | |||
return relativeName; | |||
} | |||
/** | |||
* Adds a String to the Vector if it isn't already included. | |||
*/ | |||
private static void addUnlessPresent(Vector v, String s) { | |||
if (v.indexOf(s) == -1) { | |||
v.addElement(s); | |||
} | |||
} | |||
/** | |||
* Concatenates the system class path in the order specified by | |||
* the ${build.sysclasspath} property - using "last" as | |||
* default value. | |||
*/ | |||
public Path concatSystemClasspath() { | |||
return concatSystemClasspath("last"); | |||
} | |||
/** | |||
* Concatenates the system class path in the order specified by | |||
* the ${build.sysclasspath} property - using the supplied value | |||
* if ${build.sysclasspath} has not been set. | |||
*/ | |||
public Path concatSystemClasspath(String defValue) { | |||
Path result = new Path(getProject()); | |||
String order = defValue; | |||
if (getProject() != null) { | |||
String o = getProject().getProperty("build.sysclasspath"); | |||
if (o != null) { | |||
order = o; | |||
} | |||
} | |||
if (order.equals("only")) { | |||
// only: the developer knows what (s)he is doing | |||
result.addExisting(Path.systemClasspath); | |||
} else if (order.equals("first")) { | |||
// first: developer could use a little help | |||
result.addExisting(Path.systemClasspath); | |||
result.addExisting(this); | |||
} else if (order.equals("ignore")) { | |||
// ignore: don't trust anyone | |||
result.addExisting(this); | |||
} else { | |||
// last: don't trust the developer | |||
if (!order.equals("last")) { | |||
log("invalid value for build.sysclasspath: " + order, | |||
Project.MSG_WARN); | |||
} | |||
result.addExisting(this); | |||
result.addExisting(Path.systemClasspath); | |||
} | |||
return result; | |||
} | |||
/** | |||
* Add the Java Runtime classes to this Path instance. | |||
*/ | |||
public void addJavaRuntime() { | |||
if (System.getProperty("java.vendor").toLowerCase(Locale.US).indexOf("microsoft") >= 0) { | |||
// Pull in *.zip from packages directory | |||
FileSet msZipFiles = new FileSet(); | |||
msZipFiles.setDir(new File(System.getProperty("java.home") + File.separator + "Packages")); | |||
msZipFiles.setIncludes("*.ZIP"); | |||
addFileset(msZipFiles); | |||
} else if("Kaffe".equals(System.getProperty("java.vm.name"))) { | |||
FileSet kaffeJarFiles = new FileSet(); | |||
kaffeJarFiles.setDir(new File(System.getProperty("java.home") | |||
+ File.separator + "share" | |||
+ File.separator + "kaffe")); | |||
kaffeJarFiles.setIncludes("*.jar"); | |||
addFileset(kaffeJarFiles); | |||
} | |||
else if (Project.getJavaVersion() == Project.JAVA_1_1) { | |||
addExisting(new Path(null, | |||
System.getProperty("java.home") | |||
+ File.separator + "lib" | |||
+ File.separator | |||
+ "classes.zip")); | |||
} else { | |||
// JDK > 1.1 seems to set java.home to the JRE directory. | |||
addExisting(new Path(null, | |||
System.getProperty("java.home") | |||
+ File.separator + "lib" | |||
+ File.separator + "rt.jar")); | |||
// Just keep the old version as well and let addExisting | |||
// sort it out. | |||
addExisting(new Path(null, | |||
System.getProperty("java.home") | |||
+ File.separator +"jre" | |||
+ File.separator + "lib" | |||
+ File.separator + "rt.jar")); | |||
// Added for MacOS X | |||
addExisting(new Path(null, | |||
System.getProperty("java.home") | |||
+ File.separator + ".." | |||
+ File.separator + "Classes" | |||
+ File.separator + "classes.jar")); | |||
addExisting(new Path(null, | |||
System.getProperty("java.home") | |||
+ File.separator + ".." | |||
+ File.separator + "Classes" | |||
+ File.separator + "ui.jar")); | |||
} | |||
} | |||
/** | |||
* Emulation of extdirs feature in java >= 1.2. | |||
* This method adds all files in the given | |||
* directories (but not in sub-directories!) to the classpath, | |||
* so that you don't have to specify them all one by one. | |||
* @param extdirs - Path to append files to | |||
*/ | |||
public void addExtdirs(Path extdirs) { | |||
if (extdirs == null) { | |||
String extProp = System.getProperty("java.ext.dirs"); | |||
if (extProp != null) { | |||
extdirs = new Path(getProject(), extProp); | |||
} else { | |||
return; | |||
} | |||
} | |||
String[] dirs = extdirs.list(); | |||
for (int i=0; i<dirs.length; i++) { | |||
File dir = getProject().resolveFile(dirs[i]); | |||
if (dir.exists() && dir.isDirectory()) { | |||
FileSet fs = new FileSet(); | |||
fs.setDir(dir); | |||
fs.setIncludes("*"); | |||
addFileset(fs); | |||
} | |||
} | |||
} | |||
} |