ServiceReferenceImpl.java

00001 /*
00002  * Copyright (c) 2003-2004, KNOPFLERFISH project
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following
00007  * conditions are met:
00008  *
00009  * - Redistributions of source code must retain the above copyright
00010  *   notice, this list of conditions and the following disclaimer.
00011  *
00012  * - Redistributions in binary form must reproduce the above
00013  *   copyright notice, this list of conditions and the following
00014  *   disclaimer in the documentation and/or other materials
00015  *   provided with the distribution.
00016  *
00017  * - Neither the name of the KNOPFLERFISH project nor the names of its
00018  *   contributors may be used to endorse or promote products derived
00019  *   from this software without specific prior written permission.
00020  *
00021  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00027  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00028  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00029  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
00030  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00031  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
00032  * OF THE POSSIBILITY OF SUCH DAMAGE.
00033  */
00034 
00035 package org.knopflerfish.framework;
00036 
00037 import java.lang.reflect.*;
00038 import java.util.Set;
00039 import java.util.Vector;
00040 
00041 import org.osgi.framework.*;
00042 
00049 public class ServiceReferenceImpl implements ServiceReference
00050 {
00051 
00055   private ServiceRegistrationImpl registration;
00056 
00057 
00063   ServiceReferenceImpl(ServiceRegistrationImpl reg) {
00064     registration = reg;
00065   }
00066 
00067   //
00068   // ServiceReference interface
00069   //
00070 
00076   public Object getProperty(String key) {
00077     synchronized (registration.properties) {
00078       if (registration.properties != null) {
00079         return cloneObject(registration.properties.get(key));
00080       } else {
00081         return null;
00082       }
00083     }
00084   }
00085 
00086 
00092   public String[] getPropertyKeys() {
00093     synchronized (registration.properties) {
00094       return registration.properties.keyArray();
00095     }
00096   }
00097 
00098 
00104   public Bundle getBundle() {
00105     return registration.bundle;
00106   }
00107 
00108 
00114   public boolean equals(Object o) {
00115     if (o instanceof ServiceReferenceImpl) {
00116       return registration == ((ServiceReferenceImpl)o).registration;
00117     }
00118     return false;
00119   }
00120 
00121 
00127   public int hashCode() {
00128     return registration.hashCode();
00129   }
00130 
00131   //
00132   // ServiceReference interface OSGI R2
00133   //
00134 
00146   public Bundle[] getUsingBundles() {
00147     synchronized (registration.properties) {
00148       if (registration.reference != null && registration.dependents.size() > 0) {
00149         Set bs = registration.dependents.keySet();
00150         Bundle[] res =  new Bundle[bs.size()];
00151         return (Bundle[])bs.toArray(res);
00152       } else {
00153         return null;
00154       }
00155     }
00156   }
00157 
00158   //
00159   // Package methods
00160   //
00161 
00168   Object getService(final BundleImpl bundle) {
00169     Object s = null;
00170     synchronized (registration.properties) {
00171       if (registration.available) {
00172         Integer ref = (Integer)registration.dependents.get(bundle);
00173         if (ref == null) {
00174           String[] classes = (String[])registration.properties.get(Constants.OBJECTCLASS);
00175           bundle.framework.perm.checkGetServicePerms(classes);
00176           if (registration.service instanceof ServiceFactory) {
00177             try {
00178               s = bundle.framework.perm.callGetService((ServiceFactory)registration.service, bundle, registration);
00179             } catch (Throwable pe) {
00180               bundle.framework.listeners.frameworkError(registration.bundle, pe);
00181               return null;
00182             }
00183             if (s == null) {
00184               return null;
00185             }
00186             BundleClassLoader bcl = (BundleClassLoader)registration.bundle.getClassLoader();
00187             for (int i = 0; i < classes.length; i++) {
00188               Class c = null;
00189               try {
00190                 c = bcl.loadClass(classes[i], true);
00191               } catch (ClassNotFoundException ignore) { } // Already checked
00192               if (!c.isInstance(s)) {
00193                 bundle.framework.listeners.frameworkError(registration.bundle, new BundleException("ServiceFactory produced an object that did not implement: " + classes[i]));
00194                 return null;
00195               }
00196             }
00197             registration.serviceInstances.put(bundle, s);
00198           } else {
00199             s = registration.service;
00200           }
00201           registration.dependents.put(bundle, new Integer(1));
00202         } else {
00203           int count = ref.intValue();
00204           registration.dependents.put(bundle, new Integer(count + 1));
00205           if (registration.service instanceof ServiceFactory) {
00206             s = registration.serviceInstances.get(bundle);
00207           } else {
00208             s = registration.service;
00209           }
00210         }
00211       }
00212     }
00213     return s;
00214   }
00215 
00216 
00227   boolean ungetService(BundleImpl bundle, boolean checkRefCounter) {
00228     synchronized (registration.properties) {
00229       if (registration.reference != null) {
00230         Object countInteger = registration.dependents.remove(bundle);
00231         if (countInteger != null) {
00232           int count = ((Integer) countInteger).intValue();
00233           if (checkRefCounter && count > 1) {
00234             registration.dependents.put(bundle, new Integer(count - 1));
00235             return true;
00236           } else {
00237             Object sfi = registration.serviceInstances.remove(bundle);
00238             if (sfi != null) {
00239               try {
00240                 ((ServiceFactory)registration.service).ungetService(bundle, registration, sfi);
00241               } catch (Throwable e) {
00242                 bundle.framework.listeners.frameworkError(registration.bundle, e);
00243               }
00244             }
00245           }
00246         }
00247       }
00248     }
00249     return false;
00250   }
00251 
00252 
00259   PropertiesDictionary getProperties() {
00260     return registration.properties;
00261   }
00262 
00263   //
00264   // Private methods
00265   //    
00266     
00274   Object cloneObject(Object val) {
00275     if (val instanceof Object []) {
00276       val = ((Object [])val).clone();
00277       int len = Array.getLength(val);
00278       if (len > 0 && Array.get(val, 0).getClass().isArray()) {
00279         for (int i = 0; i < len; i++) {
00280           Array.set(val, i, cloneObject(Array.get(val, i)));
00281         }
00282       }
00283     } else if (val instanceof boolean []) {
00284       val = ((boolean [])val).clone();
00285     } else if (val instanceof byte []) {
00286       val = ((byte [])val).clone();
00287     } else if (val instanceof char []) {
00288       val = ((char [])val).clone();
00289     } else if (val instanceof double []) {
00290       val = ((double [])val).clone();
00291     } else if (val instanceof float []) {
00292       val = ((float [])val).clone();
00293     } else if (val instanceof int []) {
00294       val = ((int [])val).clone();
00295     } else if (val instanceof long []) {
00296       val = ((long [])val).clone();
00297     } else if (val instanceof short []) {
00298       val = ((short [])val).clone();
00299     } else if (val instanceof Vector) {
00300       Vector c = (Vector)((Vector)val).clone();
00301       for (int i = 0; i < c.size(); i++) {
00302         c.setElementAt(cloneObject(c.elementAt(i)), i);
00303       }
00304       val = c;
00305     }
00306     return val;
00307   }
00308 
00309   public boolean isAssignableTo(Bundle bundle, String className) {
00310     int pos = className.lastIndexOf('.');
00311     if (pos != -1) {
00312       String name = className.substring(0, pos);
00313       Pkg p = registration.bundle.framework.packages.getPkg(name);
00314       if (p != null) {
00315         if (p.providers.size() > 1) {
00316           BundlePackages pkgExporter = registration.bundle.bpkgs.getProviderBundlePackages(name);
00317           BundlePackages bb = ((BundleImpl)bundle).bpkgs.getProviderBundlePackages(name);
00318           // TBD Should we fail if bundle doesn't have an import?
00319           return bb == null || pkgExporter == bb;
00320         } else {
00321           // Since we do not have multiple providers its no problem
00322           return true;
00323         }
00324       } else {
00325         // Not a package under package control. System package?
00326         if (name.startsWith("java.")) {
00327           return true;
00328         } else {
00329           return true;
00330           // return registration.bundle == bundle;
00331         }
00332       }
00333     }
00334     return false;
00335   }
00336 
00337 }

Generated on Mon Jan 11 21:19:16 2010 for OpenMobileIS by  doxygen 1.5.4