You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by cz...@apache.org on 2004/11/04 11:24:23 UTC

svn commit: rev 56583 - in cocoon/trunk/src: core/java/org/apache/cocoon/components core/java/org/apache/cocoon/core/container samples/org/apache/cocoon/samples/parentcm

Author: cziegeler
Date: Thu Nov  4 02:24:21 2004
New Revision: 56583

Added:
   cocoon/trunk/src/core/java/org/apache/cocoon/components/ServiceInfo.java
Modified:
   cocoon/trunk/src/core/java/org/apache/cocoon/core/container/AbstractComponentHandler.java
   cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ComponentFactory.java
   cocoon/trunk/src/core/java/org/apache/cocoon/core/container/PoolableComponentHandler.java
   cocoon/trunk/src/samples/org/apache/cocoon/samples/parentcm/Configurator.java
Log:
Add class for meta information and move all avalon stuff into component factory

Added: cocoon/trunk/src/core/java/org/apache/cocoon/components/ServiceInfo.java
==============================================================================
--- (empty file)
+++ cocoon/trunk/src/core/java/org/apache/cocoon/components/ServiceInfo.java	Thu Nov  4 02:24:21 2004
@@ -0,0 +1,185 @@
+/*
+ * Copyright 1999-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.cocoon.components;
+
+import java.lang.reflect.Method;
+
+import org.apache.avalon.framework.configuration.Configuration;
+
+/**
+ * Meta-information about a service
+ *  
+ * @version CVS $Id: LifecycleHelper.java 55255 2004-10-21 19:41:15Z cziegeler $
+ */
+public class ServiceInfo {
+
+    public static final int MODEL_PRIMITIVE = 0;
+    public static final int MODEL_SINGLETON = 1;
+    public static final int MODEL_POOLED    = 2;
+    
+    private int model;
+    private String initMethodName;
+    private String destroyMethodName;
+    private String poolInMethodName;
+    private String poolOutMethodName;
+    private Class serviceClass;
+    private Method initMethod;
+    private Method destroyMethod;
+    private Method poolInMethod;
+    private Method poolOutMethod;
+    private Configuration configuration;
+    
+    public ServiceInfo() {
+        this.model = MODEL_PRIMITIVE;
+    }
+        
+    /**
+     * @return Returns the model.
+     */
+    public int getModel() {
+        return model;
+    }
+    
+    /**
+     * @param model The model to set.
+     */
+    public void setModel(int model) {
+        this.model = model;
+    }
+    
+    /**
+     * @return Returns the destroyMethod.
+     */
+    public String getDestroyMethodName() {
+        return destroyMethodName;
+    }
+    
+    /**
+     * @param destroyMethod The destroyMethod to set.
+     */
+    public void setDestroyMethodName(String destroyMethod) {
+        this.destroyMethodName = destroyMethod;
+    }
+    
+    /**
+     * @return Returns the initMethod.
+     */
+    public String getInitMethodName() {
+        return initMethodName;
+    }
+    
+    /**
+     * @param initMethod The initMethod to set.
+     */
+    public void setInitMethodName(String initMethod) {
+        this.initMethodName = initMethod;
+    }
+    
+    /**
+     * @return Returns the poolInMethodName
+     */
+    public String getPoolInMethodName() {
+        return this.poolInMethodName;
+    }
+    
+    /**
+     * @param poolMethod The poolInMethod name to set.
+     */
+    public void setPoolInMethodName(String poolMethod) {
+        this.poolInMethodName = poolMethod;
+    }
+    
+    /**
+     * @return Returns the poolOutMethodName
+     */
+    public String getPoolOutMethodName() {
+        return this.poolOutMethodName;
+    }
+    
+    /**
+     * @param poolMethod The poolOutMethod name to set.
+     */
+    public void setPoolOutMethodName(String poolMethod) {
+        this.poolOutMethodName = poolMethod;
+    }
+
+    /**
+     * @return Returns the destroyMethod.
+     */
+    public Method getDestroyMethod() throws Exception {
+        if ( this.destroyMethod == null && this.destroyMethodName != null ) {
+            this.destroyMethod = this.serviceClass.getMethod(this.destroyMethodName, null);
+        }
+        return destroyMethod;
+    }
+
+    /**
+     * @return Returns the initMethod.
+     */
+    public Method getInitMethod() throws Exception {
+        if ( this.initMethod == null && this.initMethodName != null ) {
+            this.initMethod = this.serviceClass.getMethod(this.initMethodName, null);
+        }
+        return initMethod;
+    }
+
+    /**
+     * @return Returns the poolInMethod.
+     */
+    public Method getPoolInMethod() throws Exception {
+        if ( this.poolInMethod == null && this.poolInMethodName != null ) {
+            this.poolInMethod = this.serviceClass.getMethod(this.poolInMethodName, null);
+        }
+        return poolInMethod;
+    }
+
+    /**
+     * @return Returns the poolInMethod.
+     */
+    public Method getPoolOutMethod() throws Exception {
+        if ( this.poolOutMethod == null && this.poolOutMethodName != null ) {
+            this.poolOutMethod = this.serviceClass.getMethod(this.poolOutMethodName, null);
+        }
+        return poolOutMethod;
+    }
+
+    /**
+     * @return Returns the serviceClass.
+     */
+    public Class getServiceClass() {
+        return serviceClass;
+    }
+    
+    /**
+     * @param serviceClass The serviceClass to set.
+     */
+    public void setServiceClass(Class serviceClass) {
+        this.serviceClass = serviceClass;
+    }
+        
+    /**
+     * @return Returns the configuration.
+     */
+    public Configuration getConfiguration() {
+        return configuration;
+    }
+    /**
+     * @param configuration The configuration to set.
+     */
+    public void setConfiguration(Configuration configuration) {
+        this.configuration = configuration;
+    }
+}

