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 2006/02/13 13:37:18 UTC
svn commit: r377366 - in /cocoon/trunk/cocoon-core: ./
src/main/java/org/apache/cocoon/
src/main/java/org/apache/cocoon/components/source/impl/
src/main/java/org/apache/cocoon/core/container/spring/
Author: cziegeler
Date: Mon Feb 13 04:37:14 2006
New Revision: 377366
URL: http://svn.apache.org/viewcvs?rev=377366&view=rev
Log:
Adding prototype for spring based container
Added:
cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/
cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/ApplicationContextFactory.java (with props)
cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/AvalonEnvironment.java (with props)
cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/AvalonServiceManager.java (with props)
cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/AvalonServiceSelector.java (with props)
cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/CocoonSettingsConfigurer.java (with props)
cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/CocoonXmlWebApplicationContext.java (with props)
cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/ComponentInfo.java (with props)
cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/ConfigReader.java (with props)
cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/ConfigurationInfo.java (with props)
cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/PoolableFactoryBean.java (with props)
cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/XmlConfigCreator.java (with props)
Modified:
cocoon/trunk/cocoon-core/pom.xml
cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/Cocoon.java
cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/components/source/impl/ContextSourceFactory.java
Modified: cocoon/trunk/cocoon-core/pom.xml
URL: http://svn.apache.org/viewcvs/cocoon/trunk/cocoon-core/pom.xml?rev=377366&r1=377365&r2=377366&view=diff
==============================================================================
--- cocoon/trunk/cocoon-core/pom.xml (original)
+++ cocoon/trunk/cocoon-core/pom.xml Mon Feb 13 04:37:14 2006
@@ -305,6 +305,11 @@
<artifactId>jakarta-bcel</artifactId>
<version>20040329</version>
</dependency>
+ <dependency>
+ <groupId>springframework</groupId>
+ <artifactId>spring</artifactId>
+ <version>1.2.6</version>
+ </dependency>
</dependencies>
<profiles>
<profile>
Modified: cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/Cocoon.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/Cocoon.java?rev=377366&r1=377365&r2=377366&view=diff
==============================================================================
--- cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/Cocoon.java (original)
+++ cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/Cocoon.java Mon Feb 13 04:37:14 2006
@@ -42,11 +42,16 @@
import org.apache.cocoon.core.Core;
import org.apache.cocoon.core.Settings;
import org.apache.cocoon.core.container.RoleManager;
+import org.apache.cocoon.core.container.spring.ApplicationContextFactory;
+import org.apache.cocoon.core.container.spring.AvalonEnvironment;
+import org.apache.cocoon.core.container.spring.ConfigReader;
+import org.apache.cocoon.core.container.spring.ConfigurationInfo;
import org.apache.cocoon.environment.Environment;
import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.cocoon.environment.Request;
import org.apache.cocoon.environment.Session;
import org.apache.cocoon.environment.internal.EnvironmentHelper;
+import org.apache.cocoon.servlet.CocoonServlet;
import org.apache.cocoon.util.location.Location;
import org.apache.cocoon.util.location.LocationImpl;
import org.apache.cocoon.util.location.LocationUtils;
@@ -55,6 +60,7 @@
import org.apache.excalibur.source.Source;
import org.apache.excalibur.source.SourceResolver;
import org.apache.excalibur.source.impl.URLSource;
+import org.springframework.context.ApplicationContext;
import org.xml.sax.InputSource;
import java.io.BufferedInputStream;
@@ -64,6 +70,8 @@
import java.util.HashMap;
import java.util.Map;
+import javax.servlet.ServletConfig;
+
/**
* The Cocoon Object is the main Kernel for the entire Cocoon system.
*
@@ -223,7 +231,7 @@
this.loggerManager = loggerManager;
}
- /* (non-Javadoc)
+ /**
* @see org.apache.avalon.framework.activity.Initializable#initialize()
*/
public void initialize() throws Exception {
@@ -239,6 +247,20 @@
throw new ConfigurationException(
"Could not open configuration file: " + settings.getConfiguration(), e);
}
+
+ // Test setup spring container
+ System.out.println("Setting up test Spring container");
+ AvalonEnvironment env = new AvalonEnvironment();
+ env.context = this.context;
+ env.core = this.core;
+ env.logger = this.getLogger();
+ env.servletContext = ((ServletConfig)this.context.get(CocoonServlet.CONTEXT_SERVLET_CONFIG)).getServletContext();
+ env.settings = this.core.getSettings();
+ ApplicationContext rootContext = ApplicationContextFactory.createRootApplicationContext(env);
+ ConfigurationInfo result = ConfigReader.readConfiguration(this.configurationFile.getURI(), env);
+ ApplicationContext mainContext = ApplicationContextFactory.createApplicationContext(env, result, rootContext);
+ System.out.println("Getting something from mainContext: " + mainContext.getBean(Core.ROLE));
+ // END Test setup
this.serviceManager = new CocoonServiceManager(this.parentServiceManager);
ContainerUtil.enableLogging(this.serviceManager, this.rootLogger.getChildLogger("manager"));
Modified: cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/components/source/impl/ContextSourceFactory.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/components/source/impl/ContextSourceFactory.java?rev=377366&r1=377365&r2=377366&view=diff
==============================================================================
--- cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/components/source/impl/ContextSourceFactory.java (original)
+++ cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/components/source/impl/ContextSourceFactory.java Mon Feb 13 04:37:14 2006
@@ -34,6 +34,7 @@
import org.apache.avalon.framework.thread.ThreadSafe;
import org.apache.cocoon.Constants;
import org.apache.cocoon.environment.Context;
+import org.apache.cocoon.servlet.CocoonServlet;
import org.apache.commons.lang.BooleanUtils;
import org.apache.excalibur.source.Source;
import org.apache.excalibur.source.SourceException;
@@ -82,7 +83,7 @@
throws ContextException {
this.envContext = (Context)context.get(Constants.CONTEXT_ENVIRONMENT_CONTEXT);
try {
- this.servletContext = ((ServletConfig) context.get("servlet-config")).getServletContext();
+ this.servletContext = ((ServletConfig) context.get(CocoonServlet.CONTEXT_SERVLET_CONFIG)).getServletContext();
} catch (ContextException ignore) {
// in other environments (CLI etc.), we don't have a servlet context
}
Added: cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/ApplicationContextFactory.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/ApplicationContextFactory.java?rev=377366&view=auto
==============================================================================
--- cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/ApplicationContextFactory.java (added)
+++ cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/ApplicationContextFactory.java Mon Feb 13 04:37:14 2006
@@ -0,0 +1,192 @@
+/*
+ * Copyright 2006 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.core.container.spring;
+
+import java.util.Map;
+
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.DefaultConfiguration;
+import org.apache.avalon.framework.container.ContainerUtil;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.logger.Logger;
+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.core.Core;
+import org.apache.cocoon.core.Settings;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.BeanCreationException;
+import org.springframework.beans.factory.BeanFactory;
+import org.springframework.beans.factory.BeanInitializationException;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor;
+import org.springframework.context.ApplicationContext;
+import org.springframework.core.io.ByteArrayResource;
+import org.springframework.core.io.Resource;
+import org.springframework.web.context.WebApplicationContext;
+
+/**
+ * This factory creates new Spring {@link ApplicationContext} objects which support
+ * the Avalon style component configuration.
+ *
+ * @since 2.2
+ * @version $Id$
+ */
+public class ApplicationContextFactory {
+
+ /**
+ * Create a new (sub) application context.
+ *
+ * @param env
+ * @param info
+ * @param parent The parent application context or null.
+ * @return A new application context
+ * @throws Exception
+ */
+ public static ApplicationContext createApplicationContext(AvalonEnvironment env,
+ ConfigurationInfo info,
+ ApplicationContext parent)
+ throws Exception {
+ final String xmlConfig = (new XmlConfigCreator()).createConfig(info.getComponents());
+ Resource rsc = new ByteArrayResource(xmlConfig.getBytes("utf-8"));
+ CocoonXmlWebApplicationContext context = new CocoonXmlWebApplicationContext(rsc, parent);
+ context.addBeanFactoryPostProcessor(new CocoonSettingsConfigurer(env.settings));
+
+ // TODO: Add context specific information
+ //context.setSourceResolver(this.resolver);
+ //context.setEnvironmentHelper(this.environmentHelper);
+ context.setServletContext(env.servletContext);
+ AvalonPostProcessor processor = new AvalonPostProcessor();
+ processor.components = info.getComponents();
+ processor.logger = env.logger;
+ if ( info.rootLogger != null ) {
+ processor.logger = env.logger.getChildLogger(info.rootLogger);
+ }
+ processor.context = env.context;
+ context.refresh();
+ processor.beanFactory = context.getBeanFactory();
+ context.getBeanFactory().addBeanPostProcessor(processor);
+ if ( info.rootLogger != null ) {
+ context.getBeanFactory().registerSingleton(Logger.class.getName(), processor.logger);
+ }
+ return context;
+ }
+
+ /**
+ * Create the root application context.
+ * This context is the root of all Cocoon based Spring application contexts. If
+ * the default Spring context is created using the Spring context listener, that
+ * default context will be the parent of this root context.
+ *
+ * @param env
+ * @return A new root application context.
+ * @throws Exception
+ */
+ public static ApplicationContext createRootApplicationContext(AvalonEnvironment env)
+ throws Exception {
+ final ApplicationContext parent = (ApplicationContext)env.servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
+ CocoonXmlWebApplicationContext context = new CocoonXmlWebApplicationContext(null, parent);
+ context.refresh();
+ final ConfigurableListableBeanFactory factory = context.getBeanFactory();
+ factory.registerSingleton(Context.class.getName(), env.context);
+ factory.registerSingleton(Logger.class.getName(), env.logger);
+ factory.registerSingleton(Core.class.getName(), env.core);
+ factory.registerSingleton(Settings.class.getName(), env.settings);
+ return context;
+ }
+
+ /**
+ * This is a Spring BeanPostProcessor adding support for the Avalon lifecycle interfaces.
+ */
+ protected static final class AvalonPostProcessor implements DestructionAwareBeanPostProcessor {
+
+ protected static final Configuration EMPTY_CONFIG = new DefaultConfiguration("empty");
+
+ protected Logger logger;
+ protected Context context;
+ protected BeanFactory beanFactory;
+ protected Map components;
+
+ /**
+ * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization(java.lang.Object, java.lang.String)
+ */
+ public Object postProcessAfterInitialization(Object bean, String beanName)
+ throws BeansException {
+ try {
+ ContainerUtil.start(bean);
+ } catch (Exception e) {
+ throw new BeanInitializationException("Unable to start bean " + beanName, e);
+ }
+ return bean;
+ }
+
+ /**
+ * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization(java.lang.Object, java.lang.String)
+ */
+ public Object postProcessBeforeInitialization(Object bean, String beanName)
+ throws BeansException {
+ final ComponentInfo info = (ComponentInfo)this.components.get(beanName);
+ if ( info == null ) {
+ // no info so just return as this is not an Avalon component
+ return bean;
+ }
+ try {
+ if ( info.getLoggerCategory() != null ) {
+ ContainerUtil.enableLogging(bean, this.logger.getChildLogger(info.getLoggerCategory()));
+ } else {
+ ContainerUtil.enableLogging(bean, this.logger);
+ }
+ ContainerUtil.contextualize(bean, context);
+ ContainerUtil.service(bean, (ServiceManager)this.beanFactory.getBean(ServiceManager.class.getName()));
+ if ( info != null ) {
+ Configuration config = info.getConfiguration();
+ if ( config == null ) {
+ config = EMPTY_CONFIG;
+ }
+ if ( bean instanceof Configurable ) {
+ ContainerUtil.configure(bean, config);
+ } else if ( bean instanceof Parameterizable ) {
+ Parameters p = info.getParameters();
+ if ( p == null ) {
+ p = Parameters.fromConfiguration(config);
+ info.setParameters(p);
+ }
+ ContainerUtil.parameterize(bean, p);
+ }
+ }
+ ContainerUtil.initialize(bean);
+ } catch (Exception e) {
+ throw new BeanCreationException("Unable to initialize Avalon component with role " + beanName, e);
+ }
+ return bean;
+ }
+
+ /**
+ * @see org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor#postProcessBeforeDestruction(java.lang.Object, java.lang.String)
+ */
+ public void postProcessBeforeDestruction(Object bean, String beanName)
+ throws BeansException {
+ try {
+ ContainerUtil.stop(bean);
+ } catch (Exception e) {
+ throw new BeanInitializationException("Unable to stop bean " + beanName, e);
+ }
+ ContainerUtil.dispose(bean);
+ }
+ }
+}
Propchange: cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/ApplicationContextFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/ApplicationContextFactory.java
------------------------------------------------------------------------------
svn:keywords = Id
Added: cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/AvalonEnvironment.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/AvalonEnvironment.java?rev=377366&view=auto
==============================================================================
--- cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/AvalonEnvironment.java (added)
+++ cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/AvalonEnvironment.java Mon Feb 13 04:37:14 2006
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2006 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.core.container.spring;
+
+import javax.servlet.ServletContext;
+
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.cocoon.core.Core;
+import org.apache.cocoon.core.Settings;
+
+/**
+ * This is a simple bean used to pass all Avalon related environment information
+ * to the application context.
+ *
+ * @since 2.2
+ * @version $Id$
+ */
+public final class AvalonEnvironment {
+ public ServletContext servletContext;
+ public Context context;
+ public Logger logger;
+ public Core core;
+ public Settings settings;
+}
\ No newline at end of file
Propchange: cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/AvalonEnvironment.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/AvalonEnvironment.java
------------------------------------------------------------------------------
svn:keywords = Id
Added: cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/AvalonServiceManager.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/AvalonServiceManager.java?rev=377366&view=auto
==============================================================================
--- cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/AvalonServiceManager.java (added)
+++ cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/AvalonServiceManager.java Mon Feb 13 04:37:14 2006
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2006 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.core.container.spring;
+
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.BeanFactory;
+import org.springframework.beans.factory.BeanFactoryAware;
+
+/**
+ * This bean acts like a Avalon {@link ServiceManager}.
+ *
+ * @since 2.2
+ * @version $Id$
+ */
+final class AvalonServiceManager
+ implements ServiceManager, BeanFactoryAware {
+
+
+ protected BeanFactory beanFactory;
+
+ public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
+ this.beanFactory = beanFactory;
+ }
+
+ /**
+ * @see org.apache.avalon.framework.service.ServiceManager#hasService(java.lang.String)
+ */
+ public boolean hasService(String role) {
+ return this.beanFactory.containsBean(role);
+ }
+
+ /**
+ * @see org.apache.avalon.framework.service.ServiceManager#lookup(java.lang.String)
+ */
+ public Object lookup(String role) throws ServiceException {
+ if ( !this.hasService(role) ) {
+ throw new ServiceException("AvalonServiceManager",
+ "Component with '" + role + "' is not defined in this service manager.");
+ }
+ return this.beanFactory.getBean(role);
+ }
+
+ /**
+ * @see org.apache.avalon.framework.service.ServiceManager#release(java.lang.Object)
+ */
+ public void release(Object component) {
+ // we never release
+ }
+}
\ No newline at end of file
Propchange: cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/AvalonServiceManager.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/AvalonServiceManager.java
------------------------------------------------------------------------------
svn:keywords = Id
Added: cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/AvalonServiceSelector.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/AvalonServiceSelector.java?rev=377366&view=auto
==============================================================================
--- cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/AvalonServiceSelector.java (added)
+++ cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/AvalonServiceSelector.java Mon Feb 13 04:37:14 2006
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2006 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.core.container.spring;
+
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.ServiceSelector;
+
+/**
+ * This bean acts like a Avalon {@link ServiceSelector}.
+ *
+ * @since 2.2
+ * @version $Id$
+ */
+public class AvalonServiceSelector implements ServiceSelector {
+
+ protected final String role;
+ protected final ServiceManager manager;
+ protected String defaultKey;
+
+ public AvalonServiceSelector(ServiceManager manager, String r) {
+ this.role = r + '/';
+ this.manager = manager;
+ }
+
+ public void setDefault(String value) {
+ this.defaultKey = value;
+ }
+
+ /**
+ * @see org.apache.avalon.framework.service.ServiceSelector#select(java.lang.Object)
+ */
+ public Object select(Object key) throws ServiceException {
+ if ( key == null || key.toString().length() == 0 ) {
+ key = this.defaultKey;
+ }
+ return this.manager.lookup(this.role + key);
+ }
+
+ /**
+ * @see org.apache.avalon.framework.service.ServiceSelector#isSelectable(java.lang.Object)
+ */
+ public boolean isSelectable(Object key) {
+ return this.manager.hasService(this.role + key);
+ }
+
+ /**
+ * @see org.apache.avalon.framework.service.ServiceSelector#release(java.lang.Object)
+ */
+ public void release(Object component) {
+ this.manager.release(component);
+ }
+}
Propchange: cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/AvalonServiceSelector.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/AvalonServiceSelector.java
------------------------------------------------------------------------------
svn:keywords = Id
Added: cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/CocoonSettingsConfigurer.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/CocoonSettingsConfigurer.java?rev=377366&view=auto
==============================================================================
--- cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/CocoonSettingsConfigurer.java (added)
+++ cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/CocoonSettingsConfigurer.java Mon Feb 13 04:37:14 2006
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2005-2006 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.core.container.spring;
+
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.cocoon.core.Settings;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.BeanDefinitionStoreException;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.BeanDefinitionVisitor;
+import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
+
+/**
+ * Make the properties of the Cocoon settings available within Spring configuration.
+ *
+ * @since 2.2
+ * @version $Id$
+ */
+public class CocoonSettingsConfigurer
+ extends PropertyPlaceholderConfigurer
+ implements BeanFactoryPostProcessor {
+
+ protected final Settings settings;
+
+ public CocoonSettingsConfigurer(Settings settings) {
+ this.settings = settings;
+ }
+
+ /**
+ * @see org.springframework.beans.factory.config.PropertyPlaceholderConfigurer#processProperties(org.springframework.beans.factory.config.ConfigurableListableBeanFactory, java.util.Properties)
+ */
+ protected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess,
+ Properties props)
+ throws BeansException {
+ final BeanDefinitionVisitor visitor = new CocoonSettingsResolvingBeanDefinitionVisitor(this.settings);
+ String[] beanNames = beanFactoryToProcess.getBeanDefinitionNames();
+ for (int i = 0; i < beanNames.length; i++) {
+ BeanDefinition bd = beanFactoryToProcess.getBeanDefinition(beanNames[i]);
+ try {
+ visitor.visitBeanDefinition(bd);
+ } catch (BeanDefinitionStoreException ex) {
+ throw new BeanDefinitionStoreException(bd
+ .getResourceDescription(), beanNames[i], ex
+ .getMessage());
+ }
+ }
+ }
+
+ protected class CocoonSettingsResolvingBeanDefinitionVisitor
+ extends BeanDefinitionVisitor {
+
+ protected final Properties props;
+
+ public CocoonSettingsResolvingBeanDefinitionVisitor(Settings settings) {
+ this.props = new Properties();
+
+ List propsList = settings.getProperties();
+ for (int i = 0; i < propsList.size(); i++) {
+ String propName = (String) propsList.get(i);
+ props.put(propName, settings.getProperty(propName));
+ }
+ }
+
+ protected String resolveStringValue(String strVal) {
+ return parseStringValue(strVal, this.props, null);
+ }
+ }
+
+}
Propchange: cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/CocoonSettingsConfigurer.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/CocoonSettingsConfigurer.java
------------------------------------------------------------------------------
svn:keywords = Id
Added: cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/CocoonXmlWebApplicationContext.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/CocoonXmlWebApplicationContext.java?rev=377366&view=auto
==============================================================================
--- cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/CocoonXmlWebApplicationContext.java (added)
+++ cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/CocoonXmlWebApplicationContext.java Mon Feb 13 04:37:14 2006
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2006 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.core.container.spring;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+
+import org.apache.avalon.framework.CascadingRuntimeException;
+import org.apache.cocoon.environment.internal.EnvironmentHelper;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceResolver;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
+import org.springframework.context.ApplicationContext;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.UrlResource;
+import org.springframework.web.context.support.XmlWebApplicationContext;
+
+/**
+ * This is a Cocoon specific implementation of a Spring {@link ApplicationContext}.
+ *
+ * @since 2.2
+ * @version $Id$
+ */
+public class CocoonXmlWebApplicationContext extends XmlWebApplicationContext {
+
+ public static final String DEFAULT_SPRING_CONFIG = "conf/applicationContext.xml";
+
+ final private Resource avalonResource;
+ protected SourceResolver resolver;
+ protected String baseURL;
+
+
+ public CocoonXmlWebApplicationContext(Resource avalonResource,
+ ApplicationContext parent) {
+ this.setParent(parent);
+ this.avalonResource = avalonResource;
+ }
+
+ /**
+ * @see org.springframework.web.context.support.XmlWebApplicationContext#loadBeanDefinitions(org.springframework.beans.factory.xml.XmlBeanDefinitionReader)
+ */
+ protected void loadBeanDefinitions(XmlBeanDefinitionReader reader)
+ throws BeansException, IOException {
+ super.loadBeanDefinitions(reader);
+ if ( this.avalonResource != null ) {
+ reader.loadBeanDefinitions(this.avalonResource);
+ }
+ }
+
+ public void setSourceResolver(SourceResolver aResolver) {
+ this.resolver = aResolver;
+ }
+
+ public void setEnvironmentHelper(EnvironmentHelper eh) {
+ this.baseURL = eh.getContext();
+ if ( !this.baseURL.endsWith("/") ) {
+ this.baseURL = this.baseURL + '/';
+ }
+ }
+
+ /**
+ * Resolve file paths beneath the root of the web application.
+ * <p>Note: Even if a given path starts with a slash, it will get
+ * interpreted as relative to the web application root directory
+ * (which is the way most servlet containers handle such paths).
+ * @see org.springframework.web.context.support.ServletContextResource
+ */
+ protected Resource getResourceByPath(String path) {
+ if ( path.startsWith("/") ) {
+ path = path.substring(1);
+ }
+ path = this.baseURL + path;
+ try {
+ return new UrlResource(path);
+ } catch (MalformedURLException mue) {
+ // FIXME - for now, we simply call super
+ return super.getResourceByPath(path);
+ }
+ }
+
+ /**
+ * The default location for the context is "conf/applicationContext.xml"
+ * which is searched relative to the current sitemap.
+ * @return The default config locations if they exist otherwise an empty array.
+ */
+ protected String[] getDefaultConfigLocations() {
+ if ( this.resolver != null ) {
+ Source testSource = null;
+ try {
+ testSource = this.resolver.resolveURI(DEFAULT_SPRING_CONFIG);
+ if (testSource.exists()) {
+ return new String[] {DEFAULT_SPRING_CONFIG};
+ }
+ } catch(MalformedURLException e) {
+ throw new CascadingRuntimeException("Malformed URL when resolving Spring default config location [ " + DEFAULT_SPRING_CONFIG + "]. This is an unrecoverable programming error. Check the code where this exception was thrown.", e);
+ } catch(IOException e) {
+ throw new CascadingRuntimeException("Cannot resolve default config location ["+ DEFAULT_SPRING_CONFIG + "] due to an IOException. See cause for details.", e);
+ } finally {
+ this.resolver.release(testSource);
+ }
+ }
+ return new String[]{};
+ }
+
+}
Propchange: cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/CocoonXmlWebApplicationContext.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/CocoonXmlWebApplicationContext.java
------------------------------------------------------------------------------
svn:keywords = Id
Added: cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/ComponentInfo.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/ComponentInfo.java?rev=377366&view=auto
==============================================================================
--- cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/ComponentInfo.java (added)
+++ cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/ComponentInfo.java Mon Feb 13 04:37:14 2006
@@ -0,0 +1,221 @@
+/*
+ * Copyright 2006 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.core.container.spring;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.parameters.Parameters;
+
+/**
+ * Meta-information about a component.
+ *
+ * @since 2.2
+ * @version $Id$
+ */
+public final class ComponentInfo {
+
+ public static final int MODEL_UNKNOWN = -1;
+ public static final int MODEL_PRIMITIVE = 0;
+ public static final int MODEL_SINGLETON = 1;
+ public static final int MODEL_POOLED = 2;
+ public static final int MODEL_NON_THREAD_SAFE_POOLED = 3;
+
+ public static final String TYPE_SINGLETON = "singleton";
+ public static final String TYPE_POOLED = "pooled";
+ public static final String TYPE_NON_THREAD_SAFE_POOLED = "non-thread-safe-pooled";
+
+ private int model;
+ private String initMethodName;
+ private String destroyMethodName;
+ private String poolInMethodName;
+ private String poolOutMethodName;
+ private String serviceClassName;
+ private Configuration configuration;
+ private Parameters parameters;
+ private String loggerCategory;
+ private String role;
+
+ public ComponentInfo() {
+ 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 serviceClassName.
+ */
+ public String getServiceClassName() {
+ return serviceClassName;
+ }
+
+ /**
+ * @param serviceClassName The serviceClassName to set.
+ */
+ public void setServiceClassName(String serviceClassName) {
+ this.serviceClassName = serviceClassName;
+ }
+
+ /**
+ * @return Returns the configuration.
+ */
+ public Configuration getConfiguration() {
+ return configuration;
+ }
+
+ /**
+ * @param configuration The configuration to set.
+ */
+ public void setConfiguration(Configuration configuration) {
+ this.configuration = configuration;
+ }
+
+ public String getLocation() {
+ return this.configuration.getLocation();
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ return "ServiceInfo: {class=" + this.getServiceClassName()+"}";
+ }
+
+ public void fill(Configuration attr) {
+ // test model
+ final String model = attr.getAttribute("model", null);
+ if ( TYPE_POOLED.equals(model) ) {
+ this.setModel(ComponentInfo.MODEL_POOLED);
+ this.setPoolInMethodName(attr.getAttribute("pool-in", null));
+ this.setPoolOutMethodName(attr.getAttribute("pool-out", null));
+ } else if (TYPE_NON_THREAD_SAFE_POOLED.equals(model)) {
+ this.setModel(ComponentInfo.MODEL_NON_THREAD_SAFE_POOLED);
+ this.setPoolInMethodName(attr.getAttribute("pool-in", null));
+ this.setPoolOutMethodName(attr.getAttribute("pool-out", null));
+ } else if ( TYPE_SINGLETON.equals(model) ) {
+ this.setModel(ComponentInfo.MODEL_SINGLETON);
+ }
+ // init/destroy methods
+ this.setInitMethodName(attr.getAttribute("init", null));
+ this.setDestroyMethodName(attr.getAttribute("destroy", null));
+ // logging
+ this.setLoggerCategory(attr.getAttribute("logger", null));
+ this.setRole(attr.getAttribute("role", null));
+ }
+
+ /**
+ * @return Returns the loggerCategory.
+ */
+ public String getLoggerCategory() {
+ return this.loggerCategory;
+ }
+
+ /**
+ * @param loggerCategory The loggerCategory to set.
+ */
+ public void setLoggerCategory(String loggerCategory) {
+ this.loggerCategory = loggerCategory;
+ }
+
+ /**
+ * @param role The role to set.
+ */
+ public void setRole( String role ) {
+ this.role = role;
+ }
+
+ /**
+ * @return Returns the role.
+ */
+ public String getRole() {
+ return role;
+ }
+
+ public Parameters getParameters() {
+ return parameters;
+ }
+
+ public void setParameters(Parameters parameters) {
+ this.parameters = parameters;
+ }
+
+}
Propchange: cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/ComponentInfo.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/ComponentInfo.java
------------------------------------------------------------------------------
svn:keywords = Id
Added: cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/ConfigReader.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/ConfigReader.java?rev=377366&view=auto
==============================================================================
--- cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/ConfigReader.java (added)
+++ cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/ConfigReader.java Mon Feb 13 04:37:14 2006
@@ -0,0 +1,392 @@
+/*
+ * Copyright 2006 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.core.container.spring;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.configuration.DefaultConfigurationSerializer;
+import org.apache.cocoon.configuration.ConfigurationBuilder;
+import org.apache.cocoon.core.source.SimpleSourceResolver;
+import org.apache.cocoon.matching.helpers.WildcardHelper;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceResolver;
+import org.apache.excalibur.source.TraversableSource;
+
+/**
+ * This component reads in Avalon style configuration files and returns all
+ * contained components and their configurations.
+ *
+ * @since 2.2
+ * @version $Id$
+ */
+public class ConfigReader {
+
+ /** Parameter map for the context protocol */
+ protected static final Map CONTEXT_PARAMETERS = Collections.singletonMap("force-traversable", Boolean.TRUE);
+
+ protected SourceResolver resolver;
+
+ /** Map for shorthand to role mapping. */
+ private final Map shorthands = new HashMap();
+
+ /** Map for role to default classname mapping. */
+ private final Map classNames = new HashMap();
+
+ /** Map for role->key to classname mapping. */
+ private final Map keyClassNames = new HashMap();
+
+ /** List of components. */
+ private final Map components = new HashMap();
+
+ /** Root logger. */
+ private String rootLogger;
+
+ /** Avalon environment. */
+ private AvalonEnvironment environment;
+
+ public static ConfigurationInfo readConfiguration(String source, AvalonEnvironment env)
+ throws Exception {
+ final SimpleSourceResolver sourceResolver = new SimpleSourceResolver();
+ sourceResolver.enableLogging(env.logger);
+ sourceResolver.contextualize(env.context);
+
+ ConfigReader converter = new ConfigReader();
+ converter.resolver = sourceResolver;
+ converter.environment = env;
+
+ converter.convert(source);
+
+ ConfigurationInfo info = new ConfigurationInfo();
+ info.setComponents(converter.components);
+ info.setRootLogger(converter.rootLogger);
+ return info;
+ }
+
+ public ConfigReader() {
+ // nothing to do
+ }
+
+ protected void convert(String relativePath)
+ throws Exception {
+ final Source root = this.resolver.resolveURI(relativePath);
+ try {
+ ConfigurationBuilder b = new ConfigurationBuilder(this.environment.settings);
+ Configuration config = b.build(root.getInputStream());
+
+ // It's possible to define a logger on a per sitemap/service manager base.
+ // This is the default logger for all components defined with this sitemap/manager.
+ this.rootLogger = config.getAttribute("logger", null);
+
+ // and load configuration with a empty list of loaded configurations
+ parseConfiguration(config, root.getURI(), new HashSet());
+ final Iterator i = this.classNames.values().iterator();
+ while ( i.hasNext() ) {
+ final ComponentInfo current = (ComponentInfo)i.next();
+ this.components.put(current.getRole(), current);
+ }
+ } finally {
+ this.resolver.release(root);
+ }
+ }
+
+ protected void parseConfiguration(final Configuration configuration,
+ String contextURI,
+ Set loadedURIs)
+ throws ConfigurationException {
+ final Configuration[] configurations = configuration.getChildren();
+
+ for( int i = 0; i < configurations.length; i++ ) {
+ final Configuration componentConfig = configurations[i];
+
+ final String componentName = componentConfig.getName();
+
+ if ("include".equals(componentName)) {
+ this.handleInclude(contextURI, loadedURIs, componentConfig);
+
+ } else {
+ // Component declaration
+ // Find the role
+ String role = componentConfig.getAttribute("role", null);
+ if (role == null) {
+ // Get the role from the role manager if not explicitely specified
+ role = (String)this.shorthands.get( componentName );
+ if (role == null) {
+ // Unknown role
+ throw new ConfigurationException("Unknown component type '" + componentName +
+ "' at " + componentConfig.getLocation());
+ }
+ }
+
+ // Find the className
+ String className = componentConfig.getAttribute("class", null);
+ ComponentInfo info;
+ if (className == null) {
+ // Get the default class name for this role
+ info = (ComponentInfo)this.classNames.get( role );
+ if (info == null) {
+ throw new ConfigurationException("Cannot find a class for role " + role + " at " + componentConfig.getLocation());
+ }
+ this.classNames.remove(info);
+ className = info.getServiceClassName();
+ } else {
+ info = new ComponentInfo();
+ }
+ // If it has a "name" attribute, add it to the role (similar to the
+ // declaration within a service selector)
+ // Note: this has to be done *after* finding the className above as we change the role
+ String name = componentConfig.getAttribute("name", null);
+ if (name != null) {
+ role = role + "/" + name;
+ }
+ info.fill(componentConfig);
+ info.setServiceClassName(className);
+ info.setRole(role);
+ info.setConfiguration(componentConfig);
+
+ this.components.put(info.getRole(), info);
+ // now if this is a selector, then we have to register the single components
+ if ( info.getConfiguration() != null && className.endsWith("Selector") ) {
+ String classAttribute = null;
+ if ( className.equals("org.apache.cocoon.core.container.DefaultServiceSelector") ) {
+ classAttribute = "class";
+ } else if (className.equals("org.apache.cocoon.components.treeprocessor.sitemap.ComponentsSelector") ) {
+ classAttribute = "src";
+ }
+ if ( classAttribute == null ) {
+ // TODO: Unknown selector
+ try {
+ System.out.println("** Found unknown selector: " + className);
+ DefaultConfigurationSerializer dcs = new DefaultConfigurationSerializer();
+ System.out.println(dcs.serialize(info.getConfiguration()));
+ System.out.println("----------------------------------------------------");
+ } catch (Exception ignore) {
+ }
+ } else {
+ String componentRole = role;
+ if ( componentRole.endsWith("Selector") ) {
+ componentRole = componentRole.substring(0, componentRole.length() - 8);
+ }
+ componentRole += '/';
+ Configuration[] children = info.getConfiguration().getChildren();
+ for (int j=0; j<children.length; j++) {
+ final Configuration current = children[j];
+ final ComponentInfo childInfo = new ComponentInfo();
+ childInfo.fill(current);
+ childInfo.setConfiguration(current);
+ childInfo.setServiceClassName(current.getAttribute(classAttribute));
+ childInfo.setRole(componentRole + current.getAttribute("name"));
+ this.components.put(childInfo.getRole(), childInfo);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ protected void handleInclude(final String contextURI,
+ final Set loadedURIs,
+ final Configuration includeStatement)
+ throws ConfigurationException {
+ final String includeURI = includeStatement.getAttribute("src", null);
+ String directoryURI = null;
+ if ( includeURI == null ) {
+ // check for directories
+ directoryURI = includeStatement.getAttribute("dir", null);
+ }
+ if ( includeURI == null && directoryURI == null ) {
+ throw new ConfigurationException("Include statement must either have a 'src' or 'dir' attribute, at " +
+ includeStatement.getLocation());
+ }
+
+ if ( includeURI != null ) {
+ Source src = null;
+ try {
+ src = this.resolver.resolveURI(includeURI, contextURI, null);
+
+ this.loadURI(src, loadedURIs, includeStatement);
+ } catch (Exception e) {
+ throw new ConfigurationException("Cannot load '" + includeURI + "' at " + includeStatement.getLocation(), e);
+ } finally {
+ this.resolver.release(src);
+ }
+
+ } else {
+ final String pattern = includeStatement.getAttribute("pattern", null);
+ int[] parsedPattern = null;
+ if ( pattern != null ) {
+ parsedPattern = WildcardHelper.compilePattern(pattern);
+ }
+ Source directory = null;
+ try {
+ directory = this.resolver.resolveURI(directoryURI, contextURI, CONTEXT_PARAMETERS);
+ if ( directory instanceof TraversableSource ) {
+ final Iterator children = ((TraversableSource)directory).getChildren().iterator();
+ while ( children.hasNext() ) {
+ final Source s = (Source)children.next();
+ try {
+ if ( parsedPattern == null || this.match(s.getURI(), parsedPattern)) {
+ this.loadURI(s, loadedURIs, includeStatement);
+ }
+ } finally {
+ this.resolver.release(s);
+ }
+ }
+ } else {
+ throw new ConfigurationException("Include.dir must point to a directory, '" + directory.getURI() + "' is not a directory.'");
+ }
+ } catch (IOException ioe) {
+ throw new ConfigurationException("Unable to read configurations from " + directoryURI);
+ } finally {
+ this.resolver.release(directory);
+ }
+ }
+ }
+
+ protected void loadURI(final Source src,
+ final Set loadedURIs,
+ final Configuration includeStatement)
+ throws ConfigurationException {
+ // If already loaded: do nothing
+ final String uri = src.getURI();
+
+ if (!loadedURIs.contains(uri)) {
+ // load it and store it in the read set
+ Configuration includeConfig = null;
+ try {
+ ConfigurationBuilder builder = new ConfigurationBuilder(this.environment.settings);
+ includeConfig = builder.build(src.getInputStream(), uri);
+ } catch (Exception e) {
+ throw new ConfigurationException("Cannot load '" + uri + "' at " + includeStatement.getLocation(), e);
+ }
+ loadedURIs.add(uri);
+
+ // what is it?
+ String includeKind = includeConfig.getName();
+ if (includeKind.equals("components")) {
+ // more components
+ this.parseConfiguration(includeConfig, uri, loadedURIs);
+ } else if (includeKind.equals("role-list")) {
+ // more roles
+ this.configureRoles(includeConfig);
+ } else {
+ throw new ConfigurationException("Unknow document '" + includeKind + "' included at " +
+ includeStatement.getLocation());
+ }
+ }
+ }
+
+ private boolean match(String uri, int[] parsedPattern ) {
+ int pos = uri.lastIndexOf('/');
+ if ( pos != -1 ) {
+ uri = uri.substring(pos+1);
+ }
+ return WildcardHelper.match(null, uri, parsedPattern);
+ }
+
+ /**
+ * Reads a configuration object and creates the role, shorthand,
+ * and class name mapping.
+ *
+ * @param configuration The configuration object.
+ * @throws ConfigurationException if the configuration is malformed
+ */
+ protected final void configureRoles( final Configuration configuration )
+ throws ConfigurationException {
+ final Configuration[] roles = configuration.getChildren();
+
+ for( int i = 0; i < roles.length; i++ ) {
+ Configuration role = roles[i];
+
+ if (!"role".equals(role.getName())) {
+ throw new ConfigurationException("Unexpected '" + role.getName() + "' element at " + role.getLocation());
+ }
+
+ final String roleName = role.getAttribute("name");
+ final String shorthand = role.getAttribute("shorthand", null);
+ final String defaultClassName = role.getAttribute("default-class", null);
+
+ if (shorthand != null) {
+ // Store the shorthand and check that its consistent with any previous one
+ Object previous = this.shorthands.put( shorthand, roleName );
+ if (previous != null && !previous.equals(roleName)) {
+ throw new ConfigurationException("Shorthand '" + shorthand + "' already used for role " +
+ previous + ": inconsistent declaration at " + role.getLocation());
+ }
+ }
+
+ if ( defaultClassName != null ) {
+ ComponentInfo info = (ComponentInfo)this.classNames.get(roleName);
+ if (info == null) {
+ // Create a new info and store it
+ info = new ComponentInfo();
+ info.setServiceClassName(defaultClassName);
+ info.fill(role);
+ info.setRole(roleName);
+ info.setConfiguration(role);
+ this.classNames.put(roleName, info);
+ } else {
+ // Check that it's consistent with the existing info
+ if (!defaultClassName.equals(info.getServiceClassName())) {
+ throw new ConfigurationException("Invalid redeclaration: default class already set to " + info.getServiceClassName() +
+ " for role " + roleName + " at " + role.getLocation());
+ }
+ //FIXME: should check also other ServiceInfo members
+ }
+ }
+
+ final Configuration[] keys = role.getChildren( "hint" );
+ if( keys.length > 0 ) {
+ Map keyMap = (Map)this.keyClassNames.get(roleName);
+ if (keyMap == null) {
+ keyMap = new HashMap();
+ this.keyClassNames.put(roleName, keyMap);
+ }
+
+ for( int j = 0; j < keys.length; j++ ) {
+ Configuration key = keys[j];
+
+ final String shortHand = key.getAttribute( "shorthand" ).trim();
+ final String className = key.getAttribute( "class" ).trim();
+
+ ComponentInfo info = (ComponentInfo)keyMap.get(shortHand);
+ if (info == null) {
+ info = new ComponentInfo();
+ info.setServiceClassName(className);
+ info.fill(key);
+ info.setConfiguration(key);
+ keyMap.put( shortHand, info );
+ } else {
+ // Check that it's consistent with the existing info
+ if (!className.equals(info.getServiceClassName())) {
+ throw new ConfigurationException("Invalid redeclaration: class already set to " + info.getServiceClassName() +
+ " for hint " + shortHand + " at " + key.getLocation());
+ }
+ //FIXME: should check also other ServiceInfo members
+ }
+ }
+ }
+ }
+ }
+}
Propchange: cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/ConfigReader.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/ConfigReader.java
------------------------------------------------------------------------------
svn:keywords = Id
Added: cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/ConfigurationInfo.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/ConfigurationInfo.java?rev=377366&view=auto
==============================================================================
--- cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/ConfigurationInfo.java (added)
+++ cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/ConfigurationInfo.java Mon Feb 13 04:37:14 2006
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2006 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.core.container.spring;
+
+import java.util.Map;
+
+/**
+ * This bean stores information about a complete Avalon style configuration.
+ * It can be passed to an {@link XmlConfigCreator} to create a Spring like
+ * configuration.
+ *
+ * @since 2.2
+ * @version $Id$
+ */
+public class ConfigurationInfo {
+
+ protected Map components;
+
+ protected String rootLogger;
+
+ public Map getComponents() {
+ return components;
+ }
+
+ public void setComponents(Map components) {
+ this.components = components;
+ }
+
+ public String getRootLogger() {
+ return rootLogger;
+ }
+
+ public void setRootLogger(String rootLogger) {
+ this.rootLogger = rootLogger;
+ }
+
+
+}
Propchange: cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/ConfigurationInfo.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/ConfigurationInfo.java
------------------------------------------------------------------------------
svn:keywords = Id
Added: cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/PoolableFactoryBean.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/PoolableFactoryBean.java?rev=377366&view=auto
==============================================================================
--- cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/PoolableFactoryBean.java (added)
+++ cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/PoolableFactoryBean.java Mon Feb 13 04:37:14 2006
@@ -0,0 +1,361 @@
+/*
+ * Copyright 2002-2005 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.core.container.spring;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Set;
+
+import org.apache.avalon.excalibur.pool.Recyclable;
+import org.apache.cocoon.core.Core;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.BeanFactory;
+import org.springframework.beans.factory.BeanFactoryAware;
+import org.springframework.beans.factory.FactoryBean;
+
+/**
+ * This factory bean adds simple pooling support to Spring.
+ *
+ * @since 2.2
+ * @version $Id$
+ */
+public class PoolableFactoryBean
+ implements FactoryBean, BeanFactoryAware {
+
+ /** The default max size of the pool. */
+ public static final int DEFAULT_MAX_POOL_SIZE = 64;
+
+ /** All the interfaces for the proxy. */
+ protected final Class[] interfaces;
+
+ /** The pooled component. */
+ protected final String name;
+
+ /** The class. */
+ protected final Class beanClass;
+
+ /** The corresponding bean factory. */
+ protected BeanFactory beanFactory;
+
+ /**
+ * Object used to synchronize access to the get and put methods
+ */
+ protected final Object semaphore = new Object();
+
+ /**
+ * The maximum size of the pool.
+ */
+ private final int max;
+
+ /**
+ * List of the Poolable instances which are available for use.
+ */
+ private LinkedList ready;
+
+ /**
+ * Store the size of the ready list to optimize operations which require this value.
+ */
+ private int readySize;
+
+ /**
+ * Total number of Poolable instances in the pool
+ */
+ private int size;
+
+ /**
+ * Total number of Poolable instances created
+ */
+ private int highWaterMark;
+
+ /** Pool-in-method-name. */
+ protected String poolInMethodName;
+
+ /** Pool-out-method-name. */
+ protected String poolOutMethodName;
+
+ protected Method poolInMethod;
+ protected Method poolOutMethod;
+
+ /**
+ * Create a PoolableComponentHandler which manages a pool of Components
+ * created by the specified factory object.
+ *
+ * @param name The name of the bean which should be pooled.
+ */
+ public PoolableFactoryBean( String name, String className )
+ throws Exception {
+ this(name, className, DEFAULT_MAX_POOL_SIZE);
+ }
+
+ /**
+ * Create a PoolableComponentHandler which manages a pool of Components
+ * created by the specified factory object.
+ *
+ * @param name The name of the bean which should be pooled.
+ */
+ public PoolableFactoryBean( String name, String className, int poolMax )
+ throws Exception {
+ this.name = name;
+ this.max = ( poolMax <= 0 ? Integer.MAX_VALUE : poolMax );
+ this.beanClass = Class.forName(className);
+ final HashSet workInterfaces = new HashSet();
+
+ // Get *all* interfaces
+ this.guessWorkInterfaces( this.beanClass, workInterfaces );
+
+ this.interfaces = (Class[]) workInterfaces.toArray( new Class[workInterfaces.size()] );
+
+ // Create the pool lists.
+ this.ready = new LinkedList();
+ }
+
+ public void setPoolInMethodName(String poolInMethodName) {
+ this.poolInMethodName = poolInMethodName;
+ }
+
+ public void setPoolOutMethodName(String poolOutMethodName) {
+ this.poolOutMethodName = poolOutMethodName;
+ }
+
+ public void initialize() throws Exception {
+ if ( this.poolInMethodName != null ) {
+ this.poolInMethod = this.beanClass.getMethod(this.poolInMethodName, null);
+ } else {
+ this.poolInMethod = null;
+ }
+ if ( this.poolOutMethodName != null ) {
+ this.poolOutMethod = this.beanClass.getMethod(this.poolOutMethodName, null);
+ } else {
+ this.poolOutMethod = null;
+ }
+ }
+ /**
+ * Dispose of associated Pools and Factories.
+ */
+ public void dispose() {
+ // Any Poolables in the ready list need to be disposed of
+ synchronized( this.semaphore ) {
+ // Remove objects in the ready list.
+ for( Iterator iter = this.ready.iterator(); iter.hasNext(); ) {
+ Object poolable = iter.next();
+ iter.remove();
+ this.readySize--;
+ this.permanentlyRemovePoolable( poolable );
+ }
+ }
+ }
+
+ /**
+ * Permanently removes a poolable from the pool's active list and
+ * destroys it so that it will not ever be reused.
+ * <p>
+ * This method is only called by threads that have m_semaphore locked.
+ */
+ protected void permanentlyRemovePoolable( Object poolable ) {
+ this.size--;
+ }
+
+ /**
+ * Gets a Poolable from the pool. If there is room in the pool, a new Poolable will be
+ * created. Depending on the parameters to the constructor, the method may block or throw
+ * an exception if a Poolable is not available on the pool.
+ *
+ * @return Always returns a Poolable. Contract requires that put must always be called with
+ * the Poolable returned.
+ * @throws Exception An exception may be thrown as described above or if there is an exception
+ * thrown by the ObjectFactory's newInstance() method.
+ */
+ protected Object getFromPool() throws Exception {
+ Object poolable;
+ synchronized( this.semaphore ) {
+ // Look for a Poolable at the end of the m_ready list
+ if ( this.readySize > 0 ){
+ // A poolable is ready and waiting in the pool
+ poolable = this.ready.removeLast();
+ this.readySize--;
+ } else {
+ // Create a new poolable. May throw an exception if the poolable can not be
+ // instantiated.
+ poolable = this.beanFactory.getBean(this.name);
+ this.size++;
+ this.highWaterMark = (this.highWaterMark < this.size ? this.size : this.highWaterMark);
+ }
+ }
+
+ this.exitingPool(poolable);
+
+ return poolable;
+ }
+
+ /**
+ * Returns a poolable to the pool
+ *
+ * @param poolable Poolable to return to the pool.
+ */
+ protected void putIntoPool( final Object poolable ) {
+ try {
+ this.enteringPool(poolable);
+ } catch (Exception ignore) {
+ // ignore this
+ }
+
+ synchronized( this.semaphore ) {
+ if( this.size <= this.max ) {
+ this.ready.addLast( poolable );
+ this.readySize++;
+ } else {
+ // More Poolables were created than can be held in the pool, so remove.
+ this.permanentlyRemovePoolable( poolable );
+ }
+ }
+ }
+
+ /**
+ * Handle service specific methods for getting it out of the pool
+ */
+ public void exitingPool( final Object component )
+ throws Exception {
+ if ( this.poolOutMethod != null ) {
+ this.poolOutMethod.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();
+ }
+ if ( this.poolInMethod != null ) {
+ this.poolInMethod.invoke(component, null);
+ }
+ }
+
+ /**
+ * @see org.springframework.beans.factory.BeanFactoryAware#setBeanFactory(org.springframework.beans.factory.BeanFactory)
+ */
+ public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
+ this.beanFactory = beanFactory;
+ }
+
+ /**
+ * @see org.springframework.beans.factory.FactoryBean#getObject()
+ */
+ public Object getObject() throws Exception {
+ return Proxy.newProxyInstance(this.getClass().getClassLoader(),
+ this.interfaces,
+ new ProxyHandler(this));
+ }
+
+ /**
+ * @see org.springframework.beans.factory.FactoryBean#getObjectType()
+ */
+ public Class getObjectType() {
+ return this.beanClass;
+ }
+
+ /**
+ * @see org.springframework.beans.factory.FactoryBean#isSingleton()
+ */
+ public boolean isSingleton() {
+ return false;
+ }
+
+ /**
+ * Get a list of interfaces to proxy by scanning through
+ * all interfaces a class implements.
+ *
+ * @param clazz the class
+ * @param workInterfaces the set of current work interfaces
+ */
+ private void guessWorkInterfaces( final Class clazz,
+ final Set workInterfaces ) {
+ if ( null != clazz ) {
+ this.addInterfaces( clazz.getInterfaces(), workInterfaces );
+
+ this.guessWorkInterfaces( clazz.getSuperclass(), workInterfaces );
+ }
+ }
+
+ /**
+ * Get a list of interfaces to proxy by scanning through
+ * all interfaces a class implements.
+ *
+ * @param interfaces the array of interfaces
+ * @param workInterfaces the set of current work interfaces
+ */
+ private void addInterfaces( final Class[] interfaces,
+ final Set workInterfaces ) {
+ for ( int i = 0; i < interfaces.length; i++ ) {
+ workInterfaces.add( interfaces[i] );
+ this.addInterfaces(interfaces[i].getInterfaces(), workInterfaces);
+ }
+ }
+
+ protected static final class ProxyHandler implements InvocationHandler, Core.CleanupTask {
+
+ private final ThreadLocal componentHolder = new ThreadLocal();
+ private final PoolableFactoryBean handler;
+
+ public ProxyHandler(PoolableFactoryBean handler) {
+ this.handler = handler;
+ }
+
+ /**
+ * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
+ */
+ public Object invoke(Object proxy, Method method, Object[] args)
+ throws Throwable {
+ if ( method.getName().equals("hashCode") && args == null ) {
+ return new Integer(this.hashCode());
+ }
+ if ( this.componentHolder.get() == null ) {
+ this.componentHolder.set(this.handler.getFromPool());
+ Core.addCleanupTask(this);
+ }
+ try {
+ return method.invoke(this.componentHolder.get(), args);
+ } catch (InvocationTargetException ite) {
+ throw ite.getTargetException();
+ }
+ }
+
+
+ /**
+ * @see org.apache.cocoon.core.Core.CleanupTask#invoke()
+ */
+ public void invoke() {
+ try {
+ final Object o = this.componentHolder.get();
+ this.handler.putIntoPool(o);
+ } catch (Exception ignore) {
+ // we ignore this
+ }
+ this.componentHolder.set(null);
+ }
+ }
+
+
+}
Propchange: cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/PoolableFactoryBean.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/PoolableFactoryBean.java
------------------------------------------------------------------------------
svn:keywords = Id
Added: cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/XmlConfigCreator.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/XmlConfigCreator.java?rev=377366&view=auto
==============================================================================
--- cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/XmlConfigCreator.java (added)
+++ cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/XmlConfigCreator.java Mon Feb 13 04:37:14 2006
@@ -0,0 +1,174 @@
+/*
+ * Copyright 2006 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.core.container.spring;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.avalon.framework.service.ServiceManager;
+import org.springframework.util.StringUtils;
+
+/**
+ * This is a simple component that uses a {@link ConfigurationInfo} to create
+ * a Spring like configuration xml document.
+ *
+ * TODO: LogManager?
+ * TODO: configure(Core)
+ * TODO: register aliases for shorthands
+ * @since 2.2
+ * @version $Id$
+ */
+public class XmlConfigCreator {
+
+ protected static final String XMLHEADER = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+ protected static final String DOCTYPE =
+ "<!DOCTYPE beans PUBLIC \"-//SPRING//DTD BEAN//EN\" \"http://www.springframework.org/dtd/spring-beans.dtd\">\n";
+
+ public String createConfig(Map components)
+ throws Exception {
+ final List pooledRoles = new ArrayList();
+ final StringBuffer buffer = new StringBuffer();
+ buffer.append(XMLHEADER);
+ buffer.append(DOCTYPE);
+ buffer.append("<beans>\n");
+
+ // start with "static" components: ServiceManager
+ buffer.append("<bean");
+ this.appendAttribute(buffer, "id", ServiceManager.class.getName());
+ this.appendAttribute(buffer, "class", AvalonServiceManager.class.getName());
+ buffer.append("/>\n");
+
+ final Iterator i = components.entrySet().iterator();
+ while ( i.hasNext() ) {
+ final Map.Entry entry = (Map.Entry)i.next();
+ final ComponentInfo current = (ComponentInfo)entry.getValue();
+ final String role = current.getRole();
+
+ String className = current.getServiceClassName();
+ boolean isSelector = false;
+ boolean singleton = true;
+ boolean poolable = false;
+ // Test for Selector - we skip them
+ if ( className.equals("org.apache.cocoon.core.container.DefaultServiceSelector")
+ || className.equals("org.apache.cocoon.components.treeprocessor.sitemap.ComponentsSelector") ) {
+ // Add selector
+ className = AvalonServiceSelector.class.getName();
+ isSelector = true;
+ } else {
+ if ( current.getModel() == ComponentInfo.MODEL_NON_THREAD_SAFE_POOLED
+ || current.getModel() == ComponentInfo.MODEL_POOLED ) {
+ poolable = true;
+ singleton = false;
+ } else if ( current.getModel() != ComponentInfo.MODEL_SINGLETON ) {
+ singleton = false;
+ }
+ }
+ buffer.append("<bean");
+ if ( !poolable ) {
+ this.appendAttribute(buffer, "name", this.xml(role));
+ } else {
+ this.appendAttribute(buffer, "name", this.xml(role + "Pooled"));
+ }
+ this.appendAttribute(buffer, "class", className);
+ this.appendAttribute(buffer, "init-method", current.getInitMethodName());
+ this.appendAttribute(buffer, "destroy-method", current.getDestroyMethodName());
+ this.appendAttribute(buffer, "singleton", String.valueOf(singleton));
+ if ( !isSelector ) {
+ buffer.append("/>\n");
+ } else {
+ buffer.append(">\n");
+ buffer.append(" <constructor-arg ref=\"");
+ buffer.append(ServiceManager.class.getName());
+ buffer.append("\"/>\n");
+ buffer.append(" <constructor-arg type=\"java.lang.String\"><value>");
+ buffer.append(role.substring(0, role.length()-8));
+ buffer.append("</value></constructor-arg>\n");
+ if ( current.getConfiguration() != null
+ && current.getConfiguration().getAttribute("default", null) != null ) {
+ buffer.append(" <property name=\"default\"><value>");
+ buffer.append(current.getConfiguration().getAttribute("default"));
+ buffer.append("</value></property>\n");
+ }
+ buffer.append("</bean>\n");
+ }
+ if ( poolable ) {
+ // add the factory for poolables
+ buffer.append("<bean");
+ this.appendAttribute(buffer, "name", this.xml(role));
+ this.appendAttribute(buffer, "class", PoolableFactoryBean.class.getName());
+ this.appendAttribute(buffer, "singleton", "true");
+ this.appendAttribute(buffer, "init-method", "initialize");
+ this.appendAttribute(buffer, "destroy-method", "dispose");
+ buffer.append(">\n");
+ buffer.append(" <constructor-arg type=\"java.lang.String\"><value>");
+ buffer.append(this.xml(role) + "Pooled");
+ buffer.append("</value></constructor-arg>\n");
+ buffer.append(" <constructor-arg type=\"java.lang.String\"><value>");
+ buffer.append(className);
+ buffer.append("</value></constructor-arg>\n");
+ if ( current.getConfiguration() != null ) {
+ final String poolMax = current.getConfiguration().getAttribute("pool-max", null);
+ if ( poolMax != null ) {
+ buffer.append(" <constructor-arg><value>");
+ buffer.append(poolMax);
+ buffer.append("</value></constructor-arg>\n");
+ }
+ }
+ if ( current.getPoolInMethodName() != null ) {
+ buffer.append(" <property name=\"poolInMethodName\"><value>");
+ buffer.append(current.getPoolInMethodName());
+ buffer.append("</value></property>\n");
+ }
+ if ( current.getPoolOutMethodName() != null ) {
+ buffer.append("<property name=\"poolOutMethodName\"><value>");
+ buffer.append(current.getPoolOutMethodName());
+ buffer.append("</property>\n");
+ }
+ buffer.append("</bean>\n");
+ pooledRoles.add(role);
+ }
+ }
+ buffer.append("</beans>\n");
+
+ // now change roles for pooled components (from {role} to {role}Pooled
+ final Iterator prI = pooledRoles.iterator();
+ while ( prI.hasNext() ) {
+ final String role = (String)prI.next();
+ final Object info = components.remove(role);
+ components.put(role + "Pooled", info);
+ }
+ return buffer.toString();
+ }
+
+ protected String xml(String value) {
+ value = StringUtils.replace(value, "&", "&");
+ value = StringUtils.replace(value, "<", "<");
+ value = StringUtils.replace(value, ">", ">");
+ return value;
+ }
+
+ protected void appendAttribute(StringBuffer buffer, String attr, String value) {
+ if ( value != null ) {
+ buffer.append(' ');
+ buffer.append(attr);
+ buffer.append("=\"");
+ buffer.append(value);
+ buffer.append("\"");
+ }
+ }
+}
Propchange: cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/XmlConfigCreator.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/trunk/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/XmlConfigCreator.java
------------------------------------------------------------------------------
svn:keywords = Id