KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > opensugar > cube > serviceRegistry > ServiceRegistryEntry


1 /*
2  * JEFFREE: Java(TM) Embedded Framework FREE
3  * Copyright (C) 1999-2003 - Opensugar
4  *
5  * The contents of this file are subject to the Jeffree Public License,
6  * as defined by the file JEFFREE_LICENSE.TXT
7  *
8  * You may not use this file except in compliance with the License.
9  * You may obtain a copy of the License on the Objectweb web site
10  * (www.objectweb.org).
11  *
12  * Software distributed under the License is distributed on an "AS IS" basis,
13  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
14  * the specific terms governing rights and limitations under the License.
15  *
16  * The Original Code is JEFFREE, including the java package com.opensugar.cube,
17  * released January 1, 2003.
18  *
19  * The Initial Developer of the Original Code is Opensugar.
20  * The Original Code is Copyright Opensugar.
21  * All Rights Reserved.
22  *
23  * Initial developer(s): Pierre Scokaert (Opensugar)
24  * Contributor(s):
25  */

26
27 package com.opensugar.cube.serviceRegistry;
28
29 import com.opensugar.cube.BundleImpl;
30 import com.opensugar.cube.ServiceReferenceImpl;
31
32 import org.osgi.framework.Bundle;
33 import org.osgi.framework.ServiceRegistration;
34 import org.osgi.framework.ServiceReference;
35 import org.osgi.framework.ServiceFactory;
36 import org.osgi.framework.Constants;
37
38 import java.util.Vector JavaDoc;
39 import java.util.Hashtable JavaDoc;
40 import java.util.Hashtable JavaDoc;
41
42 // An entry of the service registry.
43
// Handles users of the service.
44
public class ServiceRegistryEntry {
45
46    // the service registration for this service
47
private ServiceRegistration registration;
48    // the service object for this service (may be the service itself or a factory for the service)
49
private Object JavaDoc service;
50    // the registered users of this service
51
private Vector JavaDoc users;
52    // the service reference for this service
53
// Note: we need to keep a local copy service reference so that we can still access it after
54
// the service is unregistered (after service is unregistered, calling getReference on service
55
// registration throws an IllegalStateException)
56
private ServiceReferenceImpl reference;
57
58    // a cache of service instances // user bundle --> cached instance of service
59
private Hashtable JavaDoc cachedServiceInstances;
60
61    public ServiceRegistryEntry( ServiceRegistration registration, ServiceReferenceImpl reference, Object JavaDoc service ) {
62       this.registration = registration;
63       this.reference = reference;
64       this.service = service;
65
66       users = new Vector JavaDoc();
67       cachedServiceInstances = new Hashtable JavaDoc();
68    }
69
70    // Return the service registration for this service.
71
protected ServiceRegistration getRegistration() {
72       return registration;
73    }
74
75    // Return the service reference for this service.
76
protected ServiceReferenceImpl getReference() {
77       return reference;
78    }
79
80    // Return a service object for the specified user bundle.
81
// This method throws an IllegalStateException if the service has been unregistered.
82
// This method throws a ServiceRegistryException if the service factory throws an
83
// exception while creating a new service intance, or if the service created by the service
84
// factory is not an instance of all the classes names during this service's registration.
85
protected synchronized Object JavaDoc getService( Bundle userBundle ) throws ServiceRegistryException {
86       // call registration's getReference method so that an illegal state exception is thrown if the service has been unregistered
87
registration.getReference();
88
89       Object JavaDoc serviceInstance;
90       if ( service instanceof ServiceFactory ) {
91          // service is a service factory
92
if ( cachedServiceInstances.get( userBundle ) != null ) {
93             // a service instance is already cached for this bundle
94
return cachedServiceInstances.get( userBundle );
95          }
96          else {
97             // no service instance is cached for this bundle.
98
// create one
99
try {
100                serviceInstance = ( (ServiceFactory)service ).getService( userBundle, registration );
101             }
102             catch( Exception JavaDoc e ) {
103                throw new ServiceRegistryException( "Exception occured while calling service factory", e );
104             }
105
106             if ( serviceInstance == null ) {
107                throw new ServiceRegistryException( "Service factory returned a null object" );
108             }
109
110             // check that service instance is an instance of all the classes named during this service's registration
111
// if that is not the case, throw an exception
112
try {
113                String JavaDoc[] objectClass = (String JavaDoc[])reference.getProperty( "objectClass" );
114                BundleImpl bundle;
115                for ( int i = 0; i < objectClass.length; i++ ) {
116                   bundle = (BundleImpl)reference.getBundle();
117                   if ( !bundle.getClassLoader().loadClass( objectClass[ i ] ).isInstance( serviceInstance ) ) {
118                      throw new ServiceRegistryException( "Invalid service type created by service factory" );
119                   }
120                }
121             }
122             catch( ClassNotFoundException JavaDoc e ) {
123                throw new ServiceRegistryException( "Class not found while checking service created by service factory", e );
124             }
125
126             // cache new service instance
127
cachedServiceInstances.put( userBundle, serviceInstance );
128          }
129       }
130       else {
131          // service is a service instance (not a factory)
132
serviceInstance = service;
133       }
134       // record new user bundle (thus incrementing bundle use count)
135
addUser( userBundle );
136       // return service instance
137
return serviceInstance;
138    }
139
140    // Release the service used by the specified bundle.
141
protected synchronized boolean ungetService( Bundle userBundle ) {
142       return removeUser( userBundle );
143    }
144
145    // Determine if the specified class is one of the classes this service is registered under.
146
protected boolean isImplemented( String JavaDoc className ) {
147       if ( className == null ) {
148          return true;
149       }
150
151       String JavaDoc[] classNames = (String JavaDoc[])reference.getProperty( Constants.OBJECTCLASS );
152       for ( int i = 0; i < classNames.length; i++ ) {
153          if ( classNames[ i ].equals( className ) ) {
154             return true;
155          }
156       }
157       return false;
158    }
159
160    // Determine if this service is provided by the specified bundle.
161
protected boolean isProvidedBy( Bundle bundle ) {
162       if ( reference.getBundle().getBundleId() == bundle.getBundleId() ) {
163          return true;
164       }
165       return false;
166    }
167
168    // Determine if this service is currently used by the specified bundle.
169
protected synchronized boolean isUsedBy( Bundle bundle ) {
170       if ( users.indexOf( bundle ) != -1 ) {
171          return true;
172       }
173       return false;
174    }
175
176    // Determine if this service is still registered.
177
protected boolean isServiceStillRegistered() {
178       try {
179          // If this service is no longer registered, calling getReference() on the
180
// service registration throws an IllegalStateException.
181
registration.getReference();
182          return true;
183       }
184       catch( IllegalStateException JavaDoc e ) {
185          return false;
186       }
187    }
188
189    // This method is called by ServiceRegistrationImpl when the service is unregistered.
190
// When that happens, we need to do the following:
191
// For each bundle whose use count for this service is greater than zero,
192
// 1. set the bundle's use count for this service to zero
193
// 2. if the service was registered with a service factory, call the factory's
194
// unget method to release the service object for the bundle
195
public synchronized void serviceUnregistered() {
196       while ( users.size() > 0 ) {
197          removeUser( (Bundle)users.elementAt( 0 ) );
198       }
199    }
200
201 // *****************************************************************************
202

203    // Register a bundle as a user of this service.
204
private synchronized void addUser( Bundle user ) {
205       if ( users.indexOf( user ) == -1 ) {
206          // If the bundle is not yet a user of the service, let the service reference
207
// known the user bundle is now using it.
208
// The service reference needs to know because it needs to return the
209
// list of user bundles in its getUsingBundles() method
210
reference.addUsingBundle( user );
211       }
212
213       // Allow a user bundle to be added multiple times to the vector of users.
214
// Thus a bundle's use count for the service is obtained by counting the number
215
// of times the bundle appears in the list of users.
216
users.addElement( user );
217    }
218
219    // Unregister a bundle as a user of this service.
220
// Return true if the specified bundle was a registered user of this service, false
221
// otherwise.
222
private synchronized boolean removeUser( Bundle user ) {
223       // Remove a single occurence of user from the vector of users.
224
// Thus if a bundle has got the service multiple times, it needs to unget it
225
// multiple times before it disappears from the list of users.
226
if ( users.indexOf( user ) == -1 ) {
227          return false;
228       }
229
230       users.removeElement( user );
231       if ( users.indexOf( user ) == -1 ) {
232          // This bundle is no longer a user of this service.
233
// Release service object
234
if ( service instanceof ServiceFactory ) {
235             Object JavaDoc serviceInstance = cachedServiceInstances.get( user );
236             ( (ServiceFactory)service ).ungetService( user, registration, serviceInstance );
237          }
238          // Remove cached service object if one was created.
239
cachedServiceInstances.remove( user );
240
241          // If the bundle is no longer using this service, let the service reference
242
// known.
243
// The service reference needs to know because it needs to return the
244
// list of user bundles in its getUsingBundles() method
245
reference.removeUsingBundle( user );
246       }
247
248       return true;
249    }
250
251 }
Popular Tags