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

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;

import org.apache.cocoon.portal.services.aspects.AspectChain;
import org.apache.cocoon.portal.services.aspects.support.AspectChainImpl;
import org.apache.cocoon.spring.configurator.impl.AbstractElementParser;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.ManagedList;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.BeanDefinitionParserDelegate;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;

/**
 *
 * @version $Id$
 */
public class AspectsBeanDefinitionParser extends AbstractElementParser {

    protected final String baseClass;

    protected final Class aspectChainClass;

    public AspectsBeanDefinitionParser(final String className) {
        this.baseClass = className;
        this.aspectChainClass = AspectChainImpl.class;
    }

    public AspectsBeanDefinitionParser(final String className, Class aspectChainClass) {
        this.baseClass = className;
        this.aspectChainClass = aspectChainClass;
    }

    /**
     * @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) {
        // create a new bean definition for the aspect chain
        RootBeanDefinition beanDef = this.createBeanDefinition(this.aspectChainClass, null, false);
        final ManagedList aspectBeans = new ManagedList();
        aspectBeans.setSource(parserContext.getReaderContext().extractSource(element));
        final List aspectProperties = new ArrayList();
        final Element[] aspects = this.getChildElements(element, "aspect");
        for(int i=0; i<aspects.length; i++) {
            final String ref = this.getAttributeValue(aspects[i], "ref", null);
            final String type= this.getAttributeValue(aspects[i], "type", null);
            if ( ref == null && type == null ) {
                throw new BeanDefinitionStoreException("Element 'aspect' must have either a 'ref' or a 'type' attribute.");
            }
            if ( ref != null && type != null ) {
                throw new BeanDefinitionStoreException("Element 'aspect' must have either a 'ref' or a 'type' attribute, but not both.");
            }
            final String beanName = (ref != null ? ref : this.baseClass + '.' + type);
            aspectBeans.add(new RuntimeBeanReference(beanName));
            // properties
            final Properties props = new Properties();
            final Element[] properties = this.getChildElements(aspects[i], "property");
            for(int m=0; m<properties.length;m++) {
                props.setProperty(this.getAttributeValue(properties[m], "name", null),
                                  this.getAttributeValue(properties[m], "value", null));
            }
            if ( props.size() == 0 ) {
                aspectProperties.add(AspectChain.EMPTY_PROPERTIES);
            } else {
                aspectProperties.add(props);
            }
        }
        try {
            beanDef.getConstructorArgumentValues().addIndexedArgumentValue(0, ClassUtils.forName(this.baseClass));
        } catch (ClassNotFoundException e) {
            throw new BeanDefinitionStoreException("Unable to load aspect class: " + this.baseClass, e);
        }
        beanDef.getConstructorArgumentValues().addIndexedArgumentValue(1, aspectBeans);
        beanDef.getConstructorArgumentValues().addIndexedArgumentValue(2, aspectProperties);

        if ( !parserContext.isNested() ) {
            String id = element.getAttribute(BeanDefinitionParserDelegate.ID_ATTRIBUTE);
            String nameAttr = element.getAttribute(BeanDefinitionParserDelegate.NAME_ATTRIBUTE);

            List aliases = new ArrayList();
            if (StringUtils.hasLength(nameAttr)) {
                String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, BeanDefinitionParserDelegate.BEAN_NAME_DELIMITERS);
                aliases.addAll(Arrays.asList(nameArr));
            }

            String beanName = id;
            if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
                beanName = (String) aliases.remove(0);
                if (logger.isDebugEnabled()) {
                    logger.debug("No XML 'id' specified - using '" + beanName +
                            "' as bean name and " + aliases + " as aliases");
                }
            }
            final BeanDefinitionHolder holder = new BeanDefinitionHolder(beanDef, beanName, StringUtils.toStringArray(aliases));
            BeanDefinitionReaderUtils.registerBeanDefinition(holder, parserContext.getRegistry());
        }
        return beanDef;
    }
}