Modified: cocoon/trunk/src/core/java/org/apache/cocoon/core/container/AbstractComponentHandler.java
==============================================================================
--- cocoon/trunk/src/core/java/org/apache/cocoon/core/container/AbstractComponentHandler.java	(original)
+++ cocoon/trunk/src/core/java/org/apache/cocoon/core/container/AbstractComponentHandler.java	Thu Nov  4 02:24:21 2004
@@ -25,6 +25,7 @@
 import org.apache.avalon.framework.service.ServiceManager;
 import org.apache.avalon.framework.thread.SingleThreaded;
 import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.components.ServiceInfo;
 
 /**
  * This class acts like a Factory to instantiate the correct version
@@ -72,16 +73,29 @@
     throws Exception {
         int numInterfaces = 0;
 
+        final ServiceInfo info = new ServiceInfo();
+        info.setServiceClass(componentClass);
+        info.setConfiguration(configuration);
+        
+        // Early check for Composable
+        if ( Composable.class.isAssignableFrom( componentClass ) ) {
+            throw new Exception("Interface Composable is not supported anymore. Please change class "
+                                + componentClass.getName() + " to use Serviceable instead.");
+        }
+
         if( SingleThreaded.class.isAssignableFrom( componentClass ) ) {
             numInterfaces++;
+            info.setModel(ServiceInfo.MODEL_PRIMITIVE);
         }
 
         if( ThreadSafe.class.isAssignableFrom( componentClass ) ) {
             numInterfaces++;
+            info.setModel(ServiceInfo.MODEL_SINGLETON);
         }
 
         if( Poolable.class.isAssignableFrom( componentClass ) ) {
             numInterfaces++;
+            info.setModel(ServiceInfo.MODEL_POOLED);
         }
 
         if( numInterfaces > 1 ) {
@@ -90,27 +104,30 @@
                                  + "SingleThreaded, ThreadSafe, or Poolable" );
         }
 
-        // Early check for Composable
-        if ( Composable.class.isAssignableFrom( componentClass ) ) {
-            throw new Exception("Interface Composable is not supported anymore. Please change class "
-                                + componentClass.getName() + " to use Serviceable instead.");
+        if ( numInterfaces == 0 ) {
+            // test configuration
+            final String model = configuration.getAttribute("model", null);
+            if ( "pooled".equals(model) ) {
+                info.setModel(ServiceInfo.MODEL_POOLED);
+            } else if ( "singleton".equals(model) ) {
+                info.setModel(ServiceInfo.MODEL_SINGLETON);
+            }
         }
         
         // Create the factory to use to create the instances of the Component.
         ComponentFactory factory = new ComponentFactory( 
-                                         componentClass,
-                                         configuration,
                                          serviceManager,
                                          context,
                                          logger,
                                          loggerManager,
-                                         roleManager);
+                                         roleManager,
+                                         info);
 
         AbstractComponentHandler handler;
         
-        if( Poolable.class.isAssignableFrom( componentClass ) )  {
+        if( info.getModel() == ServiceInfo.MODEL_POOLED )  {
             handler = new PoolableComponentHandler( logger, factory, configuration );
-        } else if( ThreadSafe.class.isAssignableFrom( componentClass ) ) {
+        } else if( info.getModel() == ServiceInfo.MODEL_SINGLETON ) {
             handler = new ThreadSafeComponentHandler( logger, factory );
         } else {
             // This is a SingleThreaded component

Modified: cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ComponentFactory.java
==============================================================================
--- cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ComponentFactory.java	(original)
+++ cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ComponentFactory.java	Thu Nov  4 02:24:21 2004
@@ -16,8 +16,10 @@
  */
 package org.apache.cocoon.core.container;
 
