Package org.impalaframework.osgi.util

Source Code of org.impalaframework.osgi.util.OsgiUtils

/*
* Copyright 2007-2008 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.util;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Dictionary;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.impalaframework.exception.ExecutionException;
import org.impalaframework.exception.InvalidStateException;
import org.impalaframework.module.definition.ModuleDefinition;
import org.impalaframework.util.ExceptionUtils;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.osgi.io.OsgiBundleResource;
import org.springframework.osgi.util.OsgiBundleUtils;
import org.springframework.util.Assert;

/**
* Utility class containing general purpose methods useful for an OSGi environment.
* @author Phil Zoio
*/
public abstract class OsgiUtils {
 
  private static Log logger = LogFactory.getLog(OsgiUtils.class);
 
  /* ****************** Bundle resource related methods ************** */
 
  /**
   * Finds resources not just in the host bundle but in any bundle which
   * contains the locations. Does not guarantee that any resource is loaded
   * from any particular bundle. Instead, relies on sensible naming
   * conventions for resources to be found.
   */
  public static URL[] findResources(BundleContext bundleContext, String[] names) {

    Assert.notNull(bundleContext, "bundleContext cannot be null");
    Assert.notNull(names, "names cannot be null");
   
    if (logger.isTraceEnabled()) {
      logger.trace("Called findResources for " + Arrays.toString(names) + " from " + ExceptionUtils.callStackAsString());
    }
   
    List<URL> urls = new ArrayList<URL>();
   
    for (int i = 0; i < names.length; i++) {
      URL findResource = findResource(bundleContext, names[i]);
      if (findResource != null) {
        urls.add(findResource);
      }
    }
   
    return urls.toArray(new URL[0]);
  }

  /**
   * Finds an individual resources not just in the host bundle but in any
   * bundle which contains the locations. Does not guarantee that any resource
   * is loaded from any particular bundle. Instead, relies on sensible naming
   * conventions for resources to be found.
   */
  public static URL findResource(BundleContext bundleContext, String name) {
   
    Assert.notNull(bundleContext, "bundleContext cannot be null");
    Assert.notNull(name, "names cannot be null");
   
    if (logger.isTraceEnabled()) {
      logger.trace("Called findResource for '" + name + "' from " + ExceptionUtils.callStackAsString());
    }
   
    //first look in host bundle, then cycle through others
    final Bundle hostBundle = bundleContext.getBundle();
    URL resource = hostBundle.getResource(name);
   
    if (resource != null) return resource;

    Bundle[] bundles = bundleContext.getBundles();
   
    //Equinox will return these in install order, so it not a bad idea to cycle through the bundles in reverse order
    for (int i = (bundles.length-1); i >= 0; i--) {
      Bundle bundle = bundles[i];
      resource = bundle.getResource(name);
      if (resource != null) {
        return resource;
      }
    }
   
    return null;
  }
 
  /**
   * Finds the bundle whose name is equal to the name supplied as a method argument.
   * Cycles through the bundles accessible to the supplied {@link BundleContext} via
   * the method {@link BundleContext#getBundle()}.
   * @return the bundle which matches the name if found, otherwise <code>null</code>
   */
  @SuppressWarnings("unchecked")
  public static Bundle findBundle(BundleContext bundleContext, String name) {
   
    Assert.notNull(bundleContext, "bundleContext cannot be null");
    Assert.notNull(name, "name cannot be null");
   
    if (logger.isTraceEnabled()) {
      logger.trace("Called findBundle for '" + name + "' from " + ExceptionUtils.callStackAsString());
    }   
   
    String resource = null;
   
    //find the resources
    Bundle[] bundles = bundleContext.getBundles();
    for (Bundle bundle : bundles) {
      final Dictionary headers = bundle.getHeaders();
      resource = (String) headers.get(org.osgi.framework.Constants.BUNDLE_NAME);
      if (name.equals(resource)) {
        return bundle;
      }
    }
    return null;
  }
 
  public static Resource[] getBundleResources(Bundle bundle, List<String> resourceNames) {

    Assert.notNull(bundle, "bundleCannot be null");
    Assert.notNull(resourceNames, "resourceNames be null");
   
    if (logger.isTraceEnabled()) {
      logger.trace("Called getBundleResources for '" + resourceNames + "' from " + ExceptionUtils.callStackAsString());
    }     
   
    Resource[] resources = new Resource[resourceNames.size()];
    for (int i = 0; i < resources.length; i++) {
      resources[i] = new OsgiBundleResource(bundle, resourceNames.get(i));
    }
    return resources;
  }

  public static String getBundleLocation(Resource bundleResource) {

    Assert.notNull(bundleResource, "bundleResource be null");
   
    String bundleLocation; 
   
    try {
      //based on the original code in org.springframework.osgi.test.AbstractOsgiTests
      bundleLocation = URLDecoder.decode(bundleResource.getURL().toExternalForm(), "UTF8");
    }
    catch (Exception ex) {
      // the URL cannot be created, fall back to the description
      bundleLocation = bundleResource.getDescription();
    }
    return bundleLocation;
  }
 
  /* ****************** Bundle life cycle methods ************** */
 
