KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > osgi > framework > internal > core > BundleContextImpl


1 /*******************************************************************************
2  * Copyright (c) 2003, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11
12 package org.eclipse.osgi.framework.internal.core;
13
14 import java.io.File JavaDoc;
15 import java.io.InputStream JavaDoc;
16 import java.security.*;
17 import java.util.*;
18 import org.eclipse.osgi.event.BatchBundleListener;
19 import org.eclipse.osgi.framework.debug.Debug;
20 import org.eclipse.osgi.framework.eventmgr.EventDispatcher;
21 import org.eclipse.osgi.framework.eventmgr.EventListeners;
22 import org.eclipse.osgi.internal.profile.Profile;
23 import org.eclipse.osgi.util.NLS;
24 import org.osgi.framework.*;
25
26 /**
27  * Bundle's execution context.
28  *
29  * This object is given out to bundles and wraps the internal
30  * BundleContext object. It is destroyed when a bundle is stopped.
31  */

32
33 public class BundleContextImpl implements BundleContext, EventDispatcher {
34     public static final String JavaDoc PROP_SCOPE_SERVICE_EVENTS = "osgi.scopeServiceEvents"; //$NON-NLS-1$
35
public static final boolean scopeEvents = Boolean.valueOf(FrameworkProperties.getProperty(PROP_SCOPE_SERVICE_EVENTS, "true")).booleanValue(); //$NON-NLS-1$
36
/** true if the bundle context is still valid */
37     private boolean valid;
38
39     /** Bundle object this context is associated with. */
40     // This slot is accessed directly by the Framework instead of using
41
// the getBundle() method because the Framework needs access to the bundle
42
// even when the context is invalid while the close method is being called.
43
protected BundleHost bundle;
44
45     /** Internal framework object. */
46     protected Framework framework;
47
48     /** Services that bundle has used. Key is ServiceReference,
49      Value is ServiceUse */

50     protected Hashtable servicesInUse;
51
52     /** Listener list for bundle's BundleListeners */
53     protected EventListeners bundleEvent;
54
55     /** Listener list for bundle's SynchronousBundleListeners */
56     protected EventListeners bundleEventSync;
57
58     /** Listener list for bundle's ServiceListeners */
59     protected EventListeners serviceEvent;
60
61     /** Listener list for bundle's FrameworkListeners */
62     protected EventListeners frameworkEvent;
63
64     /** The current instantiation of the activator. */
65     protected BundleActivator activator;
66
67     /** private object for locking */
68     protected Object JavaDoc contextLock = new Object JavaDoc();
69
70     /**
71      * Construct a BundleContext which wrappers the framework for a
72      * bundle
73      *
74      * @param bundle The bundle we are wrapping.
75      */

76     protected BundleContextImpl(BundleHost bundle) {
77         this.bundle = bundle;
78         valid = true;
79         framework = bundle.framework;
80         bundleEvent = null;
81         bundleEventSync = null;
82         serviceEvent = null;
83         frameworkEvent = null;
84         servicesInUse = null;
85         activator = null;
86     }
87
88     /**
89      * Destroy the wrapper. This is called when the bundle is stopped.
90      *
91      */

92     protected void close() {
93         valid = false; /* invalidate context */
94
95         synchronized (framework.serviceEvent) {
96             if (serviceEvent != null) {
97                 framework.serviceEvent.removeListener(this);
98                 serviceEvent = null;
99             }
100         }
101         synchronized (framework.frameworkEvent) {
102             if (frameworkEvent != null) {
103                 framework.frameworkEvent.removeListener(this);
104                 frameworkEvent = null;
105             }
106         }
107         synchronized (framework.bundleEvent) {
108             if (bundleEvent != null) {
109                 framework.bundleEvent.removeListener(this);
110                 bundleEvent = null;
111             }
112         }
113         synchronized (framework.bundleEventSync) {
114             if (bundleEventSync != null) {
115                 framework.bundleEventSync.removeListener(this);
116                 bundleEventSync = null;
117             }
118         }
119
120         /* service's registered by the bundle, if any, are unregistered. */
121         ServiceReference[] publishedReferences = null;
122         synchronized (framework.serviceRegistry) {
123             publishedReferences = framework.serviceRegistry.lookupServiceReferences(this);
124         }
125
126         if (publishedReferences != null) {
127             for (int i = 0; i < publishedReferences.length; i++) {
128                 try {
129                     ((ServiceReferenceImpl) publishedReferences[i]).registration.unregister();
130                 } catch (IllegalStateException JavaDoc e) {
131                     /* already unregistered */
132                 }
133             }
134         }
135
136         /* service's used by the bundle, if any, are released. */
137         if (servicesInUse != null) {
138             int usedSize;
139             ServiceReference[] usedRefs = null;
140
141             synchronized (servicesInUse) {
142                 usedSize = servicesInUse.size();
143
144                 if (usedSize > 0) {
145                     if (Debug.DEBUG && Debug.DEBUG_SERVICES) {
146                         Debug.println("Releasing services"); //$NON-NLS-1$
147
}
148
149                     usedRefs = new ServiceReference[usedSize];
150
151                     Enumeration refsEnum = servicesInUse.keys();
152                     for (int i = 0; i < usedSize; i++) {
153                         usedRefs[i] = (ServiceReference) refsEnum.nextElement();
154                     }
155                 }
156             }
157
158             for (int i = 0; i < usedSize; i++) {
159                 ((ServiceReferenceImpl) usedRefs[i]).registration.releaseService(this);
160             }
161
162             servicesInUse = null;
163         }
164
165         bundle = null;
166     }
167
168     /**
169      * Retrieve the value of the named environment property.
170      *
171      * @param key The name of the requested property.
172      * @return The value of the requested property, or <code>null</code> if
173      * the property is undefined.
174      */

175     public String JavaDoc getProperty(String JavaDoc key) {
176         SecurityManager JavaDoc sm = System.getSecurityManager();
177
178         if (sm != null) {
179             sm.checkPropertyAccess(key);
180         }
181
182         return (framework.getProperty(key));
183     }
184
185     /**
186      * Retrieve the Bundle object for the context bundle.
187      *
188      * @return The context bundle's Bundle object.
189      */

190     public org.osgi.framework.Bundle getBundle() {
191         checkValid();
192
193         return (bundle);
194     }
195
196     /**
197      * Install a bundle from a location.
198      *
199      * The bundle is obtained from the location
200      * parameter as interpreted by the framework
201      * in an implementation dependent way. Typically, location
202      * will most likely be a URL.
203      *
204      * @param location The location identifier of the bundle to install.
205      * @return The Bundle object of the installed bundle.
206      */

207     public org.osgi.framework.Bundle installBundle(String JavaDoc location) throws BundleException {
208         checkValid();
209         //note AdminPermission is checked after bundle is loaded
210
return framework.installBundle(location);
211     }
212
213     /**
214      * Install a bundle from an InputStream.
215      *
216      * <p>This method performs all the steps listed in
217      * {@link #installBundle(java.lang.String)}, except the
218      * bundle's content will be read from the InputStream.
219      * The location identifier specified will be used
220      * as the identity of the bundle.
221      *
222      * @param location The location identifier of the bundle to install.
223      * @param in The InputStream from which the bundle will be read.
224      * @return The Bundle of the installed bundle.
225      */

226     public org.osgi.framework.Bundle installBundle(String JavaDoc location, InputStream JavaDoc in) throws BundleException {
227         checkValid();
228         //note AdminPermission is checked after bundle is loaded
229
return framework.installBundle(location, in);
230     }
231
232     /**
233      * Retrieve the bundle that has the given unique identifier.
234      *
235      * @param id The identifier of the bundle to retrieve.
236      * @return A Bundle object, or <code>null</code>
237      * if the identifier doesn't match any installed bundle.
238      */

239     public org.osgi.framework.Bundle getBundle(long id) {
240         return (framework.getBundle(id));
241     }
242
243     /**
244      * Retrieve the bundle that has the given location.
245      *
246      * @param location The location string of the bundle to retrieve.
247      * @return A Bundle object, or <code>null</code>
248      * if the location doesn't match any installed bundle.
249      */

250     public AbstractBundle getBundleByLocation(String JavaDoc location) {
251         return (framework.getBundleByLocation(location));
252     }
253
254     /**
255      * Retrieve a list of all installed bundles.
256      * The list is valid at the time
257      * of the call to getBundles, but the framework is a very dynamic
258      * environment and bundles can be installed or uninstalled at anytime.
259      *
260      * @return An array of {@link AbstractBundle} objects, one
261      * object per installed bundle.
262      */

263     public org.osgi.framework.Bundle[] getBundles() {
264         return framework.getAllBundles();
265     }
266
267     /**
268      * Add a service listener with a filter.
269      * {@link ServiceListener}s are notified when a service has a lifecycle
270      * state change.
271      * See {@link #getServiceReferences(String, String) getServiceReferences}
272      * for a description of the filter syntax.
273      * The listener is added to the context bundle's list of listeners.
274      * See {@link #getBundle() getBundle()}
275      * for a definition of context bundle.
276      *
277      * <p>The listener is called if the filter criteria is met.
278      * To filter based upon the class of the service, the filter
279      * should reference the "objectClass" property.
280      * If the filter paramater is <code>null</code>, all services
281      * are considered to match the filter.
282      * <p>If the Java runtime environment supports permissions, then additional
283      * filtering is done.
284      * {@link AbstractBundle#hasPermission(Object) Bundle.hasPermission} is called for the
285      * bundle which defines the listener to validate that the listener has the
286      * {@link ServicePermission} permission to <code>"get"</code> the service
287      * using at least one of the named classes the service was registered under.
288      *
289      * @param listener The service listener to add.
290      * @param filter The filter criteria.
291      * @exception InvalidSyntaxException If the filter parameter contains
292      * an invalid filter string which cannot be parsed.
293      * @see ServiceEvent
294      * @see ServiceListener
295      * @exception java.lang.IllegalStateException
296      * If the bundle context has stopped.
297      */

298     public void addServiceListener(ServiceListener listener, String JavaDoc filter) throws InvalidSyntaxException {
299         checkValid();
300
301         if (Debug.DEBUG && Debug.DEBUG_EVENTS) {
302             String JavaDoc listenerName = listener.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(listener)); //$NON-NLS-1$
303
Debug.println("addServiceListener[" + bundle + "](" + listenerName + ", \"" + filter + "\")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
304
}
305
306         ServiceListener filteredListener = new FilteredServiceListener(filter, listener, this);
307
308         synchronized (framework.serviceEvent) {
309             if (serviceEvent == null) {
310                 serviceEvent = new EventListeners();
311                 framework.serviceEvent.addListener(this, this);
312             }
313
314             serviceEvent.addListener(listener, filteredListener);
315         }
316     }
317
318     /**
319      * Add a service listener.
320      *
321      * <p>This method is the same as calling
322      * {@link #addServiceListener(ServiceListener, String)}
323      * with filter set to <code>null</code>.
324      *
325      * @see #addServiceListener(ServiceListener, String)
326      */

327     public void addServiceListener(ServiceListener listener) {
328         try {
329             addServiceListener(listener, null);
330         } catch (InvalidSyntaxException e) {
331             if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
332                 Debug.println("InvalidSyntaxException w/ null filter" + e.getMessage()); //$NON-NLS-1$
333
Debug.printStackTrace(e);
334             }
335         }
336     }
337
338     /**
339      * Remove a service listener.
340      * The listener is removed from the context bundle's list of listeners.
341      * See {@link #getBundle() getBundle()}
342      * for a definition of context bundle.
343      *
344      * <p>If this method is called with a listener which is not registered,
345      * then this method does nothing.
346      *
347      * @param listener The service listener to remove.
348      * @exception java.lang.IllegalStateException
349      * If the bundle context has stopped.
350      */

