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