servicereferenceimpl.java

来自「OSGI这是一个中间件,与UPNP齐名,是用于移植到嵌入式平台之上」· Java 代码 · 共 328 行

JAVA
328
字号
/* * Copyright (c) 2003-2004, KNOPFLERFISH project * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following * conditions are met: * * - Redistributions of source code must retain the above copyright *   notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above *   copyright notice, this list of conditions and the following *   disclaimer in the documentation and/or other materials *   provided with the distribution. * * - Neither the name of the KNOPFLERFISH project nor the names of its *   contributors may be used to endorse or promote products derived *   from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */package org.knopflerfish.framework;import java.lang.reflect.*;import java.security.*;import java.util.Set;import java.util.Vector;import org.osgi.framework.*;/** * Implementation of the ServiceReference object. * * @see org.osgi.framework.ServiceReference * @author Jan Stein */public class ServiceReferenceImpl implements ServiceReference{  /**   * Link to registration object for this reference.   */  private ServiceRegistrationImpl registration;  /**   * Construct a ServiceReference based on given ServiceRegistration.   *   * @param reg ServiceRegistration pointed to be this reference.   */  ServiceReferenceImpl(ServiceRegistrationImpl reg) {    registration = reg;  }  //  // ServiceReference interface  //  /**   * Get the value of a service's property.   *   * @see org.osgi.framework.ServiceReference#getProperty   */  public Object getProperty(String key) {    synchronized (registration.properties) {      if (registration.properties != null) {	return cloneObject(registration.properties.get(key));      } else {	return null;      }    }  }  /**   * Get the list of key names for the service's properties.   *   * @see org.osgi.framework.ServiceReference#getPropertyKeys   */  public String[] getPropertyKeys() {    synchronized (registration.properties) {      return registration.properties.keyArray();    }  }  /**   * Return the bundle which registered the service.   *   * @see org.osgi.framework.ServiceReference#getBundle   */  public Bundle getBundle() {    return registration.bundle;  }  /**   * Test if ServiceReferences points to same service.   *   * @see org.osgi.framework.ServiceReference   */  public boolean equals(Object o) {    if (o instanceof ServiceReferenceImpl) {      return registration == ((ServiceReferenceImpl)o).registration;    }    return false;  }  /**   * Return a hashcode for the service.   *   * @see org.osgi.framework.ServiceReference   */  public int hashCode() {    return registration.hashCode();  }  //  // ServiceReference interface OSGI R2  //  /**   * Return the bundles that are using the service wrapped by this   * ServiceReference, i.e., whose usage count for this service   * is greater than zero.   *   * @return array of bundles whose usage count for the service wrapped by   * this ServiceReference is greater than zero, or <tt>null</tt> if no   * bundles currently are using this service   *   * @since 1.1   */  public Bundle[] getUsingBundles() {    synchronized (registration.properties) {      if (registration.reference != null && registration.dependents.size() > 0) {	Set bs = registration.dependents.keySet();	Bundle[] res =  new Bundle[bs.size()];	return (Bundle[])bs.toArray(res);      } else {	return null;      }    }  }  //  // Package methods  //  /**   * Get the service object.   *   * @param bundle requester of service.   * @return Service requested or null in case of failure.   */  Object getService(final BundleImpl bundle) {    Object s = null;    synchronized (registration.properties) {      if (registration.available) {	Integer ref = (Integer)registration.dependents.get(bundle);	if (ref == null) {	  String[] classes = (String[])registration.properties.get(Constants.OBJECTCLASS);	  if (bundle.framework.bPermissions) {	    boolean perm = false;	    AccessControlContext acc = AccessController.getContext();	    for (int i = 0; i < classes.length; i++) {	      try { 		acc.checkPermission(new ServicePermission(classes[i], ServicePermission.GET));		perm = true;		break;	      } catch (AccessControlException ignore) { }	    }	    if (!perm) {	      throw new SecurityException("Bundle has not permission to get service.");	    }	  }	  if (registration.service instanceof ServiceFactory) {	    try {	      s = AccessController.doPrivileged(new PrivilegedAction() {		  public Object run() {		    return ((ServiceFactory)registration.service).getService(bundle, registration);		  }		});	    } catch (Throwable pe) {	      bundle.framework.listeners.frameworkError(registration.bundle, pe);	      return null;	    }	    if (s == null) {	      return null;	    }	    BundleClassLoader bcl = (BundleClassLoader)registration.bundle.getClassLoader();	    for (int i = 0; i < classes.length; i++) {	      Class c = null;	      try {		c = bcl.loadClass(classes[i], true);	      } catch (ClassNotFoundException ignore) { } // Already checked	      if (!c.isInstance(s)) {		bundle.framework.listeners.frameworkError(registration.bundle, new BundleException("ServiceFactory produced an object that did not implement: " + classes[i]));		return null;	      }	    }	    registration.serviceInstances.put(bundle, s);	  } else {	    s = registration.service;	  }	  registration.dependents.put(bundle, new Integer(1));	} else {	  int count = ref.intValue();	  registration.dependents.put(bundle, new Integer(count + 1));	  if (registration.service instanceof ServiceFactory) {	    s = registration.serviceInstances.get(bundle);	  } else {	    s = registration.service;	  }	}      }    }    return s;  }  /**   * Unget the service object.   *   * @param bundle Bundle who wants remove service.   * @param checkRefCounter If true decrement refence counter and remove service   *                        if we reach zero. If false remove service without   *                        checking refence counter.   * @return True if service was remove or false if only refence counter was   *         decremented.   */  boolean ungetService(BundleImpl bundle, boolean checkRefCounter) {    synchronized (registration.properties) {      if (registration.reference != null) {	Object countInteger = registration.dependents.remove(bundle);	if (countInteger != null) {	  int count = ((Integer) countInteger).intValue();	  if (checkRefCounter && count > 1) {	    registration.dependents.put(bundle, new Integer(count - 1));	    return true;	  } else {	    Object sfi = registration.serviceInstances.remove(bundle);	    if (sfi != null) {	      try {		((ServiceFactory)registration.service).ungetService(bundle, registration, sfi);	      } catch (Throwable e) {		bundle.framework.listeners.frameworkError(registration.bundle, e);	      }	    }	  }	}      }    }    return false;  }  /**   * Get all properties registered with this service.   *   * @return Dictionary containing properties or null   *         if service has been removed.    */  PropertiesDictionary getProperties() {    return registration.properties;  }  //  // Private methods  //          /**   * Clone object. Handles all service property types   * and does this recursivly.   *   * @param bundle Object to clone.   * @return Cloned object.   */  Object cloneObject(Object val) {    if (val instanceof Object []) {      val = ((Object [])val).clone();      int len = Array.getLength(val);      if (len > 0 && Array.get(val, 0).getClass().isArray()) {	for (int i = 0; i < len; i++) {	  Array.set(val, i, cloneObject(Array.get(val, i)));	}      }    } else if (val instanceof boolean []) {      val = ((boolean [])val).clone();    } else if (val instanceof byte []) {      val = ((byte [])val).clone();    } else if (val instanceof char []) {      val = ((char [])val).clone();    } else if (val instanceof double []) {      val = ((double [])val).clone();    } else if (val instanceof float []) {      val = ((float [])val).clone();    } else if (val instanceof int []) {      val = ((int [])val).clone();    } else if (val instanceof long []) {      val = ((long [])val).clone();    } else if (val instanceof short []) {      val = ((short [])val).clone();    } else if (val instanceof Vector) {      Vector c = (Vector)((Vector)val).clone();      for (int i = 0; i < c.size(); i++) {	c.setElementAt(cloneObject(c.elementAt(i)), i);      }      val = c;    }    return val;  }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?