001/*
002 * Copyright 2006-2013 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.springframework.batch.core.configuration.xml;
017
018import java.util.List;
019
020import org.springframework.batch.core.listener.AbstractListenerFactoryBean;
021import org.springframework.batch.core.listener.ListenerMetaData;
022import org.springframework.batch.core.listener.StepListenerFactoryBean;
023import org.springframework.batch.core.listener.StepListenerMetaData;
024import org.springframework.beans.MutablePropertyValues;
025import org.springframework.beans.factory.config.BeanDefinition;
026import org.springframework.beans.factory.parsing.CompositeComponentDefinition;
027import org.springframework.beans.factory.support.ManagedList;
028import org.springframework.beans.factory.xml.ParserContext;
029import org.springframework.util.xml.DomUtils;
030import org.w3c.dom.Element;
031
032/**
033 * Parser for a step listener element. Builds a {@link StepListenerFactoryBean}
034 * using attributes from the configuration.
035 *
036 * @author Dan Garrette
037 * @since 2.0
038 * @see AbstractListenerParser
039 */
040public class StepListenerParser extends AbstractListenerParser {
041
042        private static final String LISTENERS_ELE = "listeners";
043
044        private static final String MERGE_ATTR = "merge";
045
046        private final ListenerMetaData[] listenerMetaData;
047
048        public StepListenerParser() {
049                this(StepListenerMetaData.values());
050        }
051
052        public StepListenerParser(ListenerMetaData[] listenerMetaData) {
053                this.listenerMetaData = listenerMetaData;
054        }
055
056        @Override
057        protected Class<? extends AbstractListenerFactoryBean<?>> getBeanClass() {
058                return StepListenerFactoryBean.class;
059        }
060
061        @Override
062        protected ListenerMetaData[] getMetaDataValues() {
063                return listenerMetaData;
064        }
065
066        @SuppressWarnings("unchecked")
067        public void handleListenersElement(Element stepElement, BeanDefinition beanDefinition,
068                        ParserContext parserContext) {
069                MutablePropertyValues propertyValues = beanDefinition.getPropertyValues();
070                List<Element> listenersElements = DomUtils.getChildElementsByTagName(stepElement, LISTENERS_ELE);
071                if (listenersElements.size() == 1) {
072                        Element listenersElement = listenersElements.get(0);
073                        CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(listenersElement.getTagName(),
074                                        parserContext.extractSource(stepElement));
075                        parserContext.pushContainingComponent(compositeDef);
076                        ManagedList<BeanDefinition> listenerBeans = new ManagedList<BeanDefinition>();
077                        if (propertyValues.contains("listeners")) {
078                                listenerBeans = (ManagedList<BeanDefinition>) propertyValues.getPropertyValue("listeners").getValue();
079                        }
080                        listenerBeans.setMergeEnabled(listenersElement.hasAttribute(MERGE_ATTR)
081                                        && Boolean.valueOf(listenersElement.getAttribute(MERGE_ATTR)));
082                        List<Element> listenerElements = DomUtils.getChildElementsByTagName(listenersElement, "listener");
083                        if (listenerElements != null) {
084                                for (Element listenerElement : listenerElements) {
085                                        listenerBeans.add(parse(listenerElement, parserContext));
086                                }
087                        }
088                        propertyValues.addPropertyValue("listeners", listenerBeans);
089                        parserContext.popAndRegisterContainingComponent();
090                }
091        }
092
093}