Browse Source

Project Model:

* Removed "if" and "unless" conditions from targets.

* Moved parsing of "project->target" dependencies out of DefaultWorkspace,
  into DefaultProjectBuilder.

* DefaultWorkspace now detects cycles in the target dependency graph.

* DefaultWorkspace now executes the implicit target for referenced projects.

* Changes to DefaultProjectBuilder error reporting.

* Added a few more test cases for DefaultProjectBuilder.

Unit Tests:

* Moved AbstractComponentTest.getLogger() up to AbstractMyrmidonTest.

* Removed AbstractComponentTest.setup().  Components are now created on demand.

* Use BasicLogger in unit tests.


git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@271835 13f79535-47bb-0310-9956-ffa450edef68
master
adammurdoch 23 years ago
parent
commit
6ff9bf50ad
37 changed files with 1149 additions and 510 deletions
  1. +3
    -0
      proposal/myrmidon/etc/testcases/org/apache/myrmidon/components/builder/bad-version.ant
  2. +1
    -0
      proposal/myrmidon/etc/testcases/org/apache/myrmidon/components/builder/bad-xml.ant
  3. +3
    -0
      proposal/myrmidon/etc/testcases/org/apache/myrmidon/components/builder/defaults.ant
  4. +3
    -0
      proposal/myrmidon/etc/testcases/org/apache/myrmidon/components/builder/mismatched-version.ant
  5. +3
    -0
      proposal/myrmidon/etc/testcases/org/apache/myrmidon/components/builder/no-version.ant
  6. +3
    -0
      proposal/myrmidon/etc/testcases/org/apache/myrmidon/components/builder/set-base-dir.ant
  7. +3
    -0
      proposal/myrmidon/etc/testcases/org/apache/myrmidon/components/builder/set-default-target.ant
  8. +3
    -0
      proposal/myrmidon/etc/testcases/org/apache/myrmidon/components/builder/set-project-name.ant
  9. +76
    -89
      proposal/myrmidon/src/java/org/apache/myrmidon/components/builder/DefaultProjectBuilder.java
  10. +6
    -6
      proposal/myrmidon/src/java/org/apache/myrmidon/components/builder/Resources.properties
  11. +3
    -0
      proposal/myrmidon/src/java/org/apache/myrmidon/components/property/Resources.properties
  12. +1
    -2
      proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace/DefaultTaskContext.java
  13. +92
    -66
      proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace/DefaultWorkspace.java
  14. +17
    -7
      proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace/ProjectEntry.java
  15. +2
    -7
      proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace/Resources.properties
  16. +34
    -0
      proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace/TargetState.java
  17. +1
    -1
      proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/builder/ProjectBuilder.java
  18. +36
    -0
      proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/model/Dependency.java
  19. +5
    -22
      proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/model/Target.java
  20. +8
    -0
      proposal/myrmidon/src/test/org/apache/aut/vfs/AbstractFileSystemTest.java
  21. +45
    -21
      proposal/myrmidon/src/test/org/apache/myrmidon/AbstractMyrmidonTest.java
  22. +1
    -1
      proposal/myrmidon/src/test/org/apache/myrmidon/AbstractProjectTest.java
  23. +64
    -77
      proposal/myrmidon/src/test/org/apache/myrmidon/components/AbstractComponentTest.java
  24. +236
    -5
      proposal/myrmidon/src/test/org/apache/myrmidon/components/builder/DefaultProjectBuilderTest.java
  25. +22
    -42
      proposal/myrmidon/src/test/org/apache/myrmidon/components/property/AbstractPropertyResolverTest.java
  26. +4
    -6
      proposal/myrmidon/src/test/org/apache/myrmidon/components/property/ClassicPropertyResolverTest.java
  27. +46
    -0
      proposal/myrmidon/src/test/org/apache/myrmidon/components/property/DefaultPropertyResolverTest.java
  28. +1
    -3
      proposal/myrmidon/src/test/org/apache/myrmidon/components/service/InstantiatingServiceManagerTest.java
  29. +8
    -0
      proposal/myrmidon/src/testcases/org/apache/aut/vfs/AbstractFileSystemTest.java
  30. +45
    -21
      proposal/myrmidon/src/testcases/org/apache/myrmidon/AbstractMyrmidonTest.java
  31. +1
    -1
      proposal/myrmidon/src/testcases/org/apache/myrmidon/AbstractProjectTest.java
  32. +64
    -77
      proposal/myrmidon/src/testcases/org/apache/myrmidon/components/AbstractComponentTest.java
  33. +236
    -5
      proposal/myrmidon/src/testcases/org/apache/myrmidon/components/builder/DefaultProjectBuilderTest.java
  34. +22
    -42
      proposal/myrmidon/src/testcases/org/apache/myrmidon/components/property/AbstractPropertyResolverTest.java
  35. +4
    -6
      proposal/myrmidon/src/testcases/org/apache/myrmidon/components/property/ClassicPropertyResolverTest.java
  36. +46
    -0
      proposal/myrmidon/src/testcases/org/apache/myrmidon/components/property/DefaultPropertyResolverTest.java
  37. +1
    -3
      proposal/myrmidon/src/testcases/org/apache/myrmidon/components/service/InstantiatingServiceManagerTest.java

+ 3
- 0
proposal/myrmidon/etc/testcases/org/apache/myrmidon/components/builder/bad-version.ant View File

@@ -0,0 +1,3 @@
<!-- Project with invalid version -->
<project version="ant2">
</project>

+ 1
- 0
proposal/myrmidon/etc/testcases/org/apache/myrmidon/components/builder/bad-xml.ant View File

@@ -0,0 +1 @@
this ain't xml.

+ 3
- 0
proposal/myrmidon/etc/testcases/org/apache/myrmidon/components/builder/defaults.ant View File

@@ -0,0 +1,3 @@
<!-- Use all the defaults -->
<project version="2.0">
</project>

+ 3
- 0
proposal/myrmidon/etc/testcases/org/apache/myrmidon/components/builder/mismatched-version.ant View File

@@ -0,0 +1,3 @@
<!-- Project with mismatched version -->
<project version="1.0.2">
</project>

+ 3
- 0
proposal/myrmidon/etc/testcases/org/apache/myrmidon/components/builder/no-version.ant View File

@@ -0,0 +1,3 @@
<!-- Project with no version attribute -->
<project>
</project>

+ 3
- 0
proposal/myrmidon/etc/testcases/org/apache/myrmidon/components/builder/set-base-dir.ant View File

@@ -0,0 +1,3 @@
<!-- Project with a non-default base directory -->
<project version="2.0" basedir="other-base-dir">
</project>

+ 3
- 0
proposal/myrmidon/etc/testcases/org/apache/myrmidon/components/builder/set-default-target.ant View File

@@ -0,0 +1,3 @@
<!-- Project with a non-default default target -->
<project version="2.0" default="some-target">
</project>

+ 3
- 0
proposal/myrmidon/etc/testcases/org/apache/myrmidon/components/builder/set-project-name.ant View File

@@ -0,0 +1,3 @@
<!-- Project with non-default name -->
<project name="some-project" version="2.0">
</project >

+ 76
- 89
proposal/myrmidon/src/java/org/apache/myrmidon/components/builder/DefaultProjectBuilder.java View File

@@ -8,8 +8,6 @@
package org.apache.myrmidon.components.builder;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import javax.xml.parsers.SAXParser;
@@ -23,13 +21,10 @@ import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.configuration.SAXConfigurationHandler;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.myrmidon.framework.conditions.AndCondition;
import org.apache.myrmidon.framework.conditions.Condition;
import org.apache.myrmidon.framework.conditions.IsSetCondition;
import org.apache.myrmidon.framework.conditions.NotCondition;
import org.apache.myrmidon.interfaces.builder.ProjectBuilder;
import org.apache.myrmidon.interfaces.builder.ProjectException;
import org.apache.myrmidon.interfaces.model.DefaultNameValidator;
import org.apache.myrmidon.interfaces.model.Dependency;
import org.apache.myrmidon.interfaces.model.Project;
import org.apache.myrmidon.interfaces.model.Target;
import org.apache.myrmidon.interfaces.model.TypeLib;
@@ -78,31 +73,39 @@ public class DefaultProjectBuilder
private Project build( final File file, final HashMap projects )
throws ProjectException
{
final URL systemID = extractURL( file );
final Project result = (Project)projects.get( systemID.toString() );
if( null != result )
try
{
return result;
}

// Parse the project file
final Configuration configuration = parseProject( systemID );
// Check for cached project
final String systemID = extractURL( file );
final Project result = (Project)projects.get( systemID );
if( null != result )
{
return result;
}

// Build the project model
final DefaultProject project = buildProject( file, configuration );
// Parse the project file
final Configuration configuration = parseProject( systemID );

projects.put( systemID.toString(), project );
// Build the project model and add to cache
final DefaultProject project = buildProject( file, configuration );
projects.put( systemID, project );

//build using all top-level attributes
buildTopLevelProject( project, configuration, projects );
// Build using all top-level attributes
buildTopLevelProject( project, configuration, projects );

return project;
return project;
}
catch( Exception e )
{
final String message = REZ.getString( "ant.project-build.error", file.getAbsolutePath() );
throw new ProjectException( message, e );
}
}

/**
* Parses the project.
*/
private Configuration parseProject( final URL systemID )
private Configuration parseProject( final String systemID )
throws ProjectException
{
try
@@ -117,13 +120,13 @@ public class DefaultProjectBuilder

parser.setContentHandler( handler );
parser.setErrorHandler( handler );
parser.parse( systemID.toString() );
parser.parse( systemID );

return handler.getConfiguration();
}
catch( Exception e )
{
String message = REZ.getString( "ant.project-parse.error" );
final String message = REZ.getString( "ant.project-parse.error" );
throw new ProjectException( message, e );
}
}
@@ -164,7 +167,7 @@ public class DefaultProjectBuilder
File baseDirectory = file.getParentFile();
if( baseDirectoryName != null )
{
baseDirectory = new File( baseDirectory, baseDirectoryName );
baseDirectory = FileUtil.resolveFile( baseDirectory, baseDirectoryName );
}
baseDirectory = baseDirectory.getAbsoluteFile();

