leosutic    2004/03/10 14:38:29

  Added:       aspect   project.xml
               aspect/src/java/org/apache/avalon/aspect AbstractAspect.java
                        Aspect.java Avalon4ComponentHandler.java
                        DefaultKernel.java EventBus.java Handler.java
                        Kernel.java KernelEventListener.java
                        LifecycleInterceptable.java
                        LifecycleInterceptor.java LoggingAspect.java
                        SecurityAspect.java ServiceManagerAspect.java
               aspect/src/test/org/apache/avalon/aspect/test
                        AspectTestCase.java
  Log:
  Initial checkin
  
  Revision  Changes    Path
  1.1                  avalon-sandbox/aspect/project.xml
  
  Index: project.xml
  ===================================================================
  <?xml version="1.0" encoding="ISO-8859-1"?>
  
  <project>
      
      <pomVersion>3</pomVersion>
      <groupId>avalon-aspect</groupId>
      <id>avalon-aspect</id>
      <name>Aspect-oriented Container</name>
      <currentVersion>1.0</currentVersion>
      
      <organization>
          <name>Apache Software Foundation</name>
          <url>http://avalon.apache.org/</url>
          <logo>http://avalon.apache.org/images/apache-avalon-logo.png</logo>
      </organization>
      <inceptionYear>1997</inceptionYear>
      
      <package></package>
      <gumpRepositoryId>avalon-sandbox</gumpRepositoryId>
      
      <url>http://avalon.apache.org/sandbox/aspect/index.html</url>
      <issueTrackingUrl>http://nagoya.apache.org/</issueTrackingUrl>
      
      <siteAddress>avalon.apache.org</siteAddress>
      <siteDirectory>${root.site.directory}/aspect</siteDirectory>
      <distributionDirectory></distributionDirectory>
      
      <repository>
          <connection>scm:cvs:pserver:[EMAIL 
PROTECTED]:/home/cvspublic:avalon-sandbox/aspect</connection>
          <url>http://cvs.apache.org/viewcvs/avalon-sandbox/aspect/</url>
      </repository>
      
      <mailingLists>
          <mailingList>
              <name>Avalon Developer List</name>
              <subscribe>[EMAIL PROTECTED]</subscribe>
              <unsubscribe>[EMAIL PROTECTED]</unsubscribe>
              <archive>http://nagoya.apache.org/eyebrowse/[EMAIL PROTECTED]</archive>
          </mailingList>
          <mailingList>
              <name>Avalon User List</name>
              <subscribe>[EMAIL PROTECTED]</subscribe>
              <unsubscribe>[EMAIL PROTECTED]</unsubscribe>
              <archive>http://nagoya.apache.org/eyebrowse/[EMAIL PROTECTED]</archive>
          </mailingList>
      </mailingLists>
      
      <developers>
          <developer>
              <name>None</name>
              <id>none</id>
              <email>[EMAIL PROTECTED]</email>
              <organization>The Apache Software Foundation</organization>
              <roles>
                  <role>None</role>
              </roles>
          </developer>
      </developers>
      
      <contributors>
      </contributors>
      
      <build>
          
          <nagEmailAddress>[EMAIL PROTECTED]</nagEmailAddress>
          <sourceDirectory>${basedir}/src/java</sourceDirectory>
          <unitTestSourceDirectory>${basedir}/src/test</unitTestSourceDirectory>
          <integrationUnitTestSourceDirectory/>
          <aspectSourceDirectory/>
          
          <unitTest>
              <includes>
                  <include>**/*TestCase.*</include>
              </includes>
              <excludes>
                  <include>**/Abstract*.*</include>
              </excludes>
              <resources>
                  <resource>
                      <directory>${basedir}/src/test</directory>
                      <includes> 
                          <include>**/*.dtd</include>
                          <include>**/*.properties</include>
                          <include>**/*.xinfo</include>
                          <include>**/*.xtype</include>
                          <include>**/*.xprofile</include>
                          <include>**/*.xconfig</include>
                          <include>**/*.xml</include>
                          <include>**/*.xservice</include>
                          <include>**/*.mf</include>
                          <include>**/*.jar</include>
                          <include>**/*.properties</include>
                      </includes>
                  </resource>
                  <resource>
                      <directory>${basedir}/conf</directory>
                      <includes> 
                          <include>**/*.properties</include>
                      </includes>
                  </resource>
                  <!-- This fix makes aspect build with maven-10 again -->
                  <resource>
                      <directory>${basedir}/conf</directory>
                      <includes> 
                          <include>**/*.properties</include>
                      </includes>
                  </resource>
                  <resource>
                      <directory>${basedir}/src/test/conf</directory>
                      <includes> 
                          <include>**/*</include>
                      </includes>
                  </resource>
              </resources>
          </unitTest>
          
          <integrationUnitTestPatterns></integrationUnitTestPatterns>
          
          <resources>
              <resource>
                  <directory>${basedir}/src/java</directory>
                  <includes>
                      <include>**/*.dtd</include>
                      <include>**/*.properties</include>
                      <include>**/*.xinfo</include>
                      <include>**/*.xtype</include>
                      <include>**/*.xprofile</include>
                      <include>**/*.xconfig</include>
                      <include>**/*.xml</include>
                      <include>**/*.xservice</include>
                  </includes>
              </resource>
              <resource>
                  <directory>${basedir}/../</directory>
                  <includes>
                      <include>LICENSE.txt</include>
                  </includes>
              </resource>
              <resource>
                  <directory>${basedir}/conf</directory>
                  <targetPath>BLOCK-INF</targetPath>
                  <includes>
                      <include>block.xml</include>
                  </includes>
              </resource>
              <resource>
                  <directory>${basedir}/conf</directory>
                  <includes> 
                      <include>**/*.properties</include>
                  </includes>
              </resource>
          </resources>
          
          <jars></jars>
      </build>
      
      <dependencies>
          <dependency>
              <groupId>avalon-framework</groupId>
              <artifactId>avalon-framework-api</artifactId>
              <version>4.1.5</version>
          </dependency>
          <dependency>
              <groupId>avalon-framework</groupId>
              <artifactId>avalon-framework-impl</artifactId>
              <version>4.1.5</version>
          </dependency>
      </dependencies>
      
  </project>
  
  
  
  1.1                  
avalon-sandbox/aspect/src/java/org/apache/avalon/aspect/AbstractAspect.java
  
  Index: AbstractAspect.java
  ===================================================================
  package org.apache.avalon.aspect;
  
  public abstract class AbstractAspect implements Aspect, KernelEventListener {
      
      private Kernel kernel;
      
      protected Kernel getKernel () {
          return kernel;
      }
      
      public final void initAspect (Kernel kernel) {
          this.kernel = kernel;
          init ();
          String[] aspectKeys = kernel.getAspects ();
          for (int i = 0; i < aspectKeys.length; i++) {
              applyToAspect (aspectKeys[i], kernel.getAspect (aspectKeys[i]));
          }
          String[] handlerKeys = kernel.getAspects ();
          for (int i = 0; i < handlerKeys.length; i++) {
              applyToHandler (handlerKeys[i], kernel.getHandler (handlerKeys[i]));
          }
          kernel.registerEventListener (KernelEventListener.class, this);
      }
      
      protected void init () {
      }
      
      protected void applyToHandler (String key, Handler handler) {
          apply (key, handler);
      }
      
      protected void applyToAspect (String key, Aspect aspect) {
          apply (key, aspect);
      }
      
      protected abstract void apply (String key, Object object);
      
      public void handlerAdded (String key, Handler handler) {
          applyToHandler (key, handler);
      }
      
      public void aspectAdded (String key, Aspect aspect) {
          applyToAspect (key, aspect);
      }
      
  }
  
  
  1.1                  
avalon-sandbox/aspect/src/java/org/apache/avalon/aspect/Aspect.java
  
  Index: Aspect.java
  ===================================================================
  package org.apache.avalon.aspect;
  
  public interface Aspect {
      public void initAspect (Kernel kernel);
  }
  
  
  1.1                  
avalon-sandbox/aspect/src/java/org/apache/avalon/aspect/Avalon4ComponentHandler.java
  
  Index: Avalon4ComponentHandler.java
  ===================================================================
  package org.apache.avalon.aspect;
  
  import java.util.ArrayList;
  import java.util.List;
  import java.util.Iterator;
  
  import org.apache.avalon.framework.logger.LogEnabled;
  import org.apache.avalon.framework.logger.Logger;
  import org.apache.avalon.framework.logger.NullLogger;
  import org.apache.avalon.framework.service.Serviceable;
  import org.apache.avalon.framework.service.ServiceManager;
  
  /**
   * Handles singleton A4 components. Right now, we only support the LogEnabled and 
Serviceable interfaces.
   */
  public class Avalon4ComponentHandler implements Handler, LogEnabled, 
