001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  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    package org.apache.activemq.xbean;
018    
019    import java.io.IOException;
020    
021    import javax.annotation.PostConstruct;
022    import javax.annotation.PreDestroy;
023    
024    import org.apache.activemq.broker.BrokerService;
025    import org.apache.activemq.usage.SystemUsage;
026    import org.apache.commons.logging.Log;
027    import org.apache.commons.logging.LogFactory;
028    import org.osgi.framework.BundleException;
029    import org.springframework.beans.BeansException;
030    import org.springframework.context.ApplicationContext;
031    import org.springframework.context.ApplicationContextAware;
032    import org.springframework.context.ConfigurableApplicationContext;
033    import org.springframework.osgi.context.support.OsgiBundleXmlApplicationContext;
034    
035    /**
036     * An ActiveMQ Message Broker. It consists of a number of transport
037     * connectors, network connectors and a bunch of properties which can be used to
038     * configure the broker as its lazily created.
039     * 
040     * @org.apache.xbean.XBean element="broker" rootElement="true"
041     * @org.apache.xbean.Defaults {code:xml} 
042     * <broker test="foo.bar">
043     *   lets.
044     *   see what it includes.
045     * </broker>   
046     * {code}
047     * @version $Revision: 1.1 $
048     */
049    public class XBeanBrokerService extends BrokerService implements ApplicationContextAware {
050        private static final transient Log LOG = LogFactory.getLog(XBeanBrokerService.class);
051        
052        private boolean start = true;
053        private ApplicationContext applicationContext = null;
054        private boolean destroyApplicationContextOnShutdown = false;
055        private boolean destroyApplicationContextOnStop = false;
056    
057        Runnable stopContextRunnable = new Runnable() {
058            public void run() {
059                if (applicationContext instanceof ConfigurableApplicationContext) {
060                    ((ConfigurableApplicationContext) applicationContext).close();
061                }
062                if (applicationContext instanceof OsgiBundleXmlApplicationContext){
063                    try {
064                        ((OsgiBundleXmlApplicationContext)applicationContext).getBundle().stop();
065                    } catch (BundleException e) {
066                        LOG.info("Error stopping OSGi bundle " + e, e);
067                    }
068                }
069    
070            }
071        };
072        
073        public XBeanBrokerService() {
074        }
075    
076        /**
077         *
078         * @throws Exception
079         * @org.apache.xbean.InitMethod
080         */
081        @PostConstruct
082        public void afterPropertiesSet() throws Exception {
083            ensureSystemUsageHasStore();
084            if (start) {
085                start();
086            }
087            if (destroyApplicationContextOnShutdown) {
088                addShutdownHook(stopContextRunnable);
089            }
090        }
091    
092        private void ensureSystemUsageHasStore() throws IOException {
093            SystemUsage usage = getSystemUsage();
094            if (usage.getStoreUsage().getStore() == null) {
095                usage.getStoreUsage().setStore(getPersistenceAdapter());
096            }
097            if (usage.getTempUsage().getStore() == null) {
098                usage.getTempUsage().setStore(getTempDataStore());
099            }
100        }
101    
102        /**
103         *
104         * @throws Exception
105         * @org.apache.xbean.DestroyMethod
106         */
107        @PreDestroy
108        public void destroy() throws Exception {
109            stop();
110        }
111    
112        
113       @Override
114       public void stop() throws Exception {      
115           if (destroyApplicationContextOnStop) {
116               stopContextRunnable.run();
117           }
118           super.stop();
119       }
120        
121    
122        /**
123         * Sets whether or not the broker is started along with the ApplicationContext it is defined within.
124         * Normally you would want the broker to start up along with the ApplicationContext but sometimes when working
125         * with JUnit tests you may wish to start and stop the broker explicitly yourself.
126         */
127        public void setStart(boolean start) {
128            this.start = start;
129        }
130    
131        /**
132         * Sets whether the broker should shutdown the ApplicationContext when the broker jvm is shutdown.
133         * The broker can be stopped because the underlying JDBC store is unavailable for example.
134         */
135        public void setDestroyApplicationContextOnShutdown(boolean destroy) {
136            this.destroyApplicationContextOnShutdown = destroy;
137        }
138        
139        /**
140         * Sets whether the broker should shutdown the ApplicationContext when the broker is stopped.
141         * The broker can be stopped because the underlying JDBC store is unavailable for example.
142         */
143        public void setDestroyApplicationContextOnStop(boolean destroy) {
144            this.destroyApplicationContextOnStop = destroy;
145        }
146    
147            public void setApplicationContext(ApplicationContext applicationContext)
148                            throws BeansException {
149                    this.applicationContext = applicationContext;
150            }
151    
152            public ApplicationContext getApplicationContext() {
153                    return applicationContext;
154            }
155        
156        
157    }