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 public XBeanBeanDefinitionParserDelegate(XmlReaderContext readerContext) { 041 super(readerContext); 042 qnameHelper = new XBeanQNameHelper(readerContext); 043 } 044 045 public Object parsePropertySubElement(Element ele, BeanDefinition bd, String defaultTypeClassName) { 046 if (!isDefaultNamespace(ele.getNamespaceURI())) { 047 return internalParseNestedCustomElement(ele, bd); 048 } 049 else if (ele.getTagName().equals(QNAME_ELEMENT)) { 050 return parseQNameElement(ele); 051 } 052 else { 053 return super.parsePropertySubElement(ele, bd, defaultTypeClassName); 054 } 055 } 056 057 public AbstractBeanDefinition parseBeanDefinitionElement(Element ele, String beanName, BeanDefinition containingBean) { 058 AbstractBeanDefinition bd = super.parseBeanDefinitionElement(ele, beanName, containingBean); 059 qnameHelper.coerceNamespaceAwarePropertyValues(bd, ele); 060 return bd; 061 } 062 063 public boolean isDefaultNamespace(String namespaceUri) { 064 return (!StringUtils.hasLength(namespaceUri) || 065 BEANS_NAMESPACE_URI.equals(namespaceUri)) || 066 XBeanNamespaceHandler.SPRING_SCHEMA.equals(namespaceUri) || 067 XBeanNamespaceHandler.SPRING_SCHEMA_COMPAT.equals(namespaceUri); 068 } 069 070 protected Object parseQNameElement(Element element) { 071 return QNameReflectionHelper.createQName(element, getElementText(element)); 072 } 073 074 protected String getElementText(Element element) { 075 StringBuffer buffer = new StringBuffer(); 076 NodeList nodeList = element.getChildNodes(); 077 for (int i = 0, size = nodeList.getLength(); i < size; i++) { 078 Node node = nodeList.item(i); 079 if (node.getNodeType() == Node.TEXT_NODE) { 080 buffer.append(node.getNodeValue()); 081 } 082 } 083 return buffer.toString(); 084 } 085 086 private Object internalParseNestedCustomElement(Element candidateEle, BeanDefinition containingBeanDefinition) { 087 try { 088 Method mth = getClass().getSuperclass().getDeclaredMethod("parseNestedCustomElement", new Class[] { Element.class, BeanDefinition.class }); 089 mth.setAccessible(true); 090 return mth.invoke(this, new Object[] { candidateEle, containingBeanDefinition }); 091 } catch (Exception e) { 092 if (e instanceof InvocationTargetException && e.getCause() instanceof RuntimeException) { 093 throw (RuntimeException) e.getCause(); 094 } 095 throw (IllegalStateException) new IllegalStateException("Unable to invoke parseNestedCustomElement method").initCause(e); 096 } 097 } 098 099 }