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

import java.io.IOException;
import java.net.URISyntaxException;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.WeakHashMap;

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.parsing.BeanComponentDefinition;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.xml.BeanDefinitionDocumentReader;
import org.springframework.beans.factory.xml.BeanDefinitionParserDelegate;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.beans.factory.xml.XmlReaderContext;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.ResourcePatternUtils;
import org.springframework.util.ResourceUtils;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * A spring namespace handler to handle spring bean elements.
 */
public class BeansNamespaceHandler implements org.springframework.beans.factory.xml.NamespaceHandler {

    private WeakHashMap<ParserContext, BeanDefinitionReader> readers = new WeakHashMap<ParserContext, BeanDefinitionReader>();

    @Override
    public void init() {
    }

    @Override
    public BeanDefinition parse(Element ele, ParserContext parserContext) {
        BeanDefinitionHolder bdh = getReader(parserContext).parseElement(ele);
        return bdh != null ? bdh.getBeanDefinition() : null;
    }

    @Override
    public BeanDefinitionHolder decorate(Node source, BeanDefinitionHolder definition, ParserContext parserContext) {
        return definition;
    }

    private BeanDefinitionReader getReader(ParserContext parserContext) {
        BeanDefinitionReader reader = readers.get(parserContext);
        if (reader == null) {
            reader = new BeanDefinitionReader(parserContext.getReaderContext());
            readers.put(parserContext, reader);
        }
        return reader;
    }

    /**
     * Default implementation of the {@link BeanDefinitionDocumentReader} interface that
     * reads bean definitions according to the "spring-beans" DTD and XSD format
     * (Spring's default XML bean definition format).
     *
     * <p>The structure, elements, and attribute names of the required XML document
     * are hard-coded in this class. (Of course a transform could be run if necessary
     * to produce this format). {@code <beans>} does not need to be the root
     * element of the XML document: this class will parse all bean definition elements
     * in the XML file, regardless of the actual root element.
     *
     * @author Rod Johnson
     * @author Juergen Hoeller
     * @author Rob Harrop
     * @author Erik Wiersma
     * @since 18.12.2003
     */
    public static class BeanDefinitionReader {

        public static final String BEAN_ELEMENT = BeanDefinitionParserDelegate.BEAN_ELEMENT;

        public static final String NESTED_BEANS_ELEMENT = "beans";

        public static final String ALIAS_ELEMENT = "alias";

        public static final String NAME_ATTRIBUTE = "name";

        public static final String ALIAS_ATTRIBUTE = "alias";

        public static final String IMPORT_ELEMENT = "import";

        public static final String RESOURCE_ATTRIBUTE = "resource";

        public static final String PROFILE_ATTRIBUTE = "profile";

        private final XmlReaderContext readerContext;

        private BeanDefinitionParserDelegate delegate;

        public BeanDefinitionReader(XmlReaderContext readerContext) {
            this.readerContext = readerContext;
        }

        /**
         * Return the descriptor for the XML resource that this parser works on.
         */
        protected final XmlReaderContext getReaderContext() {
            return this.readerContext;
        }

        /**
         * Invoke the {@link org.springframework.beans.factory.parsing.SourceExtractor} to pull the
         * source metadata from the supplied {@link Element}.
         */
        protected Object extractSource(Element ele) {
            return getReaderContext().extractSource(ele);
        }


        public BeanDefinitionHolder parseElement(Element ele) {
            BeanDefinitionParserDelegate parent = this.delegate;
            this.delegate = createDelegate(getReaderContext(), ele.getOwnerDocument().getDocumentElement(), parent);
            BeanDefinitionHolder bdh = parseDefaultElement(ele, this.delegate);
            this.delegate = parent;
            return bdh;
        }

        /**
         * Register each bean definition within the given root {@code <beans/>} element.
         */
        protected void doRegisterBeanDefinitions(Element root) {
            // Any nested <beans> elements will cause recursion in this method. In
            // order to propagate and preserve <beans> default-* attributes correctly,
            // keep track of the current (parent) delegate, which may be null. Create
            // the new (child) delegate with a reference to the parent for fallback purposes,
            // then ultimately reset this.delegate back to its original (parent) reference.
            // this behavior emulates a stack of delegates without actually necessitating one.
            BeanDefinitionParserDelegate parent = this.delegate;
            this.delegate = createDelegate(getReaderContext(), root, parent);

            if (this.delegate.isDefaultNamespace(root)) {
                String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
                if (StringUtils.hasText(profileSpec)) {
                    String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
                            profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
                    if (!getReaderContext().getReader().getEnvironment().acceptsProfiles(specifiedProfiles)) {
                        return;
                    }
                }
            }

            parseBeanDefinitions(root, this.delegate);

            this.delegate = parent;
        }

        protected BeanDefinitionParserDelegate createDelegate(
                XmlReaderContext readerContext, Element root, BeanDefinitionParserDelegate parentDelegate) {

            BeanDefinitionParserDelegate delegate = new BeanDefinitionParserDelegate(readerContext);
            delegate.initDefaults(root, parentDelegate);
            return delegate;
        }