LifecycleInterceptable, Serviceable {
      
      private final Class componentClass;
      private Object instance = null;
      private Logger logger = new NullLogger ();
      private List lifecycleInterceptors = new ArrayList ();
      private ServiceManager serviceManager;
      
      public Avalon4ComponentHandler (Class componentClass) {
          this.componentClass = componentClass;
      }
      
      public void addLifecycleInterceptor (LifecycleInterceptor interceptor) {
          lifecycleInterceptors.add (interceptor);
      }
      
      public void enableLogging (Logger logger) {
          this.logger = logger;
      }
      
      public synchronized Object get (String accessor) {
          if (instance == null) {
              newInstance ();
          }
          
          Object lookedUpInstance = instance;
          
          Iterator iter = lifecycleInterceptors.iterator ();
          while (iter.hasNext ()) {
              Object interceptedInstance = ((LifecycleInterceptor) iter.next 
()).interceptAccess (accessor, lookedUpInstance);
              lookedUpInstance = interceptedInstance;
          }
          
          return lookedUpInstance;
      }
      
      public void release (String accessor, Object o) {
      }
      
      public void service (ServiceManager serviceManager) {
          this.serviceManager = serviceManager;
      }
      
      public void newInstance () {
          try {
              instance = componentClass.newInstance ();
              if (instance instanceof LogEnabled) {
                  ((LogEnabled) instance).enableLogging (logger);
              }
              
              if (instance instanceof Serviceable) {
                  ((Serviceable) instance).service (serviceManager);
              }
              
              Iterator iter = lifecycleInterceptors.iterator ();
              while (iter.hasNext ()) {
                  Object interceptedInstance = ((LifecycleInterceptor) iter.next 
()).interceptCreation (instance);
                  instance = interceptedInstance;
              }
              
              // Hold on, why aren't we giving the logger/service manager as part of an
              // interceptCreation call? Why the classic (instance instanceof 
LogEnabled)?
              //
              // Answer: Because you can't guarantee that the component can accept a 
logger / serviceManager
              // after it has been created (PicoContainer components, for example, must
              // receive the logger/serviceManager in the constructor). Therefore this 
can not be 
              // an done by intercepting the creation....
          } catch (Exception e) {
              e.printStackTrace ();
          }
      }
      
  }
  
  
  1.1                  
