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.beans.PropertyEditorManager;
020    import java.net.MalformedURLException;
021    import java.net.URI;
022    
023    import org.apache.activemq.broker.BrokerFactoryHandler;
024    import org.apache.activemq.broker.BrokerService;
025    import org.apache.activemq.spring.Utils;
026    import org.apache.activemq.util.IntrospectionSupport;
027    import org.apache.activemq.util.URISupport;
028    import org.apache.xbean.spring.context.ResourceXmlApplicationContext;
029    import org.apache.xbean.spring.context.impl.URIEditor;
030    import org.slf4j.Logger;
031    import org.slf4j.LoggerFactory;
032    import org.springframework.beans.BeansException;
033    import org.springframework.beans.FatalBeanException;
034    import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
035    import org.springframework.context.ApplicationContext;
036    import org.springframework.context.ApplicationContextAware;
037    import org.springframework.core.io.Resource;
038    
039    /**
040     * 
041     */
042    public class XBeanBrokerFactory implements BrokerFactoryHandler {
043        private static final transient Logger LOG = LoggerFactory.getLogger(XBeanBrokerFactory.class);
044    
045        static {
046            PropertyEditorManager.registerEditor(URI.class, URIEditor.class);
047        }
048    
049        private boolean validate = true;
050        public boolean isValidate() {
051            return validate;
052        }
053    
054        public void setValidate(boolean validate) {
055            this.validate = validate;
056        }
057    
058        public BrokerService createBroker(URI config) throws Exception {
059            String uri = config.getSchemeSpecificPart();
060            if (uri.lastIndexOf('?') != -1) {
061                IntrospectionSupport.setProperties(this, URISupport.parseQuery(uri));
062                uri = uri.substring(0, uri.lastIndexOf('?'));
063            }
064    
065            ApplicationContext context = createApplicationContext(uri);
066    
067            BrokerService broker = null;
068            try {
069                broker = (BrokerService)context.getBean("broker");
070            } catch (BeansException e) {
071            }
072    
073            if (broker == null) {
074                // lets try find by type
075                String[] names = context.getBeanNamesForType(BrokerService.class);
076                for (int i = 0; i < names.length; i++) {
077                    String name = names[i];
078                    broker = (BrokerService)context.getBean(name);
079                    if (broker != null) {
080                        break;
081                    }
082                }
083            }
084            if (broker == null) {
085                throw new IllegalArgumentException("The configuration has no BrokerService instance for resource: " + config);
086            }
087            
088            if (broker instanceof ApplicationContextAware) {
089                    ((ApplicationContextAware)broker).setApplicationContext(context);
090            }
091            
092            // TODO warning resources from the context may not be closed down!
093    
094            return broker;
095        }
096    
097        protected ApplicationContext createApplicationContext(String uri) throws MalformedURLException {
098            Resource resource = Utils.resourceFromString(uri);
099            LOG.debug("Using " + resource + " from " + uri);
100            try {
101                return new ResourceXmlApplicationContext(resource) {
102                    @Override
103                    protected void initBeanDefinitionReader(XmlBeanDefinitionReader reader) {
104                        reader.setValidating(isValidate());
105                    }
106                };
107            } catch (FatalBeanException errorToLog) {
108                LOG.error("Failed to load: " + resource + ", reason: " + errorToLog.getLocalizedMessage(), errorToLog);
109                throw errorToLog;
110            }
111        }
112    
113    }