/****************************************************************************** * Copyright (c) 2006, 2010 VMware Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * and Apache License v2.0 which accompanies this distribution. * The Eclipse Public License is available at * http://www.eclipse.org/legal/epl-v10.html and the Apache License v2.0 * is available at http://www.opensource.org/licenses/apache2.0.php. * You may elect to redistribute this code under either of these licenses. * * Contributors: * VMware Inc. *****************************************************************************/ package org.eclipse.gemini.blueprint.blueprint.config; import org.eclipse.gemini.blueprint.blueprint.config.internal.BlueprintCollectionBeanDefinitionParser; import org.eclipse.gemini.blueprint.blueprint.config.internal.BlueprintParser; import org.eclipse.gemini.blueprint.blueprint.config.internal.BlueprintReferenceBeanDefinitionParser; import org.eclipse.gemini.blueprint.blueprint.config.internal.BlueprintServiceDefinitionParser; import org.eclipse.gemini.blueprint.blueprint.config.internal.ParsingUtils; import org.eclipse.gemini.blueprint.service.importer.support.CollectionType; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanDefinitionHolder; import org.springframework.beans.factory.xml.BeanDefinitionParser; import org.springframework.beans.factory.xml.BeanDefinitionParserDelegate; import org.springframework.beans.factory.xml.ParserContext; import org.springframework.util.xml.DomUtils; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** * Namespace parser handling the root <components> element from RFC124 (the equivalent of Spring's <beans> * element). * * @author Costin Leau */ class BlueprintBeanDefinitionParser implements BeanDefinitionParser { static final String BLUEPRINT = "blueprint"; private static final String DESCRIPTION = "description"; private static final String BEAN = "bean"; static final String REFERENCE = "reference"; static final String SERVICE = "service"; static final String REFERENCE_LIST = "reference-list"; static final String REFERENCE_SET = "reference-set"; public BeanDefinition parse(Element componentsRootElement, ParserContext parserContext) { // re-initialize defaults BeanDefinitionParserDelegate delegate = parserContext.getDelegate(); delegate.initDefaults(componentsRootElement); NodeList nl = componentsRootElement.getChildNodes(); for (int i = 0; i < nl.getLength(); i++) { Node node = nl.item(i); if (node instanceof Element) { Element ele = (Element) node; String namespaceUri = ele.getNamespaceURI(); // check beans namespace if (delegate.isDefaultNamespace(namespaceUri)) { BeanDefinitionHolder holder = delegate.parseBeanDefinitionElement(ele); ParsingUtils.decorateAndRegister(ele, holder, parserContext); } // handle own components else if (BlueprintParser.NAMESPACE_URI.equals(namespaceUri)) { parseTopLevelElement(ele, parserContext); } // leave the delegate to find a parser for it else { delegate.parseCustomElement(ele); } } } return null; } /** * Parses the top elements belonging to the RFC 124 namespace. Namely these are <component>, * <description> and <type-converters> * * @param ele * @param parserContext */ protected void parseTopLevelElement(Element ele, ParserContext parserContext) { // description if (DomUtils.nodeNameEquals(ele, DESCRIPTION)) { // ignore description for now } else if (DomUtils.nodeNameEquals(ele, BEAN)) { parseComponentElement(ele, parserContext); } else if (DomUtils.nodeNameEquals(ele, REFERENCE)) { parseReferenceElement(ele, parserContext); } else if (DomUtils.nodeNameEquals(ele, SERVICE)) { parseServiceElement(ele, parserContext); } else if (DomUtils.nodeNameEquals(ele, REFERENCE_LIST)) { parseListElement(ele, parserContext); } else if (DomUtils.nodeNameEquals(ele, REFERENCE_SET)) { parseSetElement(ele, parserContext); } else if (DomUtils.nodeNameEquals(ele, TypeConverterBeanDefinitionParser.TYPE_CONVERTERS)) { parseConvertersElement(ele, parserContext); } else { throw new IllegalArgumentException("Unknown element " + ele); } } /** * Parses a <component> element. * * @param ele * @param parserContext */ protected void parseComponentElement(Element ele, ParserContext parserContext) { BeanDefinitionHolder holder = new BlueprintParser().parseAsHolder(ele, parserContext); ParsingUtils.decorateAndRegister(ele, holder, parserContext); } /** * Parses a <type-converters>. * * @param ele * @param parserContext */ protected void parseConvertersElement(Element ele, ParserContext parserContext) { BeanDefinitionParser parser = new TypeConverterBeanDefinitionParser(); parser.parse(ele, parserContext); } private void parseReferenceElement(Element ele, ParserContext parserContext) { BeanDefinitionParser parser = new BlueprintReferenceBeanDefinitionParser(); parser.parse(ele, parserContext); } private void parseServiceElement(Element ele, ParserContext parserContext) { BeanDefinitionParser parser = new BlueprintServiceDefinitionParser(); parser.parse(ele, parserContext); } private void parseListElement(Element ele, ParserContext parserContext) { BeanDefinitionParser parser = new BlueprintCollectionBeanDefinitionParser() { @Override protected CollectionType collectionType() { return CollectionType.LIST; } }; parser.parse(ele, parserContext); } private void parseSetElement(Element ele, ParserContext parserContext) { BeanDefinitionParser parser = new BlueprintCollectionBeanDefinitionParser() { @Override protected CollectionType collectionType() { return CollectionType.SET; } }; parser.parse(ele, parserContext); } }