than using the container classloader. * DefaultWorkspace and ExecManagerFactory figure out myrmidon.home using their parameters, rather than using system properties. * Split embeddor/workspace/project handling code out of CLIMain into a new EmbeddedAnt helper class. CLIMain is now responsible for setting up the logger, and command-line option handling. EmbeddedAnt is responsible for starting the embeddor, building the project, and executing targets (and cleaning-up). Should make it considerably simpler to embed myrmidon. git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@271987 13f79535-47bb-0310-9956-ffa450edef68master
@@ -74,6 +74,7 @@ public class DefaultEmbeddor | |||
private File m_homeDir; | |||
private File m_taskLibDir; | |||
private static final String MYRMIDON_HOME = "myrmidon.home"; | |||
/** | |||
* Setup basic properties of engine. | |||
@@ -133,6 +134,9 @@ public class DefaultEmbeddor | |||
{ | |||
final Workspace workspace = | |||
(Workspace)createService( Workspace.class, PREFIX + "workspace.DefaultWorkspace" ); | |||
// TODO - don't do this; need some way to pass separate sets of defines and config | |||
// to the workspace | |||
parameters.setParameter( MYRMIDON_HOME, m_parameters.getParameter( MYRMIDON_HOME ) ); | |||
setupObject( workspace, m_workspaceServiceManager, parameters ); | |||
return workspace; | |||
} | |||
@@ -186,7 +190,7 @@ public class DefaultEmbeddor | |||
throws Exception | |||
{ | |||
// Deploy all type libraries found in the classpath | |||
final ClassLoader libClassloader = Thread.currentThread().getContextClassLoader(); | |||
final ClassLoader libClassloader = getClass().getClassLoader(); | |||
final TypeDeployer typeDeployer = m_deployer.createDeployer( libClassloader ); | |||
typeDeployer.deployAll(); | |||
@@ -297,7 +301,7 @@ public class DefaultEmbeddor | |||
{ | |||
String filepath = null; | |||
filepath = getParameter( "myrmidon.home" ); | |||
filepath = getParameter( MYRMIDON_HOME ); | |||
m_homeDir = ( new File( filepath ) ).getAbsoluteFile(); | |||
checkDirectory( m_homeDir, "home-dir.name" ); | |||
@@ -147,7 +147,7 @@ public class DefaultWorkspace | |||
} | |||
private File findTypeLib( final String libraryName ) | |||
throws TaskException | |||
throws Exception | |||
{ | |||
//TODO: In future this will be expanded to allow | |||
//users to specify search path or automagically | |||
@@ -155,7 +155,7 @@ public class DefaultWorkspace | |||
//workspace specific) | |||
final String name = libraryName.replace( '/', File.separatorChar ) + ".atl"; | |||
final String home = System.getProperty( "myrmidon.home" ); | |||
final String home = m_parameters.getParameter( "myrmidon.home" ); | |||
final File homeDir = new File( home + File.separatorChar + "ext" ); | |||
final File library = new File( homeDir, name ); | |||
@@ -178,7 +178,7 @@ public class DefaultWorkspace | |||
} | |||
private void deployTypeLib( final Deployer deployer, final Project project ) | |||
throws TaskException | |||
throws Exception | |||
{ | |||
final TypeLib[] typeLibs = project.getTypeLibs(); | |||
@@ -213,7 +213,7 @@ public class DefaultWorkspace | |||
* Creates an execution frame for a project. | |||
*/ | |||
private ExecutionFrame createExecutionFrame( final Project project ) | |||
throws TaskException, ServiceException | |||
throws Exception | |||
{ | |||
//Create per frame ComponentManager | |||
final DefaultServiceManager serviceManager = | |||
@@ -12,6 +12,9 @@ import org.apache.aut.nativelib.ExecException; | |||
import org.apache.aut.nativelib.impl.DefaultExecManager; | |||
import org.apache.avalon.excalibur.i18n.ResourceManager; | |||
import org.apache.avalon.excalibur.i18n.Resources; | |||
import org.apache.avalon.framework.parameters.Parameterizable; | |||
import org.apache.avalon.framework.parameters.Parameters; | |||
import org.apache.avalon.framework.parameters.ParameterException; | |||
import org.apache.myrmidon.interfaces.service.AntServiceException; | |||
import org.apache.myrmidon.interfaces.service.ServiceFactory; | |||
@@ -22,23 +25,31 @@ import org.apache.myrmidon.interfaces.service.ServiceFactory; | |||
* @version $Revision$ $Date$ | |||
*/ | |||
public class ExecManagerFactory | |||
implements ServiceFactory | |||
implements ServiceFactory, Parameterizable | |||
{ | |||
private final static Resources REZ = | |||
ResourceManager.getPackageResources( ExecManagerFactory.class ); | |||
private Parameters m_parameters; | |||
public void parameterize( final Parameters parameters ) | |||
throws ParameterException | |||
{ | |||
m_parameters = parameters; | |||
} | |||
/** | |||
* Create the ExecManager Service. | |||
*/ | |||
public Object createService() | |||
throws AntServiceException | |||
{ | |||
final File home = getHomeDirectory(); | |||
try | |||
{ | |||
final File home = getHomeDirectory(); | |||
return new DefaultExecManager( home ); | |||
} | |||
catch( final ExecException ee ) | |||
catch( final Exception ee ) | |||
{ | |||
throw new AntServiceException( ee.getMessage(), ee ); | |||
} | |||
@@ -47,10 +58,10 @@ public class ExecManagerFactory | |||
/** | |||
* Utility method to retrieve home directory. | |||
*/ | |||
private static File getHomeDirectory() | |||
throws AntServiceException | |||
private File getHomeDirectory() | |||
throws Exception | |||
{ | |||
final String home = System.getProperty( "myrmidon.home" ); | |||
final String home = m_parameters.getParameter( "myrmidon.home" ); | |||
if( null == home ) | |||
{ | |||
final String message = REZ.getString( "missing-home-dir.error" ); | |||
@@ -8,10 +8,12 @@ | |||
package org.apache.myrmidon.frontends; | |||
import java.io.BufferedReader; | |||
import java.io.File; | |||
import java.io.InputStreamReader; | |||
import java.io.File; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import java.util.Map; | |||
import java.util.HashMap; | |||
import org.apache.avalon.excalibur.cli.CLArgsParser; | |||
import org.apache.avalon.excalibur.cli.CLOption; | |||
import org.apache.avalon.excalibur.cli.CLOptionDescriptor; | |||
@@ -20,15 +22,9 @@ import org.apache.avalon.excalibur.i18n.ResourceManager; | |||
import org.apache.avalon.excalibur.i18n.Resources; | |||
import org.apache.avalon.framework.CascadingException; | |||
import org.apache.avalon.framework.ExceptionUtil; | |||
import org.apache.avalon.framework.logger.AbstractLogEnabled; | |||
import org.apache.avalon.framework.parameters.Parameters; | |||
import org.apache.myrmidon.Constants; | |||
import org.apache.myrmidon.api.TaskException; | |||
import org.apache.myrmidon.interfaces.embeddor.Embeddor; | |||
import org.apache.myrmidon.interfaces.executor.Executor; | |||
import org.apache.myrmidon.interfaces.model.Project; | |||
import org.apache.myrmidon.interfaces.workspace.Workspace; | |||
import org.apache.myrmidon.listeners.ProjectListener; | |||
/** | |||
* The class to kick the tires and light the fires. | |||
@@ -39,14 +35,10 @@ import org.apache.myrmidon.listeners.ProjectListener; | |||
* @version $Revision$ $Date$ | |||
*/ | |||
public class CLIMain | |||
extends AbstractLogEnabled | |||
{ | |||
private final static Resources REZ = | |||
ResourceManager.getPackageResources( CLIMain.class ); | |||
private static final String DEFAULT_EMBEDDOR_CLASS = | |||
"org.apache.myrmidon.components.embeddor.DefaultEmbeddor"; | |||
//defines for the Command Line options | |||
private final static int HELP_OPT = 'h'; | |||
private final static int QUIET_OPT = 'q'; | |||
@@ -84,23 +76,19 @@ public class CLIMain | |||
LISTENER_OPT, NO_PREFIX_OPT | |||
}; | |||
///Parameters for run of myrmidon | |||
private Parameters m_parameters = new Parameters(); | |||
///List of targets supplied on command line to execute | |||
private ArrayList m_targets = new ArrayList(); | |||
///List of user supplied defines | |||
private Parameters m_defines = new Parameters(); | |||
///List of user supplied parameters for builder | |||
private Parameters m_builderParameters = new Parameters(); | |||
///Determine whether tasks are actually executed | |||
private boolean m_dryRun = false; | |||
///Enables incremental mode | |||
private boolean m_incremental; | |||
///The launcher | |||
private EmbeddedAnt m_embedded = new EmbeddedAnt(); | |||
///Log level to use | |||
//private static Priority m_priority = Priority.WARN; | |||
private static int m_priority = BasicLogger.LEVEL_WARN; | |||
/** | |||
@@ -109,12 +97,24 @@ public class CLIMain | |||
* @param args the args | |||
*/ | |||
public static void main( final String[] args ) | |||
{ | |||
final Map properties = new HashMap(); | |||
properties.put( "myrmidon.home", new File( "." ) ); | |||
main( properties, args ); | |||
} | |||
/** | |||
* Main entry point called to run standard Myrmidon. | |||
* | |||
* @param args the args | |||
*/ | |||
public static void main( final Map properties, final String[] args ) | |||
{ | |||
int exitCode = 0; | |||
final CLIMain main = new CLIMain(); | |||
try | |||
{ | |||
main.execute( args ); | |||
main.execute( properties, args ); | |||
} | |||
catch( final Throwable throwable ) | |||
{ | |||
@@ -243,10 +243,10 @@ public class CLIMain | |||
return false; | |||
case HOME_DIR_OPT: | |||
m_parameters.setParameter( "myrmidon.home", option.getArgument() ); | |||
m_embedded.setEmbeddorProperty( "myrmidon.home", option.getArgument() ); | |||
break; | |||
case TASKLIB_DIR_OPT: | |||
m_parameters.setParameter( "myrmidon.lib.path", option.getArgument() ); | |||
m_embedded.setEmbeddorProperty( "myrmidon.lib.path", option.getArgument() ); | |||
break; | |||
case LOG_LEVEL_OPT: | |||
@@ -260,26 +260,26 @@ public class CLIMain | |||
break; | |||
case INCREMENTAL_OPT: | |||
m_parameters.setParameter( "incremental", "true" ); | |||
m_incremental = true; | |||
break; | |||
case FILE_OPT: | |||
m_parameters.setParameter( "filename", option.getArgument() ); | |||
m_embedded.setProjectFile( option.getArgument() ); | |||
break; | |||
case LISTENER_OPT: | |||
m_parameters.setParameter( "listener", option.getArgument() ); | |||
m_embedded.setListener( option.getArgument() ); | |||
break; | |||
case NO_PREFIX_OPT: | |||
m_parameters.setParameter( "listener", "noprefix" ); | |||
m_embedded.setListener( "noprefix" ); | |||
break; | |||
case DEFINE_OPT: | |||
m_defines.setParameter( option.getArgument( 0 ), option.getArgument( 1 ) ); | |||
m_embedded.setWorkspaceProperty( option.getArgument( 0 ), option.getArgument( 1 ) ); | |||
break; | |||
case BUILDER_PARAM_OPT: | |||
m_builderParameters.setParameter( option.getArgument( 0 ), option.getArgument( 1 ) ); | |||
m_embedded.setBuilderProperty( option.getArgument( 0 ), option.getArgument( 1 ) ); | |||
break; | |||
case DRY_RUN_OPT: | |||
@@ -295,61 +295,42 @@ public class CLIMain | |||
return true; | |||
} | |||
private void setupDefaultParameters() | |||
{ | |||
//System property set up by launcher | |||
m_parameters.setParameter( "myrmidon.home", System.getProperty( "myrmidon.home", "." ) ); | |||
m_parameters.setParameter( "filename", "build.ant" ); | |||
m_parameters.setParameter( "log.level", "WARN" ); | |||
m_parameters.setParameter( "listener", "default" ); | |||
m_parameters.setParameter( "incremental", "false" ); | |||
} | |||
private void execute( final String[] args ) | |||
private void execute( final Map properties, final String[] args ) | |||
throws Exception | |||
{ | |||
setupDefaultParameters(); | |||
if( !parseCommandLineOptions( args ) ) | |||
try | |||
{ | |||
return; | |||
} | |||
prepareLogging(); | |||
checkHomeDir(); | |||
final File buildFile = getBuildFile(); | |||
//getLogger().debug( "Ant Bin Directory: " + m_binDir ); | |||
//getLogger().debug( "Ant Lib Directory: " + m_libDir ); | |||
//getLogger().debug( "Ant Task Lib Directory: " + m_taskLibDir ); | |||
// Set system properties set up by launcher | |||
m_embedded.setEmbeddorProperty( "myrmidon.home", properties.get( "myrmidon.home" ) ); | |||
if( m_dryRun ) | |||
{ | |||
m_parameters.setParameter( Executor.ROLE, | |||
"org.apache.myrmidon.components.executor.PrintingExecutor" ); | |||
} | |||
// Command line | |||
if( !parseCommandLineOptions( args ) ) | |||
{ | |||
return; | |||
} | |||
final Embeddor embeddor = prepareEmbeddor(); | |||
// Setup logging | |||
final BasicLogger logger = new BasicLogger( "[myrmidon] ", m_priority ); | |||
m_embedded.setLogger( logger ); | |||
try | |||
{ | |||
final ProjectListener listener = prepareListener( embeddor ); | |||
if( m_dryRun ) | |||
{ | |||
m_embedded.setEmbeddorProperty( Executor.ROLE, | |||
"org.apache.myrmidon.components.executor.PrintingExecutor" ); | |||
} | |||
//create the project | |||
final Project project = | |||
embeddor.createProject( buildFile.toString(), null, m_builderParameters ); | |||
// Set the common classloader | |||
final ClassLoader sharedClassLoader = (ClassLoader)properties.get( "myrmidon.shared.classloader" ); | |||
m_embedded.setSharedClassLoader( sharedClassLoader ); | |||
//loop over build if we are in incremental mode.. | |||
final boolean incremental = m_parameters.getParameterAsBoolean( "incremental", false ); | |||
if( !incremental ) | |||
if( !m_incremental ) | |||
{ | |||
executeBuild( embeddor, project, listener ); | |||
executeBuild(); | |||
} | |||
else | |||
{ | |||
executeIncrementalBuild( embeddor, project, listener ); | |||
executeIncrementalBuild(); | |||
} | |||
} | |||
catch( final Exception e ) | |||
@@ -359,13 +340,11 @@ public class CLIMain | |||
} | |||
finally | |||
{ | |||
shutdownEmbeddor( embeddor ); | |||
m_embedded.stop(); | |||
} | |||
} | |||
private void executeIncrementalBuild( final Embeddor embeddor, | |||
final Project project, | |||
final ProjectListener listener ) | |||
private void executeIncrementalBuild() | |||
throws Exception | |||
{ | |||
BufferedReader reader = null; | |||
@@ -374,7 +353,7 @@ public class CLIMain | |||
{ | |||
try | |||
{ | |||
executeBuild( embeddor, project, listener ); | |||
executeBuild(); | |||
} | |||
catch( final TaskException te ) | |||
{ | |||
@@ -398,6 +377,13 @@ public class CLIMain | |||
} | |||
} | |||
private void executeBuild() throws Exception | |||
{ | |||
//actually do the build ... | |||
final String[] targets = (String[])m_targets.toArray( new String[m_targets.size() ] ); | |||
m_embedded.executeTargets( targets ); | |||
} | |||
/** | |||
* Builds the error message for an exception | |||
*/ | |||
@@ -426,131 +412,7 @@ public class CLIMain | |||
} | |||
// Write the message out | |||
if( getLogger() == null ) | |||
{ | |||
System.err.println( message ); | |||
} | |||
else | |||
{ | |||
getLogger().error( message ); | |||
} | |||
} | |||
private void executeBuild( final Embeddor embeddor, | |||
final Project project, | |||
final ProjectListener listener ) | |||
throws Exception | |||
{ | |||
//actually do the build ... | |||
final Workspace workspace = embeddor.createWorkspace( m_defines ); | |||
workspace.addProjectListener( listener ); | |||
doBuild( workspace, project, m_targets ); | |||
} | |||
private File getBuildFile() throws Exception | |||
{ | |||
final String filename = m_parameters.getParameter( "filename", null ); | |||
final File buildFile = ( new File( filename ) ).getCanonicalFile(); | |||
if( !buildFile.isFile() ) | |||
{ | |||
final String message = REZ.getString( "bad-file.error", buildFile ); | |||
throw new Exception( message ); | |||
} | |||
if( getLogger().isInfoEnabled() ) | |||
{ | |||
final String message = REZ.getString( "buildfile.notice", buildFile ); | |||
getLogger().info( message ); | |||
} | |||
return buildFile; | |||
} | |||
private void checkHomeDir() throws Exception | |||
{ | |||
final String home = m_parameters.getParameter( "myrmidon.home" ); | |||
final File homeDir = ( new File( home ) ).getAbsoluteFile(); | |||
if( !homeDir.isDirectory() ) | |||
{ | |||
final String message = REZ.getString( "home-not-dir.error", homeDir ); | |||
throw new Exception( message ); | |||
} | |||
if( getLogger().isInfoEnabled() ) | |||
{ | |||
final String message = REZ.getString( "homedir.notice", homeDir ); | |||
getLogger().info( message ); | |||
} | |||
} | |||
private void prepareLogging() throws Exception | |||
{ | |||
//handle logging... | |||
final BasicLogger logger = new BasicLogger( "[myrmidon] ", m_priority ); | |||
enableLogging( logger ); | |||
} | |||
private void shutdownEmbeddor( final Embeddor embeddor ) | |||
throws Exception | |||
{ | |||
embeddor.stop(); | |||
embeddor.dispose(); | |||
} | |||
private ProjectListener prepareListener( final Embeddor embeddor ) | |||
throws Exception | |||
{ | |||
//create the listener | |||
final String listenerName = m_parameters.getParameter( "listener", null ); | |||
final ProjectListener listener = embeddor.createListener( listenerName ); | |||
return listener; | |||
} | |||
private Embeddor prepareEmbeddor() | |||
throws Exception | |||
{ | |||
final Embeddor embeddor = createEmbeddor(); | |||
setupLogger( embeddor ); | |||
embeddor.parameterize( m_parameters ); | |||
embeddor.initialize(); | |||
embeddor.start(); | |||
return embeddor; | |||
} | |||
private Embeddor createEmbeddor() | |||
throws Exception | |||
{ | |||
final Class clazz = Class.forName( DEFAULT_EMBEDDOR_CLASS ); | |||
return (Embeddor)clazz.newInstance(); | |||
} | |||
/** | |||
* Actually do the build. | |||
* | |||
* @param workspace the workspace | |||
* @param project the project | |||
* @param targets the targets to build as passed by CLI | |||
*/ | |||
private void doBuild( final Workspace workspace, | |||
final Project project, | |||
final ArrayList targets ) | |||
throws TaskException | |||
{ | |||
final int targetCount = targets.size(); | |||
//if we didn't specify a target on CLI then choose default | |||
if( 0 == targetCount ) | |||
{ | |||
workspace.executeProject( project, project.getDefaultTargetName() ); | |||
} | |||
else | |||
{ | |||
for( int i = 0; i < targetCount; i++ ) | |||
{ | |||
workspace.executeProject( project, (String)targets.get( i ) ); | |||
} | |||
} | |||
System.err.println( message ); | |||
} | |||
/** | |||
@@ -0,0 +1,295 @@ | |||
/* | |||
* 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.myrmidon.frontends; | |||
import java.io.File; | |||
import org.apache.avalon.excalibur.i18n.ResourceManager; | |||
import org.apache.avalon.excalibur.i18n.Resources; | |||
import org.apache.avalon.framework.logger.AbstractLogEnabled; | |||
import org.apache.avalon.framework.logger.Logger; | |||
import org.apache.avalon.framework.parameters.Parameters; | |||
import org.apache.myrmidon.api.TaskException; | |||
import org.apache.myrmidon.interfaces.embeddor.Embeddor; | |||
import org.apache.myrmidon.interfaces.model.Project; | |||
import org.apache.myrmidon.interfaces.workspace.Workspace; | |||
import org.apache.myrmidon.listeners.ProjectListener; | |||
/** | |||
* A utility class, that takes care of launching Myrmidon, and building and | |||
* executing a project. | |||
* | |||
* @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a> | |||
* @version $Revision$ $Date$ | |||
*/ | |||
public class EmbeddedAnt | |||
extends AbstractLogEnabled | |||
{ | |||
private final static Resources REZ | |||
= ResourceManager.getPackageResources( EmbeddedAnt.class ); | |||
private static final String DEFAULT_EMBEDDOR_CLASS = | |||
"org.apache.myrmidon.components.embeddor.DefaultEmbeddor"; | |||
private String m_projectFile = "build.ant"; | |||
private Project m_project; | |||
private String m_listenerName = "default"; | |||
private ProjectListener m_listener; | |||
private Parameters m_workspaceProps = new Parameters(); | |||
private Parameters m_builderProps = new Parameters(); | |||
private Parameters m_embeddorProps = new Parameters(); | |||
private ClassLoader m_sharedClassLoader; | |||
private Embeddor m_embeddor; | |||
/** | |||
* Sets the logger to use. | |||
*/ | |||
public void setLogger( final Logger logger ) | |||
{ | |||
enableLogging( logger ); | |||
} | |||
/** | |||
* Sets the project file to execute. Default is 'build.ant'. | |||
*/ | |||
public void setProjectFile( final String projectFile ) | |||
{ | |||
m_projectFile = projectFile; | |||
m_project = null; | |||
} | |||
/** | |||
* Sets the project to execute. This method can be used instead of | |||
* {@link #setProjectFile}, for projects models that are built | |||
* programmatically. | |||
*/ | |||
public void setProject( final Project project ) | |||
{ | |||
m_projectFile = null; | |||
m_project = project; | |||
} | |||
/** | |||
* Sets the name of the project listener to use. | |||
*/ | |||
public void setListener( final String listener ) | |||
{ | |||
m_listenerName = listener; | |||
m_listener = null; | |||
} | |||
/** | |||
* Sets the project listener to use. | |||
*/ | |||
public void setListener( final ProjectListener listener ) | |||
{ | |||
m_listenerName = null; | |||
m_listener = listener; | |||
} | |||
/** | |||
* Sets a workspace property. These are inherited by all projects executed | |||
* by this embeddor. | |||
*/ | |||
public void setWorkspaceProperty( final String name, final Object value ) | |||
{ | |||
// TODO - Make properties Objects, not Strings | |||
m_workspaceProps.setParameter( name, (String)value ); | |||
} | |||
/** | |||
* Sets a project builder property. These are used by the project builder | |||
* when it is parsing the project file. | |||
*/ | |||
public void setBuilderProperty( final String name, final Object value ) | |||
{ | |||
// TODO - Make properties Objects, not Strings | |||
m_builderProps.setParameter( name, (String)value ); | |||
} | |||
/** | |||
* Sets a task engine property. These are used to configure the task engine. | |||
*/ | |||
public void setEmbeddorProperty( final String name, final Object value ) | |||
{ | |||
// TODO - Make properties Objects, not Strings | |||
m_embeddorProps.setParameter( name, (String)value ); | |||
} | |||
/** | |||
* Sets the shared classloader, which is used as the parent classloader | |||
* for all antlibs. Default is to use the context classloader. | |||
*/ | |||
public void setSharedClassLoader( final ClassLoader classLoader ) | |||
{ | |||
m_sharedClassLoader = classLoader; | |||
} | |||
/** | |||
* Executes a set of targets in the project. This method may be called | |||
* multiple times. | |||
*/ | |||
public void executeTargets( final String[] targets ) throws Exception | |||
{ | |||
if( m_sharedClassLoader != null ) | |||
{ | |||
Thread.currentThread().setContextClassLoader( m_sharedClassLoader ); | |||
} | |||
checkHomeDir(); | |||
// Prepare the embeddor, project listener and project model | |||
final Embeddor embeddor = prepareEmbeddor(); | |||
final ProjectListener listener = prepareListener( embeddor ); | |||
final Project project = prepareProjectModel( embeddor ); | |||
// Create a new workspace | |||
final Workspace workspace = embeddor.createWorkspace( m_workspaceProps ); | |||
workspace.addProjectListener( listener ); | |||
//execute the project | |||
executeTargets( workspace, project, targets ); | |||
} | |||
/** | |||
* Shuts down the task engine, after the project has been executed. | |||
*/ | |||
public void stop() throws Exception | |||
{ | |||
try | |||
{ | |||
if( m_embeddor != null ) | |||
{ | |||
m_embeddor.stop(); | |||
m_embeddor.dispose(); | |||
} | |||
} | |||
finally | |||
{ | |||
m_embeddor = null; | |||
m_project = null; | |||
m_listener = null; | |||
} | |||
} | |||
/** | |||
* Actually do the build. | |||
*/ | |||
private void executeTargets( final Workspace workspace, | |||
final Project project, | |||
final String[] targets ) | |||
throws TaskException | |||
{ | |||
//if we didn't specify a target, then choose default | |||
if( targets == null || targets.length == 0 ) | |||
{ | |||
workspace.executeProject( project, project.getDefaultTargetName() ); | |||
} | |||
else | |||
{ | |||
for( int i = 0; i < targets.length; i++ ) | |||
{ | |||
workspace.executeProject( project, targets[ i ] ); | |||
} | |||
} | |||
} | |||
/** | |||
* Make sure myrmidon home directory has been specified, and is a | |||
* directory. | |||
*/ | |||
private void checkHomeDir() throws Exception | |||
{ | |||
final String home = m_embeddorProps.getParameter( "myrmidon.home" ); | |||
final File homeDir = ( new File( home ) ).getAbsoluteFile(); | |||
if( !homeDir.isDirectory() ) | |||
{ | |||
final String message = REZ.getString( "home-not-dir.error", homeDir ); | |||
throw new Exception( message ); | |||
} | |||
if( getLogger().isInfoEnabled() ) | |||
{ | |||
final String message = REZ.getString( "homedir.notice", homeDir ); | |||
getLogger().info( message ); | |||
} | |||
} | |||
/** | |||
* Prepares and returns the embeddor to use. | |||
*/ | |||
private Embeddor prepareEmbeddor() | |||
throws Exception | |||
{ | |||
if( m_embeddor == null ) | |||
{ | |||
m_embeddor = createEmbeddor(); | |||
setupLogger( m_embeddor ); | |||
m_embeddor.parameterize( m_embeddorProps ); | |||
m_embeddor.initialize(); | |||
m_embeddor.start(); | |||
} | |||
return m_embeddor; | |||
} | |||
/** | |||
* Creates the embeddor. | |||
*/ | |||
private Embeddor createEmbeddor() | |||
throws Exception | |||
{ | |||
final Class clazz = Class.forName( DEFAULT_EMBEDDOR_CLASS ); | |||
return (Embeddor)clazz.newInstance(); | |||
} | |||
/** | |||
* Prepares and returns the project listener to use. | |||
*/ | |||
private ProjectListener prepareListener( final Embeddor embeddor ) | |||
throws Exception | |||
{ | |||
if( m_listener == null ) | |||
{ | |||
m_listener = embeddor.createListener( m_listenerName ); | |||
} | |||
return m_listener; | |||
} | |||
/** | |||
* Prepares and returns the project model. | |||
*/ | |||
private Project prepareProjectModel( final Embeddor embeddor ) throws Exception | |||
{ | |||
if( m_project == null ) | |||
{ | |||
final File buildFile = getProjectFile(); | |||
m_project = embeddor.createProject( buildFile.toString(), null, m_builderProps ); | |||
} | |||
return m_project; | |||
} | |||
/** | |||
* Locates the project file | |||
*/ | |||
private File getProjectFile() throws Exception | |||
{ | |||
final File projectFile = ( new File( m_projectFile ) ).getCanonicalFile(); | |||
if( !projectFile.isFile() ) | |||
{ | |||
final String message = REZ.getString( "bad-file.error", projectFile ); | |||
throw new Exception( message ); | |||
} | |||
if( getLogger().isInfoEnabled() ) | |||
{ | |||
final String message = REZ.getString( "buildfile.notice", projectFile ); | |||
getLogger().info( message ); | |||
} | |||
return projectFile; | |||
} | |||
} |
@@ -14,6 +14,8 @@ import java.net.URL; | |||
import java.net.URLClassLoader; | |||
import java.util.ArrayList; | |||
import java.util.StringTokenizer; | |||
import java.util.Map; | |||
import java.util.HashMap; | |||
/** | |||
* Basic Loader that is responsible for all the hackery to get classloader to work. | |||
@@ -34,16 +36,26 @@ public final class Main | |||
{ | |||
try | |||
{ | |||
//actually try to discover the install directory based on where | |||
// the myrmidon.jar is | |||
final Map properties = new HashMap(); | |||
// Try to discover the install directory based on where the | |||
// launcher Jar is | |||
final File installDirectory = findInstallDir(); | |||
System.setProperty( "myrmidon.home", installDirectory.toString() ); | |||
properties.put( "myrmidon.home", installDirectory ); | |||
// Build the shared classloader | |||
final URL[] sharedClassPath = getSharedClassPath( installDirectory ); | |||
properties.put( "myrmidon.shared.classpath", sharedClassPath ); | |||
final URLClassLoader sharedClassLoader = new URLClassLoader( sharedClassPath ); | |||
properties.put( "myrmidon.shared.classloader", sharedClassLoader ); | |||
final URLClassLoader sharedClassLoader = createSharedClassLoader( installDirectory ); | |||
final URLClassLoader classLoader = | |||
createContainerClassLoader( installDirectory, sharedClassLoader ); | |||
// Build the container classloader | |||
final URL[] containerClassPath = getContainerClassPath( installDirectory ); | |||
properties.put( "myrmidon.container.classpath", containerClassPath ); | |||
final URLClassLoader containerClassLoader = new URLClassLoader( containerClassPath, sharedClassLoader ); | |||
properties.put( "myrmidon.container.classloader", containerClassLoader ); | |||
execMainClass( classLoader, args ); | |||
execMainClass( containerClassLoader, properties, args ); | |||
} | |||
catch( final InvocationTargetException ite ) | |||
{ | |||
@@ -57,38 +69,42 @@ public final class Main | |||
} | |||
} | |||
private static void execMainClass( final URLClassLoader classLoader, final String[] args ) | |||
/** | |||
* Executes the main class. | |||
*/ | |||
private static void execMainClass( final ClassLoader classLoader, | |||
final Map properties, | |||
final String[] args ) | |||
throws Exception | |||
{ | |||
//load class and retrieve appropriate main method. | |||
final Class clazz = classLoader.loadClass( "org.apache.myrmidon.frontends.CLIMain" ); | |||
final Method method = clazz.getMethod( "main", new Class[]{args.getClass()} ); | |||
Thread.currentThread().setContextClassLoader( classLoader ); | |||
final Method method = clazz.getMethod( "main", new Class[]{Map.class, args.getClass()} ); | |||
//kick the tires and light the fires.... | |||
method.invoke( null, new Object[]{args} ); | |||
method.invoke( null, new Object[]{properties, args} ); | |||
} | |||
private static URLClassLoader createContainerClassLoader( final File installDirectory, | |||
final URLClassLoader sharedClassLoader ) | |||
/** | |||
* Builds the classpath for the container classloader. | |||
*/ | |||
private static URL[] getContainerClassPath( final File installDirectory ) | |||
throws Exception | |||
{ | |||
// Include everything from the bin/lib/ directory | |||
final File containerLibDir = new File( installDirectory, "bin" + File.separator + "lib" ); | |||
final URL[] containerLibUrls = buildURLList( containerLibDir ); | |||
final URLClassLoader classLoader = | |||
new URLClassLoader( containerLibUrls, sharedClassLoader ); | |||
return classLoader; | |||
return buildURLList( containerLibDir ); | |||
} | |||
private static URLClassLoader createSharedClassLoader( final File installDirectory ) | |||
/** | |||
* Builds the classpath for the shared classloader. | |||
*/ | |||
private static URL[] getSharedClassPath( final File installDirectory ) | |||
throws Exception | |||
{ | |||
//setup classloader appropriately for myrmidon jar | |||
// Include everything from the lib/ directory | |||
final File libDir = new File( installDirectory, "lib" ); | |||
final URL[] libUrls = buildURLList( libDir ); | |||
final URLClassLoader libClassLoader = new URLClassLoader( libUrls ); | |||
return libClassLoader; | |||
return buildURLList( libDir ); | |||
} | |||
private static final URL[] buildURLList( final File dir ) | |||
@@ -137,25 +153,23 @@ public final class Main | |||
final String classpath = System.getProperty( "java.class.path" ); | |||
final String pathSeparator = System.getProperty( "path.separator" ); | |||
final StringTokenizer tokenizer = new StringTokenizer( classpath, pathSeparator ); | |||
final String jarName = "myrmidon-launcher.jar"; | |||
while( tokenizer.hasMoreTokens() ) | |||
{ | |||
final String element = tokenizer.nextToken(); | |||
if( element.endsWith( "myrmidon-launcher.jar" ) ) | |||
File file = ( new File( element ) ).getAbsoluteFile(); | |||
if( file.isFile() && file.getName().equals( jarName ) ) | |||
{ | |||
File file = ( new File( element ) ).getAbsoluteFile(); | |||
file = file.getParentFile(); | |||
if( null != file ) | |||
{ | |||
file = file.getParentFile(); | |||
} | |||
return file; | |||
} | |||
} | |||
throw new Exception( "Unable to locate ant.jar in classpath" ); | |||
throw new Exception( "Unable to locate " + jarName + " in classpath." ); | |||
} | |||
} |