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/08/22 22:33:31 UTC
svn commit: r433740 - in
/cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/core: ./
container/spring/ container/spring/avalon/
Author: cziegeler
Date: Tue Aug 22 13:33:30 2006
New Revision: 433740
URL: http://svn.apache.org/viewvc?rev=433740&view=rev
Log:
Add factory bean to create avalon context
New implementation to read avalon style configuration files
Update settings handling
Added:
cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/avalon/AvalonContextFactoryBean.java (with props)
cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/avalon/ConfigReader.java (with props)
Modified:
cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/core/CoreUtil.java
cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/SettingsBeanFactoryPostProcessor.java
Modified: cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/core/CoreUtil.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/core/CoreUtil.java?rev=433740&r1=433739&r2=433740&view=diff
==============================================================================
--- cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/core/CoreUtil.java (original)
+++ cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/core/CoreUtil.java Tue Aug 22 13:33:30 2006
@@ -247,7 +247,7 @@
* @param servletContext the Cocoon context
* @param contextUrl URL for the context
*/
- private static void addSourceResolverContext(DefaultContext appContext,
+ public static void addSourceResolverContext(DefaultContext appContext,
ServletContext servletContext,
String contextUrl) {
try {
@@ -267,7 +267,7 @@
* @param classloader
* @throws MalformedURLException
*/
- private static void addSettingsContext(DefaultContext appContext, Settings settings)
+ public static void addSettingsContext(DefaultContext appContext, Settings settings)
throws MalformedURLException {
appContext.put(Constants.CONTEXT_WORK_DIR, new File(settings.getWorkDirectory()));
appContext.put(Constants.CONTEXT_UPLOAD_DIR, new File(settings.getUploadDirectory()));
Modified: cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/SettingsBeanFactoryPostProcessor.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/SettingsBeanFactoryPostProcessor.java?rev=433740&r1=433739&r2=433740&view=diff
==============================================================================
--- cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/SettingsBeanFactoryPostProcessor.java (original)
+++ cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/SettingsBeanFactoryPostProcessor.java Tue Aug 22 13:33:30 2006
@@ -20,6 +20,7 @@
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -34,6 +35,7 @@
import org.apache.cocoon.configuration.SettingsDefaults;
import org.apache.cocoon.configuration.impl.MutableSettings;
import org.apache.cocoon.configuration.impl.PropertyHelper;
+import org.apache.cocoon.core.CoreInitializationException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
@@ -76,10 +78,61 @@
this.servletContext = sContext;
}
- public void init() {
+ public void init()
+ throws Exception {
final MutableSettings s = this.createSettings();
this.initSettingsFiles(s);
+ // update configuration
+ final URL u = this.getConfigFile(s.getConfiguration());
+ s.setConfiguration(u.toExternalForm());
+
+ // settings can't be changed anymore
+ s.makeReadOnly();
this.settings = s;
+ }
+
+ /**
+ * Get the URL of the main Cocoon configuration file.
+ */
+ protected URL getConfigFile(final String configFileName)
+ throws Exception {
+ if (this.logger.isDebugEnabled()) {
+ this.logger.debug("Using configuration file: " + configFileName);
+ }
+
+ URL result;
+ try {
+ // test if this is a qualified url
+ if (configFileName.indexOf(':') == -1) {
+ result = this.servletContext.getResource(configFileName);
+ } else {
+ result = new URL(configFileName);
+ }
+ } catch (Exception mue) {
+ String msg = "Setting for 'configuration' is invalid : " + configFileName;
+ this.logger.error(msg, mue);
+ throw new CoreInitializationException(msg, mue);
+ }
+
+ if (result == null) {
+ File resultFile = new File(configFileName);
+ if (resultFile.isFile()) {
+ try {
+ result = resultFile.getCanonicalFile().toURL();
+ } catch (Exception e) {
+ String msg = "Setting for 'configuration' is invalid : " + configFileName;
+ this.logger.error(msg, e);
+ throw new CoreInitializationException(msg, e);
+ }
+ }
+ }
+
+ if (result == null) {
+ String msg = "Setting for 'configuration' doesn't name an existing resource : " + configFileName;
+ this.logger.error(msg);
+ throw new CoreInitializationException(msg);
+ }
+ return result;
}
/**
Added: cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/avalon/AvalonContextFactoryBean.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/avalon/AvalonContextFactoryBean.java?rev=433740&view=auto
==============================================================================
--- cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/avalon/AvalonContextFactoryBean.java (added)
+++ cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/avalon/AvalonContextFactoryBean.java Tue Aug 22 13:33:30 2006
@@ -0,0 +1,92 @@
+/*
+ * 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.avalon;
+
+import javax.servlet.ServletContext;
+
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.DefaultContext;
+import org.apache.cocoon.configuration.Settings;
+import org.apache.cocoon.core.CoreUtil;
+import org.apache.cocoon.core.container.util.ComponentContext;
+import org.springframework.beans.factory.FactoryBean;
+import org.springframework.web.context.ServletContextAware;
+
+/**
+ *
+ * @since 2.2
+ * @version $Id$
+ */
+public class AvalonContextFactoryBean
+ implements FactoryBean, ServletContextAware {
+
+ /** The servlet context. */
+ protected ServletContext servletContext;
+
+ /** The settings. */
+ protected Settings settings;
+
+ protected Context context;
+
+ /**
+ * @see org.springframework.web.context.ServletContextAware#setServletContext(javax.servlet.ServletContext)
+ */
+ public void setServletContext(ServletContext sContext) {
+ this.servletContext = sContext;
+ }
+
+ protected void init()
+ throws Exception {
+ final DefaultContext appContext = new ComponentContext();
+
+ // add root url
+ String contextUrl = CoreUtil.getContextUrl(this.servletContext, "/WEB-INF/web.xml");
+ CoreUtil.addSourceResolverContext(appContext, servletContext, contextUrl);
+
+ // add the Avalon context attributes that are contained in the settings
+ CoreUtil.addSettingsContext(appContext, settings);
+ this.context = appContext;
+ }
+
+ /**
+ * @see org.springframework.beans.factory.FactoryBean#getObject()
+ */
+ public Object getObject() throws Exception {
+ return this.context;
+ }
+
+ /**
+ * @see org.springframework.beans.factory.FactoryBean#getObjectType()
+ */
+ public Class getObjectType() {
+ return Context.class;
+ }
+
+ /**
+ * @see org.springframework.beans.factory.FactoryBean#isSingleton()
+ */
+ public boolean isSingleton() {
+ return true;
+ }
+
+ public Settings getSettings() {
+ return settings;
+ }
+
+ public void setSettings(Settings settings) {
+ this.settings = settings;
+ }
+}
Propchange: cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/avalon/AvalonContextFactoryBean.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/avalon/AvalonContextFactoryBean.java
------------------------------------------------------------------------------
svn:keywords = Id
Added: cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/avalon/ConfigReader.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/avalon/ConfigReader.java?rev=433740&view=auto
==============================================================================
--- cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/avalon/ConfigReader.java (added)
+++ cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/avalon/ConfigReader.java Tue Aug 22 13:33:30 2006
@@ -0,0 +1,550 @@
+/*
+ * 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.avalon;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+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.cocoon.core.container.spring.AvalonEnvironment;
+import org.apache.cocoon.core.container.spring.ComponentInfo;
+import org.apache.cocoon.core.container.spring.ConfigurationInfo;
+import org.apache.cocoon.core.container.util.ConfigurationBuilder;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceLoader;
+import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+import org.xml.sax.InputSource;
+
+/**
+ * This component reads in Avalon style configuration files and returns all
+ * contained components and their configurations.
+ *
+ * @since 2.2
+ * @version $Id$
+ */
+public class ConfigReader {
+
+ /** Logger (we use the same logging mechanism as Spring!) */
+ protected final Log logger = LogFactory.getLog(getClass());
+
+ /** Resolver for reading configuration files. */
+ protected final PathMatchingResourcePatternResolver resolver;
+
+ /** The configuration info. */
+ protected final ConfigurationInfo configInfo;
+
+ /** Avalon environment. */
+ protected final AvalonEnvironment environment;
+
+ /** All component configurations. */
+ protected final List componentConfigs = new ArrayList();
+
+ public static ConfigurationInfo readConfiguration(String source, AvalonEnvironment env)
+ throws Exception {
+ final ConfigReader converter = new ConfigReader(env, null, null);
+ converter.convert(source);
+ return converter.configInfo;
+ }
+
+ public static ConfigurationInfo readConfiguration(Configuration config,
+ ConfigurationInfo parentInfo,
+ AvalonEnvironment env,
+ ResourceLoader resourceLoader)
+ throws Exception {
+ return readConfiguration(config, null, parentInfo, env, resourceLoader);
+ }
+// PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(new ServletContextResourceLoader(this.servletContext));
+
+ public static ConfigurationInfo readConfiguration(Configuration rolesConfig,
+ Configuration componentConfig,
+ ConfigurationInfo parentInfo,
+ AvalonEnvironment env,
+ ResourceLoader resourceLoader)
+ throws Exception {
+ final ConfigReader converter = new ConfigReader(env, parentInfo, resourceLoader);
+ converter.convert(rolesConfig, componentConfig, null);
+ return converter.configInfo;
+ }
+
+ private ConfigReader(AvalonEnvironment env,
+ ConfigurationInfo parentInfo,
+ ResourceLoader resourceLoader)
+ throws Exception {
+ if ( resourceLoader != null ) {
+ this.resolver = new PathMatchingResourcePatternResolver(resourceLoader);
+ } else {
+ this.resolver = new PathMatchingResourcePatternResolver();
+ }
+ this.environment = env;
+
+ // now add selectors from parent
+ if ( parentInfo != null ) {
+ this.configInfo = new ConfigurationInfo(parentInfo);
+ final Iterator i = parentInfo.getComponents().values().iterator();
+ while ( i.hasNext() ) {
+ final ComponentInfo current = (ComponentInfo)i.next();
+ if ( current.isSelector() ) {
+ this.configInfo.addRole(current.getRole(), current.copy());
+ }
+ }
+ // TODO - we should add the processor to each container
+ // This would avoid the hacky getting of the current container in the tree processor
+ /*
+ ComponentInfo processorInfo = (ComponentInfo) parentInfo.getComponents().get(Processor.ROLE);
+ if ( processorInfo != null ) {
+ this.configInfo.getComponents().put(Processor.ROLE, processorInfo.copy());
+ }
+ */
+ } else {
+ this.configInfo = new ConfigurationInfo();
+ }
+ }
+
+ protected String convertUrl(String url) {
+ if ( url == null ) {
+ return null;
+ }
+ if ( url.startsWith("context:") ) {
+ return url.substring(10);
+ }
+ if ( url.startsWith("resource:") ) {
+ return "classpath:" + url.substring(10);
+ }
+ if ( url.indexOf(':') == -1 && !url.startsWith("/")) {
+ return '/' + url;
+ }
+ return url;
+ }
+
+ protected InputSource getInputSource(Resource rsrc)
+ throws Exception {
+ final InputSource is = new InputSource(rsrc.getInputStream());
+ is.setSystemId(rsrc.getURL().toExternalForm());
+ return is;
+ }
+
+ protected String getUrl(String url, String base) {
+ return url;
+ }
+
+ protected void convert(String relativePath)
+ throws Exception {
+ if ( this.logger.isInfoEnabled() ) {
+ this.logger.info("Reading Avalon configuration from " + relativePath);
+ }
+ Resource root = this.resolver.getResource(this.convertUrl(relativePath));
+ final ConfigurationBuilder b = new ConfigurationBuilder(this.environment.settings);
+
+ final Configuration config = b.build(this.getInputSource(root));
+
+ this.convert(config, null, root.getURL().toExternalForm());
+ }
+
+ protected void convert(Configuration config, Configuration additionalConfig, String rootUri)
+ throws Exception {
+ if ( this.logger.isInfoEnabled() ) {
+ this.logger.info("Converting Avalon configuration from configuration object: " + config);
+ }
+ // 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.configInfo.setRootLogger(config.getAttribute("logger", null));
+
+ // and load configuration with a empty list of loaded configurations
+ final Set loadedConfigs = new HashSet();
+ // what is it?
+ if ( "role-list".equals(config.getName()) || "roles".equals(config.getName())) {
+ this.configureRoles(config);
+ } else {
+ this.parseConfiguration(config, null, loadedConfigs);
+ }
+
+ // test for optional user-roles attribute
+ if ( rootUri != null ) {
+ final String userRoles = config.getAttribute("user-roles", null);
+ if (userRoles != null) {
+ if ( this.logger.isInfoEnabled() ) {
+ this.logger.info("Reading additional user roles: " + userRoles);
+ }
+ final Resource userRolesSource = this.resolver.getResource(this.getUrl(userRoles, rootUri));
+ final ConfigurationBuilder b = new ConfigurationBuilder(this.environment.settings);
+ final Configuration userRolesConfig = b.build(this.getInputSource(userRolesSource));
+ this.parseConfiguration(userRolesConfig, userRolesSource.getURL().toExternalForm(), loadedConfigs);
+ }
+ }
+ if ( additionalConfig != null ) {
+ if ( "role-list".equals(additionalConfig.getName()) || "roles".equals(additionalConfig.getName())) {
+ this.configureRoles(additionalConfig);
+ } else {
+ this.parseConfiguration(additionalConfig, null, loadedConfigs);
+ }
+ }
+
+ // now process all component configurations
+ this.processComponents();
+
+ // add roles as components
+ final Iterator i = this.configInfo.getRoles().iterator();
+ while ( i.hasNext() ) {
+ final ComponentInfo current = (ComponentInfo)i.next();
+ current.setLazyInit(true);
+ this.configInfo.addComponent(current);
+ }
+ this.configInfo.clearRoles();
+ }
+
+ 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 if ( "include-beans".equals(componentName) ) {
+ this.handleBeanInclude(contextURI, componentConfig);
+ } else {
+ // Component declaration, add it to list
+ this.componentConfigs.add(componentConfig);
+ }
+ }
+ }
+
+ protected void processComponents()
+ throws ConfigurationException {
+ final Iterator i = this.componentConfigs.iterator();
+ while ( i.hasNext() ) {
+ final Configuration componentConfig = (Configuration)i.next();
+ final String componentName = componentConfig.getName();
+
+ // Find the role
+ String role = componentConfig.getAttribute("role", null);
+ String alias = null;
+ if (role == null) {
+ // Get the role from the role manager if not explicitely specified
+ role = (String)this.configInfo.getShorthands().get( componentName );
+ alias = 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);
+ // 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);
+ ComponentInfo info;
+ if (className == null) {
+ // Get the default class name for this role
+ info = this.configInfo.getRole( role );
+ if (info == null) {
+ if ( this.configInfo.getComponents().get( role) != null ) {
+ throw new ConfigurationException("Duplicate component definition for role " + role + " at " + componentConfig.getLocation());
+ }
+ throw new ConfigurationException("Cannot find a class for role " + role + " at " + componentConfig.getLocation());
+ }
+ className = info.getComponentClassName();
+ if ( name != null ) {
+ info = info.copy();
+ } else if ( !className.endsWith("Selector") ) {
+ this.configInfo.removeRole(role);
+ }
+ } else {
+ info = new ComponentInfo();
+ }
+ // check for name attribute
+ // Note: this has to be done *after* finding the className above as we change the role
+ if (name != null) {
+ role = role + "/" + name;
+ if ( alias != null ) {
+ alias = alias + '-' + name;
+ }
+ }
+ info.fill(componentConfig);
+ info.setComponentClassName(className);
+ info.setRole(role);
+ if ( alias != null ) {
+ info.setAlias(alias);
+ }
+ info.setConfiguration(componentConfig);
+
+ this.configInfo.addComponent(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 ) {
+ this.logger.warn("Found unknown selector type (continuing anyway: " + className);
+ } else {
+ String componentRole = role;
+ if ( componentRole.endsWith("Selector") ) {
+ componentRole = componentRole.substring(0, componentRole.length() - 8);
+ }
+ componentRole += '/';
+ Configuration[] children = info.getConfiguration().getChildren();
+ final Map hintConfigs = (Map)this.configInfo.getKeyClassNames().get(role);
+ for (int j=0; j<children.length; j++) {
+ final Configuration current = children[j];
+ final ComponentInfo childInfo = new ComponentInfo();
+ childInfo.fill(current);
+ childInfo.setConfiguration(current);
+ final ComponentInfo hintInfo = (hintConfigs == null ? null : (ComponentInfo)hintConfigs.get(current.getName()));
+ if ( current.getAttribute(classAttribute, null ) != null
+ || hintInfo == null ) {
+ childInfo.setComponentClassName(current.getAttribute(classAttribute));
+ } else {
+ childInfo.setComponentClassName(hintInfo.getComponentClassName());
+ }
+ childInfo.setRole(componentRole + current.getAttribute("name"));
+ this.configInfo.addComponent(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 ) {
+ Resource src = null;
+ try {
+ src = this.resolver.getResource(this.getUrl(includeURI, contextURI));
+
+ this.loadURI(src, loadedURIs, includeStatement);
+ } catch (Exception e) {
+ throw new ConfigurationException("Cannot load '" + includeURI + "' at " + includeStatement.getLocation(), e);
+ }
+
+ } else {
+ final String pattern = includeStatement.getAttribute("pattern", null);
+ try {
+ Resource[] resources = this.resolver.getResources(this.getUrl(directoryURI + '/' + pattern, contextURI));
+ if ( resources != null ) {
+ for(int i=0; i < resources.length; i++) {
+ this.loadURI(resources[i], loadedURIs, includeStatement);
+ }
+ }
+ } catch (Exception e) {
+ throw new ConfigurationException("Cannot load from directory '" + directoryURI + "' at " + includeStatement.getLocation(), e);
+ }
+ }
+ }
+
+ protected void loadURI(final Resource src,
+ final Set loadedURIs,
+ final Configuration includeStatement)
+ throws ConfigurationException, IOException {
+ // If already loaded: do nothing
+ final String uri = src.getURL().toExternalForm();
+
+ if (!loadedURIs.contains(uri)) {
+ if ( this.logger.isInfoEnabled() ) {
+ this.logger.info("Loading configuration: " + 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?
+ final 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());
+ }
+ }
+ }
+
+ protected void handleBeanInclude(final String contextURI,
+ 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) {
+ Resource src = null;
+ try {
+ src = this.resolver.getResource(this.getUrl(includeURI, contextURI));
+
+ this.configInfo.addImport(src.getURL().toExternalForm());
+ } catch (Exception e) {
+ throw new ConfigurationException("Cannot load '" + includeURI + "' at "
+ + includeStatement.getLocation(), e);
+ }
+
+ } else {
+ final String pattern = includeStatement.getAttribute("pattern", null);
+ try {
+ Resource[] resources = this.resolver.getResources(this.getUrl(directoryURI + '/' + pattern, contextURI));
+ if ( resources != null ) {
+ for(int i=0; i < resources.length; i++) {
+ this.configInfo.addImport(resources[i].getURL().toExternalForm());
+ }
+ }
+ } catch (IOException ioe) {
+ throw new ConfigurationException("Unable to read configurations from "
+ + directoryURI);
+ }
+ }
+ }
+
+ /**
+ * 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++ ) {
+ final Configuration role = roles[i];
+
+ if ( "alias".equals(role.getName()) ) {
+ final String roleName = role.getAttribute("role");
+ final String shorthand = role.getAttribute("shorthand");
+ this.configInfo.getShorthands().put(shorthand, roleName);
+ continue;
+ }
+ 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.configInfo.getShorthands().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 = this.configInfo.getRole(roleName);
+ if (info == null) {
+ // Create a new info and store it
+ info = new ComponentInfo();
+ info.setComponentClassName(defaultClassName);
+ info.fill(role);
+ info.setRole(roleName);
+ info.setConfiguration(role);
+ info.setAlias(shorthand);
+ this.configInfo.addRole(roleName, info);
+ } else {
+ // Check that it's consistent with the existing info
+ if (!defaultClassName.equals(info.getComponentClassName())) {
+ throw new ConfigurationException("Invalid redeclaration: default class already set to " + info.getComponentClassName() +
+ " 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.configInfo.getKeyClassNames().get(roleName);
+ if (keyMap == null) {
+ keyMap = new HashMap();
+ this.configInfo.getKeyClassNames().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.setComponentClassName(className);
+ info.fill(key);
+ info.setConfiguration(key);
+ info.setAlias(shortHand);
+ keyMap.put( shortHand, info );
+ } else {
+ // Check that it's consistent with the existing info
+ if (!className.equals(info.getComponentClassName())) {
+ throw new ConfigurationException("Invalid redeclaration: class already set to " + info.getComponentClassName() +
+ " for hint " + shortHand + " at " + key.getLocation());
+ }
+ //FIXME: should check also other ServiceInfo members
+ }
+ }
+ }
+ }
+ }
+}
Propchange: cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/avalon/ConfigReader.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/avalon/ConfigReader.java
------------------------------------------------------------------------------
svn:keywords = Id