ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dona...@apache.org
Subject cvs commit: jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace DefaultWorkspace.java LogTargetToListenerAdapter.java ProjectEntry.java ProjectListenerSupport.java Workspace.java
Date Fri, 29 Jun 2001 07:57:32 GMT
donaldp     01/06/29 00:57:32

  Added:       proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace
                        DefaultWorkspace.java
                        LogTargetToListenerAdapter.java ProjectEntry.java
                        ProjectListenerSupport.java Workspace.java
  Log:
  Begine reworking code/terminology of ProjectManager into Workspace.
  
  Reason: Better semantics associated with name and easier to know what to place in it.
  
  Revision  Changes    Path
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace/DefaultWorkspace.java
  
  Index: DefaultWorkspace.java
  ===================================================================
  /*
   * 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 file.
   */
  package org.apache.myrmidon.components.workspace;
  
  import java.io.File;
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.Map;
  import org.apache.avalon.framework.activity.Disposable;
  import org.apache.avalon.framework.activity.Initializable;
  import org.apache.avalon.framework.component.ComponentException;
  import org.apache.avalon.framework.component.ComponentManager;
  import org.apache.avalon.framework.component.Composable;
  import org.apache.avalon.framework.component.DefaultComponentManager;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.logger.AbstractLoggable;
  import org.apache.avalon.framework.parameters.ParameterException;
  import org.apache.avalon.framework.parameters.Parameterizable;
  import org.apache.avalon.framework.parameters.Parameters;
  import org.apache.log.Logger;
  import org.apache.myrmidon.api.DefaultTaskContext;
  import org.apache.myrmidon.api.TaskContext;
  import org.apache.myrmidon.api.TaskException;
  import org.apache.myrmidon.components.deployer.DefaultDeployer;
  import org.apache.myrmidon.components.deployer.Deployer;
  import org.apache.myrmidon.components.deployer.DeploymentException;
  import org.apache.myrmidon.components.executor.DefaultExecutionFrame;
  import org.apache.myrmidon.components.executor.ExecutionFrame;
  import org.apache.myrmidon.components.executor.Executor;
  import org.apache.myrmidon.components.model.Project;
  import org.apache.myrmidon.components.model.Target;
  import org.apache.myrmidon.components.model.TypeLib;
  import org.apache.myrmidon.components.type.TypeManager;
  import org.apache.myrmidon.framework.Condition;
  import org.apache.myrmidon.listeners.ProjectListener;
  
  /**
   * This is the default implementation of Workspace.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class DefaultWorkspace
      extends AbstractLoggable
      implements Workspace, Composable, Parameterizable, Initializable
  {
      private Executor                 m_executor;
      private ProjectListenerSupport   m_listenerSupport   = new ProjectListenerSupport();
      private ComponentManager         m_componentManager;
      private Parameters               m_parameters;
      private Project                  m_project;
      private TaskContext              m_baseContext;
      private HashMap                  m_entrys            = new HashMap();
      private TypeManager              m_typeManager;
  
      /**
       * Add a listener to project events.
       *
       * @param listener the listener
       */
      public void addProjectListener( final ProjectListener listener )
      {
          m_listenerSupport.addProjectListener( listener );
      }
  
      /**
       * Remove a listener from project events.
       *
       * @param listener the listener
       */
      public void removeProjectListener( final ProjectListener listener )
      {
          m_listenerSupport.removeProjectListener( listener );
      }
  
      /**
       * Retrieve relevent services needed for engine.
       *
       * @param componentManager the ComponentManager
       * @exception ComponentException if an error occurs
       */
      public void compose( final ComponentManager componentManager )
          throws ComponentException
      {
          m_componentManager = componentManager;
  
          m_typeManager = (TypeManager)componentManager.lookup( TypeManager.ROLE );
          m_executor = (Executor)componentManager.lookup( Executor.ROLE );
          m_project = (Project)componentManager.lookup( Project.ROLE );
      }
  
      public void parameterize( final Parameters parameters )
          throws ParameterException
      {
          m_parameters = parameters;
      }
  
      public void initialize()
          throws Exception
      {
          m_baseContext = createBaseContext();
      }
  
      /**
       * Execute a target in a particular project.
       * Execute in the project context.
       *
       * @param project the Project
       * @param target the name of the target
       * @exception TaskException if an error occurs
       */
      public void executeProject( final Project project, final String target )
          throws TaskException
      {
          final ProjectEntry entry = getProjectEntry( project );
  
          m_listenerSupport.projectStarted();
  
          executeTarget( "<init>", project.getImplicitTarget(), entry.getFrame() );
  
          execute( project, target, entry );
  
          m_listenerSupport.projectFinished();
      }
  
  
      private TaskContext createBaseContext()
          throws TaskException
      {
          final TaskContext context = new DefaultTaskContext();
  
          final String[] names = m_parameters.getNames();
          for( int i = 0; i < names.length; i++ )
          {
              final String value = m_parameters.getParameter( names[ i ], null );
              context.setProperty( names[ i ], value );
          }
  
          //Add system properties so that they overide user-defined properties
          addToContext( context, System.getProperties() );
  
          return context;
      }
  
      private File findTypeLib( final String libraryName )
          throws TaskException
      {
          //TODO: In future this will be expanded to allow
          //users to specify search path or automagically 
          //add entries to lib path (like user specific or 
          //workspace specific)
          final String name = libraryName.replace( '/', File.separatorChar ) + ".atl";
  
          final String home = System.getProperty( "myrmidon.home" );
          final File homeDir = new File( home + File.separatorChar + "ext" );
          
          final File library = new File( homeDir, name );
  
          if( library.exists() )
          {
              if( !library.canRead() )
              {
                  throw new TaskException( "Unable to read library at " + library );
              }
              else
              {
                  return library;
              }
          }
  
          throw new TaskException( "Unable to locate Type Library " + libraryName );
      }
  
      private void deployTypeLib( final Deployer deployer, final Project project )
          throws TaskException
      {
          final TypeLib[] typeLibs = project.getTypeLibs();
  
          for( int i = 0; i < typeLibs.length; i++ )
          {
              final TypeLib typeLib = typeLibs[ i ];
              final File file = findTypeLib( typeLib.getLibrary() );
  
              try
              {
                  if( null == typeLib.getRole() )
                  {
                      deployer.deploy( file );
                  }
                  else
                  {
                      deployer.deployType( typeLib.getRole(), typeLib.getName(), file );
                  }
              }
              catch( final DeploymentException de )
              {
                  throw new TaskException( "Error deploying type library " +
                                           typeLib + " at " + file, de );
              }
          }
      }
  
      private ExecutionFrame createExecutionFrame( final Project project )
          throws TaskException
      {
          final TaskContext context = new DefaultTaskContext( m_baseContext );
          context.setProperty( TaskContext.BASE_DIRECTORY, project.getBaseDirectory() );
  
          //Create per frame ComponentManager
          final DefaultComponentManager componentManager =
              new DefaultComponentManager( m_componentManager );
  
          //Add in child type manager so each frame can register different
          //sets of tasks etc
          final TypeManager typeManager = m_typeManager.createChildTypeManager();
          componentManager.put( TypeManager.ROLE, typeManager );
  
          //We need to create a new deployer so that it deploys
          //to project specific TypeManager
          final DefaultDeployer deployer = new DefaultDeployer();
          deployer.setLogger( getLogger() );
  
          try { deployer.compose( componentManager ); }
          catch( final ComponentException ce )
          {
              throw new TaskException( "Error configuring deployer", ce );
          }
  
          //HACK: Didn't call initialize because Deployer contained in Embeddor
          // Already initialized and this would be reduendent
          //deployer.initialize();
  
          componentManager.put( Deployer.ROLE, deployer );
  
          deployTypeLib( deployer, project );
  
          //We need to place projects and ProjectManager
          //in ComponentManager so as to support project-local call()
          componentManager.put( Workspace.ROLE, this );
          componentManager.put( Project.ROLE, project );
  
          final String[] names = project.getProjectNames();
          for( int i = 0; i < names.length; i++ )
          {
              final String name = names[ i ];
              final Project other = project.getProject( name );
              componentManager.put( Project.ROLE + "/" + name, other );
          }
  
          final DefaultExecutionFrame frame = new DefaultExecutionFrame();
  
          try
          {
  
              frame.setLogger( getLogger() );
              frame.contextualize( context );
              frame.compose( componentManager );
          }
          catch( final Exception e )
          {
              throw new TaskException( "Error setting up ExecutionFrame", e );
          }
  
          return frame;
      }
  
      private ProjectEntry getProjectEntry( final Project project )
          throws TaskException
      {
          ProjectEntry entry = (ProjectEntry)m_entrys.get( project );
  
          if( null == entry )
          {
              final ExecutionFrame frame = createExecutionFrame( project );
              entry = new ProjectEntry( project, frame );
              m_entrys.put( project, entry );
          }
  
          return entry;
      }
  
      private Project getProject( final String name, final Project project )
          throws TaskException
      {
          final Project other = project.getProject( name );
  
          if( null == other )
          {
              //TODO: Fix this so location information included in description
              throw new TaskException( "Project '" + name + "' not found." );
          }
  
          return other;
      }
  
      /**
       * Helper method to execute a target.
       *
       * @param project the Project
       * @param target the name of the target
       * @param context the context
       * @param done the list of targets already executed in current run
       * @exception TaskException if an error occurs
       */
      private void execute( final Project project,
                            final String targetName,
                            final ProjectEntry entry )
          throws TaskException
      {
          final int index = targetName.indexOf( "->" );
          if( -1 != index )
          {
              final String name = targetName.substring( 0, index );
              final String otherTargetName = targetName.substring( index + 2 );
  
              final Project otherProject = getProject( name, project );
              final ProjectEntry otherEntry = getProjectEntry( otherProject );
  
              //Execute target in referenced project
              execute( otherProject, otherTargetName, otherEntry );
              return;
          }
  
          final Target target = project.getTarget( targetName );
          if( null == target )
          {
              throw new TaskException( "Unable to find target " + targetName );
          }
  
          //add target to list of targets executed
          entry.completeTarget( targetName );
  
          //execute all dependencies
          final String[] dependencies = target.getDependencies();
          for( int i = 0; i < dependencies.length; i++ )
          {
              if( !entry.isTargetCompleted( dependencies[ i ] ) )
              {
                  execute( project, dependencies[ i ], entry );
              }
          }
  
          //notify listeners
          m_listenerSupport.targetStarted( targetName );
  
          executeTarget( targetName, target, entry.getFrame() );
  
          //notify listeners
          m_listenerSupport.targetFinished();
      }
  
      /**
       * Method to execute a particular target instance.
       *
       * @param targetName the name of target
       * @param target the target
       * @param context the context in which to execute
       * @exception TaskException if an error occurs
       */
      private void executeTarget( final String name,
                                  final Target target,
                                  final ExecutionFrame frame )
          throws TaskException
      {
          //check the condition associated with target.
          //if it is not satisfied then skip target
          final Condition condition = target.getCondition();
          if( null != condition )
          {
              if( false == condition.evaluate( frame.getContext() ) )
              {
                  getLogger().debug( "Skipping target " + name +
                                     " as it does not satisfy condition" );
                  return;
              }
          }
  
          getLogger().debug( "Executing target " + name );
  
          //frame.getContext().setProperty( Project.TARGET, target );
  
          //execute all tasks assciated with target
          final Configuration[] tasks = target.getTasks();
          for( int i = 0; i < tasks.length; i++ )
          {
              executeTask( tasks[ i ], frame );
          }
      }
  
      /**
       * Execute a task.
       *
       * @param task the task definition
       * @param context the context
       * @exception TaskException if an error occurs
       */
      private void executeTask( final Configuration task, final ExecutionFrame frame )
          throws TaskException
      {
          final String name = task.getName();
          getLogger().debug( "Executing task " + name );
  
          //is setting name even necessary ???
          frame.getContext().setProperty( TaskContext.NAME, name );
  
          //notify listeners
          m_listenerSupport.taskStarted( name );
  
          //run task
          m_executor.execute( task, frame );
  
          //notify listeners task has ended
          m_listenerSupport.taskFinished();
      }
  
      /**
       * Helper method to add values to a context
       *
       * @param context the context
       * @param map the map of names->values
       */
      private void addToContext( final TaskContext context, final Map map )
          throws TaskException
      {
          final Iterator keys = map.keySet().iterator();
  
          while( keys.hasNext() )
          {
              final String key = (String)keys.next();
              final Object value = map.get( key );
              context.setProperty( key, value );
          }
      }
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace/LogTargetToListenerAdapter.java
  
  Index: LogTargetToListenerAdapter.java
  ===================================================================
  /*
   * 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 file.
   */
  package org.apache.myrmidon.components.workspace;
  
  import org.apache.log.LogEvent;
  import org.apache.log.LogTarget;
  import org.apache.myrmidon.listeners.ProjectListener;
  
  /**
   * Adapter between Avalon LogKit and Project listener interfaces.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class LogTargetToListenerAdapter
      implements LogTarget
  {
      private final ProjectListener    m_listener;
  
      /**
       * Constructor taking listener to convert to.
       *
       * @param listener the ProjectListener
       */
      public LogTargetToListenerAdapter( final ProjectListener listener )
      {
          m_listener = listener;
      }
  
      /**
       * Process a log event.
       *
       * @param event the event
       */
      public void processEvent( final LogEvent event )
      {
          if( null == event.getThrowable() )
          {
              m_listener.log( event.getMessage() );
          }
          else
          {
              m_listener.log( event.getMessage(), event.getThrowable() );
          }
      }
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace/ProjectEntry.java
  
  Index: ProjectEntry.java
  ===================================================================
  /*
   * 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 file.
   */
  package org.apache.myrmidon.components.workspace;
  
  import java.util.ArrayList;
  import org.apache.myrmidon.components.executor.ExecutionFrame;
  import org.apache.myrmidon.components.model.Project;
  
  /**
   * This contains detaisl for each project that is managed by ProjectManager.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public final class ProjectEntry
  {
      private final Project         m_project;
      private final ExecutionFrame  m_frame;
      private final ArrayList       m_targetsCompleted   = new ArrayList();
  
      public ProjectEntry( final Project project,
                           final ExecutionFrame frame )
      {
          m_project = project;
          m_frame = frame;
      }
  
      public Project getProject()
      {
          return m_project;
      }
  
      public ExecutionFrame getFrame()
      {
          return m_frame;
      }
  
      public boolean isTargetCompleted( final String target )
      {
          return m_targetsCompleted.contains( target );
      }
  
      public void completeTarget( final String target )
      {
          m_targetsCompleted.add( target );
      }
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace/ProjectListenerSupport.java
  
  Index: ProjectListenerSupport.java
  ===================================================================
  /*
   * 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 file.
   */
  package org.apache.myrmidon.components.workspace;
  
  import org.apache.myrmidon.listeners.ProjectListener;
  
  /**
   * Support for the project listener event dispatching.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class ProjectListenerSupport
      implements ProjectListener
  {
      private ProjectListener[]   m_listeners = new ProjectListener[ 0 ];
  
      /**
       * Add an extra project listener that wants to receive notification of listener events.
       *
       * @param listener the listener
       */
      public void addProjectListener( final ProjectListener listener )
      {
          final ProjectListener[] listeners = new ProjectListener[ m_listeners.length + 1
];
          System.arraycopy( m_listeners, 0, listeners, 0, m_listeners.length );
          listeners[ m_listeners.length ] = listener;
          m_listeners = listeners;
      }
  
      /**
       * Remove a project listener that wants to receive notification of listener events.
       *
       * @param listener the listener
       */
      public void removeProjectListener( final ProjectListener listener )
      {
          int found = -1;
  
          for( int i = 0; i < m_listeners.length; i++ )
          {
              if( listener == m_listeners[ i ] )
              {
                  found = i;
                  break;
              }
          }
  
          if( -1 == found ) return;
  
          final ProjectListener[] listeners = new ProjectListener[ m_listeners.length - 1
];
          System.arraycopy( m_listeners, 0, listeners, 0, found );
  
          final int count = m_listeners.length - found - 1;
          System.arraycopy( m_listeners, found, listeners, found + 1, count );
  
          m_listeners = listeners;
      }
  
      /**
       * Fire a projectStarted event.
       */
      public void projectStarted()
      {
          for( int i = 0; i < m_listeners.length; i++ )
          {
              m_listeners[ i ].projectStarted();
          }
      }
  
      /**
       * Fire a projectFinished event.
       */
      public void projectFinished()
      {
          for( int i = 0; i < m_listeners.length; i++ )
          {
              m_listeners[ i ].projectFinished();
          }
      }
  
      /**
       * Fire a targetStarted event.
       *
       * @param targetName the name of target
       */
      public void targetStarted( String targetName )
      {
          for( int i = 0; i < m_listeners.length; i++ )
          {
              m_listeners[ i ].targetStarted( targetName );
          }
      }
  
      /**
       * Fire a targetFinished event.
       */
      public void targetFinished()
      {
          for( int i = 0; i < m_listeners.length; i++ )
          {
              m_listeners[ i ].targetFinished();
          }
      }
  
      /**
       * Fire a targetStarted event.
       *
       * @param targetName the name of target
       */
      public void taskStarted( String taskName )
      {
          for( int i = 0; i < m_listeners.length; i++ )
          {
              m_listeners[ i ].taskStarted( taskName );
          }
      }
  
      /**
       * Fire a taskFinished event.
       */
      public void taskFinished()
      {
          for( int i = 0; i < m_listeners.length; i++ )
          {
              m_listeners[ i ].taskFinished();
          }
      }
  
      /**
       * Fire a log event.
       *
       * @param message the log message
       */
      public void log( String message )
      {
          for( int i = 0; i < m_listeners.length; i++ )
          {
              m_listeners[ i ].log( message );
          }
      }
  
      /**
       * Fire a log event.
       *
       * @param message the log message
       * @param throwable the throwable to be logged
       */
      public void log( String message, Throwable throwable )
      {
          for( int i = 0; i < m_listeners.length; i++ )
          {
              m_listeners[ i ].log( message, throwable );
          }
      }
  }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/components/workspace/Workspace.java
  
  Index: Workspace.java
  ===================================================================
  /*
   * 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 file.
   */
  package org.apache.myrmidon.components.workspace;
  
  import java.util.Map;
  import org.apache.avalon.framework.component.Component;
  import org.apache.myrmidon.api.TaskException;
  import org.apache.myrmidon.components.model.Project;
  import org.apache.myrmidon.listeners.ProjectListener;
  
  /**
   * This is the abstraction through which Projects are managed and executed.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface Workspace
      extends Component
  {
      String ROLE = "org.apache.myrmidon.components.workspace.Workspace";
  
      /**
       * Add a listener to project events.
       *
       * @param listener the listener
       */
      void addProjectListener( ProjectListener listener );
  
      /**
       * Remove a listener from project events.
       *
       * @param listener the listener
       */
      void removeProjectListener( ProjectListener listener );
  
      /**
       * Execute a target in a particular project.
       *
       * @param project the Project
       * @param target the name of the target
       * @param defines the defines
       * @exception TaskException if an error occurs
       */
      void executeProject( Project project, String target )
          throws TaskException;
  }
  
  
  

Mime
View raw message