You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@beehive.apache.org by cs...@apache.org on 2006/04/25 21:38:01 UTC

svn commit: r396962 [1/3] - in /beehive/trunk/controls: src/runtime/org/apache/beehive/controls/runtime/bean/webcontext/ test/ test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontext/ test/src/junit-controls/org/apache/beehive/con...

Author: cschoett
Date: Tue Apr 25 12:37:54 2006
New Revision: 396962

URL: http://svn.apache.org/viewcvs?rev=396962&view=rev
Log:
New implementations of BeanContextChild, BeanContext and BeanContextServices. This is a first pass at these implementations and there is still a bit of refactoring which needs to be done.

Also included in this checkin: supporting junit tests for these implementations.  

The new implementations have not yet been wired into the CBC/CCC objects so there shouldn't be
any issues since they are not currently being used.


Added:
    beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/webcontext/
    beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/webcontext/ControlBeanContextChildSupport.java   (with props)
    beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/webcontext/ControlBeanContextServicesSupport.java   (with props)
    beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/webcontext/ControlBeanContextSupport.java   (with props)
    beehive/trunk/controls/test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontext/
    beehive/trunk/controls/test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontext/BeanContextProxyImpl.java   (with props)
    beehive/trunk/controls/test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontext/MembershipListener.java   (with props)
    beehive/trunk/controls/test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontext/Resource.txt   (with props)
    beehive/trunk/controls/test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontext/VisibilityImpl.java   (with props)
    beehive/trunk/controls/test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontextchild/
    beehive/trunk/controls/test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontextchild/AlwaysVetoListener.java   (with props)
    beehive/trunk/controls/test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontextchild/BeanDelegate.java   (with props)
    beehive/trunk/controls/test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontextchild/ChangeListener.java   (with props)
    beehive/trunk/controls/test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontextchild/DummyBeanContext.java   (with props)
    beehive/trunk/controls/test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontextservices/
    beehive/trunk/controls/test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontextservices/BCChild.java   (with props)
    beehive/trunk/controls/test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontextservices/BCChildNoServiceRelease.java   (with props)
    beehive/trunk/controls/test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontextservices/ServiceListener.java   (with props)
    beehive/trunk/controls/test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontextservices/TestBCServiceProviderImpl.java   (with props)
    beehive/trunk/controls/test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontextservices/TestNonSerializableBCServiceProviderImpl.java   (with props)
    beehive/trunk/controls/test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontextservices/TestNonSerializableService.java   (with props)
    beehive/trunk/controls/test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontextservices/TestService.java   (with props)
    beehive/trunk/controls/test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontextservices/TestServiceImpl.java   (with props)
    beehive/trunk/controls/test/src/junit-tests/org/apache/beehive/controls/test/junit/ControlBeanContextChildSupportTest.java   (with props)
    beehive/trunk/controls/test/src/junit-tests/org/apache/beehive/controls/test/junit/ControlBeanContextServicesSupportTest.java   (with props)
    beehive/trunk/controls/test/src/junit-tests/org/apache/beehive/controls/test/junit/ControlBeanContextSupportTest.java   (with props)
Modified:
    beehive/trunk/controls/test/build.xml

Added: beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/webcontext/ControlBeanContextChildSupport.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/webcontext/ControlBeanContextChildSupport.java?rev=396962&view=auto
==============================================================================
--- beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/webcontext/ControlBeanContextChildSupport.java (added)
+++ beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/webcontext/ControlBeanContextChildSupport.java Tue Apr 25 12:37:54 2006
@@ -0,0 +1,248 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * $Header:$
+ */
+
+package org.apache.beehive.controls.runtime.bean.webcontext;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.beans.PropertyVetoException;
+import java.beans.VetoableChangeListener;
+import java.beans.VetoableChangeSupport;
+import java.beans.beancontext.BeanContext;
+import java.beans.beancontext.BeanContextChild;
+import java.beans.beancontext.BeanContextServiceAvailableEvent;
+import java.beans.beancontext.BeanContextServiceRevokedEvent;
+import java.beans.beancontext.BeanContextServiceRevokedListener;
+import java.beans.beancontext.BeanContextServicesListener;
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.EventListener;
+
+/**
+ * Implementation of the BeanContextChild api for Beehive controls.
+ */
+public class ControlBeanContextChildSupport
+        implements BeanContextChild, BeanContextServiceRevokedListener,
+        BeanContextServicesListener, Serializable, EventListener {
+    private static final long serialVersionUID = 1;
+
+    private transient BeanContext _beanContext;
+    private transient boolean _vetodOnce;
+    private BeanContextChild _bccDelegate;
+    private PropertyChangeSupport _propertyChangeSupport;
+    private VetoableChangeSupport _vetoableChangeSupport;
+
+    /**
+     * Constructor.
+     */
+    public ControlBeanContextChildSupport() {
+        _beanContext = null;
+        _bccDelegate = this;
+        _vetodOnce = false;
+        _propertyChangeSupport = new PropertyChangeSupport(_bccDelegate);
+        _vetoableChangeSupport = new VetoableChangeSupport(_bccDelegate);
+    }
+
+    /**
+     * Constructor -- java bean implements BeanContextChild and delegates the interface
+     * to this implementation.
+     *
+     * @param bcc
+     */
+    public ControlBeanContextChildSupport(BeanContextChild bcc) {
+        _beanContext = null;
+        _vetodOnce = false;
+        _bccDelegate = (bcc != null) ? bcc : this;
+        _propertyChangeSupport = new PropertyChangeSupport(_bccDelegate);
+        _vetoableChangeSupport = new VetoableChangeSupport(_bccDelegate);
+    }
+
+    /**
+     * <p/>
+     * Objects that implement this interface,
+     * shall fire a java.beans.PropertyChangeEvent, with parameters:
+     * <p/>
+     * propertyName "beanContext", oldValue (the previous nesting
+     * <code>BeanContext</code> instance, or <code>null</code>),
+     * newValue (the current nesting
+     * <code>BeanContext</code> instance, or <code>null</code>).
+     * <p/>
+     * A change in the value of the nesting BeanContext property of this
+     * BeanContextChild may be vetoed by throwing the appropriate exception.
+     * </p>
+     *
+     * @param bc The <code>BeanContext</code> with which
+     *           to associate this <code>BeanContextChild</code>.
+     */
+    public synchronized void setBeanContext(BeanContext bc) throws PropertyVetoException {
+
+        if (bc == _beanContext) return;
+
+        // track if veto'd the first time, then then second time remove anyway (dont except);
+        if (!_vetodOnce) {
+            try {
+                _vetoableChangeSupport.fireVetoableChange("beanContext", _beanContext, bc);
+            }
+            catch (PropertyVetoException pve) {
+                _vetodOnce = true;
+                throw pve;
+            }
+        }
+
+        releaseBeanContextResources();
+        BeanContext oldValue = _beanContext;
+        _beanContext = bc;
+        _vetodOnce = false;
+        firePropertyChange("beanContext", oldValue, _beanContext);
+    }
+
+    /**
+     * Gets the <code>BeanContext</code> associated
+     * with this <code>BeanContextChild</code>.
+     *
+     * @return the <code>BeanContext</code> associated
+     *         with this <code>BeanContextChild</code>.
+     */
+    public synchronized BeanContext getBeanContext() {
+        return _beanContext;
+    }
+
+    /**
+     * Adds a <code>PropertyChangeListener</code>
+     * to this <code>BeanContextChild</code>
+     * in order to receive a <code>PropertyChangeEvent</code>
+     * whenever the specified property has changed.
+     *
+     * @param name the name of the property to listen on
+     * @param pcl  the <code>PropertyChangeListener</code> to add
+     */
+    public void addPropertyChangeListener(String name, PropertyChangeListener pcl) {
+        _propertyChangeSupport.addPropertyChangeListener(name, pcl);
+    }
+
+    /**
+     * Removes a <code>PropertyChangeListener</code> from this
+     * <code>BeanContextChild</code>  so that it no longer
+     * receives <code>PropertyChangeEvents</code> when the
+     * specified property is changed.
+     *
+     * @param name the name of the property that was listened on
+     * @param pcl  the <code>PropertyChangeListener</code> to remove
+     */
+    public void removePropertyChangeListener(String name, PropertyChangeListener pcl) {
+        _propertyChangeSupport.removePropertyChangeListener(name, pcl);
+    }
+
+    /**
+     * Adds a <code>VetoableChangeListener</code> to
+     * this <code>BeanContextChild</code>
+     * to receive events whenever the specified property changes.
+     *
+     * @param name the name of the property to listen on
+     * @param vcl  the <code>VetoableChangeListener</code> to add
+     */
+    public void addVetoableChangeListener(String name, VetoableChangeListener vcl) {
+        _vetoableChangeSupport.addVetoableChangeListener(name, vcl);
+    }
+
+    /**
+     * Removes a <code>VetoableChangeListener</code> from this
+     * <code>BeanContextChild</code> so that it no longer receives
+     * events when the specified property changes.
+     *
+     * @param name the name of the property that was listened on.
+     * @param vcl  the <code>VetoableChangeListener</code> to remove.
+     */
+    public void removeVetoableChangeListener(String name, VetoableChangeListener vcl) {
+        _vetoableChangeSupport.addVetoableChangeListener(name, vcl);
+    }
+
+    /**
+     * The service named has been registered. getService requests for
+     * this service may now be made.
+     *
+     * @param bcsae the <code>BeanContextServiceAvailableEvent</code>
+     */
+    public void serviceAvailable(BeanContextServiceAvailableEvent bcsae) {
+        // noop
+    }
+
+    /**
+     * The service named has been revoked. getService requests for
+     * this service will no longer be satisifed.
+     *
+     * @param bcsre the <code>BeanContextServiceRevokedEvent</code> received
+     *              by this listener.
+     */
+    public void serviceRevoked(BeanContextServiceRevokedEvent bcsre) {
+        // Noop
+    }
+
+    /**
+     * ***************************************************************
+     */
+
+    /**
+     * Get the delegate for this child.
+     */
+    protected BeanContextChild getBCCDelegate() {
+        return _bccDelegate;
+    }
+
+    /**
+     * Fire a property change event.
+     * @param name
+     * @param oldValue
+     * @param newValue
+     */
+    protected void firePropertyChange(String name, Object oldValue, Object newValue) {
+        _propertyChangeSupport.firePropertyChange(name, oldValue, newValue);
+    }
+
+    /**
+     * Release any resources that may have been acumlated from the current bean context, invoked
+     * by setBeanContext BEFORE the context is changed.
+     */
+    protected void releaseBeanContextResources() {
+        // noop
+    }
+
+    /**
+     * Serialization support -- throw IOException if a non-serializable delegate is present.
+     *
+     * @param out
+     */
+    private void writeObject(ObjectOutputStream out) throws IOException {
+        if (!_bccDelegate.equals(this) && !(_bccDelegate instanceof Serializable)) {
+            throw new IOException("Bean context child delegate does not support serialization!!!");
+        }
+        out.defaultWriteObject();
+    }
+
+    /**
+     * Deserialization support -- just deserialize.
+     *
+     * @param in
+     * @throws IOException
+     * @throws ClassNotFoundException
+     */
+    private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
+        in.defaultReadObject();
+    }
+}