351     public void removeServiceListener(ServiceListener listener) {
352         checkValid();
353
354         if (Debug.DEBUG && Debug.DEBUG_SERVICES) {
355             String JavaDoc listenerName = listener.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(listener)); //$NON-NLS-1$
356
Debug.println("removeServiceListener[" + bundle + "](" + listenerName + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
357
}
358
359         synchronized (framework.serviceEvent) {
360             if (serviceEvent != null) {
361                 serviceEvent.removeListener(listener);
362             }
363         }
364     }
365
366     /**
367      * Add a bundle listener.
368      * {@link BundleListener}s are notified when a bundle has a lifecycle
369      * state change.
370      * The listener is added to the context bundle's list of listeners.
371      * See {@link #getBundle() getBundle()}
372      * for a definition of context bundle.
373      *
374      * @param listener The bundle listener to add.
375      * @exception java.lang.IllegalStateException
376      * If the bundle context has stopped.
377      * @see BundleEvent
378      * @see BundleListener
379      */

380     public void addBundleListener(BundleListener listener) {
381         checkValid();
382
383         if (Debug.DEBUG && Debug.DEBUG_EVENTS) {
384             String JavaDoc listenerName = listener.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(listener)); //$NON-NLS-1$
385
Debug.println("addBundleListener[" + bundle + "](" + listenerName + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
386
}
387
388         if (listener instanceof SynchronousBundleListener) {
389             framework.checkAdminPermission(getBundle(), AdminPermission.LISTENER);
390             synchronized (framework.bundleEventSync) {
391                 if (bundleEventSync == null) {
392                     bundleEventSync = new EventListeners();
393                     framework.bundleEventSync.addListener(this, this);
394                 }
395
396                 bundleEventSync.addListener(listener, listener);
397             }
398         } else {
399             synchronized (framework.bundleEvent) {
400                 if (bundleEvent == null) {
401                     bundleEvent = new EventListeners();
402                     framework.bundleEvent.addListener(this, this);
403                 }
404
405                 bundleEvent.addListener(listener, listener);
406             }
407         }
408     }
409
410     /**
411      * Remove a bundle listener.
412      * The listener is removed from the context bundle's list of listeners.
413      * See {@link #getBundle() getBundle()}
414      * for a definition of context bundle.
415      *
416      * <p>If this method is called with a listener which is not registered,
417      * then this method does nothing.
418      *
419      * @param listener The bundle listener to remove.
420      * @exception java.lang.IllegalStateException
421      * If the bundle context has stopped.
422      */

