KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 2003, 2005 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 org.osgi.framework.Bundle;
15 import org.osgi.framework.ServiceReference;
16
17 /**
18  * A reference to a service.
19  *
20  * The framework returns ServiceReference objects from the
21  * {@link BundleContextImpl#getServiceReference BundleContext.getServiceReference} and
22  * {@link BundleContextImpl#getServiceReferences BundleContext.getServiceReferences} methods.
23  * <p>A ServiceReference may be shared between bundles and
24  * can be used to examine the properties of the service and to
25  * get the service object
26  * (See {@link BundleContextImpl#getService BundleContext.getService}).
27  * <p>A registered service <i>may</i> have multiple, distinct ServiceReference
28  * objects which refer to it.
29  * However these ServiceReference objects will have
30  * the same <code>hashCode</code> and the <code>equals</code> method
31  * will return <code>true</code> when compared.
32  */

33
34 public class ServiceReferenceImpl implements ServiceReference, Comparable JavaDoc {
35     /** Registered Service object. */
36     protected ServiceRegistrationImpl registration;
37
38     /**
39      * Construct a reference.
40      *
41      */

42     protected ServiceReferenceImpl(ServiceRegistrationImpl registration) {
43         this.registration = registration;
44     }
45
46     /**
47      * Get the value of a service's property.
48      *
49      * <p>This method will continue to return property values after the
50      * service has been unregistered. This is so that references to
51      * unregistered service can be interrogated.
52      * (For example: ServiceReference objects stored in the log.)
53      *
54      * @param key Name of the property.
55      * @return Value of the property or <code>null</code> if there is
56      * no property by that name.
57      */

58     public Object JavaDoc getProperty(String JavaDoc key) {
59         return (registration.getProperty(key));
60     }
61
62     /**
63      * Get the list of key names for the service's properties.
64      *
65      * <p>This method will continue to return the keys after the
66      * service has been unregistered. This is so that references to
67      * unregistered service can be interrogated.
68      * (For example: ServiceReference objects stored in the log.)
69      *
70      * @return The list of property key names.
71      */

72     public String JavaDoc[] getPropertyKeys() {
73         return (registration.getPropertyKeys());
74     }
75
76     /**
77      * Return the bundle which registered the service.
78      *
79      * <p>This method will always return <code>null</code> when the
80      * service has been unregistered. This can be used to
81      * determine if the service has been unregistered.
82      *
83      * @return The bundle which registered the service.
84      */

85     public org.osgi.framework.Bundle getBundle() {
86         return (registration.getBundle());
87     }
88
89     /**
90      * Return the list of bundles which are using the service.
91      *
92      * <p>This method will always return <code>null</code> when the
93      * service has been unregistered.
94      *
95      * @return The array of bundles using the service or null if
96      * no bundles are using the service.
97      * @see BundleContextImpl#getService
98      */

99     public org.osgi.framework.Bundle[] getUsingBundles() {
100         return (registration.getUsingBundles());
101     }
102
103     /**
104      * Return the classes under which the referenced service was registered.
105      *
106      * @return array of class names.
107      */

108     protected String JavaDoc[] getClasses() {
109         return (registration.clazzes);
110     }
111
112     /**
113      * Return the serviceid of the ServiceRegistration.
114      *
115      * @return service.id of the service
116      */

117     protected long getId() {
118         return (registration.serviceid);
119     }
120
121     /**
122      * Return the serviceranking of the ServiceRegistration.
123      *
124      * @return service.ranking of the service
125      */

126     protected int getRanking() {
127         return (registration.serviceranking);
128     }
129
130     /**
131      * Returns a hash code value for the object.
132      *
133      * @return a hash code value for this object.
134      */

135     public int hashCode() {
136         return (registration.hashCode());
137     }
138
139     /**
140      * Indicates whether some other object is "equal to" this one.
141      *
142      * @param obj the reference object with which to compare.
143      * @return <code>true</code> if this object is the same as the obj
144      * argument; <code>false</code> otherwise.
145      */

146     public boolean equals(Object JavaDoc obj) {
147         if (obj == this) {
148             return (true);
149         }
150
151         if (!(obj instanceof ServiceReferenceImpl)) {
152             return (false);
153         }
154
155         ServiceReferenceImpl other = (ServiceReferenceImpl) obj;
156
157         return (registration == other.registration);
158     }
159
160     /**
161      * Return a string representation of this reference.
162      *
163      * @return String
164      */

165     public String JavaDoc toString() {
166         return (registration.toString());
167     }
168
169     /**
170      *
171      * Compares two service objects and returns an indication as to which is higher ranked
172      * based on service ranking and service_ID.
173      *
174      * The service with the higher service ranking (as specified in its service.ranking property)
175      * is defined to be higher ranked.
176      *
177      * If there is a tie in ranking, the service with the lowest
178      * service ID (as specified in its service.id property); that is,
179      * the service that was registered first is returned.
180      *
181      * This is the same algorithm used by BundleContext.getServiceReference.
182      *
183      * @return int
184      * int = 0 if this object's ranking and
185      * service id are equivalent
186      *
187      * int < 0 if this object's ranking is lower
188      * than the argument's ranking or if the
189      * rankings are equal, this object's service
190      * id is greater than the argument's service
191      * id.
192      *
193      * int > 0 if this object's ranking is higher
194      * than than the argument's ranking or if the
195      * rankings are equal, this object's service
196      * id is less than the argument's service id.
197      *
198      *
199      * @param object
200      * an object to compare the receiver to
201      * @exception ClassCastException
202      * if the argument can not be converted
203      * into something comparable with the
204      * receiver.
205      */

206     public int compareTo(Object JavaDoc object) {
207         ServiceReferenceImpl other = (ServiceReferenceImpl) object;
208         if (this.getRanking() != other.getRanking())
209             return this.getRanking() > other.getRanking() ? -1 : 1;
210         return this.getId() == other.getId() ? 0 : this.getId() > other.getId() ? 1 : -1;
211     }
212
213     public boolean isAssignableTo(Bundle bundle, String JavaDoc className) {
214         AbstractBundle consumer = (AbstractBundle) bundle;
215         // always return false for fragments
216
if (consumer.isFragment())
217             return false;
218         BundleHost producer = (BundleHost) registration.bundle;
219         // 1) if the registrant == consumer always return true
220
if (consumer == producer)
221             return true;
222         // 2) get the package name from the specified className
223
String JavaDoc pkgName = BundleLoader.getPackageName(className);
224         if (pkgName.startsWith("java.")) //$NON-NLS-1$
225
return true;
226         BundleLoader producerBL = producer.getBundleLoader();
227         if (producerBL == null)
228             return false;
229         BundleLoader consumerBL = consumer.getBundleLoader();
230         if (consumerBL == null)
231             return false;
232         // 3) for the specified bundle, find the wiring for the package. If no wiring is found return true
233
PackageSource consumerSource = consumerBL.getPackageSource(pkgName);
234         if (consumerSource == null)
235             return true;
236         // work around the issue when the package is in the EE and we delegate to boot for that package
237
if (producerBL.isBootDelegationPackage(pkgName)) {
238             SystemBundleLoader systemLoader = (SystemBundleLoader) registration.framework.systemBundle.getBundleLoader();
239             if (systemLoader.isEEPackage(pkgName))
240                 return true; // in this case we have a common source from the EE
241
}
242         // 4) For the registrant bundle, find the wiring for the package.
243
PackageSource producerSource = producerBL.getPackageSource(pkgName);
244         if (producerSource == null) {
245             // 5) If no wiring is found for the registrant bundle then find the wiring for the classloader of the service object. If no wiring is found return false.
246
producerSource = getPackageSource(registration.service.getClass(), pkgName);
247             if (producerSource == null)
248                 return false;
249         }
250         // 6) If the two wirings found are equal then return true; otherwise return false.
251
return producerSource.hasCommonSource(consumerSource);
252     }
253
254     private PackageSource getPackageSource(Class JavaDoc serviceClass, String JavaDoc pkgName) {
255         if (serviceClass == null)
256             return null;
257         AbstractBundle serviceBundle = (AbstractBundle) registration.framework.packageAdmin.getBundle(serviceClass);
258         if (serviceBundle == null)
259             return null;
260         BundleLoader producerBL = serviceBundle.getBundleLoader();
261         if (producerBL == null)
262             return null;
263         PackageSource producerSource = producerBL.getPackageSource(pkgName);
264         if (producerSource != null)
265             return producerSource;
266         // try the interfaces
267
Class JavaDoc[] interfaces = serviceClass.getInterfaces();
268         // note that getInterfaces never returns null
269
for (int i = 0; i < interfaces.length; i++) {
270             producerSource = getPackageSource(interfaces[i], pkgName);
271             if (producerSource != null)
272                 return producerSource;
273         }
274         // try super class
275
return getPackageSource(serviceClass.getSuperclass(), pkgName);
276     }
277 }
278
Popular Tags