Package org.impalaframework.osgi.extender

Source Code of org.impalaframework.osgi.extender.ImpalaActivator

/*
* Copyright 2007-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/

package org.impalaframework.osgi.extender;

import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.impalaframework.config.PrefixedCompositePropertySource;
import org.impalaframework.config.PropertySource;
import org.impalaframework.config.PropertySourceHolder;
import org.impalaframework.config.StaticPropertiesPropertySource;
import org.impalaframework.config.SystemPropertiesPropertySource;
import org.impalaframework.exception.ExecutionException;
import org.impalaframework.exception.InvalidStateException;
import org.impalaframework.facade.Impala;
import org.impalaframework.facade.InternalOperationsFacade;
import org.impalaframework.facade.ModuleManagementFacade;
import org.impalaframework.facade.OperationsFacade;
import org.impalaframework.facade.SimpleOperationsFacade;
import org.impalaframework.module.ModuleDefinitionSource;
import org.impalaframework.module.source.InternalXmlModuleDefinitionSource;
import org.impalaframework.osgi.spring.ImpalaOsgiApplicationContext;
import org.impalaframework.osgi.startup.OsgiContextStarter;
import org.impalaframework.osgi.util.OsgiUtils;
import org.impalaframework.util.ObjectUtils;
import org.impalaframework.util.PropertyUtils;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.springframework.context.ApplicationContext;
import org.springframework.core.io.UrlResource;

/**
* Impala OSGi activator class. Responsible for two things: bootstrapping Impala itself, then loading the modules managed by
* Impala. The Spring configuration files used to bootstrap Impala will by default be found using the property <i>bootstrapLocations</i>
* in the file <i>impala.properties</i>, which will typically be made accessible to the activator using a fragment whose host
* is the extender bundle (that is, the bundle which contains this class). If this resource is not present, then
* the default locations "META-INF/impala-bootstrap.xml" and "META-INF/impala-osgi-bootstrap.xml" are used.
*
* The module definitions to be loaded can be done via one of two means. One, by using a <code>ModuleDefinitionSource</code>
* service, for example {@link org.impalaframework.osgi.test.InjectableModuleDefinitionSource} registered as an OSGi service.
* Two, by adding <i>moduledefinitions.xml</i> into the extender bundle, again using an extender fragment, as in the case
* with the Impala bootstrap locations.
* @author Phil Zoio
*/
public class ImpalaActivator implements BundleActivator {

    private static Log logger = LogFactory.getLog(ImpalaActivator.class);
   
    private InternalOperationsFacade operations;
   
    private static final String[] DEFAULT_LOCATIONS = new String[] {
            "META-INF/impala-bootstrap.xml",
            "META-INF/impala-graph-bootstrap.xml",
            "META-INF/impala-osgi-bootstrap.xml"
    };

    public void start(BundleContext bundleContext) throws Exception {

        String[] locations = getBootstrapLocations(bundleContext);
       
        if (logger.isDebugEnabled()) {
            logger.debug("Called start for bundle context from bundle '" + bundleContext.getBundle() + "'. Activator class: " + this.getClass().getName());
        }
   
        ImpalaOsgiApplicationContext applicationContext = startContext(bundleContext, locations);
       
        if (applicationContext != null) {
           
            logger.info("Started Impala application context for bundle '" + bundleContext.getBundle() + "': " + applicationContext);
            initApplicationContext(bundleContext, applicationContext);
           
        } else {
            logger.warn("No Impala application context started for bundle '" + bundleContext.getBundle() + "'");
        }
           
    }

    void initApplicationContext(BundleContext bundleContext, ApplicationContext applicationContext) {
      
        //TODO introduce constants for bean names
        ModuleManagementFacade facade = ObjectUtils.cast(applicationContext.getBean("moduleManagementFacade"),
                ModuleManagementFacade.class);
       
        if (facade == null) {
            throw new InvalidStateException("Application context '" + applicationContext.getDisplayName()
                    + "' does not contain bean named 'moduleManagementFacade'");
        }
       
        setNewOperationsFacade(facade);
        bundleContext.registerService(OperationsFacade.class.getName(), operations, null);
       
        ModuleDefinitionSource moduleDefinitionSource = maybeGetModuleDefinitionSource(bundleContext, facade);
       
        if (moduleDefinitionSource != null) {
           
            logger.info("Found module definition source for bootstrapping Impala modules: " + moduleDefinitionSource);
            operations.init(moduleDefinitionSource);
           
        } else {
           
            logger.info("No module definition source found for bootstrapping Impala modules. No modules loaded");
        }
       
    }

    void setNewOperationsFacade(ModuleManagementFacade facade) {
        operations = newOperationsFacade(facade);
        Impala.init(operations);
    }

    InternalOperationsFacade newOperationsFacade(ModuleManagementFacade facade) {
        return new SimpleOperationsFacade(facade);
    }