@@ -257,7 +260,7 @@ public class DefaultProjectBuilder
{
final String message =
REZ.getString( "ant.malformed.version", versionString );
throw new ProjectException( message, e );
throw new ProjectException( message );
}
}

@@ -338,7 +341,7 @@ public class DefaultProjectBuilder
final Configuration[] implicitTasks =
(Configuration[])implicitTaskList.toArray( new Configuration[ 0 ] );

final Target implicitTarget = new Target( null, implicitTasks, null );
final Target implicitTarget = new Target( implicitTasks, null );
project.setImplicitTarget( implicitTarget );
}

@@ -378,26 +381,30 @@ public class DefaultProjectBuilder
// Build the URL of the referenced projects
final File baseDirectory = project.getBaseDirectory();
final File file = FileUtil.resolveFile( baseDirectory, location );
final String systemID = extractURL( file ).toString();

// Locate the referenced project, building it if necessary
Project other = (Project)projects.get( systemID );
if( null == other )
{
other = build( file, projects );
}
final Project other = build( file, projects );

// Add the reference
project.addProject( name, other );
}

private URL extractURL( final File file ) throws ProjectException
/**
* Validates a project file name, and builds the canonical URL for it.
*/
private String extractURL( final File file ) throws ProjectException
{
if( ! file.isFile() )
{
final String message = REZ.getString( "ant.no-project-file.error" );
throw new ProjectException( message );
}

try
{
return file.toURL();
return file.getCanonicalFile().toURL().toString();
}
catch( MalformedURLException e )
catch( Exception e )
{
final String message = REZ.getString( "ant.project-unexpected.error" );
throw new ProjectException( message, e );
@@ -443,8 +450,6 @@ public class DefaultProjectBuilder
{
final String name = target.getAttribute( "name", null );
final String depends = target.getAttribute( "depends", null );
final String ifCondition = target.getAttribute( "if", null );
final String unlessCondition = target.getAttribute( "unless", null );

verifyTargetName( name, target );

@@ -454,10 +459,8 @@ public class DefaultProjectBuilder
getLogger().debug( message );
}

final String[] dependencies = buildDependsList( depends, target );
final Condition condition = buildCondition( ifCondition, unlessCondition );
final Target defaultTarget =
new Target( condition, target.getChildren(), dependencies );
final Dependency[] dependencies = buildDependsList( depends, target );
final Target defaultTarget = new Target( target.getChildren(), dependencies );

//add target to project
project.addTarget( name, defaultTarget );
@@ -485,70 +488,54 @@ public class DefaultProjectBuilder
}
}

private String[] buildDependsList( final String depends, final Configuration target )
private Dependency[] buildDependsList( final String depends, final Configuration target )
throws ProjectException
{
String[] dependencies = null;

//apply depends attribute
if( null != depends )
if( null == depends )
{
final String[] elements = StringUtil.split( depends, "," );
final ArrayList dependsList = new ArrayList();

for( int i = 0; i < elements.length; i++ )
{
final String dependency = elements[ i ].trim();

if( 0 == dependency.length() )
{
final String message = REZ.getString( "ant.target-bad-dependency.error",
target.getName(),
target.getLocation() );
throw new ProjectException( message );
}

if( getLogger().isDebugEnabled() )
{
final String message = REZ.getString( "ant.target-dependency.notice", dependency );
getLogger().debug( message );
}

dependsList.add( dependency );
}

dependencies = (String[])dependsList.toArray( new String[ 0 ] );
return null;
}
return dependencies;
}

private Condition buildCondition( final String ifCondition,
final String unlessCondition )
{
final AndCondition condition = new AndCondition();
final String[] elements = StringUtil.split( depends, "," );
final ArrayList dependsList = new ArrayList();

// Add the 'if' condition
if( null != ifCondition )
for( int i = 0; i < elements.length; i++ )
{
final String dependency = elements[ i ].trim();

if( getLogger().isDebugEnabled() )
{
final String message = REZ.getString( "ant.target-if.notice", ifCondition );
final String message = REZ.getString( "ant.target-dependency.notice", dependency );
getLogger().debug( message );
}
condition.add( new IsSetCondition( ifCondition ) );
}

// Add the 'unless' condition
if( null != unlessCondition )
{
if( getLogger().isDebugEnabled() )
// Split project->target dependencies
final int sep = dependency.indexOf( "->" );
final String projectName;
final String targetName;
if( sep != -1 )
{
final String message = REZ.getString( "ant.target-unless.notice", unlessCondition );
getLogger().debug( message );
projectName = dependency.substring( 0, sep );
targetName = dependency.substring( sep + 2 );
}
else
{
projectName = null;
targetName = dependency;
}

if( targetName.length() == 0 || ( projectName != null && projectName.length() == 0 ) )
{
final String message = REZ.getString( "ant.target-bad-dependency.error",
target.getName(),
target.getLocation() );
throw new ProjectException( message );
}
condition.add( new NotCondition( new IsSetCondition( unlessCondition ) ) );

dependsList.add( new Dependency( projectName, targetName ) );
}

return condition;
return (Dependency[])dependsList.toArray( new Dependency[dependsList.size() ] );
}
}

+ 6
- 6
proposal/myrmidon/src/java/org/apache/myrmidon/components/builder/Resources.properties View File

@@ -9,11 +9,10 @@ ati.attribue-unquoted.error=Expecting the value of attribute {0} to be enclosed

ant.project-banner.notice=Project {0} base directory: {1}.
ant.target-parse.notice=Parsing target: {0}.
ant.target-if.notice=Target if condition: {0}
ant.target-unless.notice=Target unless condition: {0}
ant.target-dependency.notice=Target dependency: {0}
ant.project-unexpected.error=Unexpected error building project.
ant.project-parse.error=Error parsing project.
ant.project-parse.error=Could not parse project file.
ant.project-build.error=Could not load project from "{0}".
ant.no-project-element.error=Project file must be enclosed in project element.
ant.unknown-toplevel-element.error=Unknown top-level element {0} at {1}.
ant.project-bad-name.error=Invalid project name.
@@ -26,9 +25,10 @@ ant.import-malformed.error=Malformed import at {0}. If name or type attribute is
ant.target-noname.error=Discovered un-named target at {0}.
ant.target-bad-name.error=Target with an invalid name at {0}.
ant.target-bad-dependency.error=Discovered empty dependency in target {0} at {1}.
ant.malformed.version=Malformed version string "{0}" specified in version attribute of project.
ant.version-missing.error=Missing version attribute from project.
ant.bad-version.error=Incompatible build file version detected. Expected {0} but found {1}.
ant.malformed.version=Project has an invalid version "{0}".
ant.version-missing.error=Project has no version attribute.
ant.bad-version.error=Incompatible build file version detected. Expected version {0} but found version {1}.
ant.no-project-file.error=Project file does not exist, or is not a file.

duplicate-project.error=Can not have two projects referenced in a file with the name {0}.
duplicate-target.error=Can not have two targets in a file with the name {0}.

+ 3
- 0
proposal/myrmidon/src/java/org/apache/myrmidon/components/property/Resources.properties View File

@@ -0,0 +1,3 @@
#AbstractPropertyResolver
prop.mismatched-braces.error=Malformed property with mismatched }'s.
prop.missing-value.error=Unable to find "{0}" to expand during property resolution.

+ 1
- 2
proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace/DefaultTaskContext.java View File

@@ -15,9 +15,9 @@ import org.apache.avalon.excalibur.i18n.Resources;
import org.apache.avalon.excalibur.io.FileUtil;
import org.apache.avalon.framework.context.Context;
import org.apache.avalon.framework.context.ContextException;
import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.logger.Logger;
import org.apache.myrmidon.api.TaskContext;
import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.interfaces.model.DefaultNameValidator;
@@ -60,7 +60,6 @@ public class DefaultTaskContext
m_parent = parent;
m_serviceManager = serviceManager;
m_logger = logger;
//m_propertyResolver = (PropertyResolver)getService( PropertyResolver.class );
}

/**


+ 92
- 66
proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace/DefaultWorkspace.java View File

@@ -26,12 +26,12 @@ import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.service.Serviceable;
import org.apache.myrmidon.api.TaskContext;
import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.framework.conditions.Condition;
import org.apache.myrmidon.interfaces.deployer.Deployer;
import org.apache.myrmidon.interfaces.deployer.DeploymentException;
import org.apache.myrmidon.interfaces.deployer.TypeDeployer;
import org.apache.myrmidon.interfaces.executor.ExecutionFrame;
import org.apache.myrmidon.interfaces.executor.Executor;
import org.apache.myrmidon.interfaces.model.Dependency;
import org.apache.myrmidon.interfaces.model.Project;
import org.apache.myrmidon.interfaces.model.Target;
import org.apache.myrmidon.interfaces.model.TypeLib;
@@ -123,9 +123,7 @@ public class DefaultWorkspace

m_listenerSupport.projectStarted( project.getProjectName() );

executeTarget( project, "<init>", project.getImplicitTarget(), entry.getFrame() );

execute( project, target, entry );
executeTarget( entry, target );

m_listenerSupport.projectFinished( project.getProjectName() );
}
@@ -307,105 +305,130 @@ public class DefaultWorkspace
/**
* Helper method to execute a target.
*
* @param project the Project
* @param targetName the name of the target
* @param entry the context
* @param entry the project to execute
* @param targetName the name of the target to execute
* @exception TaskException if an error occurs
*/
private void execute( final Project project,
final String targetName,
final ProjectEntry entry )
private void executeTarget( final ProjectEntry entry,
final String targetName )
throws TaskException
{
final int index = targetName.indexOf( "->" );
if( -1 != index )
// Locate the target
final Target target = entry.getProject().getTarget( targetName );
if( null == target )
{
final String name = targetName.substring( 0, index );
final String otherTargetName = targetName.substring( index + 2 );
final String message = REZ.getString( "no-target.error", targetName );
throw new TaskException( message );
}

final Project otherProject = getProject( name, project );
final ProjectEntry otherEntry = getProjectEntry( otherProject );
executeTarget( entry, targetName, target );
}