423     public void removeBundleListener(BundleListener listener) {
424         checkValid();
425
426         if (Debug.DEBUG && Debug.DEBUG_EVENTS) {
427             String JavaDoc listenerName = listener.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(listener)); //$NON-NLS-1$
428
Debug.println("removeBundleListener[" + bundle + "](" + listenerName + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
429
}
430
431         if (listener instanceof SynchronousBundleListener) {
432             framework.checkAdminPermission(getBundle(), AdminPermission.LISTENER);
433
434             synchronized (framework.bundleEventSync) {
435                 if (bundleEventSync != null) {
436                     bundleEventSync.removeListener(listener);
437                 }
438             }
439         } else {
440             synchronized (framework.bundleEvent) {
441                 if (bundleEvent != null) {
442                     bundleEvent.removeListener(listener);
443                 }
444             }
445         }
446     }
447
448     /**
449      * Add a general framework listener.
450      * {@link FrameworkListener}s are notified of general framework events.
451      * The listener is added to the context bundle's list of listeners.
452      * See {@link #getBundle() getBundle()}
453      * for a definition of context bundle.
454      *
455      * @param listener The framework listener to add.
456      * @exception java.lang.IllegalStateException
457      * If the bundle context has stopped.
458      * @see FrameworkEvent
459      * @see FrameworkListener
460      */

461     public void addFrameworkListener(FrameworkListener listener) {
462         checkValid();
463
464         if (Debug.DEBUG && Debug.DEBUG_EVENTS) {
465             String JavaDoc listenerName = listener.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(listener)); //$NON-NLS-1$
466
Debug.println("addFrameworkListener[" + bundle + "](" + listenerName + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
467
}
468
469         synchronized (framework.frameworkEvent) {
470             if (frameworkEvent == null) {
471                 frameworkEvent = new EventListeners();
472                 framework.frameworkEvent.addListener(this, this);
473             }
474
475             frameworkEvent.addListener(listener, listener);
476         }
477     }
478
479     /**
480      * Remove a framework listener.
481      * The listener is removed from the context bundle's list of listeners.
482      * See {@link #getBundle() getBundle()}
483      * for a definition of context bundle.
484      *
485      * <p>If this method is called with a listener which is not registered,
486      * then this method does nothing.
487      *
488      * @param listener The framework listener to remove.
489      * @exception java.lang.IllegalStateException
490      * If the bundle context has stopped.
491      */

492     public void removeFrameworkListener(FrameworkListener listener) {
493         checkValid();
494
495         if (Debug.DEBUG && Debug.DEBUG_EVENTS) {
496             String JavaDoc listenerName = listener.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(listener)); //$NON-NLS-1$
497
Debug.println("removeFrameworkListener[" + bundle + "](" + listenerName + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
498
}
499
500         synchronized (framework.frameworkEvent) {
501             if (frameworkEvent != null) {
502                 frameworkEvent.removeListener(listener);
503             }
504         }
505     }
506
507     /**
508      * Register a service with multiple names.
509      * This method registers the given service object with the given properties
510      * under the given class names.
511      * A {@link ServiceRegistrationImpl} object is returned.
512      * The {@link ServiceRegistrationImpl} object is for the private use of the bundle
513      * registering the service and should not be shared with other bundles.
514      * The registering bundle is defined to be the context bundle.
515      * See {@link #getBundle()} for a definition of context bundle.
516      * Other bundles can locate the service by using either the
517      * {@link #getServiceReferences getServiceReferences} or
518      * {@link #getServiceReference getServiceReference} method.
519      *
520      * <p>A bundle can register a service object that implements the
521      * {@link ServiceFactory} interface to
522      * have more flexiblity in providing service objects to different
523      * bundles.
524      *
525      * <p>The following steps are followed to register a service:
526      * <ol>
527      * <li>If the service parameter is not a {@link ServiceFactory},
528      * an <code>IllegalArgumentException</code> is thrown if the
529      * service parameter is not an <code>instanceof</code>
530      * all the classes named.
531      * <li>The service is added to the framework's service registry
532      * and may now be used by other bundles.
533      * <li>A {@link ServiceEvent} of type {@link ServiceEvent#REGISTERED}
534      * is synchronously sent.
535      * <li>A {@link ServiceRegistrationImpl} object for this registration
536      * is returned.
537      * </ol>
538      *
539      * @param clazzes The class names under which the service can be located.
540      * The class names in this array will be stored in the service's
541      * properties under the key "objectClass".
542      * @param service The service object or a {@link ServiceFactory} object.
543      * @param properties The properties for this service.
544      * The keys in the properties object must all be Strings.
545      * Changes should not be made to this object after calling this method.
546      * To update the service's properties call the
547      * {@link ServiceRegistrationImpl#setProperties ServiceRegistration.setProperties}
548      * method.
549      * This parameter may be <code>null</code> if the service has no properties.
550      * @return A {@link ServiceRegistrationImpl} object for use by the bundle
551      * registering the service to update the
552      * service's properties or to unregister the service.
553      * @exception java.lang.IllegalArgumentException If one of the following is true:
554      * <ul>
555      * <li>The service parameter is null.
556      * <li>The service parameter is not a {@link ServiceFactory} and is not an
557      * <code>instanceof</code> all the named classes in the clazzes parameter.
558      * </ul>
559      * @exception java.lang.SecurityException If the caller does not have
560      * {@link ServicePermission} permission to "register" the service for
561      * all the named classes
562      * and the Java runtime environment supports permissions.
563      * @exception java.lang.IllegalStateException
564      * If the bundle context has stopped.
565      * @see ServiceRegistrationImpl
566      * @see ServiceFactory
567      */

