Author: mcconnell Date: Tue Jun 29 00:37:38 2004 New Revision: 22261 Added: avalon/trunk/tools/magic/src/main/org/apache/avalon/tools/model/MagicPath.java avalon/trunk/tools/magic/src/main/org/apache/avalon/tools/tasks/PropertyTask.java avalon/trunk/tools/magic/src/main/org/apache/avalon/tools/tasks/ReplicateTask.java Modified: avalon/trunk/tools/magic/etc/deliverables/templates/reactor.xml avalon/trunk/tools/magic/src/main/org/apache/avalon/tools/antlib.xml avalon/trunk/tools/magic/src/main/org/apache/avalon/tools/model/Info.java avalon/trunk/tools/magic/src/main/org/apache/avalon/tools/model/Resource.java avalon/trunk/tools/magic/src/main/org/apache/avalon/tools/tasks/HomeTask.java avalon/trunk/tools/magic/src/main/org/apache/avalon/tools/tasks/ReactorTask.java Log: Update magic to provide support for ant path creation in the form <x:path mode="BUILD" id="my-path"/> enabling better integration of magic resources into classic ant build scenarios.
Modified: avalon/trunk/tools/magic/etc/deliverables/templates/reactor.xml ============================================================================== --- avalon/trunk/tools/magic/etc/deliverables/templates/reactor.xml (original) +++ avalon/trunk/tools/magic/etc/deliverables/templates/reactor.xml Tue Jun 29 00:37:38 2004 @@ -32,7 +32,7 @@ </target> <target name="default"> - <x:reactor/> + <x:reactor target="default"/> </target> </project> Modified: avalon/trunk/tools/magic/src/main/org/apache/avalon/tools/antlib.xml ============================================================================== --- avalon/trunk/tools/magic/src/main/org/apache/avalon/tools/antlib.xml (original) +++ avalon/trunk/tools/magic/src/main/org/apache/avalon/tools/antlib.xml Tue Jun 29 00:37:38 2004 @@ -19,5 +19,8 @@ <taskdef name="bar" classname="org.apache.avalon.tools.tasks.BarTask"/> <taskdef name="javadoc" classname="org.apache.avalon.tools.tasks.JavadocTask"/> <taskdef name="publish" classname="org.apache.avalon.tools.tasks.PublishTask"/> + <taskdef name="property" classname="org.apache.avalon.tools.tasks.PropertyTask"/> + <taskdef name="replicate" classname="org.apache.avalon.tools.tasks.ReplicateTask"/> + <typedef name="path" classname="org.apache.avalon.tools.model.MagicPath"/> </antlib> Modified: avalon/trunk/tools/magic/src/main/org/apache/avalon/tools/model/Info.java ============================================================================== --- avalon/trunk/tools/magic/src/main/org/apache/avalon/tools/model/Info.java (original) +++ avalon/trunk/tools/magic/src/main/org/apache/avalon/tools/model/Info.java Tue Jun 29 00:37:38 2004 @@ -135,6 +135,19 @@ } } + public String getFilename() + { + final StringBuffer buffer = new StringBuffer( getName() ); + if( null != getVersion() ) + { + buffer.append( "-" ); + buffer.append( getVersion() ); + } + buffer.append( "." ); + buffer.append( getType() ); + return buffer.toString(); + } + public String getPath() { final StringBuffer buffer = new StringBuffer( getGroup() ); Added: avalon/trunk/tools/magic/src/main/org/apache/avalon/tools/model/MagicPath.java ============================================================================== --- (empty file) +++ avalon/trunk/tools/magic/src/main/org/apache/avalon/tools/model/MagicPath.java Tue Jun 29 00:37:38 2004 @@ -0,0 +1,136 @@ +/* + * Copyright 2004 Apache Software Foundation + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.avalon.tools.model; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.types.Path; + +import java.io.File; +import java.io.IOException; + +/** + * + * @author <a href="mailto:[EMAIL PROTECTED]">Avalon Development Team</a> + * @version $Revision: 1.2 $ $Date: 2004/03/17 10:30:09 $ + */ +public class MagicPath extends Path +{ + private Context m_context; + private Home m_home; + private String m_key; + private int m_mode = Policy.RUNTIME; + + public MagicPath( Project project ) + { + super( project ); + setup(); + } + + public void setKey( final String key ) + { + m_key = key; + } + + public void setMode( final String mode ) + { + if( "ANY".equalsIgnoreCase( mode ) ) + { + m_mode = Policy.ANY; + } + else if( "BUILD".equalsIgnoreCase( mode ) ) + { + m_mode = Policy.BUILD; + } + else if( "TEST".equalsIgnoreCase( mode ) ) + { + m_mode = Policy.TEST; + } + else if( "RUNTIME".equalsIgnoreCase( mode ) ) + { + m_mode = Policy.RUNTIME; + } + else + { + final String error = + "Invalid mode argument [" + mode + + "] - use ANY, BUILD, TEST or RUNTIME."; + throw new BuildException( error ); + } + setup(); + } + + private int getMode() + { + return m_mode; + } + + private Definition getReferenceDefinition() + { + if( null != m_key ) + { + return getHome().getDefinition( m_key ); + } + else + { + return getHome().getDefinition( getKey() ); + } + } + + private void setup() + { + if( null == m_context ) + { + m_context = Context.getContext( getProject() ); + } + if( null == m_home ) + { + Home home = (Home) getProject().getReference( Home.KEY ); + if( null == home ) + { + final String error = + "Undefined home."; + throw new BuildException( error ); + } + else + { + m_home = home; + } + } + + Definition def = getReferenceDefinition(); + Path path = def.getPath( getProject(), getMode() ); + super.add( path ); + } + + private Context getContext() + { + return m_context; + } + + private String getKey() + { + return getContext().getKey(); + } + + private Home getHome() + { + return m_home; + } + +} Modified: avalon/trunk/tools/magic/src/main/org/apache/avalon/tools/model/Resource.java ============================================================================== --- avalon/trunk/tools/magic/src/main/org/apache/avalon/tools/model/Resource.java (original) +++ avalon/trunk/tools/magic/src/main/org/apache/avalon/tools/model/Resource.java Tue Jun 29 00:37:38 2004 @@ -107,6 +107,10 @@ } } + /** + * Returns a path of artifact filenames relative to the supplied scope. + * The mode may be one of ANY, BUILD, TEST or RUNTIME. + */ public Path getPath( final Project project, final int mode ) { if( null == project ) Modified: avalon/trunk/tools/magic/src/main/org/apache/avalon/tools/tasks/HomeTask.java ============================================================================== --- avalon/trunk/tools/magic/src/main/org/apache/avalon/tools/tasks/HomeTask.java (original) +++ avalon/trunk/tools/magic/src/main/org/apache/avalon/tools/tasks/HomeTask.java Tue Jun 29 00:37:38 2004 @@ -84,6 +84,10 @@ { project.setProperty( "project.version", "" ); } + project.setProperty( "project.path", info.getPath() ); + project.setProperty( "project.uri", info.getURI() ); + project.setProperty( "project.type", info.getType() ); + project.setProperty( "project.filename", info.getFilename() ); } } Added: avalon/trunk/tools/magic/src/main/org/apache/avalon/tools/tasks/PropertyTask.java ============================================================================== --- (empty file) +++ avalon/trunk/tools/magic/src/main/org/apache/avalon/tools/tasks/PropertyTask.java Tue Jun 29 00:37:38 2004 @@ -0,0 +1,224 @@ +/* + * Copyright 2004 Apache Software Foundation + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.avalon.tools.tasks; + +import org.apache.avalon.tools.model.Definition; +import org.apache.avalon.tools.model.Policy; +import org.apache.avalon.tools.model.Resource; +import org.apache.avalon.tools.model.ResourceRef; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.taskdefs.Property; + +/** + * Build a set of projects taking into account dependencies within the + * supplied fileset. + * + * @author <a href="mailto:[EMAIL PROTECTED]">Avalon Development Team</a> + * @version $Revision: 1.2 $ $Date: 2004/03/17 10:30:09 $ + */ +public class PropertyTask extends SystemTask +{ + private String m_key; + private String m_feature; + private String m_property; + + public void init() + { + if( !isInitialized() ) + { + super.init(); + } + } + + public void setKey( final String key ) + { + m_key = key; + } + + public void setFeature( final String feature ) + { + m_feature = feature; + } + + public void setProperty( final String property ) + { + m_property = property; + } + + public void execute() throws BuildException + { + if( null == m_key ) + { + m_key = getContext().getKey(); + } + if( null == m_feature ) + { + log( "Ignoring request due to missing 'feature' attribute." ); + return; + } + if( null == m_property ) + { + log( "Ignoring request due to missing 'property' attribute." ); + return; + } + + final String value = getFeature(); + if( null != value ) + { + final Property property = (Property) getProject().createTask( "property" ); + property.init(); + property.setName( m_property ); + property.setValue( value ); + property.execute(); + } + else + { + log( "Unrecognized or unsupported feature [" + m_feature + "]." ); + } + } + + private String getFeature() + { + final ResourceRef ref = new ResourceRef( m_key ); + final Resource resource = getHome().getResource( ref ); + if( m_feature.equals( "name" ) ) + { + return resource.getInfo().getName(); + } + else if( m_feature.equals( "group" ) ) + { + return resource.getInfo().getGroup(); + } + else if( m_feature.equals( "version" ) ) + { + final String version = resource.getInfo().getVersion(); + if( null == version ) return ""; + return version; + } + else if( m_feature.equals( "uri" ) ) + { + return resource.getInfo().getURI(); + } + else if( resource instanceof Definition ) + { + final Definition def = (Definition) resource; + if( m_feature.equals( "system-classpath-for-windows" ) ) + { + return getPath( def, true ); + } + else if( m_feature.equals( "system-classpath-for-unix" ) ) + { + return getPath( def, false ); + } + } + return null; + } + + private String getPath( final Definition def, final boolean windows ) + { + final StringBuffer buffer = new StringBuffer(); + final ResourceRef[] refs = + def.getResourceRefs( Policy.RUNTIME, ResourceRef.ANY, true ); + for( int i=0; i<refs.length; i++ ) + { + if( i>0 ) + { + buffer.append( ";" ); + } + + final ResourceRef ref = refs[i]; + final Resource resource = getHome().getResource( ref ); + final String path = getNativePath( windows, resource ); + buffer.append( path ); + } + + if( refs.length > 0 ) + { + buffer.append( ";" ); + } + + buffer.append( getNativePath( windows, def ) ); + return buffer.toString(); + } + + private String getNativePath( final boolean windows, final Resource resource ) + { + final String symbol = getPlatformCacheSymbol( windows ); + final StringBuffer buffer = new StringBuffer( symbol ); + final String path = resource.getInfo().getPath(); + if( windows ) + { + buffer.append( "\\" ); + buffer.append( path.replace( '/', '\\' ) ); + } + else + { + buffer.append( "/" ); + buffer.append( path ); + } + return buffer.toString(); + } + + private String getPlatformCacheSymbol( final boolean windows ) + { + if( windows ) + { + return "%MAGIC_SCD%"; + } + else + { + return "$MAGIC_SCD"; + } + } + + public static class Attribute + { + private String m_name; + private String m_value; + + public Attribute() + { + } + + public Attribute( final String name, final String value ) + { + m_name = name; + m_value = value; + } + + public void setName( final String name ) + { + m_name = name; + } + + public void setValue( final String value ) + { + m_value = value; + } + + public String getName() + { + return m_name; + } + + public String getValue() + { + return m_value; + } + } +} Modified: avalon/trunk/tools/magic/src/main/org/apache/avalon/tools/tasks/ReactorTask.java ============================================================================== --- avalon/trunk/tools/magic/src/main/org/apache/avalon/tools/tasks/ReactorTask.java (original) +++ avalon/trunk/tools/magic/src/main/org/apache/avalon/tools/tasks/ReactorTask.java Tue Jun 29 00:37:38 2004 @@ -20,9 +20,12 @@ import org.apache.avalon.tools.model.Context; import org.apache.avalon.tools.model.Definition; import org.apache.avalon.tools.model.ResourceRef; +import org.apache.avalon.tools.model.Home; + import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; import org.apache.tools.ant.taskdefs.Ant; +import org.apache.tools.ant.taskdefs.Sequential; import org.apache.tools.ant.types.DirSet; import org.apache.tools.ant.types.FileList; import org.apache.tools.ant.types.FileSet; @@ -36,27 +39,44 @@ import java.util.List; import java.util.Properties; + /** - * Build a set of projects taking into account dependencies within the - * supplied fileset. + * Build a set of projects taking into account cross-project dependencies. * * @author <a href="mailto:[EMAIL PROTECTED]">Avalon Development Team</a> * @version $Revision: 1.2 $ $Date: 2004/03/17 10:30:09 $ */ -public class ReactorTask extends SystemTask +public class ReactorTask extends Sequential { private static final String BANNER = "------------------------------------------------------------------------"; private String m_target; - private Path m_path; private List m_defs; + private Context m_context; + private Home m_home; + private boolean m_verbose = true; public void init() { - if( !isInitialized() ) + if( null == m_context ) + { + m_context = Context.getContext( getProject() ); + } + + if( null == m_home ) { - super.init(); + Home home = (Home) getProject().getReference( Home.KEY ); + if( null == home ) + { + final String error = + "Undefined home."; + throw new BuildException( error ); + } + else + { + m_home = home; + } } } @@ -65,74 +85,69 @@ m_target = target; } - public void addConfigured( final Path path ) - { - getPath().add( path ); - } - - public void addConfigured( final DirSet dirset ) - { - getPath().addDirset( dirset ); - } - - public void addConfigured( final FileSet fileset ) - { - getPath().addFileset( fileset ); - } - - public void addConfigured( final FileList list ) + public void setVerbose( final boolean flag ) { - getPath().addFilelist( list ); + m_verbose = flag; } public void execute() throws BuildException { final Project project = getProject(); - log( "Preparing build sequence." ); m_defs = getDefinitions(); final Definition[] defs = walkGraph(); - project.log( BANNER ); - for( int i=0; i<defs.length; i++ ) - { - final Definition def = defs[i]; - project.log( def.toString() ); - } - project.log( BANNER ); - for( int i=0; i<defs.length; i++ ) + + if( m_verbose ) { - final Definition def = defs[i]; - try + log( "Preparing build sequence." ); + project.log( BANNER ); + for( int i=0; i<defs.length; i++ ) { - execute( def, m_target ); + final Definition def = defs[i]; + project.log( def.toString() ); } - catch( Throwable e ) + project.log( BANNER ); + } + + if( null != m_target ) + { + for( int i=0; i<defs.length; i++ ) { - throw new BuildException( e ); + final Definition def = defs[i]; + try + { + executeTarget( def, m_target ); + } + catch( Throwable e ) + { + throw new BuildException( e ); + } } } - } - - private Path getPath() - { - if( null == m_path ) + else { - m_path = new Path( getProject() ); + for( int i=0; i<defs.length; i++ ) + { + final Definition def = defs[i]; + project.setProperty( "reactor.key", def.getKey() ); + project.setProperty( "reactor.version", def.getInfo().getVersion() ); + project.setProperty( "reactor.name", def.getInfo().getName() ); + project.setProperty( "reactor.group", def.getInfo().getGroup() ); + project.setProperty( "reactor.basedir", def.getBaseDir().toString() ); + project.setProperty( "reactor.path", def.getInfo().getPath() ); + project.setProperty( "reactor.uri", def.getInfo().getURI() ); + project.setProperty( "reactor.spec", def.getInfo().getSpec() ); + super.execute(); + } } - return m_path; - } - - public void execute( final Definition definition ) - { - execute( definition, null ); } - public void execute( final Definition definition, final String target ) + private void executeTarget( final Definition definition, final String target ) { final Ant ant = (Ant) getProject().createTask( "ant" ); ant.setDir( definition.getBaseDir() ); ant.setInheritRefs( false ); ant.setInheritAll( false ); - if( null != target ) + if(( null != target ) && (!"default".equals( target ))) { ant.setTarget( target ); } @@ -213,18 +228,6 @@ { final Project project = getProject(); final File basedir = project.getBaseDir(); - if( null == m_path ) - { - return getLocalDefinitions( basedir ); - } - else - { - return getExplicitDefinitions( basedir ); - } - } - - private List getLocalDefinitions( final File basedir ) - { try { final ArrayList list = new ArrayList(); @@ -247,60 +250,13 @@ } } - private List getExplicitDefinitions( final File basedir ) + private Context getContext() { - final ArrayList list = new ArrayList(); - - final String[] names = getPath().list(); - for( int i=0; i<names.length; i++ ) - { - final String path = names[i]; - final File file = Context.getFile( basedir, path ); - final File dir = getDir( file ); - if( file.exists() ) - { - final String key = getProjectName( dir ); - if( null != key ) - { - final ResourceRef ref = new ResourceRef( key ); - list.add( getHome().getDefinition( ref ) ); - } - else - { - log( "Skipping dir: " - + dir - + "due to unresolve project name." ); - } - } - else - { - log( "Skipping dir: " - + dir - + " as it does not exist." ); - } - } - return list; - } - - private String getProjectName( final File dir ) - { - try - { - final Properties properties = new Properties(); - final File props = new File( dir, "build.properties" ); - final InputStream stream = new FileInputStream( props ); - properties.load( stream ); - return properties.getProperty( "project.name" ); - } - catch( IOException ioe ) - { - throw new BuildException( ioe ); - } + return m_context; } - private File getDir( final File file ) + private Home getHome() { - if( file.isDirectory() ) return file; - return file.getParentFile(); + return m_home; } } Added: avalon/trunk/tools/magic/src/main/org/apache/avalon/tools/tasks/ReplicateTask.java ============================================================================== --- (empty file) +++ avalon/trunk/tools/magic/src/main/org/apache/avalon/tools/tasks/ReplicateTask.java Tue Jun 29 00:37:38 2004 @@ -0,0 +1,187 @@ +/* + * Copyright 2004 Apache Software Foundation + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.avalon.tools.tasks; + +import org.apache.avalon.tools.model.Context; +import org.apache.avalon.tools.model.Definition; +import org.apache.avalon.tools.model.ResourceRef; +import org.apache.avalon.tools.model.Home; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.taskdefs.Ant; +import org.apache.tools.ant.taskdefs.Sequential; +import org.apache.tools.ant.types.DirSet; +import org.apache.tools.ant.types.FileList; +import org.apache.tools.ant.types.FileSet; +import org.apache.tools.ant.types.Path; +import org.apache.tools.ant.taskdefs.Copy; +import org.apache.tools.ant.types.FileSet; +import org.apache.tools.ant.taskdefs.Mkdir; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; + + +/** + * Build a set of projects taking into account cross-project dependencies. + * + * @author <a href="mailto:[EMAIL PROTECTED]">Avalon Development Team</a> + * @version $Revision: 1.2 $ $Date: 2004/03/17 10:30:09 $ + */ +public class ReplicateTask extends Task +{ + private static final String BANNER = + "------------------------------------------------------------------------"; + + private File m_todir; + private String m_id; + private Context m_context; + private Home m_home; + + public void init() + { + if( null == m_context ) + { + m_context = Context.getContext( getProject() ); + } + + if( null == m_home ) + { + Home home = (Home) getProject().getReference( Home.KEY ); + if( null == home ) + { + final String error = + "Undefined home."; + throw new BuildException( error ); + } + else + { + m_home = home; + } + } + } + + /** + * The id of a repository based path. + */ + public void setRefid( String id ) + { + m_id = id; + } + + /** + * The target directory to copy cached based path elements to. + */ + public void setTodir( File todir ) + { + m_todir = todir; + } + + public void execute() + { + if( null == m_id ) + { + final String error = + "Required path id attribute is not declared on replicate task."; + throw new BuildException( error ); + } + if( null == m_todir ) + { + final String error = + "Required path id attribute is not declared on replicate task."; + throw new BuildException( error ); + } + + Object ref = getProject().getReference( m_id ); + if( null == ref ) + { + final String error = + "Replication path id [" + m_id + "] is unknown."; + throw new BuildException( error ); + } + + if( !( ref instanceof Path ) ) + { + final String error = + "Replication path id [" + m_id + "] does not reference a path " + + "(class " + ref.getClass().getName() + " is not a Path instance)."; + throw new BuildException( error ); + } + + Path path = (Path) ref; + File cache = getHome().getRepository().getCacheDirectory(); + FileSet fileset = createFileSet( cache, path ); + copy( m_todir, fileset ); + } + + private FileSet createFileSet( final File cache, final Path path ) + { + String root = cache.toString(); + String sequence = path.toString(); + String[] translation = Path.translatePath( getProject(), sequence ); + final FileSet fileset = new FileSet(); + fileset.setDir( cache ); + for( int i=0; i<translation.length; i++ ) + { + String trans = translation[i]; + if( trans.startsWith( root ) ) + { + String relativeFilename = trans.substring( root.length() + 1 ); + System.out.println( relativeFilename ); + fileset.createInclude().setName( relativeFilename ); + } + } + return fileset; + } + + private void copy( final File destination, final FileSet fileset ) + { + mkDir( destination ); + final Copy copy = (Copy) getProject().createTask( "copy" ); + copy.setPreserveLastModified( true ); + copy.setTodir( destination ); + copy.addFileset( fileset ); + copy.init(); + copy.execute(); + } + + public void mkDir( final File dir ) + { + final Mkdir mkdir = (Mkdir) getProject().createTask( "mkdir" ); + mkdir.setDir( dir ); + mkdir.init(); + mkdir.execute(); + } + + private Context getContext() + { + return m_context; + } + + private Home getHome() + { + return m_home; + } +} --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]