* 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-ffa450edef68master
@@ -0,0 +1,3 @@ | |||||
<!-- Project with invalid version --> | |||||
<project version="ant2"> | |||||
</project> |
@@ -0,0 +1 @@ | |||||
this ain't xml. |
@@ -0,0 +1,3 @@ | |||||
<!-- Use all the defaults --> | |||||
<project version="2.0"> | |||||
</project> |
@@ -0,0 +1,3 @@ | |||||
<!-- Project with mismatched version --> | |||||
<project version="1.0.2"> | |||||
</project> |
@@ -0,0 +1,3 @@ | |||||
<!-- Project with no version attribute --> | |||||
<project> | |||||
</project> |
@@ -0,0 +1,3 @@ | |||||
<!-- Project with a non-default base directory --> | |||||
<project version="2.0" basedir="other-base-dir"> | |||||
</project> |
@@ -0,0 +1,3 @@ | |||||
<!-- Project with a non-default default target --> | |||||
<project version="2.0" default="some-target"> | |||||
</project> |
@@ -0,0 +1,3 @@ | |||||
<!-- Project with non-default name --> | |||||
<project name="some-project" version="2.0"> | |||||
</project > |
@@ -8,8 +8,6 @@ | |||||
package org.apache.myrmidon.components.builder; | package org.apache.myrmidon.components.builder; | ||||
import java.io.File; | import java.io.File; | ||||
import java.net.MalformedURLException; | |||||
import java.net.URL; | |||||
import java.util.ArrayList; | import java.util.ArrayList; | ||||
import java.util.HashMap; | import java.util.HashMap; | ||||
import javax.xml.parsers.SAXParser; | 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.ConfigurationException; | ||||
import org.apache.avalon.framework.configuration.SAXConfigurationHandler; | import org.apache.avalon.framework.configuration.SAXConfigurationHandler; | ||||
import org.apache.avalon.framework.logger.AbstractLogEnabled; | 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.ProjectBuilder; | ||||
import org.apache.myrmidon.interfaces.builder.ProjectException; | import org.apache.myrmidon.interfaces.builder.ProjectException; | ||||
import org.apache.myrmidon.interfaces.model.DefaultNameValidator; | 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.Project; | ||||
import org.apache.myrmidon.interfaces.model.Target; | import org.apache.myrmidon.interfaces.model.Target; | ||||
import org.apache.myrmidon.interfaces.model.TypeLib; | import org.apache.myrmidon.interfaces.model.TypeLib; | ||||
@@ -78,31 +73,39 @@ public class DefaultProjectBuilder | |||||
private Project build( final File file, final HashMap projects ) | private Project build( final File file, final HashMap projects ) | ||||
throws ProjectException | 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. | * Parses the project. | ||||
*/ | */ | ||||
private Configuration parseProject( final URL systemID ) | |||||
private Configuration parseProject( final String systemID ) | |||||
throws ProjectException | throws ProjectException | ||||
{ | { | ||||
try | try | ||||
@@ -117,13 +120,13 @@ public class DefaultProjectBuilder | |||||
parser.setContentHandler( handler ); | parser.setContentHandler( handler ); | ||||
parser.setErrorHandler( handler ); | parser.setErrorHandler( handler ); | ||||
parser.parse( systemID.toString() ); | |||||
parser.parse( systemID ); | |||||
return handler.getConfiguration(); | return handler.getConfiguration(); | ||||
} | } | ||||
catch( Exception e ) | 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 ); | throw new ProjectException( message, e ); | ||||
} | } | ||||
} | } | ||||
@@ -164,7 +167,7 @@ public class DefaultProjectBuilder | |||||
File baseDirectory = file.getParentFile(); | File baseDirectory = file.getParentFile(); | ||||
if( baseDirectoryName != null ) | if( baseDirectoryName != null ) | ||||
{ | { | ||||
baseDirectory = new File( baseDirectory, baseDirectoryName ); | |||||
baseDirectory = FileUtil.resolveFile( baseDirectory, baseDirectoryName ); | |||||
} | } | ||||
baseDirectory = baseDirectory.getAbsoluteFile(); | baseDirectory = baseDirectory.getAbsoluteFile(); | ||||
@@ -257,7 +260,7 @@ public class DefaultProjectBuilder | |||||
{ | { | ||||
final String message = | final String message = | ||||
REZ.getString( "ant.malformed.version", versionString ); | 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 = | final Configuration[] implicitTasks = | ||||
(Configuration[])implicitTaskList.toArray( new Configuration[ 0 ] ); | (Configuration[])implicitTaskList.toArray( new Configuration[ 0 ] ); | ||||
final Target implicitTarget = new Target( null, implicitTasks, null ); | |||||
final Target implicitTarget = new Target( implicitTasks, null ); | |||||
project.setImplicitTarget( implicitTarget ); | project.setImplicitTarget( implicitTarget ); | ||||
} | } | ||||
@@ -378,26 +381,30 @@ public class DefaultProjectBuilder | |||||
// Build the URL of the referenced projects | // Build the URL of the referenced projects | ||||
final File baseDirectory = project.getBaseDirectory(); | final File baseDirectory = project.getBaseDirectory(); | ||||
final File file = FileUtil.resolveFile( baseDirectory, location ); | final File file = FileUtil.resolveFile( baseDirectory, location ); | ||||
final String systemID = extractURL( file ).toString(); | |||||
// Locate the referenced project, building it if necessary | // 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 | // Add the reference | ||||
project.addProject( name, other ); | 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 | try | ||||
{ | { | ||||
return file.toURL(); | |||||
return file.getCanonicalFile().toURL().toString(); | |||||
} | } | ||||
catch( MalformedURLException e ) | |||||
catch( Exception e ) | |||||
{ | { | ||||
final String message = REZ.getString( "ant.project-unexpected.error" ); | final String message = REZ.getString( "ant.project-unexpected.error" ); | ||||
throw new ProjectException( message, e ); | throw new ProjectException( message, e ); | ||||
@@ -443,8 +450,6 @@ public class DefaultProjectBuilder | |||||
{ | { | ||||
final String name = target.getAttribute( "name", null ); | final String name = target.getAttribute( "name", null ); | ||||
final String depends = target.getAttribute( "depends", 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 ); | verifyTargetName( name, target ); | ||||
@@ -454,10 +459,8 @@ public class DefaultProjectBuilder | |||||
getLogger().debug( message ); | 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 | //add target to project | ||||
project.addTarget( name, defaultTarget ); | 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 | throws ProjectException | ||||
{ | { | ||||
String[] dependencies = null; | |||||
//apply depends attribute | //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() ) | 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 ); | 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() ] ); | |||||
} | } | ||||
} | } |
@@ -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.project-banner.notice=Project {0} base directory: {1}. | ||||
ant.target-parse.notice=Parsing target: {0}. | 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.target-dependency.notice=Target dependency: {0} | ||||
ant.project-unexpected.error=Unexpected error building project. | 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.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.unknown-toplevel-element.error=Unknown top-level element {0} at {1}. | ||||
ant.project-bad-name.error=Invalid project name. | 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-noname.error=Discovered un-named target at {0}. | ||||
ant.target-bad-name.error=Target with an invalid name 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.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-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}. | duplicate-target.error=Can not have two targets in a file with the name {0}. |
@@ -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. |
@@ -15,9 +15,9 @@ import org.apache.avalon.excalibur.i18n.Resources; | |||||
import org.apache.avalon.excalibur.io.FileUtil; | import org.apache.avalon.excalibur.io.FileUtil; | ||||
import org.apache.avalon.framework.context.Context; | import org.apache.avalon.framework.context.Context; | ||||
import org.apache.avalon.framework.context.ContextException; | 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.ServiceException; | ||||
import org.apache.avalon.framework.service.ServiceManager; | 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.TaskContext; | ||||
import org.apache.myrmidon.api.TaskException; | import org.apache.myrmidon.api.TaskException; | ||||
import org.apache.myrmidon.interfaces.model.DefaultNameValidator; | import org.apache.myrmidon.interfaces.model.DefaultNameValidator; | ||||
@@ -60,7 +60,6 @@ public class DefaultTaskContext | |||||
m_parent = parent; | m_parent = parent; | ||||
m_serviceManager = serviceManager; | m_serviceManager = serviceManager; | ||||
m_logger = logger; | m_logger = logger; | ||||
//m_propertyResolver = (PropertyResolver)getService( PropertyResolver.class ); | |||||
} | } | ||||
/** | /** | ||||
@@ -26,12 +26,12 @@ import org.apache.avalon.framework.service.ServiceManager; | |||||
import org.apache.avalon.framework.service.Serviceable; | import org.apache.avalon.framework.service.Serviceable; | ||||
import org.apache.myrmidon.api.TaskContext; | import org.apache.myrmidon.api.TaskContext; | ||||
import org.apache.myrmidon.api.TaskException; | 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.Deployer; | ||||
import org.apache.myrmidon.interfaces.deployer.DeploymentException; | import org.apache.myrmidon.interfaces.deployer.DeploymentException; | ||||
import org.apache.myrmidon.interfaces.deployer.TypeDeployer; | import org.apache.myrmidon.interfaces.deployer.TypeDeployer; | ||||
import org.apache.myrmidon.interfaces.executor.ExecutionFrame; | import org.apache.myrmidon.interfaces.executor.ExecutionFrame; | ||||
import org.apache.myrmidon.interfaces.executor.Executor; | 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.Project; | ||||
import org.apache.myrmidon.interfaces.model.Target; | import org.apache.myrmidon.interfaces.model.Target; | ||||
import org.apache.myrmidon.interfaces.model.TypeLib; | import org.apache.myrmidon.interfaces.model.TypeLib; | ||||
@@ -123,9 +123,7 @@ public class DefaultWorkspace | |||||
m_listenerSupport.projectStarted( project.getProjectName() ); | m_listenerSupport.projectStarted( project.getProjectName() ); | ||||
executeTarget( project, "<init>", project.getImplicitTarget(), entry.getFrame() ); | |||||
execute( project, target, entry ); | |||||
executeTarget( entry, target ); | |||||
m_listenerSupport.projectFinished( project.getProjectName() ); | m_listenerSupport.projectFinished( project.getProjectName() ); | ||||
} | } | ||||
@@ -307,105 +305,130 @@ public class DefaultWorkspace | |||||
/** | /** | ||||
* Helper method to execute a target. | * 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 | * @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 | 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; | 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 ); | 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++ ) | 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 | throws TaskException | ||||
{ | { | ||||
//notify listeners | |||||
final Project project = entry.getProject(); | |||||
// Notify listeners | |||||
m_listenerSupport.targetStarted( project.getProjectName(), name ); | 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 ); | //frame.getContext().setProperty( Project.TARGET, target ); | ||||
//execute all tasks assciated with target | |||||
// Execute all tasks assciated with target | |||||
final Configuration[] tasks = target.getTasks(); | final Configuration[] tasks = target.getTasks(); | ||||
for( int i = 0; i < tasks.length; i++ ) | for( int i = 0; i < tasks.length; i++ ) | ||||
{ | { | ||||
executeTask( tasks[ i ], frame ); | |||||
executeTask( tasks[ i ], entry.getFrame() ); | |||||
} | } | ||||
//notify listeners | |||||
// Notify listeners | |||||
m_listenerSupport.targetFinished(); | m_listenerSupport.targetFinished(); | ||||
} | } | ||||
@@ -421,8 +444,11 @@ public class DefaultWorkspace | |||||
{ | { | ||||
final String name = task.getName(); | 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 ??? | //is setting name even necessary ??? | ||||
frame.getContext().setProperty( TaskContext.NAME, name ); | frame.getContext().setProperty( TaskContext.NAME, name ); | ||||
@@ -7,12 +7,15 @@ | |||||
*/ | */ | ||||
package org.apache.myrmidon.components.workspace; | 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.executor.ExecutionFrame; | ||||
import org.apache.myrmidon.interfaces.model.Project; | 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> | * @author <a href="mailto:peter@apache.org">Peter Donald</a> | ||||
* @version $Revision$ $Date$ | * @version $Revision$ $Date$ | ||||
@@ -21,7 +24,9 @@ final class ProjectEntry | |||||
{ | { | ||||
private final Project m_project; | private final Project m_project; | ||||
private final ExecutionFrame m_frame; | 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, | public ProjectEntry( final Project project, | ||||
final ExecutionFrame frame ) | final ExecutionFrame frame ) | ||||
@@ -40,13 +45,18 @@ final class ProjectEntry | |||||
return m_frame; | 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 ); | |||||
} | } | ||||
} | } |
@@ -5,10 +5,9 @@ bad-deployer-config.error=Error configuring deployer. | |||||
bad-frame.error=Error setting up ExecutionFrame. | bad-frame.error=Error setting up ExecutionFrame. | ||||
no-project.error=Project {0} not found. | no-project.error=Project {0} not found. | ||||
no-target.error=Target {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}. | exec-task.notice=Executing task {0}. | ||||
target-dependency-cycle.error=Cycle in dependencies for target {0}. | |||||
#DefaultTaskContext | #DefaultTaskContext | ||||
unknown-prop.error=Unknown property {0}. | 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-resolve.error=Unable to resolve value "{0}". | ||||
bad-find-service.error=Could not find service "{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}. | 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. |
@@ -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(); | |||||
} |
@@ -23,7 +23,7 @@ public interface ProjectBuilder | |||||
/** | /** | ||||
* build a project from source. | * build a project from source. | ||||
* | * | ||||
* @param source the source | |||||
* @param source the project file path. | |||||
* @return the constructed Project | * @return the constructed Project | ||||
* @exception ProjectException if an error occurs | * @exception ProjectException if an error occurs | ||||
*/ | */ | ||||
@@ -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; | |||||
} | |||||
} |
@@ -9,7 +9,6 @@ package org.apache.myrmidon.interfaces.model; | |||||
import java.util.ArrayList; | import java.util.ArrayList; | ||||
import org.apache.avalon.framework.configuration.Configuration; | import org.apache.avalon.framework.configuration.Configuration; | ||||
import org.apache.myrmidon.framework.conditions.Condition; | |||||
/** | /** | ||||
* Targets in build file. | * Targets in build file. | ||||
@@ -21,19 +20,13 @@ public class Target | |||||
{ | { | ||||
private final ArrayList m_dependencies = new ArrayList(); | private final ArrayList m_dependencies = new ArrayList(); | ||||
private final ArrayList m_tasks = 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++ ) | for( int i = 0; i < tasks.length; i++ ) | ||||
{ | { | ||||
m_tasks.add( tasks[ 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 | * Get dependencies of target | ||||
* | * | ||||
* @return the dependency list | * @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 ] ); | |||||
} | } | ||||
/** | /** | ||||
@@ -89,6 +89,14 @@ public abstract class AbstractFileSystemTest | |||||
m_charContent = "This is a test file." + eol + "With 2 lines in it." + eol; | 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. | * Tests resolution of absolute URI. | ||||
*/ | */ | ||||
@@ -11,13 +11,8 @@ import java.io.File; | |||||
import java.io.IOException; | import java.io.IOException; | ||||
import junit.framework.TestCase; | import junit.framework.TestCase; | ||||
import org.apache.avalon.framework.ExceptionUtil; | import org.apache.avalon.framework.ExceptionUtil; | ||||
import org.apache.avalon.framework.logger.LogKitLogger; | |||||
import org.apache.avalon.framework.logger.Logger; | 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 | * 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_testBaseDir; | ||||
private final File m_baseDir; | private final File m_baseDir; | ||||
private final static String PATTERN = "[%8.8{category}] %{message}\\n%{throwable}"; | |||||
private Logger m_logger; | |||||
public AbstractMyrmidonTest( String name ) | public AbstractMyrmidonTest( String name ) | ||||
{ | { | ||||
@@ -49,10 +43,39 @@ public abstract class AbstractMyrmidonTest | |||||
* Locates a test resource, and asserts that the resource exists | * Locates a test resource, and asserts that the resource exists | ||||
*/ | */ | ||||
protected File getTestResource( final String name ) | 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 file = new File( m_testBaseDir, name ); | ||||
file = getCanonicalFile( file ); | 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; | return file; | ||||
} | } | ||||
@@ -83,18 +106,13 @@ public abstract class AbstractMyrmidonTest | |||||
/** | /** | ||||
* Creates a logger. | * 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 ) | 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; | Throwable current = throwable; | ||||
for( int i = 0; i < messages.length; i++ ) | 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 ) | protected void assertSameMessage( final String message, final Throwable throwable ) | ||||
{ | { | ||||
assertEquals( message, throwable.getMessage() ); | |||||
assertSameMessage( new String[] { message }, throwable ); | |||||
} | } | ||||
/** | /** | ||||
@@ -54,7 +54,7 @@ public class AbstractProjectTest | |||||
// Need to set the context classloader - The default embeddor uses it | // Need to set the context classloader - The default embeddor uses it | ||||
Thread.currentThread().setContextClassLoader( getClass().getClassLoader() ); | Thread.currentThread().setContextClassLoader( getClass().getClassLoader() ); | ||||
final Logger logger = createLogger(); | |||||
final Logger logger = getLogger(); | |||||
m_embeddor = new DefaultEmbeddor(); | m_embeddor = new DefaultEmbeddor(); | ||||
m_embeddor.enableLogging( logger ); | m_embeddor.enableLogging( logger ); | ||||
@@ -14,7 +14,6 @@ import org.apache.aut.converter.Converter; | |||||
import org.apache.avalon.framework.logger.LogEnabled; | import org.apache.avalon.framework.logger.LogEnabled; | ||||
import org.apache.avalon.framework.logger.Logger; | import org.apache.avalon.framework.logger.Logger; | ||||
import org.apache.avalon.framework.service.DefaultServiceManager; | 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.ServiceManager; | ||||
import org.apache.avalon.framework.service.Serviceable; | import org.apache.avalon.framework.service.Serviceable; | ||||
import org.apache.myrmidon.AbstractMyrmidonTest; | 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.converter.DefaultMasterConverter; | ||||
import org.apache.myrmidon.components.deployer.DefaultDeployer; | import org.apache.myrmidon.components.deployer.DefaultDeployer; | ||||
import org.apache.myrmidon.components.extensions.DefaultExtensionManager; | 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.role.DefaultRoleManager; | ||||
import org.apache.myrmidon.components.type.DefaultTypeManager; | 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.classloader.ClassLoaderManager; | ||||
import org.apache.myrmidon.interfaces.configurer.Configurer; | import org.apache.myrmidon.interfaces.configurer.Configurer; | ||||
import org.apache.myrmidon.interfaces.converter.ConverterRegistry; | import org.apache.myrmidon.interfaces.converter.ConverterRegistry; | ||||
import org.apache.myrmidon.interfaces.deployer.Deployer; | import org.apache.myrmidon.interfaces.deployer.Deployer; | ||||
import org.apache.myrmidon.interfaces.extensions.ExtensionManager; | 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.RoleInfo; | ||||
import org.apache.myrmidon.interfaces.role.RoleManager; | import org.apache.myrmidon.interfaces.role.RoleManager; | ||||
import org.apache.myrmidon.interfaces.type.DefaultTypeFactory; | 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.type.TypeManager; | ||||
import org.apache.myrmidon.interfaces.property.PropertyResolver; | |||||
/** | /** | ||||
* A base class for tests for the default components. | * A base class for tests for the default components. | ||||
@@ -48,7 +46,6 @@ public abstract class AbstractComponentTest | |||||
extends AbstractMyrmidonTest | extends AbstractMyrmidonTest | ||||
{ | { | ||||
private DefaultServiceManager m_serviceManager; | private DefaultServiceManager m_serviceManager; | ||||
private Logger m_logger; | |||||
public AbstractComponentTest( final String name ) | public AbstractComponentTest( final String name ) | ||||
{ | { | ||||
@@ -58,95 +55,85 @@ public abstract class AbstractComponentTest | |||||
/** | /** | ||||
* Returns the component manager containing the components to test. | * 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, | protected void registerConverter( final Class converterClass, | ||||
final Class sourceClass, | final Class sourceClass, | ||||
final Class destClass ) | final Class destClass ) | ||||
throws ServiceException, TypeException | |||||
throws Exception | |||||
{ | { | ||||
ConverterRegistry converterRegistry = (ConverterRegistry)getServiceManager().lookup( ConverterRegistry.ROLE ); | ConverterRegistry converterRegistry = (ConverterRegistry)getServiceManager().lookup( ConverterRegistry.ROLE ); | ||||
converterRegistry.registerConverter( converterClass.getName(), sourceClass.getName(), destClass.getName() ); | converterRegistry.registerConverter( converterClass.getName(), sourceClass.getName(), destClass.getName() ); | ||||
@@ -8,9 +8,13 @@ | |||||
package org.apache.myrmidon.components.builder; | package org.apache.myrmidon.components.builder; | ||||
import java.io.File; | import java.io.File; | ||||
import java.util.Arrays; | |||||
import org.apache.avalon.excalibur.i18n.ResourceManager; | import org.apache.avalon.excalibur.i18n.ResourceManager; | ||||
import org.apache.avalon.excalibur.i18n.Resources; | import org.apache.avalon.excalibur.i18n.Resources; | ||||
import org.apache.avalon.excalibur.io.FileUtil; | |||||
import org.apache.myrmidon.AbstractMyrmidonTest; | import org.apache.myrmidon.AbstractMyrmidonTest; | ||||
import org.apache.myrmidon.interfaces.builder.ProjectException; | |||||
import org.apache.myrmidon.interfaces.model.Project; | |||||
/** | /** | ||||
* Test cases for {@link DefaultProjectBuilder}. | * Test cases for {@link DefaultProjectBuilder}. | ||||
@@ -22,7 +26,7 @@ public class DefaultProjectBuilderTest | |||||
extends AbstractMyrmidonTest | extends AbstractMyrmidonTest | ||||
{ | { | ||||
private final static Resources REZ | private final static Resources REZ | ||||
= ResourceManager.getPackageResources( DefaultProjectBuilder.class ); | |||||
= ResourceManager.getPackageResources( DefaultProjectBuilderTest.class ); | |||||
private DefaultProjectBuilder m_builder; | private DefaultProjectBuilder m_builder; | ||||
@@ -35,11 +39,227 @@ public class DefaultProjectBuilderTest | |||||
{ | { | ||||
super.setUp(); | super.setUp(); | ||||
m_builder = new DefaultProjectBuilder(); | 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 | public void testNameValidation() throws Exception | ||||
{ | { | ||||
@@ -52,7 +272,12 @@ public class DefaultProjectBuilderTest | |||||
} | } | ||||
catch( Exception e ) | 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 | // Check bad target name | ||||
@@ -64,7 +289,13 @@ public class DefaultProjectBuilderTest | |||||
} | } | ||||
catch( Exception e ) | 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 ); | |||||
} | } | ||||
} | } | ||||
} | } |
@@ -5,53 +5,51 @@ | |||||
* version 1.1, a copy of which has been included with this distribution in | * version 1.1, a copy of which has been included with this distribution in | ||||
* the LICENSE.txt file. | * the LICENSE.txt file. | ||||
*/ | */ | ||||
package org.apache.myrmidon.components.workspace; | |||||
package org.apache.myrmidon.components.property; | |||||
import java.io.File; | import java.io.File; | ||||
import java.util.Date; | import java.util.Date; | ||||
import org.apache.avalon.excalibur.i18n.ResourceManager; | import org.apache.avalon.excalibur.i18n.ResourceManager; | ||||
import org.apache.avalon.excalibur.i18n.Resources; | import org.apache.avalon.excalibur.i18n.Resources; | ||||
import org.apache.avalon.framework.context.Context; | import org.apache.avalon.framework.context.Context; | ||||
import org.apache.myrmidon.AbstractMyrmidonTest; | |||||
import org.apache.myrmidon.api.TaskException; | 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; | 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$ | * @version $Revision$ $Date$ | ||||
*/ | */ | ||||
public class DefaultPropertyResolverTest | |||||
extends AbstractComponentTest | |||||
public abstract class AbstractPropertyResolverTest | |||||
extends AbstractMyrmidonTest | |||||
{ | { | ||||
protected final static Resources REZ | protected final static Resources REZ | ||||
= ResourceManager.getPackageResources( DefaultPropertyResolver.class ); | |||||
= ResourceManager.getPackageResources( AbstractPropertyResolverTest.class ); | |||||
protected PropertyResolver m_resolver; | protected PropertyResolver m_resolver; | ||||
protected DefaultTaskContext m_context; | protected DefaultTaskContext m_context; | ||||
public DefaultPropertyResolverTest( String name ) | |||||
public AbstractPropertyResolverTest( String name ) | |||||
{ | { | ||||
super( name ); | super( name ); | ||||
} | } | ||||
protected void setUp() throws Exception | protected void setUp() throws Exception | ||||
{ | { | ||||
super.setUp(); | |||||
m_resolver = createResolver(); | 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( "intProp", new Integer( 333 ) ); | ||||
m_context.setProperty( "stringProp", "String property" ); | 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. | * Test property resolution with various different typed properties. | ||||
@@ -73,7 +71,7 @@ public class DefaultPropertyResolverTest | |||||
throws Exception | throws Exception | ||||
{ | { | ||||
m_context.setProperty( "typedProp", propObject ); | m_context.setProperty( "typedProp", propObject ); | ||||
String propString = propObject.toString(); | |||||
final String propString = propObject.toString(); | |||||
doTestResolution( "${typedProp}", propObject, m_context ); | doTestResolution( "${typedProp}", propObject, m_context ); | ||||
doTestResolution( "${typedProp} with following text", | doTestResolution( "${typedProp} with following text", | ||||
@@ -96,23 +94,6 @@ public class DefaultPropertyResolverTest | |||||
doTestResolution( "before ${prop2} between ${prop1} after", | doTestResolution( "before ${prop2} between ${prop1} after", | ||||
"before value2 between value1 after", m_context ); | "before value2 between value1 after", m_context ); | ||||
doTestResolution( "${prop1}-${int1}-${prop2}", "value1-123-value2", 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. */ | /* TODO - need to handle these cases. */ | ||||
// testFailure( "${bad${}", "", m_context ); | // testFailure( "${bad${}", "", m_context ); | ||||
// testFailure( "${ }", "", m_context ); | // testFailure( "${ }", "", m_context ); | ||||
} | } | ||||
/** | /** | ||||
* Resolves the property using the supplied context, and checks the result. | * 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 | throws Exception | ||||
{ | { | ||||
Object resolved = m_resolver.resolveProperties( value, context ); | |||||
final Object resolved = m_resolver.resolveProperties( value, context ); | |||||
assertEquals( expected, resolved ); | assertEquals( expected, resolved ); | ||||
} | } | ||||
@@ -151,9 +131,9 @@ public class DefaultPropertyResolverTest | |||||
* Attempts to resolve the value using the supplied context, expecting to | * Attempts to resolve the value using the supplied context, expecting to | ||||
* fail with the supplied error message. | * 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 | try | ||||
{ | { |
@@ -5,19 +5,18 @@ | |||||
* version 1.1, a copy of which has been included with this distribution in | * version 1.1, a copy of which has been included with this distribution in | ||||
* the LICENSE.txt file. | * 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.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> | * @author <a href="mailto:darrell@apache.org">Darrell DeBoer</a> | ||||
* @version $Revision$ $Date$ | * @version $Revision$ $Date$ | ||||
*/ | */ | ||||
public class ClassicPropertyResolverTest | public class ClassicPropertyResolverTest | ||||
extends DefaultPropertyResolverTest | |||||
extends AbstractPropertyResolverTest | |||||
{ | { | ||||
public ClassicPropertyResolverTest( String name ) | public ClassicPropertyResolverTest( String name ) | ||||
{ | { | ||||
@@ -34,8 +33,7 @@ public class ClassicPropertyResolverTest | |||||
*/ | */ | ||||
public void testUndefinedProp() throws Exception | public void testUndefinedProp() throws Exception | ||||
{ | { | ||||
String undefinedProp = "undefinedProperty"; | |||||
final String undefinedProp = "undefinedProperty"; | |||||
final String propRef = "${" + undefinedProp + "}"; | final String propRef = "${" + undefinedProp + "}"; | ||||
doTestResolution( propRef, propRef, m_context ); | doTestResolution( propRef, propRef, m_context ); | ||||
} | } |
@@ -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 ); | |||||
} | |||||
} |
@@ -44,11 +44,9 @@ public class InstantiatingServiceManagerTest | |||||
protected void setUp() | protected void setUp() | ||||
throws Exception | throws Exception | ||||
{ | { | ||||
super.setUp(); | |||||
// Set-up the service manager | // Set-up the service manager | ||||
m_serviceManager = new InstantiatingServiceManager(); | m_serviceManager = new InstantiatingServiceManager(); | ||||
m_serviceManager.enableLogging( createLogger() ); | |||||
m_serviceManager.enableLogging( getLogger() ); | |||||
m_serviceManager.service( getServiceManager() ); | m_serviceManager.service( getServiceManager() ); | ||||
m_serviceManager.parameterize( m_parameters ); | m_serviceManager.parameterize( m_parameters ); | ||||
} | } | ||||
@@ -89,6 +89,14 @@ public abstract class AbstractFileSystemTest | |||||
m_charContent = "This is a test file." + eol + "With 2 lines in it." + eol; | 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. | * Tests resolution of absolute URI. | ||||
*/ | */ | ||||
@@ -11,13 +11,8 @@ import java.io.File; | |||||
import java.io.IOException; | import java.io.IOException; | ||||
import junit.framework.TestCase; | import junit.framework.TestCase; | ||||
import org.apache.avalon.framework.ExceptionUtil; | import org.apache.avalon.framework.ExceptionUtil; | ||||
import org.apache.avalon.framework.logger.LogKitLogger; | |||||
import org.apache.avalon.framework.logger.Logger; | 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 | * 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_testBaseDir; | ||||
private final File m_baseDir; | private final File m_baseDir; | ||||
private final static String PATTERN = "[%8.8{category}] %{message}\\n%{throwable}"; | |||||
private Logger m_logger; | |||||
public AbstractMyrmidonTest( String name ) | public AbstractMyrmidonTest( String name ) | ||||
{ | { | ||||
@@ -49,10 +43,39 @@ public abstract class AbstractMyrmidonTest | |||||
* Locates a test resource, and asserts that the resource exists | * Locates a test resource, and asserts that the resource exists | ||||
*/ | */ | ||||
protected File getTestResource( final String name ) | 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 file = new File( m_testBaseDir, name ); | ||||
file = getCanonicalFile( file ); | 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; | return file; | ||||
} | } | ||||
@@ -83,18 +106,13 @@ public abstract class AbstractMyrmidonTest | |||||
/** | /** | ||||
* Creates a logger. | * 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 ) | 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; | Throwable current = throwable; | ||||
for( int i = 0; i < messages.length; i++ ) | 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 ) | protected void assertSameMessage( final String message, final Throwable throwable ) | ||||
{ | { | ||||
assertEquals( message, throwable.getMessage() ); | |||||
assertSameMessage( new String[] { message }, throwable ); | |||||
} | } | ||||
/** | /** | ||||
@@ -54,7 +54,7 @@ public class AbstractProjectTest | |||||
// Need to set the context classloader - The default embeddor uses it | // Need to set the context classloader - The default embeddor uses it | ||||
Thread.currentThread().setContextClassLoader( getClass().getClassLoader() ); | Thread.currentThread().setContextClassLoader( getClass().getClassLoader() ); | ||||
final Logger logger = createLogger(); | |||||
final Logger logger = getLogger(); | |||||
m_embeddor = new DefaultEmbeddor(); | m_embeddor = new DefaultEmbeddor(); | ||||
m_embeddor.enableLogging( logger ); | m_embeddor.enableLogging( logger ); | ||||
@@ -14,7 +14,6 @@ import org.apache.aut.converter.Converter; | |||||
import org.apache.avalon.framework.logger.LogEnabled; | import org.apache.avalon.framework.logger.LogEnabled; | ||||
import org.apache.avalon.framework.logger.Logger; | import org.apache.avalon.framework.logger.Logger; | ||||
import org.apache.avalon.framework.service.DefaultServiceManager; | 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.ServiceManager; | ||||
import org.apache.avalon.framework.service.Serviceable; | import org.apache.avalon.framework.service.Serviceable; | ||||
import org.apache.myrmidon.AbstractMyrmidonTest; | 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.converter.DefaultMasterConverter; | ||||
import org.apache.myrmidon.components.deployer.DefaultDeployer; | import org.apache.myrmidon.components.deployer.DefaultDeployer; | ||||
import org.apache.myrmidon.components.extensions.DefaultExtensionManager; | 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.role.DefaultRoleManager; | ||||
import org.apache.myrmidon.components.type.DefaultTypeManager; | 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.classloader.ClassLoaderManager; | ||||
import org.apache.myrmidon.interfaces.configurer.Configurer; | import org.apache.myrmidon.interfaces.configurer.Configurer; | ||||
import org.apache.myrmidon.interfaces.converter.ConverterRegistry; | import org.apache.myrmidon.interfaces.converter.ConverterRegistry; | ||||
import org.apache.myrmidon.interfaces.deployer.Deployer; | import org.apache.myrmidon.interfaces.deployer.Deployer; | ||||
import org.apache.myrmidon.interfaces.extensions.ExtensionManager; | 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.RoleInfo; | ||||
import org.apache.myrmidon.interfaces.role.RoleManager; | import org.apache.myrmidon.interfaces.role.RoleManager; | ||||
import org.apache.myrmidon.interfaces.type.DefaultTypeFactory; | 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.type.TypeManager; | ||||
import org.apache.myrmidon.interfaces.property.PropertyResolver; | |||||
/** | /** | ||||
* A base class for tests for the default components. | * A base class for tests for the default components. | ||||
@@ -48,7 +46,6 @@ public abstract class AbstractComponentTest | |||||
extends AbstractMyrmidonTest | extends AbstractMyrmidonTest | ||||
{ | { | ||||
private DefaultServiceManager m_serviceManager; | private DefaultServiceManager m_serviceManager; | ||||
private Logger m_logger; | |||||
public AbstractComponentTest( final String name ) | public AbstractComponentTest( final String name ) | ||||
{ | { | ||||
@@ -58,95 +55,85 @@ public abstract class AbstractComponentTest | |||||
/** | /** | ||||
* Returns the component manager containing the components to test. | * 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, | protected void registerConverter( final Class converterClass, | ||||
final Class sourceClass, | final Class sourceClass, | ||||
final Class destClass ) | final Class destClass ) | ||||
throws ServiceException, TypeException | |||||
throws Exception | |||||
{ | { | ||||
ConverterRegistry converterRegistry = (ConverterRegistry)getServiceManager().lookup( ConverterRegistry.ROLE ); | ConverterRegistry converterRegistry = (ConverterRegistry)getServiceManager().lookup( ConverterRegistry.ROLE ); | ||||
converterRegistry.registerConverter( converterClass.getName(), sourceClass.getName(), destClass.getName() ); | converterRegistry.registerConverter( converterClass.getName(), sourceClass.getName(), destClass.getName() ); | ||||
@@ -8,9 +8,13 @@ | |||||
package org.apache.myrmidon.components.builder; | package org.apache.myrmidon.components.builder; | ||||
import java.io.File; | import java.io.File; | ||||
import java.util.Arrays; | |||||
import org.apache.avalon.excalibur.i18n.ResourceManager; | import org.apache.avalon.excalibur.i18n.ResourceManager; | ||||
import org.apache.avalon.excalibur.i18n.Resources; | import org.apache.avalon.excalibur.i18n.Resources; | ||||
import org.apache.avalon.excalibur.io.FileUtil; | |||||
import org.apache.myrmidon.AbstractMyrmidonTest; | import org.apache.myrmidon.AbstractMyrmidonTest; | ||||
import org.apache.myrmidon.interfaces.builder.ProjectException; | |||||
import org.apache.myrmidon.interfaces.model.Project; | |||||
/** | /** | ||||
* Test cases for {@link DefaultProjectBuilder}. | * Test cases for {@link DefaultProjectBuilder}. | ||||
@@ -22,7 +26,7 @@ public class DefaultProjectBuilderTest | |||||
extends AbstractMyrmidonTest | extends AbstractMyrmidonTest | ||||
{ | { | ||||
private final static Resources REZ | private final static Resources REZ | ||||
= ResourceManager.getPackageResources( DefaultProjectBuilder.class ); | |||||
= ResourceManager.getPackageResources( DefaultProjectBuilderTest.class ); | |||||
private DefaultProjectBuilder m_builder; | private DefaultProjectBuilder m_builder; | ||||
@@ -35,11 +39,227 @@ public class DefaultProjectBuilderTest | |||||
{ | { | ||||
super.setUp(); | super.setUp(); | ||||
m_builder = new DefaultProjectBuilder(); | 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 | public void testNameValidation() throws Exception | ||||
{ | { | ||||
@@ -52,7 +272,12 @@ public class DefaultProjectBuilderTest | |||||
} | } | ||||
catch( Exception e ) | 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 | // Check bad target name | ||||
@@ -64,7 +289,13 @@ public class DefaultProjectBuilderTest | |||||
} | } | ||||
catch( Exception e ) | 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 ); | |||||
} | } | ||||
} | } | ||||
} | } |
@@ -5,53 +5,51 @@ | |||||
* version 1.1, a copy of which has been included with this distribution in | * version 1.1, a copy of which has been included with this distribution in | ||||
* the LICENSE.txt file. | * the LICENSE.txt file. | ||||
*/ | */ | ||||
package org.apache.myrmidon.components.workspace; | |||||
package org.apache.myrmidon.components.property; | |||||
import java.io.File; | import java.io.File; | ||||
import java.util.Date; | import java.util.Date; | ||||
import org.apache.avalon.excalibur.i18n.ResourceManager; | import org.apache.avalon.excalibur.i18n.ResourceManager; | ||||
import org.apache.avalon.excalibur.i18n.Resources; | import org.apache.avalon.excalibur.i18n.Resources; | ||||
import org.apache.avalon.framework.context.Context; | import org.apache.avalon.framework.context.Context; | ||||
import org.apache.myrmidon.AbstractMyrmidonTest; | |||||
import org.apache.myrmidon.api.TaskException; | 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; | 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$ | * @version $Revision$ $Date$ | ||||
*/ | */ | ||||
public class DefaultPropertyResolverTest | |||||
extends AbstractComponentTest | |||||
public abstract class AbstractPropertyResolverTest | |||||
extends AbstractMyrmidonTest | |||||
{ | { | ||||
protected final static Resources REZ | protected final static Resources REZ | ||||
= ResourceManager.getPackageResources( DefaultPropertyResolver.class ); | |||||
= ResourceManager.getPackageResources( AbstractPropertyResolverTest.class ); | |||||
protected PropertyResolver m_resolver; | protected PropertyResolver m_resolver; | ||||
protected DefaultTaskContext m_context; | protected DefaultTaskContext m_context; | ||||
public DefaultPropertyResolverTest( String name ) | |||||
public AbstractPropertyResolverTest( String name ) | |||||
{ | { | ||||
super( name ); | super( name ); | ||||
} | } | ||||
protected void setUp() throws Exception | protected void setUp() throws Exception | ||||
{ | { | ||||
super.setUp(); | |||||
m_resolver = createResolver(); | 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( "intProp", new Integer( 333 ) ); | ||||
m_context.setProperty( "stringProp", "String property" ); | 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. | * Test property resolution with various different typed properties. | ||||
@@ -73,7 +71,7 @@ public class DefaultPropertyResolverTest | |||||
throws Exception | throws Exception | ||||
{ | { | ||||
m_context.setProperty( "typedProp", propObject ); | m_context.setProperty( "typedProp", propObject ); | ||||
String propString = propObject.toString(); | |||||
final String propString = propObject.toString(); | |||||
doTestResolution( "${typedProp}", propObject, m_context ); | doTestResolution( "${typedProp}", propObject, m_context ); | ||||
doTestResolution( "${typedProp} with following text", | doTestResolution( "${typedProp} with following text", | ||||
@@ -96,23 +94,6 @@ public class DefaultPropertyResolverTest | |||||
doTestResolution( "before ${prop2} between ${prop1} after", | doTestResolution( "before ${prop2} between ${prop1} after", | ||||
"before value2 between value1 after", m_context ); | "before value2 between value1 after", m_context ); | ||||
doTestResolution( "${prop1}-${int1}-${prop2}", "value1-123-value2", 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. */ | /* TODO - need to handle these cases. */ | ||||
// testFailure( "${bad${}", "", m_context ); | // testFailure( "${bad${}", "", m_context ); | ||||
// testFailure( "${ }", "", m_context ); | // testFailure( "${ }", "", m_context ); | ||||
} | } | ||||
/** | /** | ||||
* Resolves the property using the supplied context, and checks the result. | * 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 | throws Exception | ||||
{ | { | ||||
Object resolved = m_resolver.resolveProperties( value, context ); | |||||
final Object resolved = m_resolver.resolveProperties( value, context ); | |||||
assertEquals( expected, resolved ); | assertEquals( expected, resolved ); | ||||
} | } | ||||
@@ -151,9 +131,9 @@ public class DefaultPropertyResolverTest | |||||
* Attempts to resolve the value using the supplied context, expecting to | * Attempts to resolve the value using the supplied context, expecting to | ||||
* fail with the supplied error message. | * 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 | try | ||||
{ | { |
@@ -5,19 +5,18 @@ | |||||
* version 1.1, a copy of which has been included with this distribution in | * version 1.1, a copy of which has been included with this distribution in | ||||
* the LICENSE.txt file. | * 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.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> | * @author <a href="mailto:darrell@apache.org">Darrell DeBoer</a> | ||||
* @version $Revision$ $Date$ | * @version $Revision$ $Date$ | ||||
*/ | */ | ||||
public class ClassicPropertyResolverTest | public class ClassicPropertyResolverTest | ||||
extends DefaultPropertyResolverTest | |||||
extends AbstractPropertyResolverTest | |||||
{ | { | ||||
public ClassicPropertyResolverTest( String name ) | public ClassicPropertyResolverTest( String name ) | ||||
{ | { | ||||
@@ -34,8 +33,7 @@ public class ClassicPropertyResolverTest | |||||
*/ | */ | ||||
public void testUndefinedProp() throws Exception | public void testUndefinedProp() throws Exception | ||||
{ | { | ||||
String undefinedProp = "undefinedProperty"; | |||||
final String undefinedProp = "undefinedProperty"; | |||||
final String propRef = "${" + undefinedProp + "}"; | final String propRef = "${" + undefinedProp + "}"; | ||||
doTestResolution( propRef, propRef, m_context ); | doTestResolution( propRef, propRef, m_context ); | ||||
} | } |
@@ -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 ); | |||||
} | |||||
} |
@@ -44,11 +44,9 @@ public class InstantiatingServiceManagerTest | |||||
protected void setUp() | protected void setUp() | ||||
throws Exception | throws Exception | ||||
{ | { | ||||
super.setUp(); | |||||
// Set-up the service manager | // Set-up the service manager | ||||
m_serviceManager = new InstantiatingServiceManager(); | m_serviceManager = new InstantiatingServiceManager(); | ||||
m_serviceManager.enableLogging( createLogger() ); | |||||
m_serviceManager.enableLogging( getLogger() ); | |||||
m_serviceManager.service( getServiceManager() ); | m_serviceManager.service( getServiceManager() ); | ||||
m_serviceManager.parameterize( m_parameters ); | m_serviceManager.parameterize( m_parameters ); | ||||
} | } | ||||