//Execute target in referenced project
execute( otherProject, otherTargetName, otherEntry );
/**
* Executes a target. Does not execute the target if it has already been
* executed. Executes the dependencies of the target, before executing
* the target itself.
*
* @param name the name of target
* @param target the target
* @param entry the project in which to execute
* @exception TaskException if an error occurs
*/
private void executeTarget( final ProjectEntry entry,
final String name,
final Target target )
throws TaskException
{
final Project project = entry.getProject();

// Check target state, to see if it has already been executed, and
// to check for dependency cycles
final TargetState state = entry.getTargetState( target );
if( state == TargetState.FINISHED )
{
// Target has been executed
return;
}

final Target target = project.getTarget( targetName );
if( null == target )
if( state == TargetState.TRAVERSING )
{
final String message = REZ.getString( "no-target.error", targetName );
// Cycle in target dependencies
final String message = REZ.getString( "target-dependency-cycle.error", name );
throw new TaskException( message );
}

//add target to list of targets executed
entry.completeTarget( targetName );
// Set state to indicate this target has been started
entry.setTargetState( target, TargetState.TRAVERSING );

// Execute the target's dependencies

// Implicit target first
if( target != project.getImplicitTarget() )
{
executeTarget( entry, "<init>", project.getImplicitTarget() );
}

//execute all dependencies
final String[] dependencies = target.getDependencies();
// Named dependencies
final Dependency[] dependencies = target.getDependencies();
for( int i = 0; i < dependencies.length; i++ )
{
if( !entry.isTargetCompleted( dependencies[ i ] ) )
final Dependency dependency = dependencies[ i ];
final String otherProjectName = dependency.getProjectName();
if( otherProjectName != null )
{
// Dependency in a referenced project
final Project otherProject = getProject( otherProjectName, project );
final ProjectEntry otherEntry = getProjectEntry( otherProject );
executeTarget( otherEntry, dependency.getTargetName() );
}
else
{
execute( project, dependencies[ i ], entry );
// Dependency in this project
executeTarget( entry, dependency.getTargetName() );
}
}

executeTarget( project, targetName, target, entry.getFrame() );
// Now execute the target itself
executeTargetNoDeps( entry, name, target );

// Mark target as complete
entry.setTargetState( target, TargetState.FINISHED );
}

/**
* Method to execute a particular target instance.
* Executes a target. Does not check whether the target has been
* executed already, and does not check that its dependencies have been
* executed.
*
* @param name the name of target
* @param target the target
* @param frame the frame in which to execute
* @exception TaskException if an error occurs
* @param entry the project to execute the target in.
* @param name the name of the target.
* @param target the target itself
*/
private void executeTarget( final Project project,
final String name,
final Target target,
final ExecutionFrame frame )
private void executeTargetNoDeps( final ProjectEntry entry,
final String name,
final Target target )
throws TaskException
{
//notify listeners
final Project project = entry.getProject();

// Notify listeners
m_listenerSupport.targetStarted( project.getProjectName(), name );

//check the condition associated with target.
//if it is not satisfied then skip target
final Condition condition = target.getCondition();
if( null != condition )
if( getLogger().isDebugEnabled() )
{
try
{
final boolean result = condition.evaluate( frame.getContext() );
if( !result )
{
final String message = REZ.getString( "skip-target.notice", name );
getLogger().debug( message );
return;
}
}
catch( final TaskException te )
{
final String message = REZ.getString( "condition-eval.error", name );
throw new TaskException( message, te );
}
final String message = REZ.getString( "exec-target.notice", project.getProjectName(), name );
getLogger().debug( message );
}

final String message = REZ.getString( "exec-target.notice", name );
getLogger().debug( message );

//frame.getContext().setProperty( Project.TARGET, target );

//execute all tasks assciated with target
// Execute all tasks assciated with target
final Configuration[] tasks = target.getTasks();
for( int i = 0; i < tasks.length; i++ )
{
executeTask( tasks[ i ], frame );
executeTask( tasks[ i ], entry.getFrame() );
}

//notify listeners
// Notify listeners
m_listenerSupport.targetFinished();
}

@@ -421,8 +444,11 @@ public class DefaultWorkspace
{
final String name = task.getName();

final String message = REZ.getString( "exec-task.notice", name );
getLogger().debug( message );
if( getLogger().isDebugEnabled() )
{
final String message = REZ.getString( "exec-task.notice", name );
getLogger().debug( message );
}

//is setting name even necessary ???
frame.getContext().setProperty( TaskContext.NAME, name );


+ 17
- 7
proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace/ProjectEntry.java View File

@@ -7,12 +7,15 @@
*/
package org.apache.myrmidon.components.workspace;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import org.apache.myrmidon.interfaces.executor.ExecutionFrame;
import org.apache.myrmidon.interfaces.model.Project;
import org.apache.myrmidon.interfaces.model.Target;

/**
* This contains detaisl for each project that is managed by ProjectManager.
* This contains details for each project that is being executed by a
* DefaultWorkspace.
*
* @author <a href="mailto:peter@apache.org">Peter Donald</a>
* @version $Revision$ $Date$
@@ -21,7 +24,9 @@ final class ProjectEntry
{
private final Project m_project;
private final ExecutionFrame m_frame;
private final ArrayList m_targetsCompleted = new ArrayList();

/** Map from Target -> TargetState for that target. */
private final Map m_targetState = new HashMap();

public ProjectEntry( final Project project,
final ExecutionFrame frame )
@@ -40,13 +45,18 @@ final class ProjectEntry
return m_frame;
}

public boolean isTargetCompleted( final String target )
public TargetState getTargetState( final Target target )
{
return m_targetsCompleted.contains( target );
TargetState state = (TargetState)m_targetState.get( target );
if( state == null )
{
state = TargetState.NOT_STARTED;
}
return state;
}

public void completeTarget( final String target )
public void setTargetState( final Target target, final TargetState state )
{
m_targetsCompleted.add( target );
m_targetState.put( target, state );
}
}

+ 2
- 7
proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace/Resources.properties View File

@@ -5,10 +5,9 @@ bad-deployer-config.error=Error configuring deployer.
bad-frame.error=Error setting up ExecutionFrame.
no-project.error=Project {0} not found.
no-target.error=Target {0} not found.
skip-target.notice=Skipping target {0} as it does not satisfy condition.
condition-eval.error=Error evaluating Condition for target {0}.
exec-target.notice=Executing target {0}.
exec-target.notice=Executing project {0}, target {1}.
exec-task.notice=Executing task {0}.
target-dependency-cycle.error=Cycle in dependencies for target {0}.

#DefaultTaskContext
unknown-prop.error=Unknown property {0}.
@@ -18,7 +17,3 @@ null-resolved-value.error=Value "{0}" resolved to null.
bad-resolve.error=Unable to resolve value "{0}".
bad-find-service.error=Could not find service "{0}".
bad-service-class.error=Find service "{0}" but it was of type {1} where it was expected to be of type {2}.

#AbstractPropertyResolver
prop.mismatched-braces.error=Malformed property with mismatched }'s.
prop.missing-value.error=Unable to find "{0}" to expand during property resolution.

+ 34
- 0
proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace/TargetState.java View File

@@ -0,0 +1,34 @@
/*
* 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.components.workspace;

/**
* An enumerated type that represents the dependency traversal state of a
* target.
*
* @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a>
* @version $Revision$ $Date$
*/
final class TargetState
{
private TargetState()
{
}

/** Target has not been started. */
public final static TargetState NOT_STARTED = new TargetState();

/**
* Target has been started, and the dependencies of the target are being
* traversed.
*/
public final static TargetState TRAVERSING = new TargetState();

/** Target has been completed. */
public final static TargetState FINISHED = new TargetState();
}

+ 1
- 1
proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/builder/ProjectBuilder.java View File

@@ -23,7 +23,7 @@ public interface ProjectBuilder
/**
* build a project from source.
*
* @param source the source
* @param source the project file path.
* @return the constructed Project
* @exception ProjectException if an error occurs
*/


+ 36
- 0
proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/model/Dependency.java View File

@@ -0,0 +1,36 @@
/*
* 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.interfaces.model;

/**
* A dependency for a target.
*
* @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a>
* @version $Revision$ $Date$
*/
public class Dependency
{
private final String m_projectName;
private final String m_targetName;

public Dependency( final String projectName, final String targetName )
{
m_projectName = projectName;
m_targetName = targetName;
}

public String getProjectName()
{
return m_projectName;
}

public String getTargetName()
{
return m_targetName;
}
}

+ 5
- 22
proposal/myrmidon/src/java/org/apache/myrmidon/interfaces/model/Target.java View File

@@ -9,7 +9,6 @@ package org.apache.myrmidon.interfaces.model;

import java.util.ArrayList;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.myrmidon.framework.conditions.Condition;

/**
* Targets in build file.
@@ -21,19 +20,13 @@ public class Target
{
private final ArrayList m_dependencies = new ArrayList();
private final ArrayList m_tasks = new ArrayList();
private final Condition m_condition;

/**
* Constructor taking condition for target.
*
* @param condition the condition
* Constructs a target.
*/
public Target( final Condition condition,
final Configuration[] tasks,
final String[] dependencies )
public Target( final Configuration[] tasks,
final Dependency[] dependencies )
{
m_condition = condition;

for( int i = 0; i < tasks.length; i++ )
{
m_tasks.add( tasks[ i ] );
@@ -48,24 +41,14 @@ public class Target
}
}

/**
* Get condition under which target is executed.
*
* @return the condition for target or null
*/
public final Condition getCondition()
{
return m_condition;
}

/**
* Get dependencies of target
*
* @return the dependency list
*/
public final String[] getDependencies()
public final Dependency[] getDependencies()
{
return (String[])m_dependencies.toArray( new String[ 0 ] );
return (Dependency[])m_dependencies.toArray( new Dependency[ 0 ] );
}

/**


+ 8
- 0
proposal/myrmidon/src/test/org/apache/aut/vfs/AbstractFileSystemTest.java View File

@@ -89,6 +89,14 @@ public abstract class AbstractFileSystemTest
m_charContent = "This is a test file." + eol + "With 2 lines in it." + eol;
}

/**
* Cleans-up test.
*/
protected void tearDown() throws Exception
{
m_manager.close();
}

/**
* Tests resolution of absolute URI.
*/


+ 45
- 21
proposal/myrmidon/src/test/org/apache/myrmidon/AbstractMyrmidonTest.java View File

