00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 package org.knopflerfish.framework;
00036
00037 import java.util.Set;
00038 import java.util.Dictionary;
00039 import java.util.HashMap;
00040 import java.util.HashSet;
00041 import java.util.ArrayList;
00042 import java.util.Iterator;
00043
00044 import org.osgi.framework.*;
00045 import org.osgi.service.packageadmin.PackageAdmin;
00046 import org.osgi.service.permissionadmin.PermissionAdmin;
00047
00048
00055 class Services {
00056
00061 private HashMap services = new HashMap();
00062
00066 private HashMap classServices = new HashMap();
00067
00071 private PermissionOps secure;
00072
00073
00074 Services(PermissionOps perm) {
00075 secure = perm;
00076 }
00077
00094 ServiceRegistration register(BundleImpl bundle,
00095 String[] classes,
00096 Object service,
00097 Dictionary properties) {
00098 if (service == null) {
00099 throw new IllegalArgumentException("Can't register null as a service");
00100 }
00101 ServiceRegistration res;
00102 synchronized (this) {
00103
00104 Class sc = service.getClass();
00105 ClassLoader scl = sc.getClassLoader();
00106 for (int i = 0; i < classes.length; i++) {
00107 String cls = classes[i];
00108 if (cls == null) {
00109 throw new IllegalArgumentException("Can't register as null class");
00110 }
00111 secure.checkRegisterServicePerm(cls);
00112 if (bundle.id != 0) {
00113 if (cls.equals(PackageAdmin.class.getName())) {
00114 throw new IllegalArgumentException("Registeration of a PackageAdmin service is not allowed");
00115 }
00116 if (cls.equals(PermissionAdmin.class.getName())) {
00117 throw new IllegalArgumentException("Registeration of a PermissionAdmin service is not allowed");
00118 }
00119 }
00120 if (!(service instanceof ServiceFactory)) {
00121 ClassLoader cl = sc.getClassLoader();
00122 Class c = null;
00123 boolean ok = false;
00124 try {
00125 if (cl != null) {
00126 c = cl.loadClass(cls);
00127 } else {
00128 c = Class.forName(cls);
00129 }
00130 ok = c.isInstance(service);
00131 } catch (ClassNotFoundException e) {
00132 for (Class csc = sc; csc != null; csc = csc.getSuperclass()) {
00133 if (cls.equals(csc.getName())) {
00134 ok = true;
00135 break;
00136 } else {
00137 Class [] ic = csc.getInterfaces();
00138 for (int iic = ic.length - 1; iic >= 0; iic--) {
00139 if (cls.equals(ic[iic].getName())) {
00140 ok = true;
00141 break;
00142 }
00143 }
00144 }
00145 }
00146 }
00147 if (!ok) {
00148 throw new IllegalArgumentException("Service object is not an instance of " + cls);
00149 }
00150 }
00151 }
00152
00153 res = new ServiceRegistrationImpl(bundle, service,
00154 new PropertiesDictionary(properties, classes, null));
00155 services.put(res, classes);
00156 for (int i = 0; i < classes.length; i++) {
00157 ArrayList s = (ArrayList) classServices.get(classes[i]);
00158 if (s == null) {
00159 s = new ArrayList(1);
00160 classServices.put(classes[i], s);
00161 }
00162 s.add(res);
00163 }
00164 }
00165 bundle.framework.listeners.serviceChanged(new ServiceEvent(ServiceEvent.REGISTERED, res.getReference()));
00166 return res;
00167 }
00168
00169
00177 synchronized ServiceReference get(BundleImpl bundle, String clazz) {
00178
00179 ArrayList v = (ArrayList) classServices.get(clazz);
00180 if (v != null) {
00181 ServiceReference lowestId = ((ServiceRegistration)v.get(0)).getReference();
00182 ServiceReference res = lowestId;
00183 int size = v.size();
00184 if (size > 1) {
00185 int rank_res = ranking(res);
00186 for (int i = 1; i < size; i++) {
00187 ServiceReference s = ((ServiceRegistration)v.get(i)).getReference();
00188 int rank_s = ranking(s);
00189 if (rank_s > rank_res && s.isAssignableTo(bundle, clazz)) {
00190 res = s;
00191 rank_res = rank_s;
00192 }
00193 }
00194 }
00195 if(res == lowestId){
00196 if(res.isAssignableTo(bundle, clazz)){
00197 return res;
00198 }
00199 else{
00200 return null;
00201 }
00202 }
00203 else{
00204 return res;
00205 }
00206 }
00207 else {
00208 return null;
00209 }
00210 }
00211
00212
00226 synchronized ServiceReference[] get(String clazz, String filter, BundleImpl bundle,
00227 boolean doAssignableToTest)
00228 throws InvalidSyntaxException {
00229 Iterator s;
00230 if (clazz == null) {
00231 s = services.keySet().iterator();
00232 if (s == null) {
00233 return null;
00234 }
00235 } else {
00236 ArrayList v = (ArrayList) classServices.get(clazz);
00237 if (v != null) {
00238 s = v.iterator();
00239 } else {
00240 return null;
00241 }
00242 }
00243 ArrayList res = new ArrayList();
00244 while (s.hasNext()) {
00245 ServiceRegistrationImpl sr = (ServiceRegistrationImpl)s.next();
00246 String[] classes = (String[]) services.get(sr);
00247
00248 if (classes == null) {
00249 return null;
00250 }
00251 if (!secure.okGetServicePerms(classes)) {
00252 continue;
00253 }
00254 if (filter == null || LDAPExpr.query(filter, sr.properties)) {
00255 if (doAssignableToTest) {
00256 int i;
00257 int length = classes.length;
00258 for (i = 0; i < length; i++) {
00259 if(!sr.getReference().isAssignableTo(bundle, classes[i])){
00260 break;
00261 }
00262 }
00263 if (i == length) {
00264 res.add(sr.getReference());
00265 }
00266 } else {
00267 res.add(sr.getReference());
00268 }
00269 }
00270 }
00271 if (res.isEmpty()) {
00272 return null;
00273 } else {
00274 ServiceReference[] a = new ServiceReference[res.size()];
00275 res.toArray((Object[])a);
00276 return a;
00277 }
00278 }
00279
00280
00286 synchronized void removeServiceRegistration(ServiceRegistrationImpl sr) {
00287 String[] classes = (String[]) sr.properties.get(Constants.OBJECTCLASS);
00288 services.remove(sr);
00289 for (int i = 0; i < classes.length; i++) {
00290 ArrayList s = (ArrayList) classServices.get(classes[i]);
00291 if (s.size() > 1) {
00292 s.remove(sr);
00293 } else {
00294 classServices.remove(classes[i]);
00295 }
00296 }
00297 }
00298
00299
00306 synchronized Set getRegisteredByBundle(Bundle b) {
00307 HashSet res = new HashSet();
00308 for (Iterator e = services.keySet().iterator(); e.hasNext();) {
00309 ServiceRegistrationImpl sr = (ServiceRegistrationImpl)e.next();
00310 if (sr.bundle == b) {
00311 res.add(sr);
00312 }
00313 }
00314 return res;
00315 }
00316
00317
00324 synchronized Set getUsedByBundle(Bundle b) {
00325 HashSet res = new HashSet();
00326 for (Iterator e = services.keySet().iterator(); e.hasNext();) {
00327 ServiceRegistrationImpl sr = (ServiceRegistrationImpl)e.next();
00328 if (sr.isUsedByBundle(b)) {
00329 res.add(sr);
00330 }
00331 }
00332 return res;
00333 }
00334
00335
00336
00337
00338
00345 private int ranking(ServiceReference s) {
00346 Object v = s.getProperty(Constants.SERVICE_RANKING);
00347 if (v != null && v instanceof Integer) {
00348 return ((Integer)v).intValue();
00349 } else {
00350 return 0;
00351 }
00352 }
00353
00354 }