Trail: JavaBeans(TM)
Lesson: Using the BeanContext API
Bean Context #1: Containment Only
Home Page > JavaBeans(TM) > Using the BeanContext API
Bean Context #1: Containment Only

The "containment" portion of the Extensible Runtime Containment and Services Protocol is defined by the BeanContext interface. In its most basic form, a BeanContext is used to logically group a set of related java beans, bean contexts, or arbitrary objects. JavaBeans nested into a BeanContext are known as "child" beans. Once nested, a child bean can query its BeanContext for various membership information, as illustrated in the following examples.

Here are some possible BeanContext containment scenarios:

The sample code presented in this chapter uses instances of the BeanContextSupport helper class to provide the basic BeanContext functionality. A BeanContextSupport object is simply a concrete implementation of the BeanContext interface.

With a BeanContextSupport instance, it is possible to:

The following test programs, which are run from the command line, illustrate the use of these methods.

The comments in the source code explain the purpose of each.

File: Example1.java
/*
 * Copyright (c) 1995 - 2008 Sun Microsystems, Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Sun Microsystems nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */ 

import java.beans.beancontext.*;

/**
 * A test program that adds a bean to a beancontext, and
 * reports on various aspects of the context's membership state. 
 * This program also shows that a bean's getBeanContext() method 
 * can be called to get a reference to its enclosing context.
 */
public class Example1 {
    private static BeanContextSupport context = new BeanContextSupport(); // The BeanContext
    private static BeanContextChildSupport bean = new BeanContextChildSupport(); // The JavaBean
  
    public static void main(String[] args) {
        report();  

        // Add the bean to the context
        System.out.println("Adding bean to context...");
        context.add(bean);

        report();
    }

    private static void report() {
        // Print out a report of the context's membership state.
        System.out.println("=============================================");

        // Is the context empty?
        System.out.println("Is the context empty? " + context.isEmpty());

        // Has the context been set for the child bean?
        boolean result = (bean.getBeanContext()!=null);
        System.out.println("Does the bean have a context yet? " + result);

        // Number of children in the context
        System.out.println("Number of children in the context: " + context.size());

        // Is the specific bean a member of the context?
        System.out.println("Is the bean a member of the context? " + context.contains(bean));

        // Equality test
        if (bean.getBeanContext() != null) {
            boolean isEqual = (bean.getBeanContext()==context); // true means both references point to the same object
            System.out.println("Contexts are the same? " + isEqual);
        }
        System.out.println("=============================================");   
    }
}
Output:
=============================================
Is the context empty? true
Does the bean have a context yet? false
Number of children in the context: 0
Is the bean a member of the context? false
=============================================
Adding bean to context...
=============================================
Is the context empty? false
Does the bean have a context yet? true
Number of children in the context: 1
Is the bean a member of the context? true
Contexts are the same? true
=============================================
File: Example2.java
/*
 * Copyright (c) 1995 - 2008 Sun Microsystems, Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Sun Microsystems nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */ 

import java.beans.beancontext.*;

/**
 * Test program that adds 100 beans to a context,
 * and calls size() to report the number of beans
 * currently nested. Finally,
 * this test calls toArray() to get references to
 * all child beans. 
 */
public class Example2 {
    public static void main(String[] args) {

        // A BeanContext 
        BeanContextSupport context = new BeanContextSupport(); 

        // Many JavaBeans
        BeanContextChildSupport[] beans = new BeanContextChildSupport[100];

        System.out.println("Number of children in the context: " + context.size());

        // Create the beans and add them to the context
        for (int i = 0; i < beans.length; i++) {
            beans[i] = new BeanContextSupport();
            context.add(beans[i]);
        }
        System.out.println("Number of children in the context: " + context.size());

        // Context now has 100 beans in it, get references to them all
        Object[] children = context.toArray();
        System.out.println("Number of objects retrieved from the context: " + children.length);
    }
}
Output:
Number of children in the context: 0
Number of children in the context: 100
Number of objects retrieved from the context: 100
File: Example3.java
/*
 * Copyright (c) 1995 - 2008 Sun Microsystems, Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Sun Microsystems nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */ 

import java.beans.beancontext.*;
import java.io.*;

/**
 * An example of how to use the instantiateChild() convenience method
 * to create a bean automatically nested into a bean context.
 */
public class Example3 {
    public static void main(String[] args) {
        BeanContextSupport context = new BeanContextSupport();
        System.out.println("Number of children nested into the context: " + context.size());

        BeanContextChildSupport child = null;
        try {
            child = (BeanContextChildSupport)context.instantiateChild("java.beans.beancontext.BeanContextChildSupport");
        }
        catch(IOException e){
            System.out.println("IOException occurred: " + e.getMessage());
        }
        catch(ClassNotFoundException e){
            System.out.println("Class not found: " + e.getMessage());
        }
        System.out.println("Number of children nested into the context: " + context.size());
    }
}
Output:
Number of children nested into the context: 0
Number of children nested into the context: 1

BeanContextMembershipEvent Notification

The BeanContext API uses the standard Java event model to register listeners and deliver events. For an overview of this standard event model, refer to Writing Event Listeners. For details about handling specific events, see Writing Event Listeners.

In a basic BeanContext, the event classes and interfaces involved are:

BeanContextMembershipEvent Notification: Sample Code

File: MembershipTest.java
/*
 * Copyright (c) 1995 - 2008 Sun Microsystems, Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Sun Microsystems nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */ 

import java.beans.beancontext.*;

/**
 * A simple test program to illustrate delivery
 * of the BeanContextMembershipEvent.
 */
public class MembershipTest {
    public static void main(String[] args) {
        BeanContextSupport context = new BeanContextSupport(); // the context
        MyMembershipListener listener = new MyMembershipListener(); 
        BeanContextChildSupport bean = new BeanContextChildSupport(); // a JavaBean
        context.addBeanContextMembershipListener(listener); // now listening!
        context.add(bean);
        context.remove(bean);
    }
}

/**
 * A custom implementation of the BeanContextMembershipListener interface.
 */
class MyMembershipListener implements BeanContextMembershipListener {
    public void childrenAdded(BeanContextMembershipEvent bcme) {
        System.out.println("Another bean has been added to the context.");
    }

    public void childrenRemoved(BeanContextMembershipEvent bcme) {
        System.out.println("A bean has been removed from the context.");
    }
}
Output:
Another bean has been added to the context.
A bean has been removed from the context.

The same example, implemented using an anonymous inner class

import java.beans.beancontext.*;

public class MembershipTest {
    public static void main(String[] args) {
        BeanContextSupport context = new BeanContextSupport();
        context.addBeanContextMembershipListener(new BeanContextMembershipListener() {
            public void childrenAdded(BeanContextMembershipEvent bcme) {
                System.out.println("Another bean has been added to the context.");
            }

            public void childrenRemoved(BeanContextMembershipEvent bcme) {
                System.out.println("A bean has been removed from the context.");
            }
        });
        BeanContextChildSupport bean = new BeanContextChildSupport();
        context.add(bean);
        context.remove(bean);
    }
}
Output:
Another bean has been added to the context.
A bean has been removed from the context.
Previous page: Overview of the BeanContext API
Next page: Bean Context #2: Containment and Services