Package org.springframework.osgi.util

Source Code of org.springframework.osgi.util.OsgiServiceReferenceUtils

/*
* Copyright 2006-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.springframework.osgi.util;

import java.util.Collections;
import java.util.Dictionary;
import java.util.LinkedHashMap;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
import org.springframework.osgi.util.internal.MapBasedDictionary;
import org.springframework.osgi.util.internal.ServiceReferenceBasedMap;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;

/**
* Utility class for retrieving OSGi service references. This class offers a
* unified filter-based access for OSGi services as well as translation of
* checked exceptions {@link InvalidSyntaxException} into unchecked ones.
*
* <p/>
*
* This classes uses {@link OsgiFilterUtils} underneath to allow multiple class
* names to be used for service reference lookup.
*
* @see OsgiFilterUtils
* @author Costin Leau
*
*/
public abstract class OsgiServiceReferenceUtils {

  private static final Log log = LogFactory.getLog(OsgiServiceReferenceUtils.class);


  /**
   * Returns a reference to the <em>best matching</em> service for the given
   * class names.
   *
   * @param bundleContext OSGi bundle context
   * @param classes array of fully qualified class names
   * @return reference to the <em>best matching</em> service
   */
  public static ServiceReference getServiceReference(BundleContext bundleContext, String[] classes) {
    return getServiceReference(bundleContext, classes, null);
  }

  /**
   * Returns a reference to the <em>best matching</em> service for the given
   * class and OSGi filter.
   *
   * @param bundleContext OSGi bundle context
   * @param clazz fully qualified class name (can be <code>null</code>)
   * @param filter valid OSGi filter (can be <code>null</code>)
   * @return reference to the <em>best matching</em> service
   */
  public static ServiceReference getServiceReference(BundleContext bundleContext, String clazz, String filter) {
    ServiceReference[] refs = getServiceReferences(bundleContext, clazz, filter);

    // pick the first service
    ServiceReference winningReference = (refs.length > 0 ? refs[0] : null);

    if (winningReference == null)
      return null;

    long winningId = getServiceId(winningReference);
    int winningRanking = getServiceRanking(winningReference);

    // start iterating in order to find the best match
    for (int i = 1; i < refs.length; i++) {
      ServiceReference reference = refs[i];
      int serviceRanking = getServiceRanking(reference);
      long serviceId = getServiceId(reference);

      if ((serviceRanking > winningRanking) || (serviceRanking == winningRanking && winningId > serviceId)) {
        winningReference = reference;
        winningId = serviceId;
        winningRanking = serviceRanking;
      }
    }

    return winningReference;
  }

  /**
   * Returns a reference to the <em>best matching</em> service for the given
   * classes and OSGi filter.
   *
   * @param bundleContext OSGi bundle context
   * @param classes array of fully qualified class names
   * @param filter valid OSGi filter (can be <code>null</code>)
   * @return reference to the <em>best matching</em> service
   */
  public static ServiceReference getServiceReference(BundleContext bundleContext, String[] classes, String filter) {
    // use #getServiceReference(BundleContext, String, String) method to
    // speed the service lookup process by
    // giving one class as a hint to the OSGi implementation

    String clazz = (ObjectUtils.isEmpty(classes) ? null : classes[0]);

    return getServiceReference(bundleContext, clazz, OsgiFilterUtils.unifyFilter(classes, filter));
  }

  /**
   * Returns a reference to the <em>best matching</em> service for the given
   * OSGi filter.
   *
   * @param bundleContext OSGi bundle context
   * @param filter valid OSGi filter (can be <code>null</code>)
   * @return reference to the <em>best matching</em> service
   */
  public static ServiceReference getServiceReference(BundleContext bundleContext, String filter) {
    return getServiceReference(bundleContext, (String) null, filter);
  }

  /**
   * Returns references to <em>all</em> services matching the given class
   * names.
   *
   * @param bundleContext OSGi bundle context
   * @param classes array of fully qualified class names
   * @return non-<code>null</code> array of references to matching services
   */
  public static ServiceReference[] getServiceReferences(BundleContext bundleContext, String[] classes) {
    return getServiceReferences(bundleContext, classes, null);
  }

  /**
   * Returns references to <em>all</em> services matching the given class
   * name and OSGi filter.
   *
   * @param bundleContext OSGi bundle context
   * @param clazz fully qualified class name (can be <code>null</code>)
   * @param filter valid OSGi filter (can be <code>null</code>)
   * @return non-<code>null</code> array of references to matching services
   */
  public static ServiceReference[] getServiceReferences(BundleContext bundleContext, String clazz, String filter) {
    Assert.notNull(bundleContext, "bundleContext should be not null");

    try {
      ServiceReference[] refs = bundleContext.getServiceReferences(clazz, filter);
      return (refs == null ? new ServiceReference[0] : refs);
    }
    catch (InvalidSyntaxException ise) {
      throw (RuntimeException) new IllegalArgumentException("invalid filter: " + ise.getFilter()).initCause(ise);
    }

  }