avalon-sandbox/aspect/src/java/org/apache/avalon/aspect/DefaultKernel.java
  
  Index: DefaultKernel.java
  ===================================================================
  package org.apache.avalon.aspect;
  
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.Map;
  
  public class DefaultKernel implements Kernel {
      
      private final EventBus eventBus = new EventBus ();
      
      private final Map aspects = new HashMap ();
      private final Map handlers = new HashMap ();
      
      public void addAspect (String name, Aspect aspect) {
          aspect.initAspect(this);
          aspects.put(name, aspect);
          Iterator iter = getEventListeners (KernelEventListener.class);
          while (iter.hasNext ()) {
              ((KernelEventListener) iter.next ()).aspectAdded (name, aspect);
          }
      }
      
      public Aspect getAspect (String name) {
          return (Aspect) aspects.get (name);
      }
      
      public String[] getAspects () {
          return (String[]) aspects.keySet ().toArray(new String[0]);
      }
      
      public void addHandler (String name, Handler handler) {
          handlers.put (name, handler);
          Iterator iter = getEventListeners (KernelEventListener.class);
          while (iter.hasNext ()) {
              ((KernelEventListener) iter.next ()).handlerAdded (name, handler);
          }        
      }
  
      public Handler getHandler (String name) {
          return (Handler) handlers.get (name);
      }
      
      public String[] getHandlers () {
          return (String[]) handlers.keySet ().toArray(new String[0]);
      }
      
      public void registerEventListener (Class eventListenerClass, Object listener) {
          eventBus.registerEventListener (eventListenerClass, listener);
      }
      
      public void unregisterEventListener (Class eventListenerClass, Object listener) {
          eventBus.unregisterEventListener (eventListenerClass, listener);
      }
      
      public Iterator getEventListeners (Class eventListenerClass) {
          return eventBus.getEventListeners (eventListenerClass);
      }
  }
  
  
  1.1                  
