Package org.apache.cocoon.core.container.spring.avalon

Source Code of org.apache.cocoon.core.container.spring.avalon.SitemapHelper

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;

import javax.servlet.ServletContext;

import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.configuration.DefaultConfiguration;
import org.apache.cocoon.classloader.reloading.Monitor;
import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.cocoon.environment.Request;
import org.apache.cocoon.processing.ProcessInfoProvider;
import org.apache.cocoon.spring.configurator.WebAppContextUtils;
import org.apache.cocoon.spring.configurator.impl.ChildXmlWebApplicationContext;
import org.apache.cocoon.util.Deprecation;
import org.springframework.core.io.Resource;
import org.springframework.web.context.WebApplicationContext;


/**
*
* @version $Id: SitemapHelper.java 588388 2007-10-25 23:23:26Z vgritsenko $
* @since 2.2
*/
public class SitemapHelper {

    private static final String CLASSLOADER_CONFIG_NAME = "classloader";

    private static final String DEFAULT_CONFIG_XCONF  = "config/avalon";

    /**
     * The default location of spring related child configuration files.
     */
    public static final String DEFAULT_CHILD_SPRING_CONFIGURATION_LOCATION = "config/spring";
    /**
     * The default location of spring related child configuration files.
     */
    public static final String DEFAULT_CHILD_PROPERTIES_LOCATION = "config/properties";

    protected static String createDefinition(String     uriPrefix,
                                             String     sitemapLocation,
                                             List       beanIncludes,
                                             List       propertyIncludes,
                                             Properties props) {
        final StringBuffer buffer = new StringBuffer();
        addHeader(buffer);
        // Child settings for sitemap
        buffer.append("  <configurator:child-settings");
        addAttribute(buffer, "name", sitemapLocation);
        buffer.append(">\n");
        if ( beanIncludes != null ) {
            final Iterator i = beanIncludes.iterator();
            while ( i.hasNext() ) {
                final String dir = (String)i.next();
                buffer.append("    <configurator:include-beans");
                addAttribute(buffer, "dir", dir);
                buffer.append("/>\n");
            }
        }
        if ( propertyIncludes != null ) {
            final Iterator i = propertyIncludes.iterator();
            while ( i.hasNext() ) {
                final String dir = (String)i.next();
                buffer.append("    <configurator:include-properties");
                addAttribute(buffer, "dir", dir);
                buffer.append("/>\n");
            }
        }
        if ( props != null ) {
            final Iterator kI = props.keySet().iterator();
            while ( kI.hasNext() ) {
                final String key = (String)kI.next();
                buffer.append("    <configurator:property");
                addAttribute(buffer, "name", key);
                addAttribute(buffer, "value", props.getProperty(key));
                buffer.append("/>\n");
            }
        }
        buffer.append("  </configurator:child-settings>\n");
        // Avalon
        buffer.append("  <avalon:sitemap");
        addAttribute(buffer, "location", sitemapLocation);
        addAttribute(buffer, "uriPrefix", uriPrefix);
        buffer.append("/>\n");
        addFooter(buffer);

        return buffer.toString();
    }

