/******************************************************************************
* 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);
}
}