568     public org.osgi.framework.ServiceRegistration registerService(String JavaDoc[] clazzes, Object JavaDoc service, Dictionary properties) {
569         checkValid();
570
571         if (service == null) {
572             if (Debug.DEBUG && Debug.DEBUG_SERVICES) {
573                 Debug.println("Service object is null"); //$NON-NLS-1$
574
}
575
576             throw new IllegalArgumentException JavaDoc(Msg.SERVICE_ARGUMENT_NULL_EXCEPTION);
577         }
578
579         int size = clazzes.length;
580
581         if (size == 0) {
582             if (Debug.DEBUG && Debug.DEBUG_SERVICES) {
583                 Debug.println("Classes array is empty"); //$NON-NLS-1$
584
}
585
586             throw new IllegalArgumentException JavaDoc(Msg.SERVICE_EMPTY_CLASS_LIST_EXCEPTION);
587         }
588
589         /* copy the array so that changes to the original will not affect us. */
590         String JavaDoc[] copy = new String JavaDoc[clazzes.length];
591         // doing this the hard way so we can intern the strings
592
for (int i = clazzes.length - 1; i >= 0; i--)
593             copy[i] = clazzes[i].intern();
594         clazzes = copy;
595
596         /* check for ServicePermissions. */
597         framework.checkRegisterServicePermission(clazzes);
598
599         if (!(service instanceof ServiceFactory)) {
600             String JavaDoc invalidService = checkServiceClass(clazzes, service);
601             if (invalidService != null) {
602                 if (Debug.DEBUG && Debug.DEBUG_SERVICES) {
603                     Debug.println("Service object is not an instanceof " + invalidService); //$NON-NLS-1$
604
}
605                 throw new IllegalArgumentException JavaDoc(NLS.bind(Msg.SERVICE_NOT_INSTANCEOF_CLASS_EXCEPTION, invalidService));
606             }
607         }
608
609         return (createServiceRegistration(clazzes, service, properties));
610     }
611
612     //Return the name of the class that is not satisfied by the service object
613
static String JavaDoc checkServiceClass(final String JavaDoc[] clazzes, final Object JavaDoc serviceObject) {
614         ClassLoader JavaDoc cl = (ClassLoader JavaDoc) AccessController.doPrivileged(new PrivilegedAction() {
615             public Object JavaDoc run() {
616                 return serviceObject.getClass().getClassLoader();
617             }
618         });
619         for (int i = 0; i < clazzes.length; i++) {
620             try {
621                 Class JavaDoc serviceClazz = cl == null ? Class.forName(clazzes[i]) : cl.loadClass(clazzes[i]);
622                 if (!serviceClazz.isInstance(serviceObject))
623                     return clazzes[i];
624             } catch (ClassNotFoundException JavaDoc e) {
625                 //This check is rarely done
626
if (extensiveCheckServiceClass(clazzes[i], serviceObject.getClass()))
627                     return clazzes[i];
628             }
629         }
630         return null;
631     }
632
633     private static boolean extensiveCheckServiceClass(String JavaDoc clazz, Class JavaDoc serviceClazz) {
634         if (clazz.equals(serviceClazz.getName()))
635             return false;
636         Class JavaDoc[] interfaces = serviceClazz.getInterfaces();
637         for (int i = 0; i < interfaces.length; i++)
638             if (!extensiveCheckServiceClass(clazz, interfaces[i]))
639                 return false;
640         Class JavaDoc superClazz = serviceClazz.getSuperclass();
641         if (superClazz != null)
642             if (!extensiveCheckServiceClass(clazz, superClazz))
643                 return false;
644         return true;
645     }
646
647     /**
648      * Create a new ServiceRegistration object. This method is used so that it may be overridden
649      * by a secure implementation.
650      *
651      * @param clazzes The class names under which the service can be located.
652      * @param service The service object or a {@link ServiceFactory} object.
653      * @param properties The properties for this service.
654      * @return A {@link ServiceRegistrationImpl} object for use by the bundle.
655      */

656     protected ServiceRegistrationImpl createServiceRegistration(String JavaDoc[] clazzes, Object JavaDoc service, Dictionary properties) {
657         return (new ServiceRegistrationImpl(this, clazzes, service, properties));
658     }
659
660     /**
661      * Register a service with a single name.
662      * This method registers the given service object with the given properties
663      * under the given class name.
664      *
665      * <p>This method is otherwise identical to
666      * {@link #registerService(java.lang.String[], java.lang.Object, java.util.Dictionary)}
667      * and is provided as a convenience when the service parameter will only be registered
668      * under a single class name.
669      *
670      * @see #registerService(java.lang.String[], java.lang.Object, java.util.Dictionary)
671      */