Propchange: beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/webcontext/ControlBeanContextChildSupport.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/webcontext/ControlBeanContextChildSupport.java
------------------------------------------------------------------------------
    svn:executable = *

Added: beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/webcontext/ControlBeanContextServicesSupport.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/webcontext/ControlBeanContextServicesSupport.java?rev=396962&view=auto
==============================================================================
--- beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/webcontext/ControlBeanContextServicesSupport.java (added)
+++ beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/webcontext/ControlBeanContextServicesSupport.java Tue Apr 25 12:37:54 2006
@@ -0,0 +1,620 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * $Header:$
+ */
+
+package org.apache.beehive.controls.runtime.bean.webcontext;
+
+import java.beans.beancontext.BeanContext;
+import java.beans.beancontext.BeanContextChild;
+import java.beans.beancontext.BeanContextServiceAvailableEvent;
+import java.beans.beancontext.BeanContextServiceProvider;
+import java.beans.beancontext.BeanContextServiceRevokedEvent;
+import java.beans.beancontext.BeanContextServiceRevokedListener;
+import java.beans.beancontext.BeanContextServices;
+import java.beans.beancontext.BeanContextServicesListener;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.TooManyListenersException;
+
+/**
+ * Implementation of BeanContextServices for Beehive Controls.  Assumes single threaded usage.
+ */
+public class ControlBeanContextServicesSupport extends ControlBeanContextSupport implements BeanContextServices {
+
+    private transient Map<Class/*service class*/, ServiceProvider> _serviceProviders;
+    private transient List<BeanContextServicesListener> _bcsListeners;
+
+    /**
+     * Constructor.
+     */
+    public ControlBeanContextServicesSupport() {
+        super();
+    }
+
+    /**
+     * Constructor which allows delegate to be passed in.
+     *
+     * @param bcc BeanContextChild delegate.
+     */
+    public ControlBeanContextServicesSupport(BeanContextChild bcc) {
+        super(bcc);
+    }
+
+    /**
+     * Adds a service to this BeanContext.
+     * <code>BeanContextServiceProvider</code>s call this method
+     * to register a particular service with this context.
+     * If the service has not previously been added, the
+     * <code>BeanContextServices</code> associates
+     * the service with the <code>BeanContextServiceProvider</code> and
+     * fires a <code>BeanContextServiceAvailableEvent</code> to all
+     * currently registered <code>BeanContextServicesListeners</code>.
+     * The method then returns <code>true</code>, indicating that
+     * the addition of the service was successful.
+     * If the given service has already been added, this method
+     * simply returns <code>false</code>.
+     *
+     * @param serviceClass    the service to add
+     * @param serviceProvider the <code>BeanContextServiceProvider</code>
+     *                        associated with the service
+     * @return true if service was added.
+     */
+    public boolean addService(Class serviceClass, BeanContextServiceProvider serviceProvider) {
+        // todo: for multithreaded usage this block needs to be synchronized
+        if (!_serviceProviders.containsKey(serviceClass)) {
+            _serviceProviders.put(serviceClass, new ServiceProvider(serviceProvider));
+            BeanContextServiceAvailableEvent bcsae = new BeanContextServiceAvailableEvent(this, serviceClass);
+            fireServiceAvailableEvent(bcsae);
+            return true;
+        }
+        // end synchronized
+        return false;
+    }
+
+    /**
+     * BeanContextServiceProviders wishing to remove
+     * a currently registered service from this context
+     * may do so via invocation of this method. Upon revocation of
+     * the service, the <code>BeanContextServices</code> fires a
+     * <code>BeanContextServiceRevokedEvent</code> to its
+     * list of currently registered
+     * <code>BeanContextServiceRevokedListeners</code> and
+     * <code>BeanContextServicesListeners</code>.
+     *
+     * @param serviceClass             the service to revoke from this BeanContextServices
+     * @param serviceProvider          the BeanContextServiceProvider associated with
+     *                                 this particular service that is being revoked
+     * @param revokeCurrentServicesNow a value of <code>true</code>
+     *                                 indicates an exceptional circumstance where the
+     *                                 <code>BeanContextServiceProvider</code> or
+     *                                 <code>BeanContextServices</code> wishes to immediately
+     *                                 terminate service to all currently outstanding references
+     *                                 to the specified service.
+     */
+    public void revokeService(Class serviceClass, BeanContextServiceProvider serviceProvider, boolean revokeCurrentServicesNow) {
+        // todo: for multithreaded usage this block needs to be synchronized
+        if (!_serviceProviders.containsKey(serviceClass)) {
+            return;
+        }
+
+        // propagate to any children implementing BeanContextServices
+        ServiceProvider sp = _serviceProviders.get(serviceClass);
+        Iterator i = iterator();
+        while (i.hasNext()) {
+            Object o = i.next();
+            if (o instanceof BeanContextServices) {
+                ((BeanContextServices) o).revokeService(serviceClass, serviceProvider, revokeCurrentServicesNow);
+            }
+        }
+
+        BeanContextServiceRevokedEvent bcsre =
+                new BeanContextServiceRevokedEvent(this, serviceClass, revokeCurrentServicesNow);
+        fireServiceRevokedEvent(bcsre);
+
+        // fire revoked event to requestor listeners, if the service is delegated the owner of the
+        // service should fire these events.
+        if (!sp.isDelegated()) {
+            sp.revokeService(bcsre);
+        }
+
+        if (revokeCurrentServicesNow || !sp.hasRequestors()) {
+            _serviceProviders.remove(serviceClass);
+        }
+        // end synchronized
+    }
+
+    /**
+     * Reports whether or not a given service is
+     * currently available from this context.
+     *
+     * @param serviceClass the service in question
+     * @return true if the service is available
+     */
+    public synchronized boolean hasService(Class serviceClass) {
+
+        // todo: for multithreaded usage this block needs to be synchronized
+        ServiceProvider sp = _serviceProviders.get(serviceClass);
+        if (sp != null && !sp.isRevoked()) {
+            return true;
+        }
+
+        // if service not found locally check in nested context
+        BeanContext bc = getBeanContext();
+        if (bc instanceof BeanContextServices) {
+            return ((BeanContextServices) bc).hasService(serviceClass);
+        }
+        return false;
+        // end synchronized
+    }
+
+    /**
+     * A <code>BeanContextChild</code>, or any arbitrary object
+     * associated with a <code>BeanContextChild</code>, may obtain
+     * a reference to a currently registered service from its
+     * nesting <code>BeanContextServices</code>
+     * via invocation of this method. When invoked, this method
+     * gets the service by calling the getService() method on the
+     * underlying <code>BeanContextServiceProvider</code>.
+     *
+     * @param child           the <code>BeanContextChild</code>
+     *                        associated with this request
+     * @param requestor       the object requesting the service
+     * @param serviceClass    class of the requested service
+     * @param serviceSelector the service dependent parameter
+     * @param bcsrl           the
+     *                        <code>BeanContextServiceRevokedListener</code> to notify
+     *                        if the service should later become revoked
+     * @return a reference to this context's named
+     *         Service as requested or <code>null</code>
+     * @throws java.util.TooManyListenersException
+     *
+     */
+    public Object getService(BeanContextChild child, Object requestor,
+                             Class serviceClass, Object serviceSelector, BeanContextServiceRevokedListener bcsrl)
+            throws TooManyListenersException {
+
+        if (!contains(child)) {
+            throw new IllegalArgumentException(child + "is not a child of this context!");
+        }
+
+        Object service;
+        BeanContext bc = getBeanContext();
+
+        // todo: for multithreaded usage this block needs to be synchronized
+        // check to see if this is a known service
+        ServiceProvider sp = _serviceProviders.get(serviceClass);
+        if (sp != null && sp.isRevoked()) {
+            return null;
+        }
+
+        if (sp != null) {
+            if (sp.isDelegated()) {
+                service = ((BeanContextServices) bc).getService(this, requestor, serviceClass, serviceSelector, bcsrl);
+            }
+            else {
+                service = sp.getBCServiceProvider().getService(this, requestor, serviceClass, serviceSelector);
+            }
+
+            if (service != null) {
+                sp.addChildReference(requestor, bcsrl);
+            }
+            return service;
+        }
+
+        // try to delegate the request to the nested BeanContextServices (if available)
+        if (bc instanceof BeanContextServices) {
+            service = ((BeanContextServices) bc).getService(this, requestor, serviceClass, serviceSelector, bcsrl);
+            if (service != null) {
+                sp = new ServiceProvider();
+                sp.addChildReference(requestor, bcsrl);
+                _serviceProviders.put(serviceClass, sp);
+                return service;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Releases a <code>BeanContextChild</code>'s
+     * (or any arbitrary object associated with a BeanContextChild)
+     * reference to the specified service by calling releaseService()
+     * on the underlying <code>BeanContextServiceProvider</code>.
+     *
+     * @param child     the <code>BeanContextChild</code>
+     * @param requestor the requestor
+     * @param service   the service
+     */
+    public void releaseService(BeanContextChild child, Object requestor, Object service) {
+
+        if (!contains(child)) {
+            throw new IllegalArgumentException(child + "is not a child of this context!");
+        }
+
+        // todo: for multithreaded usage this block needs to be synchronized
+        Class serviceClass = findServiceClass(service);
+
+        ServiceProvider sp = _serviceProviders.get(serviceClass);
+        sp.removeChildReference(requestor);
+
+        if (sp.isDelegated()) {
+            BeanContextServices bcs = (BeanContextServices) getBeanContext();
+            bcs.releaseService(this, requestor, service);
+            if (!sp.hasRequestors()) {
+                _serviceProviders.remove(serviceClass);
+            }
+        }
+        else {
+            sp.getBCServiceProvider().releaseService(this, requestor, service);
+        }
+        // end synchronized
+    }
+
+    /**
+     * Gets the currently available services for this context.
+     *
+     * @return an <code>Iterator</code> consisting of the
+     *         currently available services
+     */
+    public Iterator getCurrentServiceClasses() {
+
+        ArrayList<Class> currentClasses = new ArrayList<Class>();
+        for (Class serviceClass : _serviceProviders.keySet()) {
+            ServiceProvider sp = _serviceProviders.get(serviceClass);
+            if (!sp.isRevoked() && !sp.isDelegated()) {
+                currentClasses.add(serviceClass);
+            }
+        }
+        return currentClasses.iterator();
+    }
+
+    /**
+     * Gets the list of service dependent service parameters
+     * (Service Selectors) for the specified service, by
+     * calling getCurrentServiceSelectors() on the
+     * underlying BeanContextServiceProvider.
+     *
+     * @param serviceClass the specified service
+     * @return the currently available service selectors
+     *         for the named serviceClass
+     */
+    public Iterator getCurrentServiceSelectors(Class serviceClass) {
+
+        if (_serviceProviders.containsKey(serviceClass)) {
+            ServiceProvider sp = _serviceProviders.get(serviceClass);
+            if (!sp.isDelegated() && !sp.isRevoked()) {
+                return sp.getBCServiceProvider().getCurrentServiceSelectors(this, serviceClass);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Adds a <code>BeanContextServicesListener</code> to this BeanContext
+     *
+     * @param bcsl the <code>BeanContextServicesListener</code> to add
+     */
+    public void addBeanContextServicesListener(BeanContextServicesListener bcsl) {
+        if (!_bcsListeners.contains(bcsl)) {
+            _bcsListeners.add(bcsl);
+        }
+    }
+
+    /**
+     * Removes a <code>BeanContextServicesListener</code>
+     * from this <code>BeanContext</code>
+     *
+     * @param bcsl the <code>BeanContextServicesListener</code>
+     *             to remove from this context
+     */
+    public void removeBeanContextServicesListener(BeanContextServicesListener bcsl) {
+        _bcsListeners.remove(bcsl);
+    }
+
+    /*
+     * **********************************************************************************
+     *                          Protected
+     * **********************************************************************************
+     */
+
+    /**
+     * Invoked when all resources obtained from the current nested bean context
+     * need to be released. For BeanContextServices this means revoke any services
+     * obtained from a delegate services provider. Typically invoked when the parent
+     * context is changed.
+     */
+    protected synchronized void releaseBeanContextResources() {
+
+        for (Class serviceClass : _serviceProviders.keySet()) {
+            ServiceProvider sp = _serviceProviders.get(serviceClass);
+            if (sp.isDelegated()) {
+                sp.revokeService(new BeanContextServiceRevokedEvent(this, serviceClass, true));
+                _serviceProviders.remove(serviceClass);
+            }
+        }
+    }
+
+    /*
+     * **********************************************************************************
+     *                              Private
+     * **********************************************************************************
+     */
+
+    /**
+     * first a service available event.
+     *
+     * @param bcsae
+     */
+    private void fireServiceAvailableEvent(BeanContextServiceAvailableEvent bcsae) {
+        for (BeanContextServicesListener bcsl : _bcsListeners) {
+            bcsl.serviceAvailable(bcsae);
+        }
+    }
+
+    /**
+     * Fire a service revoked event.
+     *
+     * @param bcsre
+     */
+    private void fireServiceRevokedEvent(BeanContextServiceRevokedEvent bcsre) {
+        for (BeanContextServicesListener bcsl : _bcsListeners) {
+            bcsl.serviceRevoked(bcsre);
+        }
+    }
+
+    /**
+     * Initialize data structures.
+     */
+    protected void init() {
+        super.init();
+        _serviceProviders = Collections.synchronizedMap(new HashMap<Class, ServiceProvider>());
+        _bcsListeners = Collections.synchronizedList(new ArrayList<BeanContextServicesListener>());
+    }
+
+    /**
+     * Try to find the registered service for a service object instance.
+     * May return null if the object instance is not from a service registered
+     * with this service provider.
+     *
+     * @return Service class for service instance.
+     * @throws IllegalArgumentException if service class can not be found.
+     */
+    private Class findServiceClass(Object service) {
+        for (Class sc : _serviceProviders.keySet()) {
+            if (sc.isInstance(service)) {
+                return sc;
+            }
+        }
+        throw new IllegalArgumentException("Cannot find service provider for: " + service.getClass().getCanonicalName());
+    }
+
+    /**
+     * Deserialization support.
+     *
+     * @param ois
+     * @throws IOException
+     * @throws ClassNotFoundException
+     */
+    private synchronized void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
+        ois.defaultReadObject();
+
+        int svcsSize = ois.readInt();
+        for (int i = 0; i < svcsSize; i++) {
+            _serviceProviders.put((Class) ois.readObject(), (ServiceProvider) ois.readObject());
+        }
+
+        int listenersSize = ois.readInt();
+        for (int i = 0; i < listenersSize; i++) {
+            _bcsListeners.add((BeanContextServicesListener) ois.readObject());
+        }
+    }
+
+    /**
+     * Serialization support.
+     *
+     * @param oos
+     * @throws IOException
+     */
+    private synchronized void writeObject(ObjectOutputStream oos) throws IOException {
+
+        oos.defaultWriteObject();
+
+        // write out the service providers
+        for (Class svcClass : _serviceProviders.keySet()) {
+            ServiceProvider sp = _serviceProviders.get(svcClass);
+            if (sp.isDelegated() || sp.isRevoked() || !(sp.getBCServiceProvider() instanceof Serializable)) {
+                _serviceProviders.remove(svcClass);
+            }
+        }
+
+        oos.writeInt(_serviceProviders.size());
+        for (Map.Entry<Class, ServiceProvider> entry : _serviceProviders.entrySet()) {
+            oos.writeObject(entry.getKey());
+            oos.writeObject(entry.getValue());
+        }
+
+        // write out the event listeners
+        for (BeanContextServicesListener l : _bcsListeners) {
+            if (!(l instanceof Serializable)) {
+                _bcsListeners.remove(l);
+            }
+        }
+
+        oos.writeInt(_bcsListeners.size());
+        for (BeanContextServicesListener l : _bcsListeners) {
+            oos.writeObject(l);
+        }
+    }
+
+    /*
+    * ***************************************************************************************
+    *          Inner Classes
+    * ***************************************************************************************
+    */
+
+    /**
+     * A ServiceProvider instance is associated with a service class in a Map.  One ServiceProvider
+     * exists for a given service type.  The Service manager keeps track of all of the requestors
+     * for the given service.  It provides functionality to add new references to services, remove
+     * references to services, and to notify referenants that a service has been revoked.
+     */
+    private static final class ServiceProvider implements Serializable {
+
+        private transient HashMap<Object/*requestor*/, ChildServiceReference> _requestors;
+        private BeanContextServiceProvider _bcss;
+        private boolean _revoked;
+
+        /**
+         * Constructor for delegated service provider.
+         */
+        protected ServiceProvider() {
+            _bcss = null;
+        }
+
+        /**
+         * Constructor for local service provider.
+         */
+        protected ServiceProvider(BeanContextServiceProvider bcss) {
+            _bcss = bcss;
+        }
+
+        /**
+         * Add a child reference to this service provider.
+         *
+         * @param requestor
+         * @param bcsrl
+         * @throws TooManyListenersException
+         */
+        protected synchronized void addChildReference(Object requestor, BeanContextServiceRevokedListener bcsrl)
+                throws TooManyListenersException {
+
+            ChildServiceReference csr = getRequestors().get(requestor);
+            if (csr == null) {
+                csr = new ChildServiceReference(bcsrl);
+                getRequestors().put(requestor, csr);
+            }
+            else if (bcsrl != null && !bcsrl.equals(csr.getListener())) {
+                throw new TooManyListenersException();
+            }
+            else {
+                csr.incrementRefCount();
+            }
+        }
+
+        /**
+         * Remove a child reference from this Service provider.
+         *
+         * @param requestor
+         */
+        protected synchronized void removeChildReference(Object requestor) {
+            ChildServiceReference csr = getRequestors().get(requestor);
+            if (csr == null) return;
+            int refCount = csr.decrementRefCount();
+            if (refCount == 0) {
+                getRequestors().remove(requestor);
+            }
+        }
+
+        /**
+         * Notify all the active requestors for this service that the service
+         * has been revoked (per spec).  If this is a delegated service let
+         * the owner of the service invoke the service revoked listener.
+         */
+        protected synchronized void revokeService(BeanContextServiceRevokedEvent bcsre) {
+            for (ChildServiceReference csr : getRequestors().values()) {
+                csr.getListener().serviceRevoked(bcsre);
+            }
+            _revoked = true;
+        }
+
+        /**
+         * Get the BeanContextServiceProvider.
+         */
+        protected BeanContextServiceProvider getBCServiceProvider() {
+            return _bcss;
+        }
+
+        /**
+         * True if this is a delegated service.
+         */
+        protected boolean isDelegated() {
+            return _bcss == null;
+        }
+
+        /**
+         * True if this service has been revoked, but still has references.
+         */
+        protected boolean isRevoked() {
+            return _revoked;
+        }
+
+        /**
+         * True if any requestors are being tracked for this service.
+         */
+        protected boolean hasRequestors() {
+            return !getRequestors().isEmpty();
+        }
+
+        /**
+         * Get a reference to the transient requestors hashmap.
+         */
+        private synchronized HashMap<Object, ChildServiceReference> getRequestors() {
+            if (_requestors == null) {
+                _requestors = new HashMap<Object, ChildServiceReference>();
+            }
+            return _requestors;
+        }
+    }
+
+    /**
+     * Keeps track of the number of references to a service for a single requestor.
+     * Associated with the requestor in the ServiceProvider's _requestors Map.
+     */
+    private static final class ChildServiceReference {
+
+        private int _refCount;
+        private BeanContextServiceRevokedListener _bcsrl;
+
+        protected ChildServiceReference(BeanContextServiceRevokedListener bcsrl) {
+            _bcsrl = bcsrl;
+            _refCount = 1;
+        }
+
+        protected int incrementRefCount() {
+            return ++_refCount;
+        }
+
+        protected int decrementRefCount() {
+            return --_refCount;
+        }
+
+        protected int getRefCount() {
+            return _refCount;
+        }
+
+        protected BeanContextServiceRevokedListener getListener() {
+            return _bcsrl;
+        }
+    }
+}

Propchange: beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/webcontext/ControlBeanContextServicesSupport.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/webcontext/ControlBeanContextServicesSupport.java
------------------------------------------------------------------------------
    svn:executable = *

Added: beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/webcontext/ControlBeanContextSupport.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/webcontext/ControlBeanContextSupport.java?rev=396962&view=auto
==============================================================================
--- beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/webcontext/ControlBeanContextSupport.java (added)
+++ beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/webcontext/ControlBeanContextSupport.java Tue Apr 25 12:37:54 2006
@@ -0,0 +1,801 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * $Header:$
+ */
+
+package org.apache.beehive.controls.runtime.bean.webcontext;
+
+import java.beans.Beans;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyVetoException;
+import java.beans.VetoableChangeListener;
+import java.beans.Visibility;
+import java.beans.beancontext.BeanContext;
+import java.beans.beancontext.BeanContextChild;
+import java.beans.beancontext.BeanContextMembershipEvent;
+import java.beans.beancontext.BeanContextMembershipListener;
+import java.beans.beancontext.BeanContextProxy;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * BeanContext implementation for Beehive Controls.
+ */
+public class ControlBeanContextSupport extends ControlBeanContextChildSupport
+        implements BeanContext, Serializable, PropertyChangeListener, VetoableChangeListener {
+
+    private static final long serialVersionUID = 1L;
+
+    private transient List _children;
+    private transient HashSet<BeanContextMembershipListener> _bcMembershipListeners;
+
+    private boolean _designTime = false;
+    private boolean _mayUseGui = false;
+
+    /**
+     * Constructor.
+     */
+    public ControlBeanContextSupport() {
+        super();
+        init();
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param bcc
+     */
+    public ControlBeanContextSupport(BeanContextChild bcc) {
+        super(bcc);
+        init();
+    }
+
+    /**
+     * Instantiate the javaBean named as a
+     * child of this <code>BeanContext</code>.
+     * The implementation of the JavaBean is
+     * derived from the value of the beanName parameter,
+     * and is defined by the
+     * <code>java.beans.Beans.instantiate()</code> method.
+     *
+     * @param beanName The name of the JavaBean to instantiate
+     *                 as a child of this <code>BeanContext</code>
+     * @throws IOException
+     * @throws ClassNotFoundException if the class identified
+     *                                by the beanName parameter is not found
+     */
+    public Object instantiateChild(String beanName) throws IOException, ClassNotFoundException {
+        BeanContextChild bcc = getBCCDelegate();
+        return Beans.instantiate(bcc.getClass().getClassLoader(), beanName, (BeanContext) bcc);
+    }
+
+    /**
+     * Analagous to <code>java.lang.ClassLoader.getResourceAsStream()</code>,
+     * this method allows a <code>BeanContext</code> implementation
+     * to interpose behavior between the child <code>Component</code>
+     * and underlying <code>ClassLoader</code>.
+     *
+     * @param name the resource name
+     * @param bcc  the specified child
+     * @return an <code>InputStream</code> for reading the resource,
+     *         or <code>null</code> if the resource could not
+     *         be found.
+     * @throws IllegalArgumentException if the resource is not valid
+     */
+    public InputStream getResourceAsStream(String name, BeanContextChild bcc) throws IllegalArgumentException {
+
+        // bcc must be a child of this context
+        if (!contains(bcc)) {
+            throw new IllegalArgumentException("Child is not a member of this context");
+        }
+
+        ClassLoader cl = bcc.getClass().getClassLoader();
+        InputStream is;
+        if (cl != null && (is = cl.getResourceAsStream(name)) != null) {
+            return is;
+        }
+        return ClassLoader.getSystemResourceAsStream(name);
+    }
+
+    /**
+     * Analagous to <code>java.lang.ClassLoader.getResource()</code>, this
+     * method allows a <code>BeanContext</code> implementation to interpose
+     * behavior between the child <code>Component</code>
+     * and underlying <code>ClassLoader</code>.
+     *
+     * @param name the resource name
+     * @param bcc  the specified child
+     * @return a <code>URL</code> for the named
+     *         resource for the specified child
+     * @throws IllegalArgumentException if the resource is not valid
+     */
+    public URL getResource(String name, BeanContextChild bcc) throws IllegalArgumentException {
+
+        // bcc must be a child of this context
+        if (!contains(bcc)) {
+            throw new IllegalArgumentException("Child is not a member of this context");
+        }
+
+        ClassLoader cl = bcc.getClass().getClassLoader();
+        URL url;
+        if (cl != null && (url = cl.getResource(name)) != null) {
+            return url;
+        }
+        return ClassLoader.getSystemResource(name);
+    }
+
+    /**
+     * Adds the specified <code>BeanContextMembershipListener</code>
+     * to receive <code>BeanContextMembershipEvents</code> from
+     * this <code>BeanContext</code> whenever it adds
+     * or removes a child <code>Component</code>(s).
+     *
+     * @param bcml the <code>BeanContextMembershipListener</code> to be added
+     */
+    public void addBeanContextMembershipListener(BeanContextMembershipListener bcml) {
+        _bcMembershipListeners.add(bcml);
+    }
+
+    /**
+     * Removes the specified <code>BeanContextMembershipListener</code>
+     * so that it no longer receives <code>BeanContextMembershipEvent</code>s
+     * when the child <code>Component</code>(s) are added or removed.
+     *
+     * @param bcml the <code>BeanContextMembershipListener</code>
+     *             to be removed
+     */
+    public void removeBeanContextMembershipListener(BeanContextMembershipListener bcml) {
+        _bcMembershipListeners.remove(bcml);
+    }
+
+    /**
+     * Returns the number of elements in this collection.  If this collection
+     * contains more than <tt>Integer.MAX_VALUE</tt> elements, returns
+     * <tt>Integer.MAX_VALUE</tt>.
+     *
+     * @return the number of elements in this collection
+     */
+    public int size() {
+        return _children.size();
+    }
+
+    /**
+     * Returns <tt>true</tt> if this collection contains no elements.
+     *
+     * @return <tt>true</tt> if this collection contains no elements
+     */
+    public boolean isEmpty() {
+        return _children.isEmpty();
+    }
+
+    /**
+     * Returns <tt>true</tt> if this collection contains the specified
+     * element.  More formally, returns <tt>true</tt> if and only if this
+     * collection contains at least one element <tt>e</tt> such that
+     * <tt>(o==null ? e==null : o.equals(e))</tt>.
+     *
+     * @param o element whose presence in this collection is to be tested.
+     * @return <tt>true</tt> if this collection contains the specified
+     *         element
+     * @throws ClassCastException   if the type of the specified element
+     *                              is incompatible with this collection (optional).
+     * @throws NullPointerException if the specified element is null and this
+     *                              collection does not support null elements (optional).
+     */
+    public boolean contains(Object o) {
+        return _children.contains(o);
+    }
+
+    /**
+     * Returns an iterator over the elements in this collection.  There are no
+     * guarantees concerning the order in which the elements are returned
+     * (unless this collection is an instance of some class that provides a
+     * guarantee).
+     *
+     * @return an <tt>Iterator</tt> over the elements in this collection
+     */
+    public Iterator iterator() {
+        return Collections.unmodifiableList(_children).iterator();
+    }
+
+    /**
+     * Returns an array containing all of the elements in this collection.  If
+     * the collection makes any guarantees as to what order its elements are
+     * returned by its iterator, this method must return the elements in the
+     * same order.<p>
+     * <p/>
+     * The returned array will be "safe" in that no references to it are
+     * maintained by this collection.  (In other words, this method must
+     * allocate a new array even if this collection is backed by an array).
+     * The caller is thus free to modify the returned array.<p>
+     * <p/>
+     * This method acts as bridge between array-based and collection-based
+     * APIs.
+     *
+     * @return an array containing all of the elements in this collection
+     */
+    public Object[] toArray() {
+        return _children.toArray();
+    }
+
+    /**
+     * Ensures that this collection contains the specified element (optional
+     * operation).  Returns <tt>true</tt> if this collection changed as a
+     * result of the call.  (Returns <tt>false</tt> if this collection does
+     * not permit duplicates and already contains the specified element.)<p>
+     * <p/>
+     * Collections that support this operation may place limitations on what
+     * elements may be added to this collection.  In particular, some
+     * collections will refuse to add <tt>null</tt> elements, and others will
+     * impose restrictions on the type of elements that may be added.
+     * Collection classes should clearly specify in their documentation any
+     * restrictions on what elements may be added.<p>
+     * <p/>
+     * If a collection refuses to add a particular element for any reason
+     * other than that it already contains the element, it <i>must</i> throw
+     * an exception (rather than returning <tt>false</tt>).  This preserves
+     * the invariant that a collection always contains the specified element
+     * after this call returns.
+     *
+     * @param o element whose presence in this collection is to be ensured.
+     * @return <tt>true</tt> if this collection changed as a result of the
+     *         call
+     * @throws UnsupportedOperationException <tt>add</tt> is not supported by
+     *                                       this collection.
+     * @throws ClassCastException            class of the specified element prevents it
+     *                                       from being added to this collection.
+     * @throws NullPointerException          if the specified element is null and this
+     *                                       collection does not support null elements.
+     * @throws IllegalArgumentException      some aspect of this element prevents
+     *                                       it from being added to this collection.
+     */
+    public boolean add(Object o) {
+
+        if (contains(o)) return false;
+
+        // todo: for multithreaded usage this block needs to be synchronized
+        // spec says if the object being added implements BeanContextChild or BeanContextProxy
+        // need to set the bean context of the object to this bean context.
+        BeanContextChild bcc = null;
+        if (o instanceof BeanContextProxy) {
+            bcc = ((BeanContextProxy) o).getBeanContextProxy();
+        }
+        else if (o instanceof BeanContextChild) {
+            bcc = (BeanContextChild) o;
+        }
+
+        if (bcc != null) {
+            try {
+                bcc.setBeanContext(this);
+            }
+            catch (PropertyVetoException e) {
+                throw new IllegalStateException(e);
+            }
+
+            bcc.addPropertyChangeListener("beanContext", this);
+            bcc.addVetoableChangeListener("beanContext", this);
+        }
+
+        if (o instanceof Visibility) {
+            if (_mayUseGui) {
+                ((Visibility) o).okToUseGui();
+            }
+            else {
+                ((Visibility) o).dontUseGui();
+            }
+        }
+
+        if (o instanceof BeanContextMembershipListener) {
+            addBeanContextMembershipListener((BeanContextMembershipListener) o);
+        }
+
+        _children.add(o);
+
+        BeanContextMembershipEvent bcme = new BeanContextMembershipEvent(this, new Object[]{o});
+        fireMembershipEvent(bcme, true);
+//        }
+        return true;
+    }
+
+    /**
+     * Removes a single instance of the specified element from this
+     * collection, if it is present (optional operation).  More formally,
+     * removes an element <tt>e</tt> such that <tt>(o==null ?  e==null :
+     * o.equals(e))</tt>, if this collection contains one or more such
+     * elements.  Returns true if this collection contained the specified
+     * element (or equivalently, if this collection changed as a result of the
+     * call).
+     *
+     * @param o element to be removed from this collection, if present.
+     * @return <tt>true</tt> if this collection changed as a result of the
+     *         call
+     * @throws ClassCastException            if the type of the specified element
+     *                                       is incompatible with this collection (optional).
+     * @throws NullPointerException          if the specified element is null and this
+     *                                       collection does not support null elements (optional).
+     * @throws UnsupportedOperationException remove is not supported by this
+     *                                       collection.
+     */
+    public boolean remove(Object o) {
+        return internalRemove(o, true);
+    }
+
+    /**
+     * Adds all of the elements in the specified collection to this collection
+     * (optional operation).  The behavior of this operation is undefined if
+     * the specified collection is modified while the operation is in progress.
+     * (This implies that the behavior of this call is undefined if the
+     * specified collection is this collection, and this collection is
+     * nonempty.)
+     *
+     * @param c elements to be inserted into this collection.
+     * @return <tt>true</tt> if this collection changed as a result of the
+     *         call
+     * @throws UnsupportedOperationException if this collection does not
+     *                                       support the <tt>addAll</tt> method.
+     * @throws ClassCastException            if the class of an element of the specified
+     *                                       collection prevents it from being added to this collection.
+     * @throws NullPointerException          if the specified collection contains one
+     *                                       or more null elements and this collection does not support null
+     *                                       elements, or if the specified collection is <tt>null</tt>.
+     * @throws IllegalArgumentException      some aspect of an element of the
+     *                                       specified collection prevents it from being added to this
+     *                                       collection.
+     * @see #add(Object)
+     */
+    public boolean addAll(Collection c) {
+        // NOOP : Not Supported
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Removes all of the elements from this collection (optional operation).
+     * This collection will be empty after this method returns unless it
+     * throws an exception.
+     *
+     * @throws UnsupportedOperationException if the <tt>clear</tt> method is
+     *                                       not supported by this collection.
+     */
+    public void clear() {
+        // NOOP: Not supported
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Retains only the elements in this collection that are contained in the
+     * specified collection (optional operation).  In other words, removes from
+     * this collection all of its elements that are not contained in the
+     * specified collection.
+     *
+     * @param c elements to be retained in this collection.
+     * @return <tt>true</tt> if this collection changed as a result of the
+     *         call
+     * @throws UnsupportedOperationException if the <tt>retainAll</tt> method
+     *                                       is not supported by this Collection.
+     * @throws ClassCastException            if the types of one or more elements
+     *                                       in this collection are incompatible with the specified
+     *                                       collection (optional).
+     * @throws NullPointerException          if this collection contains one or more
+     *                                       null elements and the specified collection does not support null
+     *                                       elements (optional).
+     * @throws NullPointerException          if the specified collection is
+     *                                       <tt>null</tt>.
+     * @see #remove(Object)
+     * @see #contains(Object)
+     */
+    public boolean retainAll(Collection c) {
+        // NOOP: Not supported
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Removes all this collection's elements that are also contained in the
+     * specified collection (optional operation).  After this call returns,
+     * this collection will contain no elements in common with the specified
+     * collection.
+     *
+     * @param c elements to be removed from this collection.
+     * @return <tt>true</tt> if this collection changed as a result of the
+     *         call
+     * @throws UnsupportedOperationException if the <tt>removeAll</tt> method
+     *                                       is not supported by this collection.
+     * @throws ClassCastException            if the types of one or more elements
+     *                                       in this collection are incompatible with the specified
+     *                                       collection (optional).
+     * @throws NullPointerException          if this collection contains one or more
+     *                                       null elements and the specified collection does not support
+     *                                       null elements (optional).
+     * @throws NullPointerException          if the specified collection is
+     *                                       <tt>null</tt>.
+     * @see #remove(Object)
+     * @see #contains(Object)
+     */
+    public boolean removeAll(Collection c) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Returns <tt>true</tt> if this collection contains all of the elements
+     * in the specified collection.
+     *
+     * @param c collection to be checked for containment in this collection.
+     * @return <tt>true</tt> if this collection contains all of the elements
+     *         in the specified collection
+     * @throws ClassCastException   if the types of one or more elements
+     *                              in the specified collection are incompatible with this
+     *                              collection (optional).
+     * @throws NullPointerException if the specified collection contains one
+     *                              or more null elements and this collection does not support null
+     *                              elements (optional).
+     * @throws NullPointerException if the specified collection is
+     *                              <tt>null</tt>.
+     * @see #contains(Object)
+     */
+    public boolean containsAll(Collection c) {
+        return _children.containsAll(c);
+    }
+
+    /**
+     * Returns an array containing all of the elements in this collection;
+     * the runtime type of the returned array is that of the specified array.
+     * If the collection fits in the specified array, it is returned therein.
+     * Otherwise, a new array is allocated with the runtime type of the
+     * specified array and the size of this collection.<p>
+     * <p/>
+     * If this collection fits in the specified array with room to spare
+     * (i.e., the array has more elements than this collection), the element
+     * in the array immediately following the end of the collection is set to
+     * <tt>null</tt>.  This is useful in determining the length of this
+     * collection <i>only</i> if the caller knows that this collection does
+     * not contain any <tt>null</tt> elements.)<p>
+     * <p/>
+     * If this collection makes any guarantees as to what order its elements
+     * are returned by its iterator, this method must return the elements in
+     * the same order.<p>
+     * <p/>
+     * Like the <tt>toArray</tt> method, this method acts as bridge between
+     * array-based and collection-based APIs.  Further, this method allows
+     * precise control over the runtime type of the output array, and may,
+     * under certain circumstances, be used to save allocation costs<p>
+     * <p/>
+     * Suppose <tt>l</tt> is a <tt>List</tt> known to contain only strings.
+     * The following code can be used to dump the list into a newly allocated
+     * array of <tt>String</tt>:
+     * <p/>
+     * <pre>
+     *     String[] x = (String[]) v.toArray(new String[0]);
+     * </pre><p>
+     * <p/>
+     * Note that <tt>toArray(new Object[0])</tt> is identical in function to
+     * <tt>toArray()</tt>.
+     *
+     * @param a the array into which the elements of this collection are to be
+     *          stored, if it is big enough; otherwise, a new array of the same
+     *          runtime type is allocated for this purpose.
+     * @return an array containing the elements of this collection
+     * @throws ArrayStoreException  the runtime type of the specified array is
+     *                              not a supertype of the runtime type of every element in this
+     *                              collection.
+     * @throws NullPointerException if the specified array is <tt>null</tt>.
+     */
+    public Object[] toArray(Object[] a) {
+        return _children.toArray(a);
+    }
+
+    /**
+     * Sets the "value" of the "designTime" property.
+     * <p/>
+     * If the implementing object is an instance of java.beans.beancontext.BeanContext,
+     * or a subinterface thereof, then that BeanContext should fire a
+     * PropertyChangeEvent, to its registered BeanContextMembershipListeners, with
+     * parameters:
+     * <ul>
+     * <li><code>propertyName</code> - <code>java.beans.DesignMode.PROPERTYNAME</code>
+     * <li><code>oldValue</code> - previous value of "designTime"
+     * <li><code>newValue</code> - current value of "designTime"
+     * </ul>
+     * Note it is illegal for a BeanContextChild to invoke this method
+     * associated with a BeanContext that it is nested within.
+     *
+     * @param designTime the current "value" of the "designTime" property
+     * @see java.beans.beancontext.BeanContext
+     * @see java.beans.beancontext.BeanContextMembershipListener
+     * @see java.beans.PropertyChangeEvent
+     */
+    public void setDesignTime(boolean designTime) {
+        if (designTime == _designTime) return;
+        _designTime = designTime;
+        firePropertyChange("designTime", !_designTime, designTime);
+    }
+
+    /**
+     * A value of true denotes that JavaBeans should behave in design time
+     * mode, a value of false denotes runtime behavior.
+     *
+     * @return the current "value" of the "designTime" property.
+     */
+
+    public boolean isDesignTime() {
+        return _designTime;
+    }
+
+    /**
+     * Determines whether this bean needs a GUI.
+     *
+     * @return True if the bean absolutely needs a GUI available in
+     *         order to get its work done.
+     */
+    public boolean needsGui() {
+        BeanContextChild bcc = getBCCDelegate();
+        if (bcc != this && bcc instanceof Visibility) {
+            return ((Visibility) bcc).needsGui();
+        }
+
+        // check children
+        for (Object o : _children) {
+            if (o instanceof Visibility) {
+                if (((Visibility) o).needsGui()) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * This method instructs the bean that it should not use the Gui.
+     */
+    public void dontUseGui() {
+        if (!_mayUseGui) return;
+
+        _mayUseGui = false;
+
+        for (Object o : _children) {
+            if (o instanceof Visibility) {
+                ((Visibility) o).dontUseGui();
+            }
+        }
+    }
+
+    /**
+     * This method instructs the bean that it is OK to use the Gui.
+     */
+    public void okToUseGui() {
+        if (_mayUseGui) return;
+
+        _mayUseGui = true;
+
+        for (Object o : _children) {
+            if (o instanceof Visibility) {
+                ((Visibility) o).okToUseGui();
+            }
+        }
+    }
+
+    /**
+     * Determines whether this bean is avoiding using a GUI.
+     *
+     * @return true if the bean is currently avoiding use of the Gui.
+     *         e.g. due to a call on dontUseGui().
+     */
+    public boolean avoidingGui() {
+        return !_mayUseGui && needsGui();
+    }
+
+    /**
+     * This method gets called when a bound property is changed.
+     *
+     * @param evt A PropertyChangeEvent object describing the event source
+     *            and the property that has changed.
+     */
+    public void propertyChange(PropertyChangeEvent evt) {
+        // monitor "beanContext" property
+        if ("beanContext".equals(evt.getPropertyName()) && contains(evt.getSource())) {
+            BeanContext bc = (BeanContext) getBCCDelegate();
+            if (bc.equals(evt.getOldValue()) && !bc.equals(evt.getNewValue())) {
+                internalRemove(evt.getSource(), false);
+            }
+        }
+    }
+
+    /**
+     * This method gets called when a constrained property is changed.
+     *
+     * @param evt a <code>PropertyChangeEvent</code> object describing the
+     *            event source and the property that has changed.
+     * @throws java.beans.PropertyVetoException
+     *          if the recipient wishes the property
+     *          change to be rolled back.
+     */
+    public void vetoableChange(PropertyChangeEvent evt) throws PropertyVetoException {
+        // monitor "beanContext" property
+        if ("beanContext".equals(evt.getPropertyName())
+                && contains(evt.getOldValue())) {
+            // noop: at this point doesn't veto
+        }
+    }
+
+    /**
+     * *************************************************************************************
+     */
+
+
+    /**
+     * Init this classes data structures.
+     */
+    protected void init() {
+        _bcMembershipListeners = new HashSet<BeanContextMembershipListener>();
+        _children = Collections.synchronizedList(new ArrayList<Object>());
+    }
+
+    /**
+     * Fire a BeanContextMembershipEvent.
+     *
+     * @param bcme          Event to fire.
+     * @param childrenAdded True if add event, false if remove event.
+     */
+    private void fireMembershipEvent(BeanContextMembershipEvent bcme, boolean childrenAdded) {
+
+        for (BeanContextMembershipListener bcml : _bcMembershipListeners) {
+            if (childrenAdded) {
+                bcml.childrenAdded(bcme);
+            }
+            else {
+                bcml.childrenRemoved(bcme);
+            }
+        }
+    }
+
+    /**
+     * There are two ways a object can be removed from a BeanContext, by either explicitly invoking the
+     * remove() api or if the child implements BeanContextChild by calling its setBeanContext() api.
+     *
+     * @param o
+     * @param publicApi
+     * @return true if successful
+     */
+    private boolean internalRemove(Object o, boolean publicApi) {
+
+        if (!contains(o)) return false;
+
+        // todo: for multithreaded usage this block needs to be synchronized
+        BeanContextChild bcc = null;
+        if (o instanceof BeanContextProxy) {
+            bcc = ((BeanContextProxy) o).getBeanContextProxy();
+        }
+        else if (o instanceof BeanContextChild) {
+            bcc = (BeanContextChild) o;
+        }
+
+        if (bcc != null) {
+
+            /*
+             If remove invoked as a result of the BeanContext receiving an unexpected PropertyChangeEvent
+             notification as a result of a 3rd party invoking setBeanContext() then the remove implementation
+             shall not invoke setBeanContext(null) on that child as part of the remove() semantics, since
+             doing so would overwrite the value previously set by the 3rd party.
+            */
+            if (publicApi) {
+
+                // remove the property/veto listeners -- we know we want to remove the bean
+                // and don't need to be notified if we have initiated the removal
+                bcc.removePropertyChangeListener("beanContext", this);
+                bcc.removeVetoableChangeListener("beanContext", this);
+
+                try {
+                    bcc.setBeanContext(null);
+                }
+                catch (PropertyVetoException e) {
+                    // rewire the listeners we removed above then except
+                    bcc.addPropertyChangeListener("beanContext", this);
+                    bcc.addVetoableChangeListener("beanContext", this);
+                    throw new IllegalStateException(e);
+                }
+            }
+        }
+
+        if (o instanceof BeanContextMembershipListener) {
+            removeBeanContextMembershipListener((BeanContextMembershipListener) o);
+        }
+
+        _children.remove(o);
+
+        BeanContextMembershipEvent bcme = new BeanContextMembershipEvent(this, new Object[]{o});
+        fireMembershipEvent(bcme, false);
+        // end synchronized block
+        return true;
+    }
+
+    /**
+     * Serialization support.
+     *
+     * @param out
+     */
+    private synchronized void writeObject(ObjectOutputStream out) throws IOException {
+
+        // todo: for multithreaded usage this block needs to be synchronized
+        out.defaultWriteObject();
+
+        // spec: only write children if not using a delegate
+        int serializable = 0;
+        for (Object child : _children) {
+            if (child instanceof Serializable) serializable++;
+        }
+
+        out.writeInt(serializable);
+        if (this.equals(getBCCDelegate())) {
+            for (Object child : _children) {
+                if (child instanceof Serializable) {
+                    out.writeObject(child);
+                }
+            }
+        }
+
+        // write event handlers
+        serializable = 0;
+        for (BeanContextMembershipListener listener : _bcMembershipListeners) {
+            if (listener instanceof Serializable) serializable++;
+        }
+
+        out.writeInt(serializable);
+        for (BeanContextMembershipListener listener : _bcMembershipListeners) {
+            if (listener instanceof Serializable) {
+                out.writeObject(listener);
+            }
+        }
+        // end synchronized block
+    }
+
+    /**
+     * Deserialization support.
+     *
+     * @param in
+     * @throws IOException
+     * @throws ClassNotFoundException
+     */
+    private synchronized void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
+
+        // todo: for multithreaded usage this block needs to be synchronized
+        in.defaultReadObject();
+        init();
+
+        int childCount = in.readInt();
+        for (int i = 0; i < childCount; i++) {
+            try {
+                add(in.readObject());
+            }
+            catch (Exception e) {
+                // noop
+            }
+        }
+
+        int listenerCount = in.readInt();
+        for (int i = 0; i < listenerCount; i++) {
+            addBeanContextMembershipListener((BeanContextMembershipListener) in.readObject());
+        }
+        // end synchronized block
+    }
+}

Propchange: beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/webcontext/ControlBeanContextSupport.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/webcontext/ControlBeanContextSupport.java
------------------------------------------------------------------------------
    svn:executable = *

Modified: beehive/trunk/controls/test/build.xml
URL: http://svn.apache.org/viewcvs/beehive/trunk/controls/test/build.xml?rev=396962&r1=396961&r2=396962&view=diff
==============================================================================
--- beehive/trunk/controls/test/build.xml (original)
+++ beehive/trunk/controls/test/build.xml Tue Apr 25 12:37:54 2006
@@ -519,6 +519,13 @@
                         destdir="${build.dir}/junit-controls-classes"
                         tempdir="${build.dir}/junit-controls-beansrc"
                         classpathref="test-junit.dependency.path"/>
+
+        <copy todir="${build.dir}/junit-controls-classes">
+            <fileset dir="src/junit-controls">
+                <include name="**/*.txt"/>
+            </fileset>
+        </copy>
+
         <control-jar destfile="${build.dir}/beehive-controls-junit-tests.jar"  basedir="${build.dir}/junit-controls-classes"/>
 
         <path id="_test.classpath">

Added: beehive/trunk/controls/test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontext/BeanContextProxyImpl.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/controls/test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontext/BeanContextProxyImpl.java?rev=396962&view=auto
==============================================================================
--- beehive/trunk/controls/test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontext/BeanContextProxyImpl.java (added)
+++ beehive/trunk/controls/test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontext/BeanContextProxyImpl.java Tue Apr 25 12:37:54 2006
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * $Header:$
+ */
+
+package org.apache.beehive.controls.test.controls.beancontext;
+
+import java.beans.beancontext.BeanContextProxy;
+import java.beans.beancontext.BeanContextChild;
+
+/**
+ */
+public class BeanContextProxyImpl implements BeanContextProxy {
+
+    private BeanContextChild _bcc;
+
+    public BeanContextProxyImpl(BeanContextChild bcc) {
+        _bcc = bcc;
+    }
+
+    public BeanContextChild getBeanContextProxy()
+    {
+        return _bcc;
+    }
+}

Propchange: beehive/trunk/controls/test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontext/BeanContextProxyImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: beehive/trunk/controls/test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontext/BeanContextProxyImpl.java
------------------------------------------------------------------------------
    svn:executable = *

Added: beehive/trunk/controls/test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontext/MembershipListener.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/controls/test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontext/MembershipListener.java?rev=396962&view=auto
==============================================================================
--- beehive/trunk/controls/test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontext/MembershipListener.java (added)
+++ beehive/trunk/controls/test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontext/MembershipListener.java Tue Apr 25 12:37:54 2006
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * $Header:$
+ */
+
+package org.apache.beehive.controls.test.controls.beancontext;
+
+import java.beans.PropertyChangeListener;
+import java.beans.VetoableChangeListener;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyVetoException;
+import java.beans.beancontext.BeanContextMembershipListener;
+import java.beans.beancontext.BeanContextMembershipEvent;
+import java.util.LinkedList;
+import java.io.Serializable;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: cschoett
+ * Date: Apr 13, 2006
+ * Time: 9:25:47 AM
+ * To change this template use File | Settings | File Templates.
+ */
+public class MembershipListener implements BeanContextMembershipListener, Serializable {
+
+    private LinkedList<BeanContextMembershipEvent> _recordedEvents;
+
+    public MembershipListener() {
+        _recordedEvents = new LinkedList<BeanContextMembershipEvent>();
+    }
+
+
+    public BeanContextMembershipEvent[] getEvents() {
+        BeanContextMembershipEvent[] result = new BeanContextMembershipEvent[_recordedEvents.size()];
+        return _recordedEvents.toArray(result);
+    }
+
+    public void reset() {
+        _recordedEvents.clear();
+    }
+
+    /**
+     * Called when a child or list of children is added to a
+     * <code>BeanContext</code> that this listener is registered with.
+     *
+     * @param bcme The <code>BeanContextMembershipEvent</code>
+     *             describing the change that occurred.
+     */
+    public void childrenAdded(BeanContextMembershipEvent bcme)
+    {
+        _recordedEvents.add(bcme);
+    }
+
+    /**
+     * Called when a child or list of children is removed
+     * from a <code>BeanContext</code> that this listener
+     * is registered with.
+     *
+     * @param bcme The <code>BeanContextMembershipEvent</code>
+     *             describing the change that occurred.
+     */
+    public void childrenRemoved(BeanContextMembershipEvent bcme)
+    {
+        _recordedEvents.add(bcme);
+    }
+}

Propchange: beehive/trunk/controls/test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontext/MembershipListener.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: beehive/trunk/controls/test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontext/MembershipListener.java
------------------------------------------------------------------------------
    svn:executable = *

Added: beehive/trunk/controls/test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontext/Resource.txt
URL: http://svn.apache.org/viewcvs/beehive/trunk/controls/test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontext/Resource.txt?rev=396962&view=auto
==============================================================================
--- beehive/trunk/controls/test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontext/Resource.txt (added)
+++ beehive/trunk/controls/test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontext/Resource.txt Tue Apr 25 12:37:54 2006
@@ -0,0 +1,2 @@
+This is a text resource file used for junit testing of the ControlBeanContextSupport class.
+xxx
\ No newline at end of file

Propchange: beehive/trunk/controls/test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontext/Resource.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Added: beehive/trunk/controls/test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontext/VisibilityImpl.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/controls/test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontext/VisibilityImpl.java?rev=396962&view=auto
==============================================================================
--- beehive/trunk/controls/test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontext/VisibilityImpl.java (added)
+++ beehive/trunk/controls/test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontext/VisibilityImpl.java Tue Apr 25 12:37:54 2006
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * $Header:$
+ */
+
+package org.apache.beehive.controls.test.controls.beancontext;
+
+import java.beans.Visibility;
+
+/**
+ */
+public class VisibilityImpl implements Visibility {
+
+    private boolean _canUseGui = false;
+    private boolean _needsGui = false;
+
+    public boolean needsGui() {
+        return _needsGui;
+    }
+
+    public void dontUseGui() {
+        _canUseGui = false;
+    }
+
+    public void okToUseGui() {
+        _canUseGui = true;
+    }
+
+    public boolean avoidingGui() {
+        return _needsGui && !_canUseGui;
+    }
+
+    public boolean getCanUseGui() {
+        return _canUseGui;
+    }
+
+    public void setNeedsGui(boolean needsGui) {
+        _needsGui = needsGui;
+    }
+}

Propchange: beehive/trunk/controls/test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontext/VisibilityImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: beehive/trunk/controls/test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontextchild/AlwaysVetoListener.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/controls/test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontextchild/AlwaysVetoListener.java?rev=396962&view=auto
==============================================================================
--- beehive/trunk/controls/test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontextchild/AlwaysVetoListener.java (added)
+++ beehive/trunk/controls/test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontextchild/AlwaysVetoListener.java Tue Apr 25 12:37:54 2006
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * $Header:$
+ */
+
+package org.apache.beehive.controls.test.controls.beancontextchild;
+
+import java.beans.VetoableChangeListener;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyVetoException;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: cschoett
+ * Date: Apr 13, 2006
+ * Time: 9:25:47 AM
+ * To change this template use File | Settings | File Templates.
+ */
+public class AlwaysVetoListener implements VetoableChangeListener {
+
+    public AlwaysVetoListener() { super(); }
+
+    /**
+     * This method gets called when a constrained property is changed.
+     *
+     * @param evt a <code>PropertyChangeEvent</code> object describing the
+     *            event source and the property that has changed.
+     * @throws java.beans.PropertyVetoException
+     *          if the recipient wishes the property
+     *          change to be rolled back.
+     */
+    public void vetoableChange(PropertyChangeEvent evt) throws PropertyVetoException {
+        throw new PropertyVetoException("VETO'd by: " + this, evt);
+    }
+}

Propchange: beehive/trunk/controls/test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontextchild/AlwaysVetoListener.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: beehive/trunk/controls/test/src/junit-controls/org/apache/beehive/controls/test/controls/beancontextchild/AlwaysVetoListener.java
------------------------------------------------------------------------------
    svn:executable = *