View Javadoc

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  }