avalon-sandbox/aspect/src/java/org/apache/avalon/aspect/EventBus.java
  
  Index: EventBus.java
  ===================================================================
  package org.apache.avalon.aspect;
  
  import java.util.ArrayList;
  import java.util.Iterator;
  import java.util.List;
  import java.util.HashMap;
  import java.util.Map;
  
  public class EventBus {
      
      private final Map listeners = new HashMap ();
      private final List EMPTY_LIST = new ArrayList ();
      
      public void registerEventListener (Class eventListenerClass, Object listener) {
          synchronized (this) {
              List li = (List) listeners.get (eventListenerClass);
              List newList = null;
              if (li != null) {
                  newList = new ArrayList (li);
              } else {
                  newList = new ArrayList ();
              }
              newList.add (listener);
              
              listeners.put (eventListenerClass, newList);
          }
      }
      
      public void unregisterEventListener (Class eventListenerClass, Object listener) {
          synchronized (this) {
              List li = (List) listeners.get (eventListenerClass);
              List newList = null;
              if (li != null) {
                  newList = new ArrayList (li);
              } else {
                  newList = new ArrayList ();
              }
              newList.remove (listener);
              if (newList.size () == 0) {
                  listeners.remove (eventListenerClass);
              } else {
                  listeners.put (eventListenerClass, newList);
              }
          }
      }
      
      public Iterator getEventListeners (Class eventListenerClass) {
          synchronized (this) {
              List li = (List) listeners.get (eventListenerClass);
              if (li != null) {
                  return li.iterator ();
              } else {
                  return EMPTY_LIST.iterator ();
              }
          }
      }
  }
  
  
  1.1                  
avalon-sandbox/aspect/src/java/org/apache/avalon/aspect/Handler.java
  
  Index: Handler.java
  ===================================================================
  package org.apache.avalon.aspect;
  
  public interface Handler {
      public Object get (String accessor);
      public void release (String accessor, Object o);
  }
  
  
  1.1                  
avalon-sandbox/aspect/src/java/org/apache/avalon/aspect/Kernel.java
  
  Index: Kernel.java
  ===================================================================
  package org.apache.avalon.aspect;
  
  import java.util.Iterator;
  
  public interface Kernel {
      void addAspect (String name, Aspect aspect);
      Aspect getAspect (String name);
      String[] getAspects ();
      
      void addHandler (String name, Handler handler);
      Handler getHandler (String name);
      String[] getHandlers ();
      
      void   registerEventListener (Class eventListenerClass, Object listener);
      void   unregisterEventListener (Class eventListenerClass, Object listener);
      Iterator getEventListeners (Class eventListenerClass);
  }
  
  
  1.1                  
avalon-sandbox/aspect/src/java/org/apache/avalon/aspect/KernelEventListener.java
  
  Index: KernelEventListener.java
  ===================================================================
  package org.apache.avalon.aspect;
  
  public interface KernelEventListener {
      public void handlerAdded (String key, Handler handler);
      public void aspectAdded (String key, Aspect aspect);
  }
  
  
  1.1                  
