avalon-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cziege...@apache.org
Subject cvs commit: avalon-excalibur/fortress/meta/src/java/org/apache/avalon/fortress/meta ComponentMetaInfoCollector.java Component.java Service.java
Date Fri, 02 Apr 2004 08:29:45 GMT
cziegeler    2004/04/02 00:29:45

  Added:       fortress/meta/src/java/org/apache/avalon/fortress/tools
                        Component.java ComponentMetaInfoCollector.java
                        Service.java
  Removed:     fortress/meta/src/java/org/apache/avalon/fortress/meta
                        ComponentMetaInfoCollector.java Component.java
                        Service.java
  Log:
  Correct package name
  
  Revision  Changes    Path
  1.1                  avalon-excalibur/fortress/meta/src/java/org/apache/avalon/fortress/tools/Component.java
  
  Index: Component.java
  ===================================================================
  /* 
   * Copyright 2003-2004 The 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.fortress.tools;
  
  import com.thoughtworks.qdox.model.*;
  import org.apache.avalon.fortress.MetaInfoEntry;
  import org.apache.avalon.fortress.util.dag.Vertex;
  import org.apache.tools.ant.BuildException;
  
  import java.io.File;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.util.*;
  
  /**
   * Represents a component, and output the meta information.
   *
   * @author <a href="mailto:dev@avalon.apache.org">The Avalon Team</a>
   * @version CVS $Revision: 1.1 $ $Date: 2004/04/02 08:29:44 $
   */
  final class Component
  {
      private static final String SINGLE_THREADED = "org.apache.avalon.framework.thread.SingleThreaded";
      private static final String THREAD_SAFE = "org.apache.avalon.framework.thread.ThreadSafe";
      private static final String POOLABLE = "org.apache.avalon.excalibur.pool.Poolable";
      private static final String RECYCLABLE = "org.apache.avalon.excalibur.pool.Recyclable";
      private static final String SERVICE_MANAGER = "org.apache.avalon.framework.service.ServiceManager";
  
      static final String ATTR_TYPE = "type";
      static final String ATTR_NAME = "name";
  
      private static final String TAG_SERVICE = "avalon.service";
      private static final String TAG_DEPENDENCY = "avalon.dependency";
      private static final String TAG_LIFESTYLE = "x-avalon.lifestyle";
      private static final String TAG_HANDLER = "fortress.handler";
      private static final String TAG_INFO = "x-avalon.info";
      private static final String TAG_NAME = "fortress.name";
  
      private static final String META_NAME = "x-avalon.name";
  
      private static final String METH_SERVICE = "service";
  
      /** The repository of components. */
      static final Set m_repository = new HashSet();
  
      private final JavaClass m_javaClass;
      private final Properties m_attributes;
      private final List m_dependencies;
      private final Vertex m_vertex;
      private final List m_dependencyNames;
      private final List m_serviceNames;
  
      /**
       * Initialize a service with the type name.
       *
       * @param javaClass
       */
      public Component( final JavaClass javaClass )
      {
          if ( javaClass == null ) throw new NullPointerException( "javaClass" );
  
          m_javaClass = javaClass;
          m_attributes = new Properties();
          m_dependencies = new ArrayList( 10 );
          m_vertex = new Vertex( this );
          m_dependencyNames = new ArrayList( 10 );
          m_serviceNames = new ArrayList( 10 );
  
          final DocletTag[] tags = javaClass.getTagsByName( TAG_SERVICE );
          for ( int t = 0; t < tags.length; t++ )
          {
              if ( tags[t].getNamedParameter( Component.ATTR_TYPE ) == null )
              {
                  throw new BuildException( "The \"type\" tag is missing from the "
                      + "\"@" + TAG_SERVICE + "\" meta tag in "
                      + javaClass.getName() );
              }
  
              final String serviceName = resolveClassName( m_javaClass.getParentSource(),
                      tags[t].getNamedParameter( Component.ATTR_TYPE ) );
              m_serviceNames.add( serviceName );
          }
  
          discoverLifecycleType();
          discoverNameInfo();
          discoverDependencies();
  
          m_repository.add( this );
      }
  
      /**
       * Recursively discover dependencies from the local class hierarchy.  This does not,
and cannot
       * discover dependencies from classes from other JARs.
       */
      private void discoverDependencies()
      {
          JavaClass currClass = m_javaClass;
  
          while ( currClass != null && discoverDependencies( currClass ) )
          {
              currClass = currClass.getSuperJavaClass();
          }
      }
  
      /**
       * Discover the dependencies that this component class requires.
       *
       * @param fromClass  The JavaClass object to gather the dependency set from.
       */
      private boolean discoverDependencies( final JavaClass fromClass )
      {
          boolean isSuccessful = true;
  
          JavaMethod[] methods = fromClass.getMethods();
          for ( int i = 0; i < methods.length; i++ )
          {
              if ( methods[i].getName().equals( METH_SERVICE ) )
              {
                  if ( methods[i].getParameters().length == 1 && methods[i].getParameters()[0].getType().getValue().equals(
SERVICE_MANAGER ) )
                  {
                      DocletTag[] dependencies = methods[i].getTagsByName( TAG_DEPENDENCY
);
                      for ( int d = 0; d < dependencies.length; d++ )
                      {
                          if ( dependencies[d].getNamedParameter( ATTR_TYPE ) == null )
                          {
                              throw new BuildException( "The \"type\" tag is missing from
a "
                                  + "\"@" + TAG_DEPENDENCY + "\" meta tag of the " + METH_SERVICE
                                  + " method in " + fromClass.getName() );
                          }
  
                          String type = resolveClassName( fromClass.getParentSource(),
                                  dependencies[d].getNamedParameter( ATTR_TYPE ) );
                          //String optional = dependencies[d].getNamedParameter("optional");
  
                          if ( null == type )
                          {
                              isSuccessful = false;
                          }
                          else
                          {
                              m_dependencyNames.add( type );
                          }
                      }
                  }
              }
          }
  
          return isSuccessful;
      }
  
      private void discoverNameInfo()
      {
          DocletTag avalonConfigName = m_javaClass.getTagByName( TAG_INFO );
          if ( null == avalonConfigName ) avalonConfigName = m_javaClass.getTagByName( TAG_NAME
);
  
          String name = MetaInfoEntry.createShortName(m_javaClass.getName());
  
          if ( avalonConfigName != null )
          {
              name = avalonConfigName.getNamedParameter( ATTR_NAME );
          }
  
          setAttribute( META_NAME, name );
      }
  
      private void discoverLifecycleType()
      {
          final DocletTag avalonLifecycle = m_javaClass.getTagByName( TAG_LIFESTYLE );
          final DocletTag fortressHandler = m_javaClass.getTagByName( TAG_HANDLER );
          String lifecycle = null;
          String handler = null;
  
          if ( avalonLifecycle == null && fortressHandler == null )
          {
              final Type[] interfaces = m_javaClass.getImplements();
              for ( int i = 0; i < interfaces.length && handler != null; i++ )
              {
                  if ( interfaces[i].getClass().getName().equals( THREAD_SAFE ) )
                  {
                      handler = MetaInfoEntry.THREADSAFE_HANDLER;
                  }
                  else if ( interfaces[i].getClass().getName().equals( POOLABLE ) ||
                          interfaces[i].getClass().getName().equals( RECYCLABLE ) )
                  {
                      handler = MetaInfoEntry.POOLABLE_HANDLER;
                  }
                  else if ( interfaces[i].getClass().getName().equals( SINGLE_THREADED ) )
                  {
                      handler = MetaInfoEntry.FACTORY_HANDLER;
                  }
              }
          }
  
          if ( null != avalonLifecycle )       // lifecycle specified directly
          {
              lifecycle = stripQuotes( avalonLifecycle.getNamedParameter( ATTR_TYPE ) );
          }
          else if ( null != fortressHandler )  // handler specified directly
          {
              handler = stripQuotes( fortressHandler.getNamedParameter( ATTR_TYPE ) );
          }
          else // no lifecycle or handler specified, and no inspection match 
          {
              handler = MetaInfoEntry.PER_THREAD_HANDLER;
          }
  
          if ( null != lifecycle ) setAttribute( TAG_LIFESTYLE, lifecycle );
          if ( null != handler ) setAttribute( TAG_HANDLER, handler );
      }
  
      /**
       * Get the type name.
       *
       * @return String
       */
      public String getType()
      {
          return m_javaClass.getFullyQualifiedName();
      }
  
      public Iterator getDependencyNames()
      {
          return m_dependencyNames.iterator();
      }
  
      public Iterator getServiceNames()
      {
          return m_serviceNames.iterator();
      }
  
      /**
       * Add a dependency to this type.
       *
       * @param service  The name of the service that depends on this.
       */
      public void addDependency( Service service )
      {
          if ( !m_dependencies.contains( service ) )
          {
              m_dependencies.add( service );
          }
      }
  
      public Vertex getVertex()
      {
          if ( m_vertex.getDependencies().size() != 0 )
          {
              Iterator it = m_dependencies.iterator();
              while ( it.hasNext() )
              {
                  Service service = (Service) it.next();
  
                  Iterator cit = service.getComponents();
                  while ( cit.hasNext() )
                  {
                      Component component = (Component) cit.next();
                      m_vertex.addDependency( component.getVertex() );
                  }
              }
          }
          return m_vertex;
      }
  
      /**
       * Set the component attribute.
       *
       * @param name   The name of the attribute
       * @param value  The attribute value
       */
      public void setAttribute( final String name, final String value )
      {
          m_attributes.setProperty( name, value );
      }
  
      /**
       * Output the meta information.
       *
       * @param rootDir
       * @throws IOException
       */
      public void serialize( final File rootDir ) throws IOException
      {
          final String fileName = getType().replace( '.', '/' ).concat( ".meta" );
          final String depsName = getType().replace( '.', '/' ).concat( ".deps" );
          File output = new File( rootDir, fileName );
          FileOutputStream writer = null;
  
          try
          {
              writer = new FileOutputStream( output );
              m_attributes.store( writer, "Meta information for " + getType() );
  
              if ( m_dependencies.size() > 0 )
              {
                  writer.close();
                  output = new File( rootDir, depsName );
                  writer = new FileOutputStream( output );
  
                  Iterator it = m_dependencies.iterator();
                  while ( it.hasNext() )
                  {
                      Service service = (Service) it.next();
                      String name = service.getType() + "\n";
                      writer.write( name.getBytes() );
                  }
              }
          }
          finally
          {
              if ( null != writer )
              {
                  writer.close();
              }
          }
      }
  
      private String stripQuotes( final String value )
      {
          if ( null == value ) return null;
          if ( value.length() < 2 ) return value;
  
          String retVal = value.trim();
  
          if ( retVal.startsWith( "\"" ) && retVal.endsWith( "\"" ) )
          {
              retVal = retVal.substring( 1, retVal.length() - 1 );
          }
  
          return retVal;
      }
  
      /**
       * Resolve the classname from the "@avalon.service" javadoc tags.
       *
       * @param serviceName  The service type name
       * @return  The fully qualified class name
       */
      protected String resolveClassName( final JavaSource sourceCode, final String serviceName
)
      {
          if ( null == sourceCode )
          {
              return null;
          }
          if ( null == serviceName )
          {
              // This should be checked by the caller so that a message which better
              //  describes the problem in a given context can be given.
              throw new IllegalStateException( "The serviceName parameter was null." );
          }
  
          final String className = stripQuotes( serviceName );
  
          if ( className != null || className.length() > 0 )
          {
              if ( className.indexOf( '.' ) < 0 )
              {
                  String checkName = checkPackage(sourceCode, sourceCode.getPackage(), className);
                  if ( ! checkName.equals(className) ) return checkName;
  
                  String[] imports = sourceCode.getImports();
                  for ( int t = 0; t < imports.length; t++ )
                  {
                      checkName = checkImport( sourceCode, imports[t], className);
                      if ( ! checkName.equals( className ) ) return checkName;
                  }
              }
          }
  
          return className;
      }
  
      private String checkImport ( final JavaSource sourceCode, final String type, final String
className)
      {
          final String tail = type.substring( type.lastIndexOf( '.' ) + 1 );
  
          if ( tail.equals( className ) )
          {
              return type;
          }
          else if ( tail.equals( "*" ) )
          {
              final String pack = type.substring( 0, type.lastIndexOf( '.' ) );
  
              String checkName = checkPackage( sourceCode, pack, className );
              if ( !checkName.equals( className ) ) return checkName;
          }
  
          return className;
      }
  
      private String checkPackage( final JavaSource sourceCode, final String pack, final String
serviceName )
      {
          String className = serviceName;
          final JavaClass klass = sourceCode.getClassLibrary().getClassByName( pack + "."
+ serviceName );
          if ( null !=  klass )
              className = klass.getFullyQualifiedName();
          return className;
      }
  }
  
  
  
  1.1                  avalon-excalibur/fortress/meta/src/java/org/apache/avalon/fortress/tools/ComponentMetaInfoCollector.java
  
  Index: ComponentMetaInfoCollector.java
  ===================================================================
  /* 
   * Copyright 2003-2004 The 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.fortress.tools;
  
  import com.thoughtworks.qdox.ant.AbstractQdoxTask;
  import com.thoughtworks.qdox.model.DocletTag;
  import com.thoughtworks.qdox.model.JavaClass;
  
  import org.apache.avalon.fortress.util.dag.CyclicDependencyException;
  import org.apache.avalon.fortress.util.dag.DirectedAcyclicGraphVerifier;
  
  import org.apache.tools.ant.BuildException;
  import org.apache.tools.ant.Project;
  
  import java.io.File;
  import java.io.FileWriter;
  import java.io.IOException;
  import java.io.PrintWriter;
  
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.List;
  import java.util.Map;
  
  /**
   * ANT task to collect all the meta information for the components.
   *
   * @author <a href="mailto:dev@avalon.apache.org">The Avalon Team</a>
   * @version CVS $Revision: 1.1 $ $Date: 2004/04/02 08:29:44 $
   */
  public final class ComponentMetaInfoCollector extends AbstractQdoxTask
  {
      /**
       * The services to write the meta info for.
       */
      private final Map m_services = new HashMap();
  
      /**
       * The destination directory for metadata files.
       */
      private File m_destDir;
  
      /**
       * The service list destination.
       */
      private File m_serviceFile;
  
      private static final String TAG_COMPONENT = "avalon.component";
  
      /**
       * Set the destination directory for the meta information.
       *
       * @param destDir  The destination directory
       */
      public void setDestDir( final File destDir )
      {
          m_destDir = destDir;
      }
  
      /**
       * Execute generator task.
       *
       * @throws BuildException if there was a problem collecting the info
       */
      public void execute()
              throws BuildException
      {
          validate();
  
          log( "Writing Info descriptors as property files (.meta)." );
  
          super.execute();
  
          try
          {
              collectInfoMetaData();
              writeComponents();
  
              writeServiceList( m_services.values().iterator() );
  
              log( "Collecting service information." );
              writeServices();
          }
          catch ( final Exception e )
          {
              throw new BuildException( e.toString(), e );
          }
          finally
          {
              Component.m_repository.clear();
          }
      }
  
      /**
       * Write the component meta information to the associated files.
       *
       * @throws IOException if there is a problem.
       */
      private void writeComponents() throws IOException, CyclicDependencyException
      {
          final List dagVerifyList = new ArrayList( Component.m_repository.size() );
          final Iterator it = Component.m_repository.iterator();
          while ( it.hasNext() )
          {
              final Component comp = (Component) it.next();
              comp.serialize( m_destDir );
              dagVerifyList.add( comp.getVertex() );
          }
  
          DirectedAcyclicGraphVerifier.verify( dagVerifyList );
      }
  
      /**
       * Write the service list to the "/service.list" file.
       *
       * @param it  The iterator for the services
       * @throws IOException if there is a problem writing the file
       */
      public void writeServiceList( final Iterator it ) throws IOException
      {
          final PrintWriter writer = new PrintWriter( new FileWriter( m_serviceFile ) );
          int numServices = 0;
  
          while ( it.hasNext() )
          {
              writer.println( ( (Service) it.next() ).getType() );
              numServices++;
          }
  
          writer.close();
  
          if ( numServices == 0 )
          {
              m_serviceFile.delete();
          }
      }
  
      /**
       * Validate that the parameters are valid.
       */
      private void validate()
      {
          if ( null == m_destDir )
          {
              final String message =
                      "DestDir (" + m_destDir + ") not specified";
              throw new BuildException( message );
          }
  
          if ( !m_destDir.isDirectory() )
          {
              final String message =
                      "DestDir (" + m_destDir + ") is not a directory.";
              throw new BuildException( message );
          }
  
          if ( !m_destDir.exists() && !m_destDir.mkdirs() )
          {
              final String message =
                      "DestDir (" + m_destDir + ") could not be created.";
              throw new BuildException( message );
          }
  
          m_serviceFile = new File( m_destDir, "services.list" );
      }
  
      /**
       * Output the metadata files.
       */
      private void collectInfoMetaData()
      {
          final Iterator it = allClasses.iterator();
          while ( it.hasNext() )
          {
              final JavaClass javaClass = (JavaClass) it.next();
              final DocletTag tag = javaClass.getTagByName( TAG_COMPONENT );
  
              if ( null != tag )
              {
                  final Component comp = new Component( javaClass );
  
                  Iterator sit = comp.getServiceNames();
                  while ( sit.hasNext() )
                  {
                      String servName = (String) sit.next();
                      Service service = getService( servName );
                      service.addComponent( comp );
                  }
  
                  Iterator dit = comp.getDependencyNames();
                  while ( dit.hasNext() )
                  {
                      String depName = (String) dit.next();
                      Service service = getService( depName );
                      comp.addDependency( service );
                  }
              }
          }
      }
  
      /**
       * Get the unique Service object for the specified type.
       *
       * @param type  The service type name
       * @return the Service object
       */
      protected Service getService( final String type )
      {
          Service service = (Service) m_services.get( type );
  
          if ( null == service )
          {
              service = new Service( type );
              m_services.put( service.getType(), service );
          }
  
          return service;
      }
  
      /**
       * Collect all the services and write out the implementations.
       */
      private void writeServices()
      {
          final File baseDir = new File( m_destDir, "META-INF/services/" );
          baseDir.mkdirs();
  
          final Iterator services = m_services.values().iterator();
  
          while ( services.hasNext() )
          {
              final Service service = (Service) services.next();
              log( "Processing service " + service.getType(), Project.MSG_VERBOSE );
              try
              {
                  service.serialize( m_destDir );
              }
              catch ( Exception e )
              {
                  log( "Could not save information for service " + service.getType(), Project.MSG_WARN
);
              }
          }
      }
  }
  
  
  
  1.1                  avalon-excalibur/fortress/meta/src/java/org/apache/avalon/fortress/tools/Service.java
  
  Index: Service.java
  ===================================================================
  /* 
   * Copyright 2003-2004 The 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.fortress.tools;
  
  import java.io.File;
  import java.io.FileWriter;
  import java.io.IOException;
  import java.io.PrintWriter;
  import java.util.HashSet;
  import java.util.Iterator;
  import java.util.Set;
  
  /**
   * Encapsulate the Service information, and encapsulate all the
   * logic to serialize the service.
   *
   * @author <a href="mailto:dev@avalon.apache.org">The Avalon Team</a>
   * @version CVS $Revision: 1.1 $ $Date: 2004/04/02 08:29:44 $
   */
  final class Service
  {
      private final Set m_components;
  
      private final String m_type;
  
      /**
       * Initialize a service with the type name.
       *
       * @param type
       */
      public Service( final String type )
      {
          if ( type == null ) throw new NullPointerException( "type" );
  
          m_type = type;
          m_components = new HashSet();
      }
  
      /**
       * Get the service type name.
       *
       * @return  the type name
       */
      public String getType()
      {
          return m_type;
      }
  
      /**
       * Add a component to the service.
       *
       * @param type  the type name for the component
       */
      public void addComponent( final Component type )
      {
          if ( type == null ) throw new NullPointerException( "type" );
  
          m_components.add( type );
      }
  
      public Iterator getComponents()
      {
          return m_components.iterator();
      }
  
      /**
       * Output the service info.
       *
       * @param rootDir
       * @throws IOException
       */
      public void serialize( final File rootDir ) throws IOException
      {
          if ( m_components.isEmpty() ) return;
  
          final File serviceFile = new File( rootDir, "META-INF/services/" + getType() );
          PrintWriter writer = null;
  
          try
          {
              writer = new PrintWriter( new FileWriter( serviceFile ) );
  
              final Iterator it = m_components.iterator();
              while ( it.hasNext() )
              {
                  final Component comp = (Component) it.next();
                  writer.println( comp.getType() );
              }
          }
          finally
          {
              if ( null != writer )
              {
                  writer.close();
              }
          }
      }
  }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: cvs-unsubscribe@avalon.apache.org
For additional commands, e-mail: cvs-help@avalon.apache.org


Mime
View raw message