Package org.apache.cocoon.spring.configurator.impl

Source Code of org.apache.cocoon.spring.configurator.impl.AbstractSettingsBeanFactoryPostProcessor$CocoonSettingsResolvingBeanDefinitionVisitor

/*
* 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.spring.configurator.impl;

import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.Set;

import javax.servlet.ServletContext;

import org.apache.cocoon.configuration.MutableSettings;
import org.apache.cocoon.configuration.PropertyHelper;
import org.apache.cocoon.configuration.PropertyProvider;
import org.apache.cocoon.configuration.Settings;
import org.apache.cocoon.spring.configurator.ResourceFilter;
import org.apache.cocoon.spring.configurator.ResourceUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.HierarchicalBeanFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionVisitor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.io.FileSystemResourceLoader;
import org.springframework.core.io.ResourceLoader;
import org.springframework.web.context.ServletContextAware;
import org.springframework.web.context.support.ServletContextResourceLoader;

/**
* This is a bean factory post processor which handles all the settings stuff
* for Cocoon. It reads in all properties files and replaces references to
* them in the spring configuration files.
* In addition this bean acts as a factory bean providing the settings object.
*
* @see SettingsBeanFactoryPostProcessor
* @see ChildSettingsBeanFactoryPostProcessor
* @since 1.0
* @version $Id: AbstractSettingsBeanFactoryPostProcessor.java 677626 2008-07-17 16:06:10Z gkossakowski $
*/
public abstract class AbstractSettingsBeanFactoryPostProcessor
    extends PropertyPlaceholderConfigurer
    implements ServletContextAware, ResourceLoaderAware, FactoryBean {

    /** Logger (we use the same logging mechanism as Spring!) */
    protected final Log logger = LogFactory.getLog(getClass());

    protected ServletContext servletContext;

    protected MutableSettings settings;

    protected BeanFactory beanFactory;

    protected ResourceLoader resourceLoader;
   
    protected ResourceFilter resourceFilter;

    /**
     * Additional properties.
     */
    protected Properties additionalProperties;

    /**
     * List of additional property directories.
     */
    protected List directories;

    /**
     * @see org.springframework.beans.factory.config.PropertyPlaceholderConfigurer#setBeanFactory(org.springframework.beans.factory.BeanFactory)
     */
    public void setBeanFactory(BeanFactory factory) {
        super.setBeanFactory(factory);
        this.beanFactory = factory;
    }

    /**
     * @see org.springframework.web.context.ServletContextAware#setServletContext(javax.servlet.ServletContext)
     */
    public void setServletContext(ServletContext sContext) {
        this.servletContext = sContext;
    }

    /**
     * @see org.springframework.context.ResourceLoaderAware#setResourceLoader(org.springframework.core.io.ResourceLoader)
     */
    public void setResourceLoader(ResourceLoader loader) {
        this.resourceLoader = loader;
    }
   
    public void setResourceFilter(ResourceFilter resourceFilter) {
        this.resourceFilter = resourceFilter;
    }

    public void setDirectories(List directories) {
        this.directories = directories;
    }

    public void setAdditionalProperties(Properties props) {
        this.additionalProperties = props;
    }

    /**
     * Initialize this processor.
     * Setup the settings object.
     *
     * @throws Exception
     */
    public void init()
    throws Exception {
        settings = createSettings();
        dumpSettings();
    }

    /**
     * Get the running mode.
     * This method should be implemented by subclasses.
     */
    protected abstract String getRunningMode();

    /**
     * Return a parent settings object if available.
     */
    protected Settings getParentSettings() {
        final BeanFactory parentBeanFactory = ((HierarchicalBeanFactory) this.beanFactory).getParentBeanFactory();
        if (parentBeanFactory != null) {
            return (Settings) parentBeanFactory.getBean(Settings.ROLE);
        }

        return null;
    }

    /**
     * Create a new settings object.
     * If a parent settings object is available a new child settings object is created.
     * Otherwise a new root settings object with the running mode is instantiated.
     */
    protected MutableSettings createMutableSettingsInstance() {
        final Settings parentSettings = getParentSettings();
        if (parentSettings == null) {
            return new MutableSettings(getRunningMode());
        }

        return new MutableSettings(parentSettings);
    }

    /**
     * This method can be used by subclasses to initialize the settings and/or
     * the properties before {@link #createSettings()} does it's work.
     */
    protected void preInit(final MutableSettings s, final Properties properties) {
        // default implementation does nothing
    }

    /**
     * This method can be used by subclasses to initialize the settings and/or
     * the properties after {@link #createSettings()} did it's work.
     */
    protected void postInit(final MutableSettings s, final Properties properties) {
        // default implementation does nothing
    }

    protected String getNameForPropertyProvider() {
        return null;
    }

    /**
     * Create a settings object.
     * This method creates the settings by executing the following task:
     * <ol>
     * <li>Create a new mutable settings object invoking {@link #createMutableSettingsInstance()}.
     * <li>Configure the properties and settings object by calling {@link #preInit(MutableSettings, Properties)}.
     * <li>Invoke a {@link PropertyProvider} if configured in the same application context (or its parent)
     * <li>Add properties from configured directories {@link #directories}.
     * <li>Add additional properties configured at {@link #additionalProperties}
     * <li>Apply system properties
     * <li>Configure the properties and settings object by calling {@link #postInit(MutableSettings, Properties)}.
     * <li>Replace references in properties
     * <li>Configure the settings object with the properties
     * <li>Make the settings object read-only.
     * </ol>
     *
     * @return A new Settings object
     */
    protected MutableSettings createSettings() {
        final String mode = getRunningMode();
        // create an empty settings objects
        final MutableSettings s = createMutableSettingsInstance();
        // create the initial properties
        final Properties properties = new Properties();

        // invoke pre initialization hook
        preInit(s, properties);

        // check for property providers
        if (this.beanFactory != null && this.beanFactory.containsBean(PropertyProvider.ROLE) ) {
            try {
                final PropertyProvider provider = (PropertyProvider) this.beanFactory.getBean(PropertyProvider.ROLE);
                final Properties providedProperties = provider.getProperties(s, mode, this.getNameForPropertyProvider());
                if (providedProperties != null) {
                    properties.putAll(providedProperties);
                }
            } catch (Exception ignore) {
                this.logger.warn("Unable to get properties from provider.", ignore);
                this.logger.warn("Continuing initialization.");
            }
        }

        // add aditional directories
        if (this.directories != null) {
            final Iterator i = directories.iterator();
            while (i.hasNext()) {
                final String directory = (String) i.next();
                // now read all properties from the properties directory
                ResourceUtils.readProperties(directory, properties, getResourceLoader(), this.resourceFilter, this.logger);
                // read all properties from the mode dependent directory
                ResourceUtils.readProperties(directory + '/' + mode, properties, getResourceLoader(), this.resourceFilter, this.logger);
            }
        }

        // add additional properties
        if (this.additionalProperties != null) {
            PropertyHelper.replaceAll(this.additionalProperties, s);
            properties.putAll(this.additionalProperties);
        }

        // now overwrite with system properties
        try {
            properties.putAll(System.getProperties());
        } catch (SecurityException se) {
            // we ignore this
        }

        // invoke post initialization hook
        postInit(s, properties);

        PropertyHelper.replaceAll(properties, getParentSettings());
        // configure settings
        s.configure(properties);
        s.makeReadOnly();

        return s;
    }

    protected ResourceLoader getResourceLoader() {
        if (this.resourceLoader != null) {
            return this.resourceLoader;
        }
        if (this.servletContext != null) {
            return new ServletContextResourceLoader(this.servletContext);
        } else {
            return new FileSystemResourceLoader();
        }
    }

    protected String getSystemProperty(String key) {
        return getSystemProperty(key, null);
    }

    protected String getSystemProperty(String key, String defaultValue) {
        try {
            return System.getProperty(key, defaultValue);
        } catch (SecurityException se) {
            // we ignore this
            return defaultValue;
        }
    }

    /**
     * @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 e) {
                throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanNames[i], e);
            }
        }
    }

    /**
     * @see org.springframework.beans.factory.config.PropertyPlaceholderConfigurer#resolvePlaceholder(java.lang.String, java.util.Properties)
     */
    protected String resolvePlaceholder(String placeholder, Properties props) {
        return PropertyHelper.getProperty(placeholder, props, null);
    }

    protected class CocoonSettingsResolvingBeanDefinitionVisitor
        extends BeanDefinitionVisitor {

        protected final Properties props;
        protected final Set visitedPlaceholders = new HashSet();

        public CocoonSettingsResolvingBeanDefinitionVisitor(Settings settings) {
            this.props = new SettingsProperties(settings);
        }

        protected String resolveStringValue(String strVal) {
            return parseStringValue(strVal, this.props, visitedPlaceholders);
        }
    }

    /**
     * Dump the settings object
     */
    protected void dumpSettings() {
        if (this.logger.isDebugEnabled()) {
            this.logger.debug("===== Settings Start =====");
            this.logger.debug(this.settings.toString());
            final List names = this.settings.getPropertyNames();
            final Iterator i = names.iterator();
            while (i.hasNext()) {
                final String name = (String) i.next();
                this.logger.debug("Property: " + name + "=" + this.settings.getProperty(name));
            }
            this.logger.debug("===== Settings End =====");
        }
    }

    /**
     * @see org.springframework.beans.factory.FactoryBean#getObject()
     */
    public Object getObject() throws Exception {
        return this.settings;
    }

    /**
     * @see org.springframework.beans.factory.FactoryBean#getObjectType()
     */
    public Class getObjectType() {
        return Settings.class;
    }

    /**
     * @see org.springframework.beans.factory.FactoryBean#isSingleton()
     */
    public boolean isSingleton() {
        return true;
    }
}
TOP

Related Classes of org.apache.cocoon.spring.configurator.impl.AbstractSettingsBeanFactoryPostProcessor$CocoonSettingsResolvingBeanDefinitionVisitor

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.