avalon-sandbox/aspect/src/java/org/apache/avalon/aspect/LifecycleInterceptable.java
  
  Index: LifecycleInterceptable.java
  ===================================================================
  package org.apache.avalon.aspect;
  
  public interface LifecycleInterceptable {
      public void addLifecycleInterceptor (LifecycleInterceptor interceptor);
  }
  
  
  1.1                  
avalon-sandbox/aspect/src/java/org/apache/avalon/aspect/LifecycleInterceptor.java
  
  Index: LifecycleInterceptor.java
  ===================================================================
  package org.apache.avalon.aspect;
  
  public interface LifecycleInterceptor {
      public Object interceptCreation (Object instance);
      public Object interceptAccess (String accessor, Object instance);
  }
  
  
  1.1                  
avalon-sandbox/aspect/src/java/org/apache/avalon/aspect/LoggingAspect.java
  
  Index: LoggingAspect.java
  ===================================================================
  package org.apache.avalon.aspect;
  
  import org.apache.avalon.framework.logger.ConsoleLogger;
  import org.apache.avalon.framework.logger.Logger;
  import org.apache.avalon.framework.logger.LogEnabled;
  
  /**
   * Supplies a Logger.
   *
   * <p>Applies to: Any LogEnabled Handler or Aspect
   */
  public class LoggingAspect extends AbstractAspect {
      
      private final Logger logger;
      
      public LoggingAspect (Logger logger) {
          this.logger = logger;
      }
      
      public void apply (String key, Object object) {
          if (object instanceof LogEnabled) {
              ((LogEnabled) object).enableLogging (logger.getChildLogger (key));
          }
      }
  }
  
  
  1.1                  
avalon-sandbox/aspect/src/java/org/apache/avalon/aspect/SecurityAspect.java
  
  Index: SecurityAspect.java
  ===================================================================
  package org.apache.avalon.aspect;
  
  import java.lang.reflect.Proxy;
  import java.lang.reflect.InvocationHandler;
  import java.lang.reflect.Method;
  
  import org.apache.avalon.framework.logger.ConsoleLogger;
  import org.apache.avalon.framework.logger.Logger;
  import org.apache.avalon.framework.logger.LogEnabled;
  import org.apache.avalon.framework.logger.NullLogger;
  import org.apache.avalon.framework.service.Serviceable;
  import org.apache.avalon.framework.service.ServiceManager;
  
  /**
   * Supplies a very simple security manager. (Allow everything, just log it.)
   *
   * <p>Applies to: Any LifecycleInterceptable Handler
   */
  public class SecurityAspect extends AbstractAspect implements LogEnabled {
      
      private Logger logger = new NullLogger ();
      
      public void applyToHandler (String key, Handler handler) {
          if (handler instanceof LifecycleInterceptable) {
              ((LifecycleInterceptable) handler).addLifecycleInterceptor (new 
SecurityInterceptor (key));
          }
      }
      
      public void apply (String key, Object object) {
      }
      
      public void enableLogging (Logger logger) {
          this.logger = logger;
      }
      
      private class SecurityInterceptor implements LifecycleInterceptor {
          
          private final String accessed;
          
          public SecurityInterceptor (String accessed) {
              this.accessed = accessed;
          }
          
          public Object interceptCreation (Object instance) {
              return instance;
          }
          
          public Object interceptAccess (String accessor, Object instance) {
              try {
                  Class[] proxyInterfaces = instance.getClass ().getInterfaces ();
                  InvocationHandler securityHandler = new SecurityInvocationHandler 
(accessor, accessed, instance);
                  
                  return Proxy.newProxyInstance(instance.getClass ().getClassLoader(),
                      proxyInterfaces,
                      securityHandler);
              } catch (Exception e) {
                  logger.error ("Unable to proxy: " + e, e);
                  return instance;
              }
          }
      }
      
      private class SecurityInvocationHandler implements InvocationHandler {
          
          private final String accessor;
          private final String accessed;
          private final Object instance;
          
          public SecurityInvocationHandler (String accessor, String accessed, Object 
instance) {
              this.accessor = accessor;
              this.accessed = accessed;
              this.instance = instance;
          }
          
          public Object invoke(Object proxy, Method method, Object[] args) throws 
Throwable {
              logger.warn ("'" + accessor + "' is invoking method " + method.getName 
() + " in '" + accessed + "'");
              return method.invoke (instance, args);
          }
      }
  }
  
  
  1.1                  