@@ -11,13 +11,8 @@ import java.io.File;
import java.io.IOException;
import junit.framework.TestCase;
import org.apache.avalon.framework.ExceptionUtil;
import org.apache.avalon.framework.logger.LogKitLogger;
import org.apache.avalon.framework.logger.Logger;
import org.apache.log.Hierarchy;
import org.apache.log.LogTarget;
import org.apache.log.Priority;
import org.apache.log.format.PatternFormatter;
import org.apache.log.output.io.StreamTarget;
import org.apache.myrmidon.frontends.BasicLogger;

/**
* A base class for Myrmidon tests. Provides utility methods for locating
@@ -30,8 +25,7 @@ public abstract class AbstractMyrmidonTest
{
private final File m_testBaseDir;
private final File m_baseDir;

private final static String PATTERN = "[%8.8{category}] %{message}\\n%{throwable}";
private Logger m_logger;

public AbstractMyrmidonTest( String name )
{
@@ -49,10 +43,39 @@ public abstract class AbstractMyrmidonTest
* Locates a test resource, and asserts that the resource exists
*/
protected File getTestResource( final String name )
{
return getTestResource( name, true );
}

/**
* Locates a test resource.
*/
protected File getTestResource( final String name, final boolean mustExist )
{
File file = new File( m_testBaseDir, name );
file = getCanonicalFile( file );
assertTrue( "Test file \"" + file + "\" does not exist.", file.exists() );
if( mustExist )
{
assertTrue( "Test file \"" + file + "\" does not exist.", file.exists() );
}
else
{
assertTrue( "Test file \"" + file + "\" should not exist.", !file.exists() );
}

return file;
}

/**
* Locates a test directory, creating it if it does not exist.
*/
protected File getTestDirectory( final String name )
{
File file = new File( m_testBaseDir, name );
file = getCanonicalFile( file );

assertTrue( "Test directory \"" + file + "\" does not exist or is not a directory.",
file.isDirectory() || file.mkdirs() );
return file;
}

@@ -83,18 +106,13 @@ public abstract class AbstractMyrmidonTest
/**
* Creates a logger.
*/
protected Logger createLogger()
protected Logger getLogger()
{
// Setup a logger
final Priority priority = Priority.WARN;
final org.apache.log.Logger targetLogger = Hierarchy.getDefaultHierarchy().getLoggerFor( "myrmidon" );

final PatternFormatter formatter = new PatternFormatter( PATTERN );
final StreamTarget target = new StreamTarget( System.out, formatter );
targetLogger.setLogTargets( new LogTarget[]{target} );
targetLogger.setPriority( priority );

return new LogKitLogger( targetLogger );
if( m_logger == null )
{
m_logger = new BasicLogger( "[test]", BasicLogger.LEVEL_WARN );
}
return m_logger;
}