  /**
   * Attempt to install bundle from bundle {@link Resource}, probably
   * {@link OsgiBundleResource}. If the {@link Resource#exists()} returns
   * true, then the {@link Bundle} is installed using the resource's
   * {@link InputStream}. Otherwise, the bundle's location is passed to the
   * {@link BundleContext#installBundle(String)} method.
   */
  public static Bundle installBundle(BundleContext bundleContext, Resource bundleResource) {
   
    Assert.notNull(bundleContext, "bundleContext cannot be null");
    Assert.notNull(bundleResource, "bundleResource cannot be null");
   
    if (logger.isTraceEnabled()) {
      logger.trace("Called installBundle for resource '" + bundleResource + "' from " + ExceptionUtils.callStackAsString());
    }     
   
    Bundle bundle = null;
   
    InputStream stream = null;
    try {
     
      final String bundleLocation = getBundleLocation(bundleResource);
     
      if (isDirectory(bundleResource)) {
        bundle = bundleContext.installBundle(bundleLocation);
      }
      else {
     
        boolean exists = bundleResource.exists();
        if (exists) {
         
          stream = bundleResource.getInputStream();
         
          if (stream == null) {
            throw new InvalidStateException("Unable to get stream when attempting to install bundle from resource: " + bundleResource.getDescription());
          }
         
          bundle = bundleContext.installBundle(bundleLocation, stream);
        }
      }
     
    } catch (BundleException e) {
      throw new ExecutionException("Unable to install bundle from resource: " + bundleResource.getDescription(), e);
    } catch (IOException e) {
      throw new ExecutionException("IO exception attempting to install bundle from resource: " + bundleResource.getDescription(), e);
    } finally {
      maybeCloseStream(stream);
    }
    return bundle;
  }

  private static boolean isDirectory(Resource bundleResource) {
    if (bundleResource instanceof FileSystemResource) {
      FileSystemResource res = (FileSystemResource) bundleResource;
      File file = res.getFile();
      if (file.isDirectory()) {
        return true;
      }
    }
    return false;
  }

  public static void startBundle(Bundle bundle) {
   
    Assert.notNull(bundle, "bundle cannot be null");
   
    if (logger.isTraceEnabled()) {
      logger.trace("Called startBundle for budnle '" + bundle.getSymbolicName() + "' from " + ExceptionUtils.callStackAsString());
   
   
    if (!OsgiBundleUtils.isFragment(bundle)) {
      try {
        bundle.start();
       
      } catch (BundleException e) {
        throw new ExecutionException("Unable to start bundle with symbolic name '" + bundle.getSymbolicName() + "': " + e.getMessage(), e);
      }
    }
  }

  public static void updateBundle(Bundle bundle, final Resource bundleResource) {
   
    Assert.notNull(bundle, "bundle cannot be null");
    Assert.notNull(bundleResource, "bundleResource cannot be null");
   
    if (logger.isTraceEnabled()) {
      logger.trace("Called updateBundle for budnle '" + bundle.getSymbolicName() + "' using resource '" + bundleResource + " from " + ExceptionUtils.callStackAsString());
    }     

    InputStream stream = null;
   
    try {
     
      if (isDirectory(bundleResource)) {
        bundle.update();
      }
      else {
        if (bundleResource.exists()) {
       
          stream = bundleResource.getInputStream();
       
          if (stream == null) {
            throw new InvalidStateException("Unable to get stream when attempting to update bundle '"
                + bundle.getSymbolicName() + "' from resource: " + bundleResource.getDescription());
          }
         
          bundle.update(stream);
         
        }
      }
     
     
    } catch (BundleException e) {
      throw new ExecutionException("Unable to update bundle '"
            + bundle.getSymbolicName() + "' from resource '" + bundleResource.getDescription()
            + "': " + e.getMessage(), e);
    } catch (IOException e) {
      throw new ExecutionException("IO exception attempting to update bundle '"
            + bundle.getSymbolicName() + "' from resource: '" + bundleResource.getDescription()
            + "': " + e.getMessage(), e);
    } finally {
      maybeCloseStream(stream);
    }
  }

  public static boolean stopBundle(Bundle bundle) {
   
    Assert.notNull(bundle, "bundle cannot be null");
   
    if (logger.isTraceEnabled()) {
      logger.trace("Called stopBundle for budnle '" + bundle.getSymbolicName() + "' from " + ExceptionUtils.callStackAsString());
   
   
    try {
      bundle.stop();
    } catch (BundleException e) {
      throw new ExecutionException("Unable to stop bundle with symbolic name '" + bundle.getSymbolicName() + "': " + e.getMessage(), e);
    }
    return true;
  }

  public static void checkBundle(ModuleDefinition moduleDefinition, Bundle bundle) {
    if (bundle == null) {
      throw new InvalidStateException("Unable to find bundle with name corresponding with module '" + moduleDefinition + "'. Check to see whether this module installed properly.");
    }
  }

  private static void maybeCloseStream(InputStream stream) {
    if (stream != null) {
      try {
        stream.close();
      } catch (IOException e) {
      }
    }
  }
 
}
TOP

Related Classes of org.impalaframework.osgi.util.OsgiUtils

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.