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 }