View Javadoc
1   /*
2    * Copyright 2008 The Kuali Foundation
3    * 
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    * http://www.opensource.org/licenses/ecl2.php
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.ole.sys.spring.datadictionary;
17  
18  import org.apache.log4j.Logger;
19  import org.springframework.beans.factory.support.AbstractBeanDefinition;
20  import org.springframework.beans.factory.support.BeanDefinitionBuilder;
21  import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
22  import org.springframework.beans.factory.xml.ParserContext;
23  import org.springframework.util.StringUtils;
24  import org.w3c.dom.Element;
25  import org.w3c.dom.Node;
26  import org.w3c.dom.NodeList;
27  
28  public abstract class KualiBeanDefinitionParserBase extends AbstractBeanDefinitionParser {
29  
30      private static Logger LOG = Logger.getLogger(KualiBeanDefinitionParserBase.class);
31      
32      protected void parseEmbeddedPropertyElements(Element element, BeanDefinitionBuilder bean) {
33          NodeList children = element.getChildNodes();
34          for ( int i = 0; i < children.getLength(); i++ ) {
35              Node child = children.item(i);
36              if ( child.getLocalName() != null && child.getLocalName().equals("property") ) {
37                  Element propertyElement = (Element)child;                
38                  String propName = propertyElement.getAttribute("name");
39                  String propValue = propertyElement.getAttribute("value");
40                  if ( propValue != null ) {
41                      bean.addPropertyValue(propName, propValue);
42                  } else if ( propertyElement.getAttribute("ref") != null ) {
43                      bean.addPropertyReference(propName, propertyElement.getAttribute("ref") );
44                  }
45              }
46          }        
47      }
48      
49      protected void handleAbstractAttribute( Element element, BeanDefinitionBuilder bean) {
50          String abstractStr = element.getAttribute("abstract");
51          
52          if ( StringUtils.hasText(abstractStr) ) {
53              bean.setAbstract( Boolean.valueOf(abstractStr) );
54          }
55      }
56      
57      /* The below copied from AbstractSingleBeanDefinitionParser and modified to allow for parent beans to be handled. */
58      /**
59       * Creates a {@link BeanDefinitionBuilder} instance for the
60       * {@link #getBeanClass bean Class} and passes it to the
61       * {@link #doParse} strategy method.
62       * @param element the element that is to be parsed into a single BeanDefinition
63       * @param parserContext the object encapsulating the current state of the parsing process
64       * @return the BeanDefinition resulting from the parsing of the supplied {@link Element}
65       * @throws IllegalStateException if the bean {@link Class} returned from
66       * {@link #getBeanClass(org.w3c.dom.Element)} is <code>null</code>
67       * @see #doParse
68       */
69      @SuppressWarnings("unchecked")
70      protected final AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
71          BeanDefinitionBuilder builder = null;
72          
73          String parent = element.getAttribute("parent");
74          String beanClass = element.getAttribute("class");
75          if ( StringUtils.hasText(beanClass) ) {
76              try {
77                  builder = BeanDefinitionBuilder.rootBeanDefinition(Class.forName(beanClass));
78              } catch (Exception ex) {
79                  LOG.fatal( "Unable to resolve class given in class element of a " + element.getLocalName() + " element with id " + element.getAttribute("id"), ex );
80                  throw new RuntimeException(ex);
81              }
82          } else  if ( StringUtils.hasText(parent)) {
83              builder = BeanDefinitionBuilder.childBeanDefinition(parent);
84          } else if ( getBeanClass(element) != null ) {
85              builder = BeanDefinitionBuilder.rootBeanDefinition(getBeanClass(element));
86          } else {
87              builder = BeanDefinitionBuilder.childBeanDefinition(getBaseBeanTypeParent(element)); 
88          }
89          builder.setSource(parserContext.extractSource(element));
90          if (parserContext.isNested()) {
91              // Inner bean definition must receive same singleton status as containing bean.
92              builder.setSingleton(parserContext.getContainingBeanDefinition().isSingleton());
93          }
94          if (parserContext.isDefaultLazyInit()) {
95              // Default-lazy-init applies to custom bean definitions as well.
96              builder.setLazyInit(true);
97          }
98          doParse(element, parserContext, builder);
99          return builder.getBeanDefinition();
100     }
101 
102     /**
103      * Parse the supplied {@link Element} and populate the supplied
104      * {@link BeanDefinitionBuilder} as required.
105      * <p>The default implementation delegates to the <code>doParse</code>
106      * version without ParserContext argument.
107      * @param element the XML element being parsed
108      * @param parserContext the object encapsulating the current state of the parsing process
109      * @param builder used to define the <code>BeanDefinition</code>
110      * @see #doParse(Element, BeanDefinitionBuilder)
111      */
112     protected abstract void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder);
113 
114     protected abstract String getBaseBeanTypeParent( Element element );
115     
116     protected Class getBeanClass( Element element ) {
117         return null;
118     }
119 }