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

Source Code of org.apache.cocoon.spring.configurator.impl.AbstractSettingsElementParser

/*
* 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.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;

import org.apache.cocoon.spring.configurator.ResourceFilter;
import org.apache.cocoon.spring.configurator.ResourceUtils;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.w3c.dom.Element;

/**
* Abstract class for the settings element parsers.
*
* @see ChildSettingsElementParser
* @see SettingsElementParser
* @version $Id: AbstractSettingsElementParser.java 677626 2008-07-17 16:06:10Z gkossakowski $
* @since 1.0
*/
public abstract class AbstractSettingsElementParser extends AbstractElementParser {

    /**
     * Get the current running mode
     */
    protected abstract String getRunningMode(Element e);

    /**
     * Create and register the settings bean factory post processor.
     */
    protected abstract void createSettingsBeanFactoryPostProcessor(Element       element,
                                                                   ParserContext parserContext,
                                                                   String        runningMode);

    private ResourceFilter resourceFilter;
   
    /**
     * Get additional includes of property directories.
     */
    protected List getPropertyIncludes(Element childSettingsElement) {
        List propertyDirs = null;
        if ( childSettingsElement != null ) {
            final Element[] propertyDirConfigs = this.getChildElements(childSettingsElement, "include-properties");
            if ( propertyDirConfigs != null && propertyDirConfigs.length > 0 ) {
                propertyDirs = new ArrayList();
                for(int i=0; i < propertyDirConfigs.length; i++) {
                    propertyDirs.add(this.getAttributeValue(propertyDirConfigs[i], "dir", null));
                }
            }
        }
        return propertyDirs;
    }

    /**
     * Get additional properties.
     */
    protected Properties getAdditionalProperties(Element childSettingsElement) {
        Properties variables = null;
        final Element[] properties = this.getChildElements(childSettingsElement, "property");
        if ( properties != null && properties.length > 0 ) {
            variables = new Properties();
            for(int i=0; i<properties.length; i++) {
                variables.setProperty(this.getAttributeValue(properties[i], "name", null),
                                      this.getAttributeValue(properties[i], "value", null));
            }
        }
        return variables;
    }

    /**
     * Get additional includes of bean configurations.
     */
    protected List getBeanIncludes(Element childSettingsElement) {
        final List includes = new ArrayList();
        // search for includes
        if ( childSettingsElement.hasChildNodes() ) {
            final Element[] includeElements = this.getChildElements(childSettingsElement, "include-beans");
            if ( includeElements != null ) {
                for(int i = 0 ; i < includeElements.length; i++ ) {
                    final String dir = this.getAttributeValue(includeElements[i], "dir", null);

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

    /**
     * Return the includes for the property override configuration
     */
    protected List getBeanPropertyOverrideIncludes(Element settingsElement) {
        return this.getBeanIncludes(settingsElement);
    }

    /**
     * @see org.springframework.beans.factory.xml.BeanDefinitionParser#parse(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext)
     */
    public BeanDefinition parse(Element element, ParserContext parserContext) {
        final String runningMode = this.getRunningMode(element);
       
        try {
            this.resourceFilter = getResourceFilter(element);
        } catch (Exception e) {
            throw new BeanDefinitionStoreException("Unable to read filter configuration", e);
        }

        // create factory for settings object
        this.createSettingsBeanFactoryPostProcessor(element, parserContext, runningMode);

        // Get bean includes for property overrides
        final List overridePropertyIncludes = this.getBeanPropertyOverrideIncludes(element);

        // If there are bean includes for a directory, we register a property placeholder configurer
        if ( overridePropertyIncludes.size() > 0 ) {
            this.registerPropertyOverrideConfigurer(parserContext, overridePropertyIncludes);
        }

        // register additonal components
        this.registerComponents(element, parserContext);

        // Get bean includes
        final List beanIncludes = this.getBeanIncludes(element);
        // process bean includes!
        final Iterator beanIncludeIterator = beanIncludes.iterator();
        while ( beanIncludeIterator.hasNext() ) {
            final String dir = (String)beanIncludeIterator.next();

            try {
                this.handleBeanInclude(parserContext, dir, false);
                this.handleBeanInclude(parserContext, dir + "/" + runningMode, true);
            } catch (Exception e) {
                throw new BeanDefinitionStoreException("Unable to read spring configurations from " + dir, e);
            }
        }

        return null;
    }

    /**
     * This method can be used for subclasses to register additional components.
     */
    protected void registerComponents(Element settingsElement, ParserContext parserContext) {
        // nothing to do here
    }

    /**
     * Handle include for spring bean configurations.
     */
    protected void handleBeanInclude(final ParserContext parserContext,
                                     final String        path,
                                     final boolean       optional)
    throws Exception {
        final ResourcePatternResolver resolver =
            (ResourcePatternResolver) parserContext.getReaderContext().getReader().getResourceLoader();

        // check if the directory to read from exists
        // we only check if optional is set to true
        boolean load = true;
        if ( optional
             && !ResourceUtils.isClasspathUri(path) ) {
            final Resource rsrc = resolver.getResource(path);
            if ( !rsrc.exists()) {
                load = false;
            }
        }
        if ( load ) {
            try {
                Resource[] resources = resolver.getResources(path + "/*.xml");
                resources = ResourceUtils.filterResources(resources, getResourceFilter());
                Arrays.sort(resources, ResourceUtils.getResourceComparator());
                for (int i = 0; i < resources.length; i++) {
                    this.handleImport(parserContext, resources[i].getURL().toExternalForm());
                }
            } catch (IOException ioe) {
                throw new Exception("Unable to read configurations from " + path, ioe);
            }
        }
    }

    protected void handleImport(ParserContext parserContext, String uri) {
        final ResourceLoader resourceLoader = parserContext.getReaderContext().getReader().getResourceLoader();
        parserContext.getDelegate().getReaderContext().getReader().loadBeanDefinitions(resourceLoader.getResource(uri));
    }

    /**
     * Register a property placeholder configurer. The configurer will read all
     * *.properties files from the specified locations.
     *
     * @param parserContext
     * @param locations
     */
    protected void registerPropertyOverrideConfigurer(final ParserContext parserContext,
                                                      final List          locations) {
        final RootBeanDefinition beanDef = this.createBeanDefinition(ExtendedPropertyOverrideConfigurer.class.getName(),
                null, true);
        beanDef.getPropertyValues().addPropertyValue("locations", locations);
        beanDef.getPropertyValues().addPropertyValue("resourceLoader",
                parserContext.getReaderContext().getReader().getResourceLoader());
        beanDef.getPropertyValues().addPropertyValue("resourceFilter", getResourceFilter());
        beanDef.getPropertyValues().addPropertyValue("beanNameSeparator", "/");
        this.register(beanDef, ExtendedPropertyOverrideConfigurer.class.getName(), parserContext.getRegistry());
    }
   
   
    protected ResourceFilter getResourceFilter(Element e) throws Exception {
        Element[] filters = this.getChildElements(e, "filter");
       
        if (filters.length == 0)
            return null;
        else if (filters.length > 1)
            throw new RuntimeException("Only one filter definition is allowed and you configured " + filters.length + " filters.");
       
        String filterClassName = filters[0].getAttribute("class");
        if (filterClassName.length() == 0)
            throw new RuntimeException("Missing 'class' attribute.");
        return (ResourceFilter)java.lang.Class.forName(filterClassName).newInstance();
    }
   
    protected final ResourceFilter getResourceFilter() {
        return this.resourceFilter;
    }
}
TOP

Related Classes of org.apache.cocoon.spring.configurator.impl.AbstractSettingsElementParser

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.