        /**
         * Parse the elements at the root level in the document:
         * "import", "alias", "bean".
         * @param root the DOM root element of the document
         */
        protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
            if (delegate.isDefaultNamespace(root)) {
                NodeList nl = root.getChildNodes();
                for (int i = 0; i < nl.getLength(); i++) {
                    Node node = nl.item(i);
                    if (node instanceof Element) {
                        Element ele = (Element) node;
                        if (delegate.isDefaultNamespace(ele)) {
                            parseDefaultElement(ele, delegate);
                        }
                        else {
                            delegate.parseCustomElement(ele);
                        }
                    }
                }
            }
            else {
                delegate.parseCustomElement(root);
            }
        }

        private BeanDefinitionHolder parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
            BeanDefinitionHolder bdh = null;
            if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
                importBeanDefinitionResource(ele);
            }
            else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
                processAliasRegistration(ele);
            }
            else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
                bdh = processBeanDefinition(ele, delegate);
            }
            else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
                // recurse
                doRegisterBeanDefinitions(ele);
            }
            return bdh;
        }

        /**
         * Parse an "import" element and load the bean definitions
         * from the given resource into the bean factory.
         */
        protected void importBeanDefinitionResource(Element ele) {
            String location = ele.getAttribute(RESOURCE_ATTRIBUTE);
            if (!StringUtils.hasText(location)) {
                getReaderContext().error("Resource location must not be empty", ele);
                return;
            }

            // Resolve system properties: e.g. "${user.dir}"
            location = getReaderContext().getReader().getEnvironment().resolveRequiredPlaceholders(location);

            Set<Resource> actualResources = new LinkedHashSet<Resource>(4);

            // Discover whether the location is an absolute or relative URI
            boolean absoluteLocation = false;
            try {
                absoluteLocation = ResourcePatternUtils.isUrl(location) || ResourceUtils.toURI(location).isAbsolute();
            }
            catch (URISyntaxException ex) {
                // cannot convert to an URI, considering the location relative
                // unless it is the well-known Spring prefix "classpath*:"
            }

            // Absolute or relative?
            if (absoluteLocation) {
                try {
                    int importCount = getReaderContext().getReader().loadBeanDefinitions(location, actualResources);
//                    if (logger.isDebugEnabled()) {
//                        logger.debug("Imported " + importCount + " bean definitions from URL location [" + location + "]");
//                    }
                }
                catch (BeanDefinitionStoreException ex) {
                    getReaderContext().error(
                            "Failed to import bean definitions from URL location [" + location + "]", ele, ex);
                }
            }
            else {
                // No URL -> considering resource location as relative to the current file.
                try {
                    int importCount;
                    Resource relativeResource = getReaderContext().getResource().createRelative(location);
                    if (relativeResource.exists()) {
                        importCount = getReaderContext().getReader().loadBeanDefinitions(relativeResource);
                        actualResources.add(relativeResource);
                    }
                    else {
                        String baseLocation = getReaderContext().getResource().getURL().toString();
                        importCount = getReaderContext().getReader().loadBeanDefinitions(
                                StringUtils.applyRelativePath(baseLocation, location), actualResources);
                    }
//                    if (logger.isDebugEnabled()) {
//                        logger.debug("Imported " + importCount + " bean definitions from relative location [" + location + "]");
//                    }
                }
                catch (IOException ex) {
                    getReaderContext().error("Failed to resolve current resource location", ele, ex);
                }
                catch (BeanDefinitionStoreException ex) {
                    getReaderContext().error("Failed to import bean definitions from relative location [" + location + "]",
                            ele, ex);
                }
            }
            Resource[] actResArray = actualResources.toArray(new Resource[actualResources.size()]);
            getReaderContext().fireImportProcessed(location, actResArray, extractSource(ele));
        }

        /**
         * Process the given alias element, registering the alias with the registry.
         */
        protected void processAliasRegistration(Element ele) {
            String name = ele.getAttribute(NAME_ATTRIBUTE);
            String alias = ele.getAttribute(ALIAS_ATTRIBUTE);
            boolean valid = true;
            if (!StringUtils.hasText(name)) {
                getReaderContext().error("Name must not be empty", ele);
                valid = false;
            }
            if (!StringUtils.hasText(alias)) {
                getReaderContext().error("Alias must not be empty", ele);
                valid = false;
            }
            if (valid) {
                try {
                    getReaderContext().getRegistry().registerAlias(name, alias);
                }
                catch (Exception ex) {
                    getReaderContext().error("Failed to register alias '" + alias +
                            "' for bean with name '" + name + "'", ele, ex);
                }
                getReaderContext().fireAliasRegistered(name, alias, extractSource(ele));
            }
        }

        /**
         * Process the given bean element, parsing the bean definition
         * and registering it with the registry.
         */
        protected BeanDefinitionHolder processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
            BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
            if (bdHolder != null) {
                bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
                try {
                    // Register the final decorated instance.
                    BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
                }
                catch (BeanDefinitionStoreException ex) {
                    getReaderContext().error("Failed to register bean definition with name '" +
                            bdHolder.getBeanName() + "'", ele, ex);
                }
                // Send registration event.
                getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
            }
            return bdHolder;
        }
    }

}