  /**
   * Returns references to <em>all</em> services matching the given class
   * names and OSGi filter.
   *
   * @param bundleContext OSGi bundle context
   * @param classes array of fully qualified class names
   * @param filter valid OSGi filter (can be <code>null</code>)
   * @return non-<code>null</code> array of references to matching services
   */
  public static ServiceReference[] getServiceReferences(BundleContext bundleContext, String[] classes, String filter) {
    // use #getServiceReferences(BundleContext, String, String) method to
    // speed the service lookup process by
    // giving one class as a hint to the OSGi implementation

    String clazz = (ObjectUtils.isEmpty(classes) ? null : classes[0]);
    return getServiceReferences(bundleContext, clazz, OsgiFilterUtils.unifyFilter(classes, filter));
  }

  /**
   * Returns references to <em>all</em> services matching the OSGi filter.
   *
   * @param bundleContext OSGi bundle context
   * @param filter valid OSGi filter (can be <code>null</code>)
   * @return non-<code>null</code> array of references to matching services
   */
  public static ServiceReference[] getServiceReferences(BundleContext bundleContext, String filter) {
    return getServiceReferences(bundleContext, (String) null, filter);
  }

  /**
   * Returns the service id ({@link Constants#SERVICE_ID}) of the given
   * service reference.
   *
   * @param reference OSGi service reference
   * @return service id
   */
  public static long getServiceId(ServiceReference reference) {
    Assert.notNull(reference);
    return ((Long) reference.getProperty(Constants.SERVICE_ID)).longValue();
  }

  /**
   * Returns the service ranking ({@link Constants#SERVICE_RANKING}) of the
   * given service reference.
   *
   * @param reference OSGi service reference
   * @return service ranking
   */
  public static int getServiceRanking(ServiceReference reference) {
    Assert.notNull(reference);

    Object ranking = reference.getProperty(Constants.SERVICE_RANKING);
    // if the property is not supplied or of incorrect type, use a
    // default
    return ((ranking != null && ranking instanceof Integer) ? ((Integer) ranking).intValue() : 0);
  }

  /**
   * Returns the advertised class names ({@link Constants#OBJECTCLASS}) of
   * the given service reference.
   *
   * @param reference OSGi service reference
   * @return service advertised class names
   */
  public static String[] getServiceObjectClasses(ServiceReference reference) {
    Assert.notNull(reference);
    return (String[]) reference.getProperty(Constants.OBJECTCLASS);
  }

  /**
   * Returns a {@link Map} containing the properties available for the given
   * service reference. This method takes a snapshot of the properties; future
   * changes to the service properties will not be reflected in the returned
   * dictionary.
   *
   * <p/> Note that the returned type implements the {@link java.util.Map}
   * interface also.
   *
   * @param reference OSGi service reference
   * @return a <code>Dictionary</code> containing the service reference
   * properties taken as a snapshot
   */
  public static Dictionary getServicePropertiesSnapshot(ServiceReference reference) {
    return new MapBasedDictionary(getServicePropertiesSnapshotAsMap(reference));
  }

  /**
   * Returns a {@link Map} containing the properties available for the given
   * service reference. This method takes a snapshot of the properties; future
   * changes to the service properties will not be reflected in the returned
   * dictionary.
   *
   * @param reference OSGi service reference
   * @return a <code>Map</code> containing the service reference properties
   * taken as a snapshot
   */
  public static Map getServicePropertiesSnapshotAsMap(ServiceReference reference) {
    Assert.notNull(reference);
    String[] keys = reference.getPropertyKeys();

    Map map = new LinkedHashMap(keys.length);

    for (int i = 0; i < keys.length; i++) {
      map.put(keys[i], reference.getProperty(keys[i]));
    }

    // mark it as read-only
    map = Collections.unmodifiableMap(map);
    return map;
  }

  /**
   * Returns a {@link Dictionary} containing the properties available for the
   * given service reference. The returned object will reflect any updates
   * made to to the <code>ServiceReference</code> through the owning
   * <code>ServiceRegistration</code>.
   *
   *
   * <p/> Note that the returned type implements the {@link java.util.Map}
   * interface also.
   *
   * @param reference OSGi service reference
   * @return a <code>Dictionary</code> containing the latest service
   * reference properties
   */
  public static Dictionary getServiceProperties(ServiceReference reference) {
    return new MapBasedDictionary(getServicePropertiesAsMap(reference));
  }

  /**
   * Returns a {@link Map} containing the properties available for the given
   * service reference. The returned object will reflect any updates made to
   * to the <code>ServiceReference</code> through the owning
   * <code>ServiceRegistration</code>. Consider using
   * {@link #getServiceProperties(ServiceReference)} which returns an object
   * that extends {@link Dictionary} as well as implements the {@link Map}
   * interface.
   *
   * @param reference OSGi service reference
   * @return a <code>Map</code> containing the latest service reference
   * properties
   * @see #getServiceProperties(ServiceReference)
   */
  public static Map getServicePropertiesAsMap(ServiceReference reference) {
    Assert.notNull(reference);
    return new ServiceReferenceBasedMap(reference);

  }

  /**
   * Checks if the given filter matches at least one OSGi service or not.
   *
   * @param bundleContext OSGi bundle context
   * @param filter valid OSGi filter (can be <code>null</code>)
   * @return true if the filter matches at least one OSGi service, false
   * otherwise
   */
  public static boolean isServicePresent(BundleContext bundleContext, String filter) {
    return !ObjectUtils.isEmpty(getServiceReferences(bundleContext, filter));
  }
}
TOP

Related Classes of org.springframework.osgi.util.OsgiServiceReferenceUtils

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.