As mentioned in the introduction, the BeanContext API also provides a
standard mechanism through which JavaBeans can discover and utilize the
services offered by their enclosing BeanContext.
Service capability is defined by the
BeanContextServices
interface. Because this interface is a BeanContext extension, it inherits all
BeanContext membership capabilities.
The discovery and
requesting of services can be summarized in the following steps:
java.beans.beancontext.BeanContextServicesListener interface joins the bean context (the context itself
is a BeanContextServices implementation),
and registers its intent to be notified of new services via the context's
addBeanContextServicesListener(BeanContextServicesListener bcsl) method.
java.beans.beancontext.BeanContextServiceProvider registers
a new service with the context via the
context's addService() method. The context notifies
all currently registered listeners that this new service has been added.
BeanContextServices: Service Related Methods
java.beans.beancontext.BeanContextServicesSupport object as the bean context, it is possible to:
BeanContext:
boolean addService(java.lang.Class serviceClass, BeanContextServiceProvider serviceProvider)
BeanContext:
boolean addService(Class serviceClass, BeanContextServiceProvider bcsp, boolean fireEvent)
void revokeService(java.lang.Class serviceClass, BeanContextServiceProvider serviceProvider, boolean revokeCurrentServicesNow) BeanContextChild's (or any arbitrary object associated with a BeanContextChild) reference to the specified service:
void releaseService(BeanContextChild child, java.lang.Object requestor, java.lang.Object service) BeanContextServicesListener
void addBeanContextServicesListener(BeanContextServicesListener bcsl) BeanContextServicesListener:
void removeBeanContextServicesListener(BeanContextServicesListener bcsl)
Iterator getCurrentServiceClasses()
boolean hasService(java.lang.Class serviceClass)
Object getService(BeanContextChild child, java.lang.Object requestor, java.lang.Class serviceClass, java.lang.Object serviceSelector, BeanContextServiceRevokedListener bcsrl)
Iterator getCurrentServiceSelectors(java.lang.Class serviceClass)JavaBeans nested into a BeanContextServices implement BeanContextServicesListener
to listen for new services
being added, and/or BeanContextServiceRevokedListener to listen for services being revoked.
There are two event types that may be intercepted by such listeners:
BeanContextServiceAvailableEvent: received by the BeanContextServicesListener in
order to identify the service being registered.
BeanContextServiceRevokedEvent: received by the
BeanContextServiceRevokedListener in order to identify the
service being revoked.
JavaBeans can query their enclosing bean context for a list of available services, or ask for a specific service
by name. The service itself, however, is actually delivered by a BeanContextServiceProvider.
The provider can be any object that implements the
java.beans.beancontext.BeanContextServiceProvider interface. Services
become available in a context via the bean context's addService() registration method.
BeanContextServiceProvider offers the following three methods, which will be automatically called when a bean requests (or releases) a service from its context:
Object getService(BeanContextServices bcs, java.lang.Object requestor, java.lang.Class serviceClass, java.lang.Object serviceSelector) Iterator getCurrentServiceSelectors(BeanContextServices bcs, java.lang.Class serviceClass) public void releaseService(BeanContextServices bcs, java.lang.Object requestor, java.lang.Object service) Release a service from any object that currently has a reference to it
The service itself is best described by this paragraph from the specification:
A service, represented by a Class object, is typically a reference to either an interface, or to an implementation that is not publicly instantiable. This Class defines an interface protocol or contract between a BeanContextServiceProvider, the factory of the service, and an arbitrary object associated with a BeanContextChild that is currently nested within the BeanContext the service is registered with.
The following section presents a sample application that uses a word counting service to count the number of words in a given text file.
DocumentBean.java: A JavaBean that encapsulates a File object. Create an instance of this bean by passing it
a String indicating the name of the text file to represent. This bean extends BeanContextChildSupport, which allows
it to listen for addition/revocation of services in its context. When the bean detects that a
WordCount service
has been added to the context, it requests the service to count the number of words it contains.
WordCountServiceProvider.java: A class that acts as the
factory for delivering the WordCount service. This
class implements the BeanContextServiceProvider interface.
WordCount.java: This interface defines the service itself.
DocumentTester.java: The main test program.
File:
DocumentBean.java
import java.beans.beancontext.*;
import java.io.*;
import java.util.*;
public final class DocumentBean extends BeanContextChildSupport {
private File document;
private BeanContextServices context;
public DocumentBean(String fileName) {
document = new File(fileName);
}
public void serviceAvailable(BeanContextServiceAvailableEvent bcsae) {
System.out.println("[Detected a service being added to the context]");
// Get a reference to the context
BeanContextServices context = bcsae.getSourceAsBeanContextServices();
System.out.println("Is the context offering a WordCount service? "
+ context.hasService(WordCount.class));
// Use the service, if it's available
if (context.hasService(WordCount.class)) {
System.out.println("Attempting to use the service...");
try {
WordCount service = (WordCount)context.getService(this, this,
WordCount.class, document, this);
System.out.println("Got the service!");
service.countWords();
} catch(Exception e) { }
}
}
public void serviceRevoked(BeanContextServiceRevokedEvent bcsre) {
System.out.println("[Detected a service being revoked from the context]");
}
}
File:
WordCountServiceProvider.java
import java.beans.beancontext.*;
import java.util.*;
import java.io.*;
public final class WordCountServiceProvider implements BeanContextServiceProvider {
public Object getService(BeanContextServices bcs,
Object requestor,
Class serviceClass,
Object serviceSelector) {
// For this demo, we know that the cast from serviceSelector
// to File will always work.
final File document = (File)serviceSelector;
return new WordCount() {
public void countWords() {
try {
// Create a Reader to the DocumentBean's File
BufferedReader br = new BufferedReader(new FileReader(document));
String line = null;
int wordCount = 0;
while ((line = br.readLine()) != null) {
StringTokenizer st = new StringTokenizer(line);
while (st.hasMoreTokens()) {
System.out.println("Word " + (++wordCount)
+ " is: " + st.nextToken());
}
}
System.out.println("Total number of words in the document: "
+ wordCount);
System.out.println("[WordCount service brought to you by WordCountServiceProvider]");
br.close();
} catch(Exception e) { }
}
};
}
public void releaseService(BeanContextServices bcs,
Object requestor,
Object service) {
// do nothing
}
public Iterator getCurrentServiceSelectors(BeanContextServices bcs, Class serviceClass) {
return null; // do nothing
}
}
File:
WordCount.java
public interface WordCount {
public abstract void countWords();
}
File:
DocumentTester.java
import java.beans.beancontext.*;
import java.util.*;
public class DocumentTester {
public static void main(String[] args) {
BeanContextServicesSupport context = new BeanContextServicesSupport(); // a bean context
DocumentBean doc1 = new DocumentBean("Test.txt");
context.add(doc1);
context.addBeanContextServicesListener(doc1); // listen for new services
WordCountServiceProvider provider = new WordCountServiceProvider();
context.addService(WordCount.class, provider); // add the service to the context
}
}
File:
Test.txt
This text will be analyzed by the WordCount service.
[Detected a service being added to the context] Is the context offering a WordCount service? true Attempting to use the service... Got the service! Word 1 is: This Word 2 is: text Word 3 is: will Word 4 is: be Word 5 is: analyzed Word 6 is: by Word 7 is: the Word 8 is: WordCount Word 9 is: service. Total number of words in the document: 9 [WordCount service brought to you by WordCountServiceProvider]