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.getBeanDefinition().setSource(parserContext.extractSource(element));
90          if (parserContext.isNested()) {
91              // Inner bean definition must receive same singleton status as containing bean.
92              boolean singleton = parserContext.getContainingBeanDefinition().isSingleton();
93              if(singleton)
94                  builder.setScope("singleton");
95          }
96          if (parserContext.isDefaultLazyInit()) {
97              // Default-lazy-init applies to custom bean definitions as well.
98              builder.setLazyInit(true);
99          }
100         doParse(element, parserContext, builder);
101         return builder.getBeanDefinition();
102     }
103 
104     /**
105      * Parse the supplied {@link Element} and populate the supplied
106      * {@link BeanDefinitionBuilder} as required.
107      * <p>The default implementation delegates to the <code>doParse</code>
108      * version without ParserContext argument.
109      * @param element the XML element being parsed
110      * @param parserContext the object encapsulating the current state of the parsing process
111      * @param builder used to define the <code>BeanDefinition</code>
112      * @see #doParse(Element, BeanDefinitionBuilder)
113      */
114     protected abstract void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder);
115 
116     protected abstract String getBaseBeanTypeParent( Element element );
117     
118     protected Class getBeanClass( Element element ) {
119         return null;
120     }
121 }