001    /** 
002     * 
003     * Copyright 2004 Protique Ltd
004     * 
005     * Licensed under the Apache License, Version 2.0 (the "License"); 
006     * you may not use this file except in compliance with the License. 
007     * You may obtain a copy of the License at 
008     * 
009     * http://www.apache.org/licenses/LICENSE-2.0
010     * 
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS, 
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
014     * See the License for the specific language governing permissions and 
015     * limitations under the License. 
016     * 
017     **/
018    package org.activemq.spring;
019    
020    import org.apache.commons.logging.Log;
021    import org.apache.commons.logging.LogFactory;
022    import org.springframework.beans.BeansException;
023    import org.springframework.beans.factory.BeanFactory;
024    import org.springframework.beans.factory.support.DefaultListableBeanFactory;
025    import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
026    import org.springframework.core.io.InputStreamResource;
027    import org.springframework.core.io.Resource;
028    import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
029    
030    import java.io.InputStream;
031    
032    /**
033     * A Spring BeanFactory for creating ActiveMQ objects
034     *
035     * @version $Revision$
036     */
037    public class ActiveMQBeanFactory extends DefaultListableBeanFactory {
038        private static final Log log = LogFactory.getLog(ActiveMQBeanFactory.class);
039        
040        private XmlBeanDefinitionReader reader;
041    
042        /**
043         * A static factory method which can be used easily from spring.xml
044         *
045         * @param resource XML resource to load bean definitions from
046         */
047        public static ActiveMQBeanFactory newInstance(String brokerName, Resource resource) {
048            return new ActiveMQBeanFactory(brokerName, resource);
049        }
050    
051        /**
052         * Create a new ActiveMQBeanFactory with the given resource,
053         * which must be parsable using DOM.
054         *
055         * @param resource XML resource to load bean definitions from
056         * @throws org.springframework.beans.BeansException
057         *          in case of loading or parsing errors
058         */
059        public ActiveMQBeanFactory(String brokerName, Resource resource) throws BeansException {
060            this(brokerName, resource, null);
061        }
062    
063        /**
064         * Create a new ActiveMQBeanFactory with the given InputStream,
065         * which must be parsable using DOM.
066         * <p>It's preferable to use a Resource argument instead of an
067         * InputStream, to retain location information. This constructor
068         * is mainly kept for backward compatibility.
069         *
070         * @param is XML InputStream to load bean definitions from
071         * @throws BeansException in case of loading or parsing errors
072         * @see #ActiveMQBeanFactory(String, Resource)
073         */
074        public ActiveMQBeanFactory(String brokerName, InputStream is) throws BeansException {
075            this(brokerName, new InputStreamResource(is, "(no description)"), null);
076        }
077    
078        /**
079         * Create a new ActiveMQBeanFactory with the given input stream,
080         * which must be parsable using DOM.
081         *
082         * @param resource          XML resource to load bean definitions from
083         * @param parentBeanFactory parent bean factory
084         * @throws BeansException in case of loading or parsing errors
085         */
086        public ActiveMQBeanFactory(String brokerName, Resource resource, BeanFactory parentBeanFactory) throws BeansException {
087            super(parentBeanFactory);
088            reader = createReader(brokerName);
089            reader.loadBeanDefinitions(resource);
090            
091            // Check to see if we have a PropertyPlaceholderConfigurer bean already.
092            if (this.getBeanNamesForType(PropertyPlaceholderConfigurer.class).length == 0) {
093                PropertyPlaceholderConfigurer configurer = new PropertyPlaceholderConfigurer();
094                configurer.setSystemPropertiesMode(PropertyPlaceholderConfigurer.SYSTEM_PROPERTIES_MODE_FALLBACK);
095                configurer.postProcessBeanFactory(this);
096                log.debug("Using System properties to configure bean factory.");
097            }
098            else {
099                log.debug("Already have a PropertyPlaceholderConfigurer, using that to configure bean factory.");
100            }
101        }
102    
103        protected XmlBeanDefinitionReader getReader() {
104            return reader;
105        }
106    
107        /**
108         * A hook to allow custom ActiveMQBeanFactory implementations to provide
109         * their own custom parser of the XML to perform macro processing
110         * or perform XSLT etc
111         *
112         * @return
113         */
114        protected XmlBeanDefinitionReader createReader(String brokerName) {
115            return new ActiveMQBeanDefinitionReader(this, brokerName);
116        }
117    }