avalon-sandbox/aspect/src/java/org/apache/avalon/aspect/ServiceManagerAspect.java
  
  Index: ServiceManagerAspect.java
  ===================================================================
  package org.apache.avalon.aspect;
  
  import org.apache.avalon.framework.logger.ConsoleLogger;
  import org.apache.avalon.framework.logger.Logger;
  import org.apache.avalon.framework.logger.LogEnabled;
  import org.apache.avalon.framework.service.Serviceable;
  import org.apache.avalon.framework.service.ServiceManager;
  
  /**
   * Supplies a ServiceManager.
   *
   * <p>Applies to: Any Serviceable Handler
   */
  public class ServiceManagerAspect extends AbstractAspect {
      
      public void applyToHandler (String key, Handler handler) {
          if (handler instanceof Serviceable) {
              try {
                  ((Serviceable) handler).service (new ServiceManagerImpl (key));
              } catch (Exception e) {
                  e.printStackTrace ();
              }
          }
      }
      
      public void apply (String key, Object object) {
      }
      
      private class ServiceManagerImpl implements ServiceManager {
          
          private final String accessor;
          
          public ServiceManagerImpl (String accessor) {
              this.accessor = accessor;
          }
          
          public boolean hasService (String key) {
              Handler h = getKernel ().getHandler (key);
              return h != null;
          }
          
          public Object lookup (String key) {
              Handler h = getKernel ().getHandler (key);
              return h.get (accessor);
          }
          
          public void release (Object o) {
              // Do something smart here...
          }
      }
  }
  
  
  1.1                  
avalon-sandbox/aspect/src/test/org/apache/avalon/aspect/test/AspectTestCase.java
  
  Index: AspectTestCase.java
  ===================================================================
  package org.apache.avalon.aspect.test;
  
  import org.apache.avalon.aspect.*;
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  import org.apache.avalon.framework.logger.ConsoleLogger;
  import org.apache.avalon.framework.service.Serviceable;
  import org.apache.avalon.framework.service.ServiceManager;
  import junit.framework.TestCase;
  
  public class AspectTestCase extends TestCase {
      
      public static interface InterfaceA {
          public void methodA () throws Exception;
      }
      
      public static interface InterfaceB{
          public void methodB () throws Exception;
      }
      
      public static class ComponentA extends AbstractLogEnabled implements InterfaceA, 
Serviceable {
          
          private ServiceManager manager;
          
          public void service (ServiceManager manager) {
              this.manager = manager;
          }
          
          public void methodA () throws Exception {
              getLogger ().info ("methodA called");
              
              InterfaceB b = (InterfaceB) manager.lookup ("b");
              b.methodB ();
              manager.release (b);
              
              getLogger ().info ("methodA returning");
          }
      } 
      
      public static class ComponentB extends AbstractLogEnabled implements InterfaceB {
          public void methodB () throws Exception {
              getLogger ().info ("methodB called & returning");
          }
      } 
      
      public void testAll () throws Exception {
          Kernel kernel = new DefaultKernel ();
          kernel.addAspect ("logging", new LoggingAspect (new ConsoleLogger ()));
          kernel.addAspect ("servicemanager", new ServiceManagerAspect ());
          kernel.addAspect ("security", new SecurityAspect ());
          
          kernel.addHandler ("a", new Avalon4ComponentHandler (ComponentA.class));
          kernel.addHandler ("b", new Avalon4ComponentHandler (ComponentB.class));
          
          Handler aHandler = kernel.getHandler ("a");
          InterfaceA a = (InterfaceA) aHandler.get ("AspectTestCase");
          a.methodA ();
          aHandler.release ("AspectTestCase", a);
      }
  }
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to