672     public org.osgi.framework.ServiceRegistration registerService(String JavaDoc clazz, Object JavaDoc service, Dictionary properties) {
673         String JavaDoc[] clazzes = new String JavaDoc[] {clazz};
674
675         return (registerService(clazzes, service, properties));
676     }
677
678     /**
679      * Returns a list of <tt>ServiceReference</tt> objects. This method returns a list of
680      * <tt>ServiceReference</tt> objects for services which implement and were registered under
681      * the specified class and match the specified filter criteria.
682      *
683      * <p>The list is valid at the time of the call to this method, however as the Framework is
684      * a very dynamic environment, services can be modified or unregistered at anytime.
685      *
686      * <p><tt>filter</tt> is used to select the registered service whose
687      * properties objects contain keys and values which satisfy the filter.
688      * See {@link FilterImpl}for a description of the filter string syntax.
689      *
690      * <p>If <tt>filter</tt> is <tt>null</tt>, all registered services
691      * are considered to match the filter.
692      * <p>If <tt>filter</tt> cannot be parsed, an {@link InvalidSyntaxException}will
693      * be thrown with a human readable message where the filter became unparsable.
694      *
695      * <p>The following steps are required to select a service:
696      * <ol>
697      * <li>If the Java Runtime Environment supports permissions, the caller is checked for the
698      * <tt>ServicePermission</tt> to get the service with the specified class.
699      * If the caller does not have the correct permission, <tt>null</tt> is returned.
700      * <li>If the filter string is not <tt>null</tt>, the filter string is
701      * parsed and the set of registered services which satisfy the filter is
702      * produced.
703      * If the filter string is <tt>null</tt>, then all registered services
704      * are considered to satisfy the filter.
705      * <li>If <code>clazz</code> is not <tt>null</tt>, the set is further reduced to
706      * those services which are an <tt>instanceof</tt> and were registered under the specified class.
707      * The complete list of classes of which a service is an instance and which
708      * were specified when the service was registered is available from the
709      * service's {@link Constants#OBJECTCLASS}property.
710      * <li>An array of <tt>ServiceReference</tt> to the selected services is returned.
711      * </ol>
712      *
713      * @param clazz The class name with which the service was registered, or
714      * <tt>null</tt> for all services.
715      * @param filter The filter criteria.
716      * @return An array of <tt>ServiceReference</tt> objects, or
717      * <tt>null</tt> if no services are registered which satisfy the search.
718      * @exception InvalidSyntaxException If <tt>filter</tt> contains
719      * an invalid filter string which cannot be parsed.
720      */