+import java.lang.reflect.Method;
+
 import org.apache.avalon.excalibur.logger.LoggerManager;
-import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.excalibur.pool.Recyclable;
 import org.apache.avalon.framework.container.ContainerUtil;
 import org.apache.avalon.framework.context.Context;
 import org.apache.avalon.framework.logger.LogEnabled;
@@ -25,6 +27,7 @@
 import org.apache.avalon.framework.parameters.Parameterizable;
 import org.apache.avalon.framework.parameters.Parameters;
 import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.components.ServiceInfo;
 
 /**
  * Factory for Avalon based components.
@@ -33,11 +36,8 @@
  */
 public class ComponentFactory {
     
-    /** The class which this <code>ComponentFactory</code>
-     * should create.
-     */
-    private final Class componentClass;
-
+    private final ServiceInfo serviceInfo;
+    
     /** The Context for the component
      */
     private final Context context;
@@ -46,10 +46,6 @@
      */
     private final ServiceManager serviceManager;
     
-    /** The configuration for this component.
-     */
-    private final Configuration configuration;
-
     /** The parameters for this component
      */
     private Parameters parameters;
@@ -69,20 +65,18 @@
      * @param context the <code>Context</code> to pass to <code>Contexutalizable</code>s.
      *
      */
-    public ComponentFactory( final Class componentClass,
-                             final Configuration configuration,
-                             final ServiceManager serviceManager,
+    public ComponentFactory( final ServiceManager serviceManager,
                              final Context context,
                              final Logger logger,
                              final LoggerManager loggerManager,
-                             final RoleManager roleManager) {
-        this.componentClass = componentClass;
-        this.configuration = configuration;
+                             final RoleManager roleManager,
+                             final ServiceInfo info) {
         this.serviceManager = serviceManager;
         this.context = context;
         this.logger = logger;
         this.loggerManager = loggerManager;
         this.roleManager = roleManager;
+        this.serviceInfo = info;
     }
 
     /**
@@ -90,18 +84,18 @@
      */
     public Object newInstance()
     throws Exception {
-        final Object component = this.componentClass.newInstance();
+        final Object component = this.serviceInfo.getServiceClass().newInstance();
 
         if( this.logger.isDebugEnabled() ) {
             this.logger.debug( "ComponentFactory creating new instance of " +
-                    this.componentClass.getName() + "." );
+                    this.serviceInfo.getServiceClass().getName() + "." );
         }
 
         if ( component instanceof LogEnabled ) {
-            if( null == this.configuration ) {
+            if( this.serviceInfo.getConfiguration() != null ) {
                 ContainerUtil.enableLogging( component, this.logger );
             } else {
-                final String logger = this.configuration.getAttribute( "logger", null );
+                final String logger = this.serviceInfo.getConfiguration().getAttribute( "logger", null );
                 if( null == logger ) {
                     this.logger.debug( "no logger attribute available, using standard logger" );
                     ContainerUtil.enableLogging( component, this.logger );
@@ -120,24 +114,29 @@
             ((CocoonServiceSelector)component).setRoleManager(this.roleManager);
         }
         
-        ContainerUtil.configure( component, this.configuration );
+        ContainerUtil.configure( component, this.serviceInfo.getConfiguration() );
 
         if( component instanceof Parameterizable ) {
             if ( this.parameters == null ) {
-                this.parameters = Parameters.fromConfiguration( this.configuration );
+                this.parameters = Parameters.fromConfiguration( this.serviceInfo.getConfiguration() );
             }
             ContainerUtil.parameterize( component, this.parameters );
         }
 
         ContainerUtil.initialize( component );
 
+        final Method method = this.serviceInfo.getInitMethod();
+        if ( method != null ) {
+            method.invoke(component, null);
+        }
+
         ContainerUtil.start( component );
 
         return component;
     }
 
     public Class getCreatedClass() {
-        return this.componentClass;
+        return this.serviceInfo.getServiceClass();
     }
 
     /**
@@ -147,11 +146,41 @@
     throws Exception {
         if( this.logger.isDebugEnabled() ) {
             this.logger.debug( "ComponentFactory decommissioning instance of " +
-                    this.componentClass.getName() + "." );
+                    this.serviceInfo.getServiceClass().getName() + "." );
         }
 
         ContainerUtil.stop( component );
         ContainerUtil.dispose( component );
+
+        final Method method = this.serviceInfo.getDestroyMethod();
+        if ( method != null ) {
+            method.invoke(component, null);
+        }
     }
 
+    /**
+     * Handle service specific methods for getting it out of the pool
+     */
+    public void exitingPool( final Object component )
+    throws Exception {
+        final Method method = this.serviceInfo.getPoolOutMethod();
+        if ( method != null ) {
+            method.invoke(component, null);
+        }         
+    }
+
+    /**
+     * Handle service specific methods for putting it into the pool
+     */
+    public void enteringPool( final Object component )
+    throws Exception {
+        // Handle Recyclable objects
+        if( component instanceof Recyclable ) {
+            ( (Recyclable)component ).recycle();
+        }
+        final Method method = this.serviceInfo.getPoolInMethod();
+        if ( method != null ) {
+            method.invoke(component, null);
+        }         
+    }
 }

Modified: cocoon/trunk/src/core/java/org/apache/cocoon/core/container/PoolableComponentHandler.java
==============================================================================
--- cocoon/trunk/src/core/java/org/apache/cocoon/core/container/PoolableComponentHandler.java	(original)
+++ cocoon/trunk/src/core/java/org/apache/cocoon/core/container/PoolableComponentHandler.java	Thu Nov  4 02:24:21 2004
@@ -19,7 +19,6 @@
 import java.util.Iterator;
 import java.util.LinkedList;
 
-import org.apache.avalon.excalibur.pool.Recyclable;
 import org.apache.avalon.framework.configuration.Configuration;
 import org.apache.avalon.framework.logger.Logger;
 
@@ -114,7 +113,7 @@
         synchronized( this.semaphore ) {
             // Remove objects in the ready list.
             for( Iterator iter = this.ready.iterator(); iter.hasNext(); ) {
-                Object poolable = (Object)iter.next();
+                Object poolable = iter.next();
                 iter.remove();
                 this.readySize--;
                 this.permanentlyRemovePoolable( poolable );
@@ -169,6 +168,8 @@
             }
         }
 
+        this.factory.exitingPool(poolable);
+        
         if( this.logger.isDebugEnabled() ) {
             this.logger.debug( "Got a " + poolable.getClass().getName() + " from the pool." );
         }
@@ -182,14 +183,14 @@
      * @param poolable Poolable to return to the pool.
      */
     protected void doPut( final Object poolable ) {
-        // Handle Recyclable objects
-        if( poolable instanceof Recyclable ) {
-            ( (Recyclable)poolable ).recycle();
+        try {
+            this.factory.enteringPool(poolable);
+        } catch (Exception ignore) {
+            this.logger.warn("Exception during putting component back into the pool.", ignore);
         }
 
         synchronized( this.semaphore ) {
-            if( this.size <= this.max )
-            {
+            if( this.size <= this.max ) {
                 if( this.disposed ) {
                     // The pool has already been disposed.
                     if( this.logger.isDebugEnabled() ) {

Modified: cocoon/trunk/src/samples/org/apache/cocoon/samples/parentcm/Configurator.java
==============================================================================
--- cocoon/trunk/src/samples/org/apache/cocoon/samples/parentcm/Configurator.java	(original)
+++ cocoon/trunk/src/samples/org/apache/cocoon/samples/parentcm/Configurator.java	Thu Nov  4 02:24:21 2004
@@ -48,9 +48,9 @@
             //
             DefaultConfiguration config = new DefaultConfiguration("roles", "");
             DefaultConfiguration timeComponent = new DefaultConfiguration("role", "roles");
-            timeComponent.addAttribute("name", Time.ROLE);
-            timeComponent.addAttribute("default-class", TimeComponent.class.getName());
-            timeComponent.addAttribute("shorthand", "samples-parentcm-time");
+            timeComponent.setAttribute("name", Time.ROLE);
+            timeComponent.setAttribute("default-class", TimeComponent.class.getName());
+            timeComponent.setAttribute("shorthand", "samples-parentcm-time");
             config.addChild(timeComponent);
 
             //