/* * The Kuali Financial System, a comprehensive financial management system for higher education. * * Copyright 2005-2014 The Kuali Foundation * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.kuali.kfs.sys.spring.datadictionary; import org.apache.log4j.Logger; import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser; import org.springframework.beans.factory.xml.ParserContext; import org.springframework.util.StringUtils; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; public abstract class KualiBeanDefinitionParserBase extends AbstractBeanDefinitionParser { private static Logger LOG = Logger.getLogger(KualiBeanDefinitionParserBase.class); protected void parseEmbeddedPropertyElements(Element element, BeanDefinitionBuilder bean) { NodeList children = element.getChildNodes(); for ( int i = 0; i < children.getLength(); i++ ) { Node child = children.item(i); if ( child.getLocalName() != null && child.getLocalName().equals("property") ) { Element propertyElement = (Element)child; String propName = propertyElement.getAttribute("name"); String propValue = propertyElement.getAttribute("value"); if ( propValue != null ) { bean.addPropertyValue(propName, propValue); } else if ( propertyElement.getAttribute("ref") != null ) { bean.addPropertyReference(propName, propertyElement.getAttribute("ref") ); } } } } protected void handleAbstractAttribute( Element element, BeanDefinitionBuilder bean) { String abstractStr = element.getAttribute("abstract"); if ( StringUtils.hasText(abstractStr) ) { bean.setAbstract( Boolean.valueOf(abstractStr) ); } } /* The below copied from AbstractSingleBeanDefinitionParser and modified to allow for parent beans to be handled. */ /** * Creates a {@link BeanDefinitionBuilder} instance for the * {@link #getBeanClass bean Class} and passes it to the * {@link #doParse} strategy method. * @param element the element that is to be parsed into a single BeanDefinition * @param parserContext the object encapsulating the current state of the parsing process * @return the BeanDefinition resulting from the parsing of the supplied {@link Element} * @throws IllegalStateException if the bean {@link Class} returned from * {@link #getBeanClass(org.w3c.dom.Element)} is <code>null</code> * @see #doParse */ @SuppressWarnings("unchecked") protected final AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) { BeanDefinitionBuilder builder = null; String parent = element.getAttribute("parent"); String beanClass = element.getAttribute("class"); if ( StringUtils.hasText(beanClass) ) { try { builder = BeanDefinitionBuilder.rootBeanDefinition(Class.forName(beanClass)); } catch (Exception ex) { LOG.fatal( "Unable to resolve class given in class element of a " + element.getLocalName() + " element with id " + element.getAttribute("id"), ex ); throw new RuntimeException(ex); } } else if ( StringUtils.hasText(parent)) { builder = BeanDefinitionBuilder.childBeanDefinition(parent); } else if ( getBeanClass(element) != null ) { builder = BeanDefinitionBuilder.rootBeanDefinition(getBeanClass(element)); } else { builder = BeanDefinitionBuilder.childBeanDefinition(getBaseBeanTypeParent(element)); } builder.setSource(parserContext.extractSource(element)); if (parserContext.isNested()) { // Inner bean definition must receive same singleton status as containing bean. builder.setSingleton(parserContext.getContainingBeanDefinition().isSingleton()); } if (parserContext.isDefaultLazyInit()) { // Default-lazy-init applies to custom bean definitions as well. builder.setLazyInit(true); } doParse(element, parserContext, builder); return builder.getBeanDefinition(); } /** * Parse the supplied {@link Element} and populate the supplied * {@link BeanDefinitionBuilder} as required. * <p>The default implementation delegates to the <code>doParse</code> * version without ParserContext argument. * @param element the XML element being parsed * @param parserContext the object encapsulating the current state of the parsing process * @param builder used to define the <code>BeanDefinition</code> * @see #doParse(Element, BeanDefinitionBuilder) */ protected abstract void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder); protected abstract String getBaseBeanTypeParent( Element element ); protected Class getBeanClass( Element element ) { return null; } }