/**
@@ -105,6 +123,12 @@ public abstract class AbstractMyrmidonTest
*/
protected void assertSameMessage( final String[] messages, final Throwable throwable )
{
//System.out.println( "exception:" );
//for( Throwable t = throwable; t != null; t = ExceptionUtil.getCause( t, true ) )
//{
// System.out.println( " " + t.getMessage() );
//}

Throwable current = throwable;
for( int i = 0; i < messages.length; i++ )
{
@@ -125,7 +149,7 @@ public abstract class AbstractMyrmidonTest
*/
protected void assertSameMessage( final String message, final Throwable throwable )
{
assertEquals( message, throwable.getMessage() );
assertSameMessage( new String[] { message }, throwable );
}

/**


+ 1
- 1
proposal/myrmidon/src/test/org/apache/myrmidon/AbstractProjectTest.java View File

@@ -54,7 +54,7 @@ public class AbstractProjectTest
// Need to set the context classloader - The default embeddor uses it
Thread.currentThread().setContextClassLoader( getClass().getClassLoader() );

final Logger logger = createLogger();
final Logger logger = getLogger();
m_embeddor = new DefaultEmbeddor();
m_embeddor.enableLogging( logger );



+ 64
- 77
proposal/myrmidon/src/test/org/apache/myrmidon/components/AbstractComponentTest.java View File

@@ -14,7 +14,6 @@ import org.apache.aut.converter.Converter;
import org.apache.avalon.framework.logger.LogEnabled;
import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.framework.service.DefaultServiceManager;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.service.Serviceable;
import org.apache.myrmidon.AbstractMyrmidonTest;
@@ -24,20 +23,19 @@ import org.apache.myrmidon.components.converter.DefaultConverterRegistry;
import org.apache.myrmidon.components.converter.DefaultMasterConverter;
import org.apache.myrmidon.components.deployer.DefaultDeployer;
import org.apache.myrmidon.components.extensions.DefaultExtensionManager;
import org.apache.myrmidon.components.property.DefaultPropertyResolver;
import org.apache.myrmidon.components.role.DefaultRoleManager;
import org.apache.myrmidon.components.type.DefaultTypeManager;
import org.apache.myrmidon.components.property.DefaultPropertyResolver;
import org.apache.myrmidon.interfaces.classloader.ClassLoaderManager;
import org.apache.myrmidon.interfaces.configurer.Configurer;
import org.apache.myrmidon.interfaces.converter.ConverterRegistry;
import org.apache.myrmidon.interfaces.deployer.Deployer;
import org.apache.myrmidon.interfaces.extensions.ExtensionManager;
import org.apache.myrmidon.interfaces.property.PropertyResolver;
import org.apache.myrmidon.interfaces.role.RoleInfo;
import org.apache.myrmidon.interfaces.role.RoleManager;
import org.apache.myrmidon.interfaces.type.DefaultTypeFactory;
import org.apache.myrmidon.interfaces.type.TypeException;
import org.apache.myrmidon.interfaces.type.TypeManager;
import org.apache.myrmidon.interfaces.property.PropertyResolver;

/**
* A base class for tests for the default components.
@@ -48,7 +46,6 @@ public abstract class AbstractComponentTest
extends AbstractMyrmidonTest
{
private DefaultServiceManager m_serviceManager;
private Logger m_logger;

public AbstractComponentTest( final String name )
{
@@ -58,95 +55,85 @@ public abstract class AbstractComponentTest
/**
* Returns the component manager containing the components to test.
*/
protected final ServiceManager getServiceManager()
{
return m_serviceManager;
}

protected final Logger getLogger()
protected final ServiceManager getServiceManager() throws Exception
{
return m_logger;
}

/**
* Returns the type manager.
*/
protected TypeManager getTypeManager()
throws ServiceException
{
return (TypeManager)getServiceManager().lookup( TypeManager.ROLE );
}

/**
* Setup the test case - prepares the set of components.
*/
protected void setUp()
throws Exception
{
m_logger = createLogger();
if( m_serviceManager == null )
{
Logger logger = getLogger();

// Create the components
m_serviceManager = new DefaultServiceManager();
List components = new ArrayList();
// Create the components
m_serviceManager = new DefaultServiceManager();
List components = new ArrayList();

Object component = new DefaultMasterConverter();
m_serviceManager.put( Converter.ROLE, component );
components.add( component );
Object component = new DefaultMasterConverter();
m_serviceManager.put( Converter.ROLE, component );
components.add( component );

component = new DefaultConverterRegistry();
m_serviceManager.put( ConverterRegistry.ROLE, component );
components.add( component );
component = new DefaultConverterRegistry();
m_serviceManager.put( ConverterRegistry.ROLE, component );
components.add( component );

component = new DefaultTypeManager();
m_serviceManager.put( TypeManager.ROLE, component );
components.add( component );
component = new DefaultTypeManager();
m_serviceManager.put( TypeManager.ROLE, component );
components.add( component );

component = new DefaultConfigurer();
m_serviceManager.put( Configurer.ROLE, component );
components.add( component );
component = new DefaultConfigurer();
m_serviceManager.put( Configurer.ROLE, component );
components.add( component );

component = new DefaultDeployer();
m_serviceManager.put( Deployer.ROLE, component );
components.add( component );
component = new DefaultDeployer();
m_serviceManager.put( Deployer.ROLE, component );
components.add( component );

final DefaultClassLoaderManager classLoaderMgr = new DefaultClassLoaderManager();
classLoaderMgr.setBaseClassLoader( getClass().getClassLoader() );
m_serviceManager.put( ClassLoaderManager.ROLE, classLoaderMgr );
components.add( classLoaderMgr );
final DefaultClassLoaderManager classLoaderMgr = new DefaultClassLoaderManager();
classLoaderMgr.setBaseClassLoader( getClass().getClassLoader() );
m_serviceManager.put( ClassLoaderManager.ROLE, classLoaderMgr );
components.add( classLoaderMgr );

component = new DefaultExtensionManager();
m_serviceManager.put( ExtensionManager.ROLE, component );
components.add( component );
component = new DefaultExtensionManager();
m_serviceManager.put( ExtensionManager.ROLE, component );
components.add( component );

component = new DefaultRoleManager();
m_serviceManager.put( RoleManager.ROLE, component );
components.add( component );
component = new DefaultRoleManager();
m_serviceManager.put( RoleManager.ROLE, component );
components.add( component );

component = new DefaultPropertyResolver();
m_serviceManager.put( PropertyResolver.ROLE, component );
components.add( component );
component = new DefaultPropertyResolver();
m_serviceManager.put( PropertyResolver.ROLE, component );
components.add( component );

// Log enable the components
for( Iterator iterator = components.iterator(); iterator.hasNext(); )
{
Object obj = iterator.next();
if( obj instanceof LogEnabled )
// Log enable the components
for( Iterator iterator = components.iterator(); iterator.hasNext(); )
{
final LogEnabled logEnabled = (LogEnabled)obj;
logEnabled.enableLogging( m_logger );
Object obj = iterator.next();
if( obj instanceof LogEnabled )
{
final LogEnabled logEnabled = (LogEnabled)obj;
logEnabled.enableLogging( logger );
}
}
}

// Compose the components
for( Iterator iterator = components.iterator(); iterator.hasNext(); )
{
Object obj = iterator.next();
if( obj instanceof Serviceable )
// Compose the components
for( Iterator iterator = components.iterator(); iterator.hasNext(); )
{
final Serviceable serviceable = (Serviceable)obj;
serviceable.service( m_serviceManager );
Object obj = iterator.next();
if( obj instanceof Serviceable )
{
final Serviceable serviceable = (Serviceable)obj;
serviceable.service( m_serviceManager );
}
}
}
return m_serviceManager;
}

/**
* Returns the type manager.
*/
protected TypeManager getTypeManager()
throws Exception
{
return (TypeManager)getServiceManager().lookup( TypeManager.ROLE );
}

/**
@@ -179,7 +166,7 @@ public abstract class AbstractComponentTest
protected void registerConverter( final Class converterClass,
final Class sourceClass,
final Class destClass )
throws ServiceException, TypeException
throws Exception
{
ConverterRegistry converterRegistry = (ConverterRegistry)getServiceManager().lookup( ConverterRegistry.ROLE );
converterRegistry.registerConverter( converterClass.getName(), sourceClass.getName(), destClass.getName() );


+ 236
- 5
proposal/myrmidon/src/test/org/apache/myrmidon/components/builder/DefaultProjectBuilderTest.java View File

@@ -8,9 +8,13 @@
package org.apache.myrmidon.components.builder;

import java.io.File;
import java.util.Arrays;
import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources;
import org.apache.avalon.excalibur.io.FileUtil;
import org.apache.myrmidon.AbstractMyrmidonTest;
import org.apache.myrmidon.interfaces.builder.ProjectException;
import org.apache.myrmidon.interfaces.model.Project;

/**
* Test cases for {@link DefaultProjectBuilder}.
@@ -22,7 +26,7 @@ public class DefaultProjectBuilderTest
extends AbstractMyrmidonTest
{
private final static Resources REZ
= ResourceManager.getPackageResources( DefaultProjectBuilder.class );
= ResourceManager.getPackageResources( DefaultProjectBuilderTest.class );

private DefaultProjectBuilder m_builder;

@@ -35,11 +39,227 @@ public class DefaultProjectBuilderTest
{
super.setUp();
m_builder = new DefaultProjectBuilder();
m_builder.enableLogging( createLogger() );
m_builder.enableLogging( getLogger() );
}

/**
* Test validation of project and target names.
* Creates a project, with default values set.
*/
private DefaultProject createProject( final File projFile )
{
final DefaultProject project = new DefaultProject();
project.setProjectName( FileUtil.removeExtension( projFile.getName() ) );
project.setBaseDirectory( getTestDirectory( "." ) );
project.setDefaultTargetName( "main" );
return project;
}

/**
* Tests bad project file name.
*/
public void testProjectFileName() throws Exception
{
// Test with a file that does not exist
File projFile = getTestResource( "unknown.ant", false );

try
{
m_builder.build( projFile.getAbsolutePath() );
fail();
}
catch( ProjectException e )
{
final String[] messages =
{
REZ.getString( "ant.project-build.error", projFile.getAbsolutePath() ),
REZ.getString( "ant.no-project-file.error" )
};
assertSameMessage( messages, e );
}

// Test with a directory
projFile = getTestDirectory( "some-dir" );

try
{
m_builder.build( projFile.getAbsolutePath() );
fail();
}
catch( ProjectException e )
{
final String[] messages =
{
REZ.getString( "ant.project-build.error", projFile.getAbsolutePath() ),
REZ.getString( "ant.no-project-file.error" )
};
assertSameMessage( messages, e );
}
}

/**
* Tests error reporting when the project file contains badly formed XML.
*/
public void testBadlyFormedFile() throws Exception
{
final File projFile = getTestResource( "bad-xml.ant" );
try
{
m_builder.build( projFile.getAbsolutePath() );
fail();
}
catch( ProjectException e )
{
final String[] messages =
{
REZ.getString( "ant.project-build.error", projFile.getAbsolutePath() ),
REZ.getString( "ant.project-parse.error" )
};
assertSameMessage( messages, e );
}
}

/**
* Tests building a project with default values for project name, base dir
* and default target.
*/
public void testDefaults() throws Exception
{
// Build project
final File projFile = getTestResource( "defaults.ant" );
Project project = m_builder.build( projFile.getAbsolutePath() );

// Compare against expected project
DefaultProject expected = createProject( projFile );
assertSameProject( expected, project );
}

/**
* Tests setting the project name.
*/
public void testProjectName() throws Exception
{
// Build project
final File projFile = getTestResource( "set-project-name.ant" );
Project project = m_builder.build( projFile.getAbsolutePath() );

// Compare against expected project
DefaultProject expected = createProject( projFile );
expected.setProjectName( "some-project" );
assertSameProject( expected, project );
}

/**
* Tests setting the base directory.
*/
public void testBaseDirectory() throws Exception
{
// Build project
final File projFile = getTestResource( "set-base-dir.ant" );
Project project = m_builder.build( projFile.getAbsolutePath() );

// Compare against expected project
DefaultProject expected = createProject( projFile );
final File baseDir = getTestDirectory( "other-base-dir" );
expected.setBaseDirectory( baseDir );
assertSameProject( expected, project );
}

/**
* Tests setting the default target name.
*/
public void testDefaultTarget() throws Exception
{
// Build project
final File projFile = getTestResource( "set-default-target.ant" );
Project project = m_builder.build( projFile.getAbsolutePath() );

// Compare against expected project
DefaultProject expected = createProject( projFile );
expected.setDefaultTargetName( "some-target" );
assertSameProject( expected, project );
}

/**
* Tests missing, invalid and incompatible project version.
*/
public void testProjectVersion() throws Exception
{
// No version
File projFile = getTestResource( "no-version.ant" );
try
{
m_builder.build( projFile.getAbsolutePath() );
fail();
}
catch( ProjectException e )
{
final String[] messages =
{
REZ.getString( "ant.project-build.error", projFile.getAbsolutePath() ),
REZ.getString( "ant.version-missing.error" )
};
assertSameMessage( messages, e );
}

// Badly formed version
projFile = getTestResource( "bad-version.ant" );
try
{
m_builder.build( projFile.getAbsolutePath() );
fail();
}
catch( ProjectException e )
{
final String[] messages =
{
REZ.getString( "ant.project-build.error", projFile.getAbsolutePath() ),
REZ.getString( "ant.malformed.version", "ant2" )
};
assertSameMessage( messages, e );
}

// Incompatible version
projFile = getTestResource( "mismatched-version.ant" );
try
{
m_builder.build( projFile.getAbsolutePath() );
fail();
}
catch( ProjectException e )
{
final String[] messages =
{
REZ.getString( "ant.project-build.error", projFile.getAbsolutePath() ),
REZ.getString( "ant.bad-version.error", "2.0.0", "1.0.2" )
};
assertSameMessage( messages, e );
}
}

/**
* Asserts that 2 projects are identical.
*/
protected void assertSameProject( final Project expected,
final Project project )
{
assertEquals( expected.getProjectName(), project.getProjectName() );
assertEquals( expected.getBaseDirectory(), project.getBaseDirectory() );
assertEquals( expected.getDefaultTargetName(), project.getDefaultTargetName() );

// TODO - make sure each of the projects are the same
assertTrue( Arrays.equals( expected.getProjectNames(), project.getProjectNames() ) );

// TODO - make sure the implicit targets are the same

// TODO - make sure each of the targets are the same
assertTrue( Arrays.equals( expected.getTargetNames(), project.getTargetNames() ) );

// TODO - implement TypeLib.equals(), or use a comparator
assertTrue( Arrays.equals( expected.getTypeLibs(), project.getTypeLibs() ) );
}

/**
* Tests validation of project and target names.
*/
public void testNameValidation() throws Exception
{
@@ -52,7 +272,12 @@ public class DefaultProjectBuilderTest
}
catch( Exception e )
{
assertSameMessage( REZ.getString( "ant.project-bad-name.error" ), e );
final String[] messages =
{
REZ.getString( "ant.project-build.error", badProjectFile.getAbsolutePath() ),
REZ.getString( "ant.project-bad-name.error" )
};
assertSameMessage( messages, e );
}

// Check bad target name
@@ -64,7 +289,13 @@ public class DefaultProjectBuilderTest
}
catch( Exception e )
{
// TODO - check error message
final String[] messages =
{
REZ.getString( "ant.project-build.error", badTargetFile.getAbsolutePath() ),
// TODO - check error message
null
};
assertSameMessage( messages, e );
}
}
}

proposal/myrmidon/src/test/org/apache/myrmidon/components/workspace/DefaultPropertyResolverTest.java → proposal/myrmidon/src/test/org/apache/myrmidon/components/property/AbstractPropertyResolverTest.java View File

@@ -5,53 +5,51 @@
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.myrmidon.components.workspace;
package org.apache.myrmidon.components.property;

import java.io.File;
import java.util.Date;
import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources;
import org.apache.avalon.framework.context.Context;
import org.apache.myrmidon.AbstractMyrmidonTest;
import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.components.AbstractComponentTest;
import org.apache.myrmidon.components.property.DefaultPropertyResolver;
import org.apache.myrmidon.components.workspace.DefaultTaskContext;
import org.apache.myrmidon.interfaces.property.PropertyResolver;

/**
* Functional tests for {@link DefaultPropertyResolver}.
* General-purpose property resolver test cases.
*
* @author <a href="mailto:darrell@apache.org">Darrell DeBoer</a>
* @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a>
* @version $Revision$ $Date$
*/
public class DefaultPropertyResolverTest
extends AbstractComponentTest
public abstract class AbstractPropertyResolverTest
extends AbstractMyrmidonTest
{
protected final static Resources REZ
= ResourceManager.getPackageResources( DefaultPropertyResolver.class );
= ResourceManager.getPackageResources( AbstractPropertyResolverTest.class );

protected PropertyResolver m_resolver;
protected DefaultTaskContext m_context;

public DefaultPropertyResolverTest( String name )
public AbstractPropertyResolverTest( String name )
{
super( name );
}

protected void setUp() throws Exception
{
super.setUp();

m_resolver = createResolver();

m_context = new DefaultTaskContext( null, getServiceManager(), getLogger() );
m_context = new DefaultTaskContext( null, null, getLogger() );
m_context.setProperty( "intProp", new Integer( 333 ) );
m_context.setProperty( "stringProp", "String property" );
}

protected PropertyResolver createResolver()
{
return new DefaultPropertyResolver();
}
/**
* Creates the resolver to test.
*/
protected abstract PropertyResolver createResolver();

/**
* Test property resolution with various different typed properties.
@@ -73,7 +71,7 @@ public class DefaultPropertyResolverTest
throws Exception
{
m_context.setProperty( "typedProp", propObject );
String propString = propObject.toString();
final String propString = propObject.toString();

doTestResolution( "${typedProp}", propObject, m_context );
doTestResolution( "${typedProp} with following text",
@@ -96,23 +94,6 @@ public class DefaultPropertyResolverTest
doTestResolution( "before ${prop2} between ${prop1} after",
"before value2 between value1 after", m_context );
doTestResolution( "${prop1}-${int1}-${prop2}", "value1-123-value2", m_context );

}

/**
* Tests handing undefined property.
*/
public void testUndefinedProp() throws Exception
{
String undefinedProp = "undefinedProperty";
doTestFailure( "${" + undefinedProp + "}",
REZ.getString( "prop.missing-value.error", undefinedProp ),
m_context );

//TODO - "" should be disallowed as a property name
doTestFailure( "${}",
REZ.getString( "prop.missing-value.error", "" ),
m_context );
}

/**
@@ -131,18 +112,17 @@ public class DefaultPropertyResolverTest
/* TODO - need to handle these cases. */
// testFailure( "${bad${}", "", m_context );
// testFailure( "${ }", "", m_context );

}