721     public org.osgi.framework.ServiceReference[] getServiceReferences(String JavaDoc clazz, String JavaDoc filter) throws InvalidSyntaxException {
722         checkValid();
723         if (Debug.DEBUG && Debug.DEBUG_SERVICES) {
724             Debug.println("getServiceReferences(" + clazz + ", \"" + filter + "\")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
725
}
726         return (framework.getServiceReferences(clazz, filter, this, false));
727     }
728
729     public ServiceReference[] getAllServiceReferences(String JavaDoc clazz, String JavaDoc filter) throws InvalidSyntaxException {
730         checkValid();
731         if (Debug.DEBUG && Debug.DEBUG_SERVICES) {
732             Debug.println("getAllServiceReferences(" + clazz + ", \"" + filter + "\")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
733
}
734         return (framework.getServiceReferences(clazz, filter, this, true));
735     }
736
737     /**
738      * Get a service reference.
739      * Retrieves a {@link ServiceReferenceImpl} for a service
740      * which implements the named class.
741      *
742      * <p>This reference is valid at the time
743      * of the call to this method, but since the framework is a very dynamic
744      * environment, services can be modified or unregistered at anytime.
745      *
746      * <p>This method is provided as a convenience for when the caller is
747      * interested in any service which implements a named class. This method is
748      * the same as calling {@link #getServiceReferences getServiceReferences}
749      * with a <code>null</code> filter string but only a single {@link ServiceReferenceImpl}
750      * is returned.
751      *
752      * @param clazz The class name which the service must implement.
753      * @return A {@link ServiceReferenceImpl} object, or <code>null</code>
754      * if no services are registered which implement the named class.
755      * @see #getServiceReferences
756      */

757     public org.osgi.framework.ServiceReference getServiceReference(String JavaDoc clazz) {
758         checkValid();
759
760         if (Debug.DEBUG && Debug.DEBUG_SERVICES) {
761             Debug.println("getServiceReference(" + clazz + ")"); //$NON-NLS-1$ //$NON-NLS-2$
762
}
763
764         try {
765             ServiceReference[] references = framework.getServiceReferences(clazz, null, this, false);
766
767             if (references != null) {
768                 int index = 0;
769
770                 int length = references.length;
771
772                 if (length > 1) /* if more than one service, select highest ranking */{
773                     int rankings[] = new int[length];
774                     int count = 0;
775                     int maxRanking = Integer.MIN_VALUE;
776
777                     for (int i = 0; i < length; i++) {
778                         int ranking = ((ServiceReferenceImpl) references[i]).getRanking();
779
780                         rankings[i] = ranking;
781
782                         if (ranking > maxRanking) {
783                             index = i;
784                             maxRanking = ranking;
785                             count = 1;
786                         } else {
787                             if (ranking == maxRanking) {
788                                 count++;
789                             }
790                         }
791                     }
792
793                     if (count > 1) /* if still more than one service, select lowest id */{
794                         long minId = Long.MAX_VALUE;
795
796                         for (int i = 0; i < length; i++) {
797                             if (rankings[i] == maxRanking) {
798                                 long id = ((ServiceReferenceImpl) references[i]).getId();
799
800                                 if (id < minId) {
801                                     index = i;
802                                     minId = id;
803                                 }
804                             }
805                         }
806                     }
807                 }
808
809                 return (references[index]);
810             }
811         } catch (InvalidSyntaxException e) {
812             if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
813                 Debug.println("InvalidSyntaxException w/ null filter" + e.getMessage()); //$NON-NLS-1$
814
Debug.printStackTrace(e);
815             }
816         }
817
818         return (null);
819     }
820
821     /**
822      * Get a service's service object.
823      * Retrieves the service object for a service.
824      * A bundle's use of a service is tracked by a
825      * use count. Each time a service's service object is returned by
826      * {@link #getService}, the context bundle's use count for the service
827      * is incremented by one. Each time the service is release by
828      * {@link #ungetService}, the context bundle's use count
829      * for the service is decremented by one.
830      * When a bundle's use count for a service
831      * drops to zero, the bundle should no longer use the service.
832      * See {@link #getBundle()} for a definition of context bundle.
833      *
834      * <p>This method will always return <code>null</code> when the
835      * service associated with this reference has been unregistered.
836      *
837      * <p>The following steps are followed to get the service object:
838      * <ol>
839      * <li>If the service has been unregistered,
840      * <code>null</code> is returned.
841      * <li>The context bundle's use count for this service is incremented by one.
842      * <li>If the context bundle's use count for the service is now one and
843      * the service was registered with a {@link ServiceFactory},
844      * the {@link ServiceFactory#getService ServiceFactory.getService} method
845      * is called to create a service object for the context bundle.
846      * This service object is cached by the framework.
847      * While the context bundle's use count for the service is greater than zero,
848      * subsequent calls to get the services's service object for the context bundle
849      * will return the cached service object.
850      * <br>If the service object returned by the {@link ServiceFactory}
851      * is not an <code>instanceof</code>
852      * all the classes named when the service was registered or
853      * the {@link ServiceFactory} throws an exception,
854      * <code>null</code> is returned and a
855      * {@link FrameworkEvent} of type {@link FrameworkEvent#ERROR} is broadcast.
856      * <li>The service object for the service is returned.
857      * </ol>
858      *
859      * @param reference A reference to the service whose service object is desired.
860      * @return A service object for the service associated with this
861      * reference, or <code>null</code> if the service is not registered.
862      * @exception java.lang.SecurityException If the caller does not have
863      * {@link ServicePermission} permission to "get" the service
864      * using at least one of the named classes the service was registered under
865      * and the Java runtime environment supports permissions.
866      * @exception java.lang.IllegalStateException
867      * If the bundle context has stopped.
868      * @see #ungetService
869      * @see ServiceFactory
870      */

871     public Object JavaDoc getService(org.osgi.framework.ServiceReference reference) {
872         checkValid();
873
874         synchronized (contextLock) {
875             if (servicesInUse == null)
876                 // Cannot predict how many services a bundle will use, start with a small table.
877
servicesInUse = new Hashtable(10);
878         }
879
880         ServiceRegistrationImpl registration = ((ServiceReferenceImpl) reference).registration;
881
882         framework.checkGetServicePermission(registration.clazzes);
883
884         return registration.getService(BundleContextImpl.this);
885     }
886
887     /**
888      * Unget a service's service object.
889      * Releases the service object for a service.
890      * If the context bundle's use count for the service is zero, this method
891      * returns <code>false</code>. Otherwise, the context bundle's use count for the
892      * service is decremented by one.
893      * See {@link #getBundle()} for a definition of context bundle.
894      *
895      * <p>The service's service object
896      * should no longer be used and all references to it should be destroyed
897      * when a bundle's use count for the service
898      * drops to zero.
899      *
900      * <p>The following steps are followed to unget the service object:
901      * <ol>
902      * <li>If the context bundle's use count for the service is zero or
903      * the service has been unregistered,
904      * <code>false</code> is returned.
905      * <li>The context bundle's use count for this service is decremented by one.
906      * <li>If the context bundle's use count for the service is now zero and
907      * the service was registered with a {@link ServiceFactory},
908      * the {@link ServiceFactory#ungetService ServiceFactory.ungetService} method
909      * is called to release the service object for the context bundle.
910      * <li><code>true</code> is returned.
911      * </ol>
912      *
913      * @param reference A reference to the service to be released.
914      * @return <code>false</code> if the context bundle's use count for the service
915      * is zero or if the service has been unregistered,
916      * otherwise <code>true</code>.
917      * @exception java.lang.IllegalStateException
918      * If the bundle context has stopped.
919      * @see #getService
920      * @see ServiceFactory
921      */

922     public boolean ungetService(org.osgi.framework.ServiceReference reference) {
923         checkValid();
924
925         ServiceRegistrationImpl registration = ((ServiceReferenceImpl) reference).registration;
926
927         return registration.ungetService(BundleContextImpl.this);
928     }
929
930     /**
931      * Creates a <code>File</code> object for a file in the
932      * persistent storage area provided for the bundle by the framework.
933      * If the adaptor does not have file system support, this method will
934      * return <code>null</code>.
935      *
936      * <p>A <code>File</code> object for the base directory of the
937      * persistent storage area provided for the context bundle by the framework
938      * can be obtained by calling this method with the empty string ("")
939      * as the parameter.
940      * See {@link #getBundle()} for a definition of context bundle.
941      *
942      * <p>If the Java runtime environment supports permissions,
943      * the framework the will ensure that the bundle has
944      * <code>java.io.FilePermission</code> with actions
945      * "read","write","execute","delete" for all files (recursively) in the
946      * persistent storage area provided for the context bundle by the framework.
947      *
948      * @param filename A relative name to the file to be accessed.
949      * @return A <code>File</code> object that represents the requested file or
950      * <code>null</code> if the adaptor does not have file system support.
951      * @exception java.lang.IllegalStateException
952      * If the bundle context has stopped.
953      */

954     public File JavaDoc getDataFile(String JavaDoc filename) {
955         checkValid();
956
957         return (framework.getDataFile(bundle, filename));
958     }
959
960     /**
961      * Call bundle's BundleActivator.start()
962      * This method is called by Bundle.startWorker to start the bundle.
963      *
964      * @exception org.osgi.framework.BundleException if
965      * the bundle has a class that implements the BundleActivator interface,
966      * but Framework couldn't instantiate it, or the BundleActivator.start()
967      * method failed
968      */

969     protected void start() throws BundleException {
970         activator = bundle.loadBundleActivator();
971
972         if (activator != null) {
973             try {
974                 startActivator(activator);
975             } catch (BundleException be) {
976                 activator = null;
977                 throw be;
978             }
979         }
980
981         /* activator completed successfully. We must use this
982          same activator object when we stop this bundle. */

983     }
984
985     /**
986      * Calls the start method of a BundleActivator.
987      * @param bundleActivator that activator to start
988      */

989     protected void startActivator(final BundleActivator bundleActivator) throws BundleException {
990         if (Profile.PROFILE && Profile.STARTUP)
991             Profile.logEnter("BundleContextImpl.startActivator()", null); //$NON-NLS-1$
992
try {
993             AccessController.doPrivileged(new PrivilegedExceptionAction() {
994                 public Object JavaDoc run() throws Exception JavaDoc {
995                     if (bundleActivator != null) {
996                         if (Profile.PROFILE && Profile.STARTUP)
997                             Profile.logTime("BundleContextImpl.startActivator()", "calling " + bundle.getLocation() + " bundle activator"); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
998
/* Start the bundle synchronously */
999                         bundleActivator.start(BundleContextImpl.this);
1000                        if (Profile.PROFILE && Profile.STARTUP)
1001                            Profile.logTime("BundleContextImpl.startActivator()", "returned from " + bundle.getLocation() + " bundle activator"); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
1002
}
1003                    return null;
1004                }
1005            });
1006        } catch (Throwable JavaDoc t) {
1007            if (t instanceof PrivilegedActionException) {
1008                t = ((PrivilegedActionException) t).getException();
1009            }
1010
1011            if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
1012                Debug.printStackTrace(t);
1013            }
1014
1015            String JavaDoc clazz = null;
1016            clazz = bundleActivator.getClass().getName();
1017
1018            throw new BundleException(NLS.bind(Msg.BUNDLE_ACTIVATOR_EXCEPTION, new Object JavaDoc[] {clazz, "start", bundle.getSymbolicName() == null ? "" + bundle.getBundleId() : bundle.getSymbolicName()}), t); //$NON-NLS-1$ //$NON-NLS-2$
1019
} finally {
1020            if (Profile.PROFILE && Profile.STARTUP)
1021                Profile.logExit("BundleContextImpl.startActivator()"); //$NON-NLS-1$
1022
}
1023
1024    }
1025
1026    /**
1027     * Call bundle's BundleActivator.stop()
1028     * This method is called by Bundle.stopWorker to stop the bundle.
1029     *
1030     * @exception org.osgi.framework.BundleException if
1031     * the bundle has a class that implements the BundleActivator interface,
1032     * and the BundleActivator.stop() method failed
1033     */