    /**
     * Add the header for the xml configuration file.
     */
    protected static void addHeader(StringBuffer buffer) {
        buffer.append("<beans xmlns=\"http://www.springframework.org/schema/beans\"");
        buffer.append(" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"");
        buffer.append(" xmlns:util=\"http://www.springframework.org/schema/util\"");
        buffer.append(" xmlns:configurator=\"http://cocoon.apache.org/schema/configurator\"");
        buffer.append(" xmlns:avalon=\"http://cocoon.apache.org/schema/avalon\"");
        buffer.append(" xsi:schemaLocation=\"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd");
        buffer.append(" http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd");
        buffer.append(" http://cocoon.apache.org/schema/configurator http://cocoon.apache.org/schema/configurator/cocoon-configurator-1.0.xsd");
        buffer.append(" http://cocoon.apache.org/schema/avalon http://cocoon.apache.org/schema/avalon/cocoon-avalon-1.0.xsd\">\n");
    }

    /**
     * Add the footer for the xml configuration file.
     */
    protected static void addFooter(StringBuffer buffer) {
        buffer.append("</beans>\n");
    }

    /**
     * Append an attribute to the xml stream if it has a value.
     */
    protected static void addAttribute(StringBuffer buffer, String name, String value) {
        if ( value != null ) {
            buffer.append(' ');
            buffer.append(name);
            buffer.append("=\"");
            buffer.append(value);
            buffer.append("\"");
        }
    }

    /**
     * Should the default includes be read for this sitemap?
     */
    protected static boolean isUsingDefaultIncludes(Configuration config) {
        return config.getChild("components").getAttributeAsBoolean("use-default-includes", true);
    }

    /**
     * Get all includes for bean configurations from the sitemap.
     * @param sitemap
     * @return
     */
    protected static List getBeanIncludes(WebApplicationContext webAppContext,
                                          String                contextUrl,
                                          Configuration         sitemap)
    throws ConfigurationException {
        final List includes = new ArrayList();
        if ( isUsingDefaultIncludes(sitemap) ) {
            final Resource rsrc = webAppContext.getResource(contextUrl + DEFAULT_CHILD_SPRING_CONFIGURATION_LOCATION);
            if ( rsrc.exists() ) {
                includes.add(DEFAULT_CHILD_SPRING_CONFIGURATION_LOCATION);
            }
        }
        final Configuration[] includeConfigs = sitemap.getChild("components").getChildren("include-beans");
        for(int i = 0 ; i < includeConfigs.length; i++ ) {
            final String dir = includeConfigs[i].getAttribute("dir");

            includes.add(dir);
        }
        return includes;
    }

    /**
     * Get all includes for properties from the sitemap.
     * @param sitemap
     * @return
     */
    protected static List getPropertiesIncludes(WebApplicationContext webAppContext,
                                                String                contextUrl,
                                                Configuration         sitemap)
    throws ConfigurationException {
        final List includes = new ArrayList();
        if ( isUsingDefaultIncludes(sitemap) ) {
            final Resource rsrc = webAppContext.getResource(contextUrl + DEFAULT_CHILD_PROPERTIES_LOCATION);
            if ( rsrc.exists() ) {
                includes.add(DEFAULT_CHILD_PROPERTIES_LOCATION);
            }
        }
        final Configuration[] includeConfigs = sitemap.getChild("components").getChildren("include-properties");
        for(int i = 0 ; i < includeConfigs.length; i++ ) {
            final String dir = includeConfigs[i].getAttribute("dir");

            includes.add(dir);
        }
        return includes;
    }

    /**
     * compatibility with 2.1.x - check for global variables in sitemap
     * TODO - This will be removed in later versions!
     */
    protected static Properties getGlobalSitemapVariables(Configuration sitemap)
    throws ConfigurationException {
        Properties variables = null;
        final Configuration varConfig = sitemap.getChild("pipelines").getChild("component-configurations").getChild("global-variables", false);
        if ( varConfig != null ) {
            Deprecation.logger.warn("The 'component-configurations' section in the sitemap is deprecated. Please check for alternatives.");
            variables = new Properties();
            final Configuration[] variableElements = varConfig.getChildren();
            for(int v=0; v<variableElements.length; v++) {
                variables.setProperty(variableElements[v].getName(), variableElements[v].getValue());
            }
        }
        return variables;
    }

    public static Configuration createSitemapConfiguration(Configuration config)
    throws ConfigurationException {
        Configuration componentConfig = config.getChild("components", false);
        Configuration classPathConfig;

        // by default we include configuration files and properties from
        // predefined locations
        final boolean useDefaultIncludes = isUsingDefaultIncludes(config);

        // if we want to add the default includes and have no component section
        // we have to create one!
        if ( componentConfig == null && useDefaultIncludes ) {
            componentConfig = new DefaultConfiguration("components",
                                                       config.getLocation(),
                                                       config.getNamespace(),
                                                       "");
        }

        if ( componentConfig != null ) {
            // before we pass the configuration we have to strip the
            // additional configuration parts, like classpath as these
            // are not configurations for the component container
            final DefaultConfiguration c = new DefaultConfiguration(componentConfig.getName(),
                                                                    componentConfig.getLocation(),
                                                                    componentConfig.getNamespace(),
                                                                    "");
            c.addAll(componentConfig);
            classPathConfig = c.getChild(CLASSLOADER_CONFIG_NAME, false);
            if ( classPathConfig != null ) {
                c.removeChild(classPathConfig);
            }
            // and now add default includes
            if ( useDefaultIncludes ) {
                DefaultConfiguration includeElement;
                includeElement = new DefaultConfiguration("include",
                                                          c.getLocation(),
                                                          c.getNamespace(),
                                                          "");
                includeElement.setAttribute("dir", DEFAULT_CONFIG_XCONF);
                includeElement.setAttribute("pattern", "*.xconf");
                includeElement.setAttribute("optional", "true");
                c.addChild(includeElement);
            }
            componentConfig = c;
        }
        return componentConfig;
    }

    /**
     * Create the per sitemap container.
     *
     * @param config          The sitemap as a configuration object.
     * @param sitemapLocation The uri of the sitemap
     * @param fam
     * @param servletContext  The servlet context
     * @return
     * @throws Exception
     */
    public static WebApplicationContext createContainer(Configuration  config,
                                                        String         sitemapLocation,
                                                        Monitor        fam,
                                                        ServletContext servletContext)
    throws Exception {
        // let's get the parent container first
        final WebApplicationContext parentContext = WebAppContextUtils.getCurrentWebApplicationContext();
        final ProcessInfoProvider infoProvider = (ProcessInfoProvider) parentContext.getBean(ProcessInfoProvider.ROLE);
        final Request request = ObjectModelHelper.getRequest(infoProvider.getObjectModel());
        // let's determine our context url
        int pos = sitemapLocation.lastIndexOf('/');
        if ( sitemapLocation.lastIndexOf(File.separatorChar) > pos ) {
            pos = sitemapLocation.lastIndexOf(File.separatorChar);
        }
        final String contextUrl = sitemapLocation.substring(0, pos + 1);


        // get classloader
//      TODO rcl           
//        final ClassLoader classloader = createClassLoader(parentContext, config, fam, servletContext, sitemapResolver);
        final ClassLoader classloader = Thread.currentThread().getContextClassLoader();
       
        // create root bean definition
        final String definition = createDefinition(request.getSitemapURIPrefix(),
                                                   sitemapLocation.substring(pos+1),
                                                   getBeanIncludes(parentContext, contextUrl, config),
                                                   getPropertiesIncludes(parentContext, contextUrl, config),
                                                   getGlobalSitemapVariables(config));
        final ChildXmlWebApplicationContext context = new ChildXmlWebApplicationContext(contextUrl,
                                                                                    definition);
        context.setServletContext(servletContext);
        context.setParent(parentContext);
        if ( classloader != null ) {
            context.setClassLoader(classloader);
        }
        context.refresh();
        return context;
    }

// TODO rcl   
//    /**
//     * Build a processing tree from a <code>Configuration</code>.
//     * @param processor
//     */
//    protected static ClassLoader createClassLoader(BeanFactory    parentFactory,
//                                                   Configuration  config,
//                                                   Monitor fam,
//                                                   ServletContext servletContext,
//                                                   SourceResolver sitemapResolver)
//    throws Exception {
//        final Configuration componentConfig = config.getChild("components", false);
//        Configuration classPathConfig = null;
//
//        if ( componentConfig != null ) {
//            classPathConfig = componentConfig.getChild(CLASSLOADER_CONFIG_NAME, false);
//        }
//        // Create class loader
//        // we don't create a new class loader if there is no new configuration
//        if ( classPathConfig == null ) {
//            return Thread.currentThread().getContextClassLoader();           
//        }
//        final String factoryRole = classPathConfig.getAttribute("factory-role", ClassLoaderFactory.ROLE);
//
//        // Create a new classloader
//        ReloadingClassLoaderConfiguration configBean = AvalonUtils.createConfiguration(sitemapResolver, classPathConfig);
//        configBean.setMonitor(fam);
//        ClassLoaderFactory clFactory = (ClassLoaderFactory)parentFactory.getBean(factoryRole);
//        return clFactory.createClassLoader(Thread.currentThread().getContextClassLoader(),
//                                           configBean,
//                                           servletContext);
//    }
}
TOP

Related Classes of org.apache.cocoon.core.container.spring.avalon.SitemapHelper

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.