1 /*** 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.xbean.spring.context.v2c; 18 19 import java.lang.reflect.InvocationTargetException; 20 import java.lang.reflect.Method; 21 22 import org.apache.xbean.spring.context.impl.PropertyEditorHelper; 23 import org.apache.xbean.spring.context.impl.QNameReflectionHelper; 24 import org.apache.xbean.spring.context.v2.XBeanNamespaceHandler; 25 import org.springframework.beans.factory.config.BeanDefinition; 26 import org.springframework.beans.factory.support.AbstractBeanDefinition; 27 import org.springframework.beans.factory.xml.BeanDefinitionParserDelegate; 28 import org.springframework.beans.factory.xml.XmlReaderContext; 29 import org.springframework.util.StringUtils; 30 import org.w3c.dom.Element; 31 import org.w3c.dom.Node; 32 import org.w3c.dom.NodeList; 33 34 public class XBeanBeanDefinitionParserDelegate extends BeanDefinitionParserDelegate { 35 36 public static final String QNAME_ELEMENT = "qname"; 37 38 private XBeanQNameHelper qnameHelper; 39 40 public XBeanBeanDefinitionParserDelegate(XmlReaderContext readerContext) { 41 super(readerContext); 42 qnameHelper = new XBeanQNameHelper(readerContext); 43 } 44 45 public Object parsePropertySubElement(Element ele, BeanDefinition bd, String defaultTypeClassName) { 46 if (!isDefaultNamespace(ele.getNamespaceURI())) { 47 return internalParseNestedCustomElement(ele, bd); 48 } 49 else if (ele.getTagName().equals(QNAME_ELEMENT)) { 50 return parseQNameElement(ele); 51 } 52 else { 53 return super.parsePropertySubElement(ele, bd, defaultTypeClassName); 54 } 55 } 56 57 public AbstractBeanDefinition parseBeanDefinitionElement(Element ele, String beanName, BeanDefinition containingBean) { 58 AbstractBeanDefinition bd = super.parseBeanDefinitionElement(ele, beanName, containingBean); 59 qnameHelper.coerceNamespaceAwarePropertyValues(bd, ele); 60 return bd; 61 } 62 63 public boolean isDefaultNamespace(String namespaceUri) { 64 return (!StringUtils.hasLength(namespaceUri) || 65 BEANS_NAMESPACE_URI.equals(namespaceUri)) || 66 XBeanNamespaceHandler.SPRING_SCHEMA.equals(namespaceUri) || 67 XBeanNamespaceHandler.SPRING_SCHEMA_COMPAT.equals(namespaceUri); 68 } 69 70 protected Object parseQNameElement(Element element) { 71 return QNameReflectionHelper.createQName(element, getElementText(element)); 72 } 73 74 protected String getElementText(Element element) { 75 StringBuffer buffer = new StringBuffer(); 76 NodeList nodeList = element.getChildNodes(); 77 for (int i = 0, size = nodeList.getLength(); i < size; i++) { 78 Node node = nodeList.item(i); 79 if (node.getNodeType() == Node.TEXT_NODE) { 80 buffer.append(node.getNodeValue()); 81 } 82 } 83 return buffer.toString(); 84 } 85 86 private Object internalParseNestedCustomElement(Element candidateEle, BeanDefinition containingBeanDefinition) { 87 try { 88 Method mth = getClass().getSuperclass().getDeclaredMethod("parseNestedCustomElement", new Class[] { Element.class, BeanDefinition.class }); 89 mth.setAccessible(true); 90 return mth.invoke(this, new Object[] { candidateEle, containingBeanDefinition }); 91 } catch (Exception e) { 92 if (e instanceof InvocationTargetException && e.getCause() instanceof RuntimeException) { 93 throw (RuntimeException) e.getCause(); 94 } 95 throw (IllegalStateException) new IllegalStateException("Unable to invoke parseNestedCustomElement method").initCause(e); 96 } 97 } 98 99 }