1034    protected void stop() throws BundleException {
1035        try {
1036            AccessController.doPrivileged(new PrivilegedExceptionAction() {
1037                public Object JavaDoc run() throws Exception JavaDoc {
1038                    if (activator != null) {
1039                        /* Stop the bundle synchronously */
1040                        activator.stop(BundleContextImpl.this);
1041                    }
1042                    return null;
1043                }
1044            });
1045        } catch (Throwable JavaDoc t) {
1046            if (t instanceof PrivilegedActionException) {
1047                t = ((PrivilegedActionException) t).getException();
1048            }
1049
1050            if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
1051                Debug.printStackTrace(t);
1052            }
1053
1054            String JavaDoc clazz = (activator == null) ? "" : activator.getClass().getName(); //$NON-NLS-1$
1055

1056            throw new BundleException(NLS.bind(Msg.BUNDLE_ACTIVATOR_EXCEPTION, new Object JavaDoc[] {clazz, "stop", bundle.getSymbolicName() == null ? "" + bundle.getBundleId() : bundle.getSymbolicName()}), t); //$NON-NLS-1$ //$NON-NLS-2$
1057
} finally {
1058            activator = null;
1059        }
1060    }
1061
1062    /**
1063     * Provides a list of {@link ServiceReference}s for the services
1064     * registered by this bundle
1065     * or <code>null</code> if the bundle has no registered
1066     * services.
1067     *
1068     * <p>The list is valid at the time
1069     * of the call to this method, but the framework is a very dynamic
1070     * environment and services can be modified or unregistered at anytime.
1071     *
1072     * @return An array of {@link ServiceReference} or <code>null</code>.
1073     * @exception java.lang.IllegalStateException If the
1074     * bundle has been uninstalled.
1075     * @see ServiceRegistrationImpl
1076     * @see ServiceReferenceImpl
1077     */

1078    protected ServiceReference[] getRegisteredServices() {
1079        ServiceReference[] services = null;
1080
1081        synchronized (framework.serviceRegistry) {
1082            services = framework.serviceRegistry.lookupServiceReferences(this);
1083            if (services == null) {
1084                return null;
1085            }
1086            int removed = 0;
1087            for (int i = services.length - 1; i >= 0; i--) {
1088                ServiceReferenceImpl ref = (ServiceReferenceImpl) services[i];
1089                String JavaDoc[] classes = ref.getClasses();
1090                try { /* test for permission to the classes */
1091                    framework.checkGetServicePermission(classes);
1092                } catch (SecurityException JavaDoc se) {
1093                    services[i] = null;
1094                    removed++;
1095                }
1096            }
1097            if (removed > 0) {
1098                ServiceReference[] temp = services;
1099                services = new ServiceReference[temp.length - removed];
1100                for (int i = temp.length - 1; i >= 0; i--) {
1101                    if (temp[i] == null)
1102                        removed--;
1103                    else
1104                        services[i - removed] = temp[i];
1105                }
1106            }
1107        }
1108        return (services);
1109
1110    }
1111
1112    /**
1113     * Provides a list of {@link ServiceReferenceImpl}s for the
1114     * services this bundle is using,
1115     * or <code>null</code> if the bundle is not using any services.
1116     * A bundle is considered to be using a service if the bundle's
1117     * use count for the service is greater than zero.
1118     *
1119     * <p>The list is valid at the time
1120     * of the call to this method, but the framework is a very dynamic
1121     * environment and services can be modified or unregistered at anytime.
1122     *
1123     * @return An array of {@link ServiceReferenceImpl} or <code>null</code>.
1124     * @exception java.lang.IllegalStateException If the
1125     * bundle has been uninstalled.
1126     * @see ServiceReferenceImpl
1127     */

1128    protected ServiceReferenceImpl[] getServicesInUse() {
1129        if (servicesInUse == null) {
1130            return (null);
1131        }
1132
1133        synchronized (servicesInUse) {
1134            int size = servicesInUse.size();
1135
1136            if (size == 0) {
1137                return (null);
1138            }
1139
1140            ServiceReferenceImpl[] references = new ServiceReferenceImpl[size];
1141            int refcount = 0;
1142
1143            Enumeration refsEnum = servicesInUse.keys();
1144
1145            for (int i = 0; i < size; i++) {
1146                ServiceReferenceImpl reference = (ServiceReferenceImpl) refsEnum.nextElement();
1147
1148                try {
1149                    framework.checkGetServicePermission(reference.registration.clazzes);
1150                } catch (SecurityException JavaDoc se) {
1151                    continue;
1152                }
1153
1154                references[refcount] = reference;
1155                refcount++;
1156            }
1157
1158            if (refcount < size) {
1159                if (refcount == 0) {
1160                    return (null);
1161                }
1162
1163                ServiceReferenceImpl[] refs = references;
1164                references = new ServiceReferenceImpl[refcount];
1165
1166                System.arraycopy(refs, 0, references, 0, refcount);
1167            }
1168
1169            return (references);
1170        }
1171    }
1172
1173    /**
1174     * Bottom level event dispatcher for the BundleContext.
1175     *
1176     * @param originalListener listener object registered under.
1177     * @param l listener to call (may be filtered).
1178     * @param action Event class type
1179     * @param object Event object
1180     */