    ModuleDefinitionSource maybeGetModuleDefinitionSource(BundleContext bundleContext, ModuleManagementFacade facade) {
       
        ModuleDefinitionSource moduleDefinitionSource = null;
       
        //TODO use dictionary property to distinguish between possible different services with the same interface
        ServiceReference serviceReference = bundleContext.getServiceReference(ModuleDefinitionSource.class.getName());
       
        if (serviceReference != null) {
            Object service = bundleContext.getService(serviceReference);
            moduleDefinitionSource = ObjectUtils.cast(service, ModuleDefinitionSource.class);
       
            if (logger.isDebugEnabled()) {
                logger.debug("Found module definitionSource injected into OSGi service registry: " + moduleDefinitionSource);
            }
        } else {
           
            if (logger.isDebugEnabled()) {
                logger.debug("No module definitionSource injected into OSGi service registry.");
            }
        }
       
        if (moduleDefinitionSource == null) {
            //TODO test this with a real example
            moduleDefinitionSource = maybeLoadXmlResource(bundleContext, facade);
        }
        return moduleDefinitionSource;
    }

    ModuleDefinitionSource maybeLoadXmlResource(BundleContext bundleContext, ModuleManagementFacade facade) {
       
        URL moduleDefinitionResourceURL = getModuleDefinitionsResourceURL(bundleContext);
        if (moduleDefinitionResourceURL != null) {
           
            if (logger.isDebugEnabled()) {
                logger.debug("Found module definition reource URL from bundle context: " + moduleDefinitionResourceURL);
            }
           
            InternalXmlModuleDefinitionSource source = new InternalXmlModuleDefinitionSource(facade.getModuleLocationResolver(), facade.getTypeReaderRegistry());
            source.setResource(new UrlResource(moduleDefinitionResourceURL));
            return source;
        } else {
           
            if (logger.isDebugEnabled()) {
                logger.debug("No module definition reource URL from bundle context");
            }
        }
       
        return null;
    }

    ImpalaOsgiApplicationContext startContext(BundleContext bundleContext, String[] locations) {
       
        OsgiContextStarter contextStarter = newContextStarter();
        contextStarter.setBundleContext(bundleContext);
       
        ApplicationContext context = contextStarter.startContext(Arrays.asList(locations));
        ImpalaOsgiApplicationContext applicationContext = ObjectUtils.cast(context, ImpalaOsgiApplicationContext.class);
        return applicationContext;
    }

    OsgiContextStarter newContextStarter() {
       
        OsgiContextStarter contextStarter = new OsgiContextStarter();
        return contextStarter;
    }

    String[] getBootstrapLocations(BundleContext bundleContext) {
       
        URL bootstrapLocationsResource = getBootstrapLocationsResourceURL(bundleContext);
       
        String[] locations = null;
       
        if (bootstrapLocationsResource != null) {
           
            try {
                final Properties resourceProperties = PropertyUtils.loadProperties(bootstrapLocationsResource);
               
                //FIXME use PropertiesLoader implementation
               
                List<PropertySource> propertySources = new ArrayList<PropertySource>();
               
                //property value sought first in system property
                propertySources.add(new SystemPropertiesPropertySource());
               
                //then in impala properties file
                propertySources.add(new StaticPropertiesPropertySource(resourceProperties));

                PrefixedCompositePropertySource propertySource = new PrefixedCompositePropertySource("impala.", propertySources);
               
                PropertySourceHolder.getInstance().setPropertySource(propertySource);              
               
                String locationString = resourceProperties.getProperty("bootstrapLocations");
               
                if (locationString != null) {
                    locations = locationString.split(",");
                }      
               
                if (logger.isDebugEnabled()) {
                    logger.debug("Using Impala bootstrap locations found from resource '" + bootstrapLocationsResource + ": " + Arrays.toString(locations));
                }
            } catch (ExecutionException e) {
                logger.error("Unable to load Impala bootstrap resource from specified location: " + e.getMessage(), e);
                throw e;
            }
        }
       
        if (locations == null) {
            locations = DEFAULT_LOCATIONS;
           
            if (logger.isDebugEnabled()) {
                logger.debug("Using default Impala bootstrap locations: " + Arrays.toString(locations));
            }
        }
       
        return locations;
    }

    protected URL getBootstrapLocationsResourceURL(BundleContext bundleContext) {
        //TODO allow this location to be overridden using System property
        return OsgiUtils.findResource(bundleContext, "impala.properties");
    }
   
    protected URL getModuleDefinitionsResourceURL(BundleContext bundleContext) {
        //TODO allow this location to be overridden using System property
        return OsgiUtils.findResource(bundleContext, "moduledefinitions.xml");
    }

    /**
     * Unloads Impala modules and shuts down Impala's {@link ApplicationContext}.
     */
    public void stop(BundleContext bundleContext) throws Exception {
       
        if (operations != null) {      
            operations.unloadRootModule();
            operations.getModuleManagementFacade().close();
        }
    }
}
TOP

Related Classes of org.impalaframework.osgi.extender.ImpalaActivator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.