001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.xbean.spring.context.v2c;
018
019 import java.lang.reflect.InvocationTargetException;
020 import java.lang.reflect.Method;
021
022 import org.apache.xbean.spring.context.impl.PropertyEditorHelper;
023 import org.apache.xbean.spring.context.impl.QNameReflectionHelper;
024 import org.apache.xbean.spring.context.v2.XBeanNamespaceHandler;
025 import org.springframework.beans.factory.config.BeanDefinition;
026 import org.springframework.beans.factory.support.AbstractBeanDefinition;
027 import org.springframework.beans.factory.xml.BeanDefinitionParserDelegate;
028 import org.springframework.beans.factory.xml.XmlReaderContext;
029 import org.springframework.util.StringUtils;
030 import org.w3c.dom.Element;
031 import org.w3c.dom.Node;
032 import org.w3c.dom.NodeList;
033
034 public class XBeanBeanDefinitionParserDelegate extends BeanDefinitionParserDelegate {
035
036 public static final String QNAME_ELEMENT = "qname";
037
038 private XBeanQNameHelper qnameHelper;
039
040 static {
041 PropertyEditorHelper.registerCustomEditors();
042 }
043
044 public XBeanBeanDefinitionParserDelegate(XmlReaderContext readerContext) {
045 super(readerContext);
046 qnameHelper = new XBeanQNameHelper(readerContext);
047 }
048
049 public Object parsePropertySubElement(Element ele, BeanDefinition bd, String defaultTypeClassName) {
050 if (!isDefaultNamespace(ele.getNamespaceURI())) {
051 return internalParseNestedCustomElement(ele);
052 }
053 else if (ele.getTagName().equals(QNAME_ELEMENT)) {
054 return parseQNameElement(ele);
055 }
056 else {
057 return super.parsePropertySubElement(ele, bd, defaultTypeClassName);
058 }
059 }
060
061 public AbstractBeanDefinition parseBeanDefinitionElement(Element ele, String beanName, BeanDefinition containingBean) {
062 AbstractBeanDefinition bd = super.parseBeanDefinitionElement(ele, beanName, containingBean);
063 qnameHelper.coerceNamespaceAwarePropertyValues(bd, ele);
064 return bd;
065 }
066
067 public boolean isDefaultNamespace(String namespaceUri) {
068 return (!StringUtils.hasLength(namespaceUri) ||
069 BEANS_NAMESPACE_URI.equals(namespaceUri)) ||
070 XBeanNamespaceHandler.SPRING_SCHEMA.equals(namespaceUri) ||
071 XBeanNamespaceHandler.SPRING_SCHEMA_COMPAT.equals(namespaceUri);
072 }
073
074 protected Object parseQNameElement(Element element) {
075 return QNameReflectionHelper.createQName(element, getElementText(element));
076 }
077
078 protected String getElementText(Element element) {
079 StringBuffer buffer = new StringBuffer();
080 NodeList nodeList = element.getChildNodes();
081 for (int i = 0, size = nodeList.getLength(); i < size; i++) {
082 Node node = nodeList.item(i);
083 if (node.getNodeType() == Node.TEXT_NODE) {
084 buffer.append(node.getNodeValue());
085 }
086 }
087 return buffer.toString();
088 }
089
090 private Object internalParseNestedCustomElement(Element candidateEle) {
091 try {
092 Method mth = getClass().getSuperclass().getDeclaredMethod("parseNestedCustomElement", new Class[] { Element.class, BeanDefinition.class });
093 mth.setAccessible(true);
094 return mth.invoke(this, new Object[] { candidateEle, null });
095 } catch (Exception e) {
096 if (e instanceof InvocationTargetException && e.getCause() instanceof RuntimeException) {
097 throw (RuntimeException) e.getCause();
098 }
099 throw (IllegalStateException) new IllegalStateException("Unable to invoke parseNestedCustomElement method").initCause(e);
100 }
101 }
102
103 }