1181    public void dispatchEvent(Object JavaDoc originalListener, Object JavaDoc l, int action, Object JavaDoc object) {
1182        // save the bundle ref to a local variable
1183
// to avoid interference from another thread closing this context
1184
AbstractBundle tmpBundle = bundle;
1185        try {
1186            if (isValid()) /* if context still valid */{
1187                switch (action) {
1188                    case Framework.BUNDLEEVENT :
1189                    case Framework.BUNDLEEVENTSYNC : {
1190                        BundleListener listener = (BundleListener) l;
1191
1192                        if (Debug.DEBUG && Debug.DEBUG_EVENTS) {
1193                            String JavaDoc listenerName = listener.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(listener)); //$NON-NLS-1$
1194
Debug.println("dispatchBundleEvent[" + tmpBundle + "](" + listenerName + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
1195
}
1196
1197                        BundleEvent event = (BundleEvent) object;
1198                        switch (event.getType()) {
1199                            case Framework.BATCHEVENT_BEGIN : {
1200                                if (listener instanceof BatchBundleListener)
1201                                    ((BatchBundleListener) listener).batchBegin();
1202                                break;
1203                            }
1204                            case Framework.BATCHEVENT_END : {
1205                                if (listener instanceof BatchBundleListener)
1206                                    ((BatchBundleListener) listener).batchEnd();
1207                                break;
1208                            }
1209                            default : {
1210                                listener.bundleChanged((BundleEvent) object);
1211                            }
1212                        }
1213                        break;
1214                    }
1215
1216                    case Framework.SERVICEEVENT : {
1217                        ServiceEvent event = (ServiceEvent) object;
1218
1219                        ServiceListener listener = (ServiceListener) l;
1220                        if (Debug.DEBUG && Debug.DEBUG_EVENTS) {
1221                            String JavaDoc listenerName = listener.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(listener)); //$NON-NLS-1$
1222
Debug.println("dispatchServiceEvent[" + tmpBundle + "](" + listenerName + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
1223
}
1224                        listener.serviceChanged(event);
1225
1226                        break;
1227                    }
1228
1229                    case Framework.FRAMEWORKEVENT : {
1230                        FrameworkListener listener = (FrameworkListener) l;
1231
1232                        if (Debug.DEBUG && Debug.DEBUG_EVENTS) {
1233                            String JavaDoc listenerName = listener.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(listener)); //$NON-NLS-1$
1234
Debug.println("dispatchFrameworkEvent[" + tmpBundle + "](" + listenerName + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
1235
}
1236
1237                        listener.frameworkEvent((FrameworkEvent) object);
1238                        break;
1239                    }
1240                }
1241            }
1242        } catch (Throwable JavaDoc t) {
1243            if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
1244                Debug.println("Exception in bottom level event dispatcher: " + t.getMessage()); //$NON-NLS-1$
1245
Debug.printStackTrace(t);
1246            }
1247            // allow the adaptor to handle this unexpected error
1248
framework.adaptor.handleRuntimeError(t);
1249            publisherror: {
1250                if (action == Framework.FRAMEWORKEVENT) {
1251                    FrameworkEvent event = (FrameworkEvent) object;
1252                    if (event.getType() == FrameworkEvent.ERROR) {
1253                        break publisherror; // avoid infinite loop
1254
}
1255                }
1256
1257                framework.publishFrameworkEvent(FrameworkEvent.ERROR, tmpBundle, t);
1258            }
1259        }
1260    }
1261
1262    /**
1263     * Check for permission to listen to a service.
1264     */

1265    protected boolean hasListenServicePermission(ServiceEvent event) {
1266        ProtectionDomain domain = bundle.getProtectionDomain();
1267
1268        if (domain != null) {
1269            ServiceReferenceImpl reference = (ServiceReferenceImpl) event.getServiceReference();
1270
1271            String JavaDoc[] names = reference.getClasses();
1272
1273            int len = names.length;
1274
1275            for (int i = 0; i < len; i++) {
1276                if (domain.implies(new ServicePermission(names[i], ServicePermission.GET))) {
1277                    return true;
1278                }
1279            }
1280
1281            return false;
1282        }
1283
1284        return (true);
1285    }
1286
1287    /**
1288     * Construct a Filter object. This filter object may be used
1289     * to match a ServiceReference or a Dictionary.
1290     * See Filter
1291     * for a description of the filter string syntax.
1292     *
1293     * @param filter The filter string.
1294     * @return A Filter object encapsulating the filter string.
1295     * @exception InvalidSyntaxException If the filter parameter contains
1296     * an invalid filter string which cannot be parsed.
1297     */

1298    public org.osgi.framework.Filter createFilter(String JavaDoc filter) throws InvalidSyntaxException {
1299        checkValid();
1300
1301        return (new FilterImpl(filter));
1302    }
1303
1304    /**
1305     * This method checks that the context is still valid. If the context is
1306     * no longer valid, an IllegalStateException is thrown.
1307     *
1308     * @exception java.lang.IllegalStateException
1309     * If the context bundle has stopped.
1310     */

1311    protected void checkValid() {
1312        if (!isValid()) {
1313            throw new IllegalStateException JavaDoc(Msg.BUNDLE_CONTEXT_INVALID_EXCEPTION);
1314        }
1315    }
1316
1317    /**
1318     * This method checks that the context is still valid.
1319     *
1320     * @return true if the context is still valid; false otherwise
1321     */

1322    protected boolean isValid() {
1323        return valid;
1324    }
1325
1326    boolean isAssignableTo(ServiceReferenceImpl reference) {
1327        if (!scopeEvents)
1328            return true;
1329        String JavaDoc[] clazzes = reference.getClasses();
1330        for (int i = 0; i < clazzes.length; i++)
1331            if (!reference.isAssignableTo(bundle, clazzes[i]))
1332                return false;
1333        return true;
1334    }
1335}
1336
Popular Tags