/**
* Resolves the property using the supplied context, and checks the result.
*/
protected void doTestResolution( String value,
Object expected,
Context context )
protected void doTestResolution( final String value,
final Object expected,
final Context context )
throws Exception
{
Object resolved = m_resolver.resolveProperties( value, context );
final Object resolved = m_resolver.resolveProperties( value, context );

assertEquals( expected, resolved );
}
@@ -151,9 +131,9 @@ public class DefaultPropertyResolverTest
* Attempts to resolve the value using the supplied context, expecting to
* fail with the supplied error message.
*/
protected void doTestFailure( String value,
String expectedErrorMessage,
Context context )
protected void doTestFailure( final String value,
final String expectedErrorMessage,
final Context context )
{
try
{

proposal/myrmidon/src/test/org/apache/myrmidon/components/workspace/ClassicPropertyResolverTest.java → proposal/myrmidon/src/test/org/apache/myrmidon/components/property/ClassicPropertyResolverTest.java View File

@@ -5,19 +5,18 @@
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.myrmidon.components.workspace;
package org.apache.myrmidon.components.property;

import org.apache.myrmidon.interfaces.property.PropertyResolver;
import org.apache.myrmidon.components.property.ClassicPropertyResolver;

/**
* A test for {@link ClassicPropertyResolver}
* A test for {@link ClassicPropertyResolver}.
*
* @author <a href="mailto:darrell@apache.org">Darrell DeBoer</a>
* @version $Revision$ $Date$
*/
public class ClassicPropertyResolverTest
extends DefaultPropertyResolverTest
extends AbstractPropertyResolverTest
{
public ClassicPropertyResolverTest( String name )
{
@@ -34,8 +33,7 @@ public class ClassicPropertyResolverTest
*/
public void testUndefinedProp() throws Exception
{
String undefinedProp = "undefinedProperty";

final String undefinedProp = "undefinedProperty";
final String propRef = "${" + undefinedProp + "}";
doTestResolution( propRef, propRef, m_context );
}

+ 46
- 0
proposal/myrmidon/src/test/org/apache/myrmidon/components/property/DefaultPropertyResolverTest.java View File

@@ -0,0 +1,46 @@
/*
* 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.components.property;

import org.apache.myrmidon.interfaces.property.PropertyResolver;

/**
* Functional tests for {@link DefaultPropertyResolver}.
*
* @author <a href="mailto:darrell@apache.org">Darrell DeBoer</a>
* @version $Revision$ $Date$
*/
public class DefaultPropertyResolverTest
extends AbstractPropertyResolverTest
{
public DefaultPropertyResolverTest( String name )
{
super( name );
}

protected PropertyResolver createResolver()
{
return new DefaultPropertyResolver();
}

/**
* Tests handing undefined property.
*/
public void testUndefinedProp() throws Exception
{
final String undefinedProp = "undefinedProperty";
doTestFailure( "${" + undefinedProp + "}",
REZ.getString( "prop.missing-value.error", undefinedProp ),
m_context );

//TODO - "" should be disallowed as a property name
doTestFailure( "${}",
REZ.getString( "prop.missing-value.error", "" ),
m_context );
}
}

+ 1
- 3
proposal/myrmidon/src/test/org/apache/myrmidon/components/service/InstantiatingServiceManagerTest.java View File

@@ -44,11 +44,9 @@ public class InstantiatingServiceManagerTest
protected void setUp()
throws Exception
{
super.setUp();

// Set-up the service manager
m_serviceManager = new InstantiatingServiceManager();
m_serviceManager.enableLogging( createLogger() );
m_serviceManager.enableLogging( getLogger() );
m_serviceManager.service( getServiceManager() );
m_serviceManager.parameterize( m_parameters );
}


+ 8
- 0
proposal/myrmidon/src/testcases/org/apache/aut/vfs/AbstractFileSystemTest.java View File

@@ -89,6 +89,14 @@ public abstract class AbstractFileSystemTest
m_charContent = "This is a test file." + eol + "With 2 lines in it." + eol;
}

/**
* Cleans-up test.
*/
protected void tearDown() throws Exception
{
m_manager.close();
}

/**
* Tests resolution of absolute URI.
*/


+ 45
- 21
proposal/myrmidon/src/testcases/org/apache/myrmidon/AbstractMyrmidonTest.java View File

@@ -11,13 +11,8 @@ import java.io.File;
import java.io.IOException;
import junit.framework.TestCase;
import org.apache.avalon.framework.ExceptionUtil;
import org.apache.avalon.framework.logger.LogKitLogger;
import org.apache.avalon.framework.logger.Logger;
import org.apache.log.Hierarchy;
import org.apache.log.LogTarget;
import org.apache.log.Priority;
import org.apache.log.format.PatternFormatter;
import org.apache.log.output.io.StreamTarget;
import org.apache.myrmidon.frontends.BasicLogger;

/**
* A base class for Myrmidon tests. Provides utility methods for locating
@@ -30,8 +25,7 @@ public abstract class AbstractMyrmidonTest
{
private final File m_testBaseDir;
private final File m_baseDir;

private final static String PATTERN = "[%8.8{category}] %{message}\\n%{throwable}";
private Logger m_logger;

public AbstractMyrmidonTest( String name )
{
@@ -49,10 +43,39 @@ public abstract class AbstractMyrmidonTest
* Locates a test resource, and asserts that the resource exists
*/
protected File getTestResource( final String name )
{
return getTestResource( name, true );
}

/**
* Locates a test resource.
*/
protected File getTestResource( final String name, final boolean mustExist )
{
File file = new File( m_testBaseDir, name );
file = getCanonicalFile( file );
assertTrue( "Test file \"" + file + "\" does not exist.", file.exists() );
if( mustExist )
{
assertTrue( "Test file \"" + file + "\" does not exist.", file.exists() );
}
else
{
assertTrue( "Test file \"" + file + "\" should not exist.", !file.exists() );
}

return file;
}

/**
* Locates a test directory, creating it if it does not exist.
*/
protected File getTestDirectory( final String name )
{
File file = new File( m_testBaseDir, name );
file = getCanonicalFile( file );

assertTrue( "Test directory \"" + file + "\" does not exist or is not a directory.",
file.isDirectory() || file.mkdirs() );
return file;
}

@@ -83,18 +106,13 @@ public abstract class AbstractMyrmidonTest
/**
* Creates a logger.
*/
protected Logger createLogger()
protected Logger getLogger()
{
// Setup a logger
final Priority priority = Priority.WARN;
final org.apache.log.Logger targetLogger = Hierarchy.getDefaultHierarchy().getLoggerFor( "myrmidon" );

final PatternFormatter formatter = new PatternFormatter( PATTERN );
final StreamTarget target = new StreamTarget( System.out, formatter );
targetLogger.setLogTargets( new LogTarget[]{target} );
targetLogger.setPriority( priority );

return new LogKitLogger( targetLogger );
if( m_logger == null )
{
m_logger = new BasicLogger( "[test]", BasicLogger.LEVEL_WARN );
}
return m_logger;
}

/**
@@ -105,6 +123,12 @@ public abstract class AbstractMyrmidonTest
*/
protected void assertSameMessage( final String[] messages, final Throwable throwable )
{
//System.out.println( "exception:" );
//for( Throwable t = throwable; t != null; t = ExceptionUtil.getCause( t, true ) )
//{
// System.out.println( " " + t.getMessage() );
//}

Throwable current = throwable;
for( int i = 0; i < messages.length; i++ )
{
@@ -125,7 +149,7 @@ public abstract class AbstractMyrmidonTest
*/
protected void assertSameMessage( final String message, final Throwable throwable )
{
assertEquals( message, throwable.getMessage() );
assertSameMessage( new String[] { message }, throwable );
}

/**


+ 1
- 1
proposal/myrmidon/src/testcases/org/apache/myrmidon/AbstractProjectTest.java View File

@@ -54,7 +54,7 @@ public class AbstractProjectTest
// Need to set the context classloader - The default embeddor uses it
Thread.currentThread().setContextClassLoader( getClass().getClassLoader() );

final Logger logger = createLogger();
final Logger logger = getLogger();
m_embeddor = new DefaultEmbeddor();
m_embeddor.enableLogging( logger );



+ 64
- 77
proposal/myrmidon/src/testcases/org/apache/myrmidon/components/AbstractComponentTest.java View File

@@ -14,7 +14,6 @@ import org.apache.aut.converter.Converter;
import org.apache.avalon.framework.logger.LogEnabled;
import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.framework.service.DefaultServiceManager;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.service.Serviceable;
import org.apache.myrmidon.AbstractMyrmidonTest;
@@ -24,20 +23,19 @@ import org.apache.myrmidon.components.converter.DefaultConverterRegistry;
import org.apache.myrmidon.components.converter.DefaultMasterConverter;
import org.apache.myrmidon.components.deployer.DefaultDeployer;
import org.apache.myrmidon.components.extensions.DefaultExtensionManager;
import org.apache.myrmidon.components.property.DefaultPropertyResolver;
import org.apache.myrmidon.components.role.DefaultRoleManager;
import org.apache.myrmidon.components.type.DefaultTypeManager;
import org.apache.myrmidon.components.property.DefaultPropertyResolver;
import org.apache.myrmidon.interfaces.classloader.ClassLoaderManager;
import org.apache.myrmidon.interfaces.configurer.Configurer;
import org.apache.myrmidon.interfaces.converter.ConverterRegistry;
import org.apache.myrmidon.interfaces.deployer.Deployer;
import org.apache.myrmidon.interfaces.extensions.ExtensionManager;
import org.apache.myrmidon.interfaces.property.PropertyResolver;
import org.apache.myrmidon.interfaces.role.RoleInfo;
import org.apache.myrmidon.interfaces.role.RoleManager;
import org.apache.myrmidon.interfaces.type.DefaultTypeFactory;
import org.apache.myrmidon.interfaces.type.TypeException;
import org.apache.myrmidon.interfaces.type.TypeManager;
import org.apache.myrmidon.interfaces.property.PropertyResolver;

/**
* A base class for tests for the default components.
@@ -48,7 +46,6 @@ public abstract class AbstractComponentTest
extends AbstractMyrmidonTest
{
private DefaultServiceManager m_serviceManager;
private Logger m_logger;

public AbstractComponentTest( final String name )
{
@@ -58,95 +55,85 @@ public abstract class AbstractComponentTest
/**
* Returns the component manager containing the components to test.
*/
protected final ServiceManager getServiceManager()
{
return m_serviceManager;
}

protected final Logger getLogger()
protected final ServiceManager getServiceManager() throws Exception
{
return m_logger;
}

/**
* Returns the type manager.
*/
protected TypeManager getTypeManager()
throws ServiceException
{
return (TypeManager)getServiceManager().lookup( TypeManager.ROLE );
}

/**
* Setup the test case - prepares the set of components.
*/
protected void setUp()
throws Exception
{
m_logger = createLogger();
if( m_serviceManager == null )
{
Logger logger = getLogger();

// Create the components
m_serviceManager = new DefaultServiceManager();
List components = new ArrayList();
// Create the components
m_serviceManager = new DefaultServiceManager();
List components = new ArrayList();

Object component = new DefaultMasterConverter();
m_serviceManager.put( Converter.ROLE, component );
components.add( component );
Object component = new DefaultMasterConverter();
m_serviceManager.put( Converter.ROLE, component );
components.add( component );

component = new DefaultConverterRegistry();
m_serviceManager.put( ConverterRegistry.ROLE, component );
components.add( component );
component = new DefaultConverterRegistry();
m_serviceManager.put( ConverterRegistry.ROLE, component );
components.add( component );

component = new DefaultTypeManager();
m_serviceManager.put( TypeManager.ROLE, component );
components.add( component );
component = new DefaultTypeManager();
m_serviceManager.put( TypeManager.ROLE, component );
components.add( component );

component = new DefaultConfigurer();
m_serviceManager.put( Configurer.ROLE, component );
components.add( component );
component = new DefaultConfigurer();
m_serviceManager.put( Configurer.ROLE, component );
components.add( component );

component = new DefaultDeployer();
m_serviceManager.put( Deployer.ROLE, component );
components.add( component );
component = new DefaultDeployer();
m_serviceManager.put( Deployer.ROLE, component );
components.add( component );

final DefaultClassLoaderManager classLoaderMgr = new DefaultClassLoaderManager();
classLoaderMgr.setBaseClassLoader( getClass().getClassLoader() );
m_serviceManager.put( ClassLoaderManager.ROLE, classLoaderMgr );
components.add( classLoaderMgr );
final DefaultClassLoaderManager classLoaderMgr = new DefaultClassLoaderManager();
classLoaderMgr.setBaseClassLoader( getClass().getClassLoader() );
m_serviceManager.put( ClassLoaderManager.ROLE, classLoaderMgr );
components.add( classLoaderMgr );

component = new DefaultExtensionManager();
m_serviceManager.put( ExtensionManager.ROLE, component );
components.add( component );
component = new DefaultExtensionManager();
m_serviceManager.put( ExtensionManager.ROLE, component );
components.add( component );

component = new DefaultRoleManager();
m_serviceManager.put( RoleManager.ROLE, component );
components.add( component );
component = new DefaultRoleManager();
m_serviceManager.put( RoleManager.ROLE, component );
components.add( component );

component = new DefaultPropertyResolver();
m_serviceManager.put( PropertyResolver.ROLE, component );
components.add( component );
component = new DefaultPropertyResolver();
m_serviceManager.put( PropertyResolver.ROLE, component );
components.add( component );

// Log enable the components
for( Iterator iterator = components.iterator(); iterator.hasNext(); )
{
Object obj = iterator.next();
if( obj instanceof LogEnabled )
// Log enable the components
for( Iterator iterator = components.iterator(); iterator.hasNext(); )
{
final LogEnabled logEnabled = (LogEnabled)obj;
logEnabled.enableLogging( m_logger );
Object obj = iterator.next();
if( obj instanceof LogEnabled )
{
final LogEnabled logEnabled = (LogEnabled)obj;
logEnabled.enableLogging( logger );
}
}
}

// Compose the components
for( Iterator iterator = components.iterator(); iterator.hasNext(); )
{
Object obj = iterator.next();
if( obj instanceof Serviceable )
// Compose the components
for( Iterator iterator = components.iterator(); iterator.hasNext(); )
{
final Serviceable serviceable = (Serviceable)obj;
serviceable.service( m_serviceManager );
Object obj = iterator.next();
if( obj instanceof Serviceable )
{
final Serviceable serviceable = (Serviceable)obj;
serviceable.service( m_serviceManager );
}
}
}
return m_serviceManager;
}

/**
* Returns the type manager.
*/
protected TypeManager getTypeManager()
throws Exception
{
return (TypeManager)getServiceManager().lookup( TypeManager.ROLE );
}

/**
@@ -179,7 +166,7 @@ public abstract class AbstractComponentTest
protected void registerConverter( final Class converterClass,
final Class sourceClass,
final Class destClass )
throws ServiceException, TypeException
throws Exception
{
ConverterRegistry converterRegistry = (ConverterRegistry)getServiceManager().lookup( ConverterRegistry.ROLE );
converterRegistry.registerConverter( converterClass.getName(), sourceClass.getName(), destClass.getName() );


+ 236
- 5
proposal/myrmidon/src/testcases/org/apache/myrmidon/components/builder/DefaultProjectBuilderTest.java View File

@@ -8,9 +8,13 @@
package org.apache.myrmidon.components.builder;

import java.io.File;
import java.util.Arrays;
import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources;
import org.apache.avalon.excalibur.io.FileUtil;
import org.apache.myrmidon.AbstractMyrmidonTest;
import org.apache.myrmidon.interfaces.builder.ProjectException;
import org.apache.myrmidon.interfaces.model.Project;

/**
* Test cases for {@link DefaultProjectBuilder}.
@@ -22,7 +26,7 @@ public class DefaultProjectBuilderTest
extends AbstractMyrmidonTest
{
private final static Resources REZ
= ResourceManager.getPackageResources( DefaultProjectBuilder.class );
= ResourceManager.getPackageResources( DefaultProjectBuilderTest.class );

private DefaultProjectBuilder m_builder;

@@ -35,11 +39,227 @@ public class DefaultProjectBuilderTest
{
super.setUp();
m_builder = new DefaultProjectBuilder();
m_builder.enableLogging( createLogger() );
m_builder.enableLogging( getLogger() );
}

/**
* Test validation of project and target names.
* Creates a project, with default values set.
*/
private DefaultProject createProject( final File projFile )
{
final DefaultProject project = new DefaultProject();
project.setProjectName( FileUtil.removeExtension( projFile.getName() ) );
project.setBaseDirectory( getTestDirectory( "." ) );
project.setDefaultTargetName( "main" );
return project;
}

/**
* Tests bad project file name.
*/
public void testProjectFileName() throws Exception
{
// Test with a file that does not exist
File projFile = getTestResource( "unknown.ant", false );

try
{
m_builder.build( projFile.getAbsolutePath() );
fail();
}
catch( ProjectException e )
{
final String[] messages =
{
REZ.getString( "ant.project-build.error", projFile.getAbsolutePath() ),
REZ.getString( "ant.no-project-file.error" )
};
assertSameMessage( messages, e );
}

// Test with a directory
projFile = getTestDirectory( "some-dir" );

try
{
m_builder.build( projFile.getAbsolutePath() );
fail();
}
catch( ProjectException e )
{
final String[] messages =
{
REZ.getString( "ant.project-build.error", projFile.getAbsolutePath() ),
REZ.getString( "ant.no-project-file.error" )
};
assertSameMessage( messages, e );
}
}

/**
* Tests error reporting when the project file contains badly formed XML.
*/
public void testBadlyFormedFile() throws Exception
{
final File projFile = getTestResource( "bad-xml.ant" );
try
{
m_builder.build( projFile.getAbsolutePath() );
fail();
}
catch( ProjectException e )
{
final String[] messages =
{
REZ.getString( "ant.project-build.error", projFile.getAbsolutePath() ),
REZ.getString( "ant.project-parse.error" )
};
assertSameMessage( messages, e );
}
}

/**
* Tests building a project with default values for project name, base dir
* and default target.
*/
public void testDefaults() throws Exception
{
// Build project
final File projFile = getTestResource( "defaults.ant" );
Project project = m_builder.build( projFile.getAbsolutePath() );

// Compare against expected project
DefaultProject expected = createProject( projFile );
assertSameProject( expected, project );
}

/**
* Tests setting the project name.
*/
public void testProjectName() throws Exception
{
// Build project
final File projFile = getTestResource( "set-project-name.ant" );
Project project = m_builder.build( projFile.getAbsolutePath() );

// Compare against expected project
DefaultProject expected = createProject( projFile );
expected.setProjectName( "some-project" );
assertSameProject( expected, project );
}

/**
* Tests setting the base directory.
*/
public void testBaseDirectory() throws Exception
{
// Build project
final File projFile = getTestResource( "set-base-dir.ant" );
Project project = m_builder.build( projFile.getAbsolutePath() );

// Compare against expected project
DefaultProject expected = createProject( projFile );
final File baseDir = getTestDirectory( "other-base-dir" );
expected.setBaseDirectory( baseDir );
assertSameProject( expected, project );
}

/**
* Tests setting the default target name.
*/
public void testDefaultTarget() throws Exception
{
// Build project
final File projFile = getTestResource( "set-default-target.ant" );
Project project = m_builder.build( projFile.getAbsolutePath() );

// Compare against expected project
DefaultProject expected = createProject( projFile );
expected.setDefaultTargetName( "some-target" );
assertSameProject( expected, project );
}

/**
* Tests missing, invalid and incompatible project version.
*/
public void testProjectVersion() throws Exception
{
// No version
File projFile = getTestResource( "no-version.ant" );
try
{
m_builder.build( projFile.getAbsolutePath() );
fail();
}
catch( ProjectException e )
{
final String[] messages =
{
REZ.getString( "ant.project-build.error", projFile.getAbsolutePath() ),
REZ.getString( "ant.version-missing.error" )
};
assertSameMessage( messages, e );
}

// Badly formed version
projFile = getTestResource( "bad-version.ant" );
try
{
m_builder.build( projFile.getAbsolutePath() );
fail();
}
catch( ProjectException e )
{
final String[] messages =
{
REZ.getString( "ant.project-build.error", projFile.getAbsolutePath() ),
REZ.getString( "ant.malformed.version", "ant2" )
};
assertSameMessage( messages, e );
}

// Incompatible version
projFile = getTestResource( "mismatched-version.ant" );
try
{
m_builder.build( projFile.getAbsolutePath() );
fail();
}
catch( ProjectException e )
{
final String[] messages =
{
REZ.getString( "ant.project-build.error", projFile.getAbsolutePath() ),
REZ.getString( "ant.bad-version.error", "2.0.0", "1.0.2" )
};
assertSameMessage( messages, e );
}
}

/**
* Asserts that 2 projects are identical.
*/
protected void assertSameProject( final Project expected,
final Project project )
{
assertEquals( expected.getProjectName(), project.getProjectName() );
assertEquals( expected.getBaseDirectory(), project.getBaseDirectory() );
assertEquals( expected.getDefaultTargetName(), project.getDefaultTargetName() );

// TODO - make sure each of the projects are the same
assertTrue( Arrays.equals( expected.getProjectNames(), project.getProjectNames() ) );

// TODO - make sure the implicit targets are the same

// TODO - make sure each of the targets are the same
assertTrue( Arrays.equals( expected.getTargetNames(), project.getTargetNames() ) );

// TODO - implement TypeLib.equals(), or use a comparator
assertTrue( Arrays.equals( expected.getTypeLibs(), project.getTypeLibs() ) );
}

/**
* Tests validation of project and target names.
*/
public void testNameValidation() throws Exception
{
@@ -52,7 +272,12 @@ public class DefaultProjectBuilderTest
}
catch( Exception e )
{
assertSameMessage( REZ.getString( "ant.project-bad-name.error" ), e );
final String[] messages =
{
REZ.getString( "ant.project-build.error", badProjectFile.getAbsolutePath() ),
REZ.getString( "ant.project-bad-name.error" )
};
assertSameMessage( messages, e );
}

// Check bad target name
@@ -64,7 +289,13 @@ public class DefaultProjectBuilderTest
}
catch( Exception e )
{
// TODO - check error message
final String[] messages =
{
REZ.getString( "ant.project-build.error", badTargetFile.getAbsolutePath() ),
// TODO - check error message
null
};
assertSameMessage( messages, e );
}
}
}

proposal/myrmidon/src/testcases/org/apache/myrmidon/components/workspace/DefaultPropertyResolverTest.java → proposal/myrmidon/src/testcases/org/apache/myrmidon/components/property/AbstractPropertyResolverTest.java View File

@@ -5,53 +5,51 @@
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.myrmidon.components.workspace;
package org.apache.myrmidon.components.property;

import java.io.File;
import java.util.Date;
import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources;
import org.apache.avalon.framework.context.Context;
import org.apache.myrmidon.AbstractMyrmidonTest;
import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.components.AbstractComponentTest;
import org.apache.myrmidon.components.property.DefaultPropertyResolver;
import org.apache.myrmidon.components.workspace.DefaultTaskContext;
import org.apache.myrmidon.interfaces.property.PropertyResolver;

/**
* Functional tests for {@link DefaultPropertyResolver}.
* General-purpose property resolver test cases.
*
* @author <a href="mailto:darrell@apache.org">Darrell DeBoer</a>
* @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a>
* @version $Revision$ $Date$
*/
public class DefaultPropertyResolverTest
extends AbstractComponentTest
public abstract class AbstractPropertyResolverTest
extends AbstractMyrmidonTest
{
protected final static Resources REZ
= ResourceManager.getPackageResources( DefaultPropertyResolver.class );
= ResourceManager.getPackageResources( AbstractPropertyResolverTest.class );

protected PropertyResolver m_resolver;
protected DefaultTaskContext m_context;

public DefaultPropertyResolverTest( String name )
public AbstractPropertyResolverTest( String name )
{
super( name );
}

protected void setUp() throws Exception
{
super.setUp();

m_resolver = createResolver();

m_context = new DefaultTaskContext( null, getServiceManager(), getLogger() );
m_context = new DefaultTaskContext( null, null, getLogger() );
m_context.setProperty( "intProp", new Integer( 333 ) );
m_context.setProperty( "stringProp", "String property" );
}

protected PropertyResolver createResolver()
{
return new DefaultPropertyResolver();
}
/**
* Creates the resolver to test.
*/
protected abstract PropertyResolver createResolver();

/**
* Test property resolution with various different typed properties.
@@ -73,7 +71,7 @@ public class DefaultPropertyResolverTest
throws Exception
{
m_context.setProperty( "typedProp", propObject );
String propString = propObject.toString();
final String propString = propObject.toString();

doTestResolution( "${typedProp}", propObject, m_context );
doTestResolution( "${typedProp} with following text",
@@ -96,23 +94,6 @@ public class DefaultPropertyResolverTest
doTestResolution( "before ${prop2} between ${prop1} after",
"before value2 between value1 after", m_context );
doTestResolution( "${prop1}-${int1}-${prop2}", "value1-123-value2", m_context );

}

/**
* Tests handing undefined property.
*/
public void testUndefinedProp() throws Exception
{
String undefinedProp = "undefinedProperty";
doTestFailure( "${" + undefinedProp + "}",
REZ.getString( "prop.missing-value.error", undefinedProp ),
m_context );

//TODO - "" should be disallowed as a property name
doTestFailure( "${}",
REZ.getString( "prop.missing-value.error", "" ),
m_context );
}

/**
@@ -131,18 +112,17 @@ public class DefaultPropertyResolverTest
/* TODO - need to handle these cases. */
// testFailure( "${bad${}", "", m_context );
// testFailure( "${ }", "", m_context );

}

/**
* Resolves the property using the supplied context, and checks the result.
*/
protected void doTestResolution( String value,
Object expected,
Context context )
protected void doTestResolution( final String value,
final Object expected,
final Context context )
throws Exception
{
Object resolved = m_resolver.resolveProperties( value, context );
final Object resolved = m_resolver.resolveProperties( value, context );

assertEquals( expected, resolved );
}
@@ -151,9 +131,9 @@ public class DefaultPropertyResolverTest
* Attempts to resolve the value using the supplied context, expecting to
* fail with the supplied error message.
*/
protected void doTestFailure( String value,
String expectedErrorMessage,
Context context )
protected void doTestFailure( final String value,
final String expectedErrorMessage,
final Context context )
{
try
{

proposal/myrmidon/src/testcases/org/apache/myrmidon/components/workspace/ClassicPropertyResolverTest.java → proposal/myrmidon/src/testcases/org/apache/myrmidon/components/property/ClassicPropertyResolverTest.java View File

@@ -5,19 +5,18 @@
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.myrmidon.components.workspace;
package org.apache.myrmidon.components.property;

import org.apache.myrmidon.interfaces.property.PropertyResolver;
import org.apache.myrmidon.components.property.ClassicPropertyResolver;

/**
* A test for {@link ClassicPropertyResolver}
* A test for {@link ClassicPropertyResolver}.
*
* @author <a href="mailto:darrell@apache.org">Darrell DeBoer</a>
* @version $Revision$ $Date$
*/
public class ClassicPropertyResolverTest
extends DefaultPropertyResolverTest
extends AbstractPropertyResolverTest
{
public ClassicPropertyResolverTest( String name )
{
@@ -34,8 +33,7 @@ public class ClassicPropertyResolverTest
*/
public void testUndefinedProp() throws Exception
{
String undefinedProp = "undefinedProperty";

final String undefinedProp = "undefinedProperty";
final String propRef = "${" + undefinedProp + "}";
doTestResolution( propRef, propRef, m_context );
}

+ 46
- 0
proposal/myrmidon/src/testcases/org/apache/myrmidon/components/property/DefaultPropertyResolverTest.java View File

@@ -0,0 +1,46 @@
/*
* 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.components.property;

import org.apache.myrmidon.interfaces.property.PropertyResolver;

/**
* Functional tests for {@link DefaultPropertyResolver}.
*
* @author <a href="mailto:darrell@apache.org">Darrell DeBoer</a>
* @version $Revision$ $Date$
*/
public class DefaultPropertyResolverTest
extends AbstractPropertyResolverTest
{
public DefaultPropertyResolverTest( String name )
{
super( name );
}

protected PropertyResolver createResolver()
{
return new DefaultPropertyResolver();
}

/**
* Tests handing undefined property.
*/
public void testUndefinedProp() throws Exception
{
final String undefinedProp = "undefinedProperty";
doTestFailure( "${" + undefinedProp + "}",
REZ.getString( "prop.missing-value.error", undefinedProp ),
m_context );

//TODO - "" should be disallowed as a property name
doTestFailure( "${}",
REZ.getString( "prop.missing-value.error", "" ),
m_context );
}
}

+ 1
- 3
proposal/myrmidon/src/testcases/org/apache/myrmidon/components/service/InstantiatingServiceManagerTest.java View File

@@ -44,11 +44,9 @@ public class InstantiatingServiceManagerTest
protected void setUp()
throws Exception
{
super.setUp();

// Set-up the service manager
m_serviceManager = new InstantiatingServiceManager();
m_serviceManager.enableLogging( createLogger() );
m_serviceManager.enableLogging( getLogger() );
m_serviceManager.service( getServiceManager() );
m_serviceManager.parameterize( m_parameters );
}


Loading…
Cancel
Save