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);
//