1. /*
  2. * @(#)BeanContextChildSupport.java 1.5 01/11/29
  3. *
  4. * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.beans.beancontext;
  8. import java.beans.PropertyChangeEvent;
  9. import java.beans.PropertyChangeListener;
  10. import java.beans.PropertyChangeSupport;
  11. import java.beans.VetoableChangeListener;
  12. import java.beans.VetoableChangeSupport;
  13. import java.beans.PropertyVetoException;
  14. import java.io.IOException;
  15. import java.io.ObjectInputStream;
  16. import java.io.ObjectOutputStream;
  17. import java.io.Serializable;
  18. /**
  19. * <p>
  20. * This is a general support class to provide support for implementing the
  21. * BeanContextChild protocol.
  22. *
  23. * This class may either be directly subclassed, or encapsulated and delegated
  24. * to in order to implement this interface for a given component.
  25. * </p>
  26. *
  27. * @author Laurence P. G. Cable
  28. * @version 1.5
  29. * @since JDK1.2
  30. *
  31. * @seealso java.beans.beancontext.BeanContext
  32. * @seealso java.beans.beancontext.BeanContextServices
  33. * @seealso java.beans.beancontext.BeanContextChild
  34. */
  35. public class BeanContextChildSupport implements BeanContextChild, BeanContextServicesListener, Serializable {
  36. static final long serialVersionUID = 6328947014421475877L;
  37. /**
  38. * construct a BeanContextChildSupport where this class has been
  39. * subclassed in order to implement the JavaBean component itself.
  40. */
  41. public BeanContextChildSupport() {
  42. super();
  43. beanContextChildPeer = this;
  44. pcSupport = new PropertyChangeSupport(beanContextChildPeer);
  45. vcSupport = new VetoableChangeSupport(beanContextChildPeer);
  46. }
  47. /**
  48. * construct a BeanContextChildSupport where the JavaBean component
  49. * itself implements BeanContextChild, and encapsulates this, delegating
  50. * that interface to this implementation
  51. */
  52. public BeanContextChildSupport(BeanContextChild bcc) {
  53. super();
  54. beanContextChildPeer = (bcc != null) ? bcc : this;
  55. pcSupport = new PropertyChangeSupport(beanContextChildPeer);
  56. vcSupport = new VetoableChangeSupport(beanContextChildPeer);
  57. }
  58. /**
  59. * setBeanContext
  60. */
  61. public synchronized void setBeanContext(BeanContext bc) throws PropertyVetoException {
  62. if (bc == beanContext) return;
  63. BeanContext oldValue = beanContext;
  64. BeanContext newValue = bc;
  65. if (!rejectedSetBCOnce) {
  66. if (rejectedSetBCOnce = !validatePendingSetBeanContext(bc)) {
  67. throw new PropertyVetoException(
  68. "setBeanContext() change rejected:",
  69. new PropertyChangeEvent(beanContextChildPeer, "beanContext", oldValue, newValue)
  70. );
  71. }
  72. try {
  73. fireVetoableChange("beanContext",
  74. oldValue,
  75. newValue
  76. );
  77. } catch (PropertyVetoException pve) {
  78. rejectedSetBCOnce = true;
  79. throw pve; // re-throw
  80. }
  81. }
  82. if (beanContext != null) releaseBeanContextResources();
  83. beanContext = newValue;
  84. rejectedSetBCOnce = false;
  85. firePropertyChange("beanContext",
  86. oldValue,
  87. newValue
  88. );
  89. if (beanContext != null) initializeBeanContextResources();
  90. }
  91. /**
  92. * @returns the current BeanContext associated with the JavaBean
  93. */
  94. public synchronized BeanContext getBeanContext() { return beanContext; }
  95. /**
  96. * add a property change listener
  97. */
  98. public void addPropertyChangeListener(String name, PropertyChangeListener pcl) {
  99. pcSupport.addPropertyChangeListener(name, pcl);
  100. }
  101. /**
  102. * remove a property change listener
  103. */
  104. public void removePropertyChangeListener(String name, PropertyChangeListener pcl) {
  105. pcSupport.removePropertyChangeListener(name, pcl);
  106. }
  107. /**
  108. * add a vetoable change listener
  109. */
  110. public void addVetoableChangeListener(String name, VetoableChangeListener vcl) {
  111. vcSupport.addVetoableChangeListener(name, vcl);
  112. }
  113. /**
  114. * remove a vetoable change listener
  115. */
  116. public void removeVetoableChangeListener(String name, VetoableChangeListener vcl) {
  117. vcSupport.removeVetoableChangeListener(name, vcl);
  118. }
  119. /**
  120. * a service provided by the nesting BeanContext has been revoked.
  121. *
  122. * subclasses may override this method in order to implement their own
  123. * behaviors
  124. */
  125. public void serviceRevoked(BeanContextServiceRevokedEvent bcsre) { }
  126. /**
  127. * a new service is available from the nesting BeanContext.
  128. *
  129. * subclasses may override this method in order to implement their own
  130. * behaviors
  131. */
  132. public void serviceAvailable(BeanContextServiceAvailableEvent bcsae) { }
  133. /**
  134. * @return the BeanContextChild peer of this class
  135. */
  136. public BeanContextChild getBeanContextChildPeer() { return beanContextChildPeer; }
  137. /**
  138. * @return true if this class is a delegate of another
  139. */
  140. public boolean isDelegated() { return !this.equals(beanContextChildPeer); }
  141. /**
  142. * fires a propertyChange Event
  143. */
  144. public void firePropertyChange(String name, Object oldValue, Object newValue) {
  145. pcSupport.firePropertyChange(name, oldValue, newValue);
  146. }
  147. /**
  148. * fires a vetoableChange Event
  149. */
  150. public void fireVetoableChange(String name, Object oldValue, Object newValue) throws PropertyVetoException {
  151. vcSupport.fireVetoableChange(name, oldValue, newValue);
  152. }
  153. /**
  154. * called from setBeanContext to validate (or otherwise) the
  155. * pending change in the nesting BeanContext property value.
  156. *
  157. * returning false will cause setBeanContext to throw
  158. * PropertyVetoException.
  159. */
  160. public boolean validatePendingSetBeanContext(BeanContext newValue) {
  161. return true;
  162. }
  163. /**
  164. * This method may be overridden by subclasses to provide their own
  165. * release behaviors. When invoked any resources held by this instance
  166. * obtained from its current BeanContext property should be released
  167. * since the object is no longer nested within that BeanContext.
  168. */
  169. protected void releaseBeanContextResources() {
  170. // do nothing
  171. }
  172. /**
  173. * This method may be overridden by subclasses to provide their own
  174. * initialization behaviors. When invoked any resources requried by the
  175. * BeanContextChild should be obtained from the current BeanContext.
  176. */
  177. protected void initializeBeanContextResources() {
  178. // do nothing
  179. }
  180. /**
  181. * Write the persistence state of the object.
  182. */
  183. private void writeObject(ObjectOutputStream oos) throws IOException {
  184. /*
  185. * dont serialize if we are delegated and the delegator isnt also
  186. * serializable.
  187. */
  188. if (!equals(beanContextChildPeer) && !(beanContextChildPeer instanceof Serializable))
  189. throw new IOException("BeanContextChildSupport beanContextChildPeer not Serializable");
  190. else
  191. oos.defaultWriteObject();
  192. }
  193. /**
  194. * Restore a persistent object, must wait for subsequent setBeanContext()
  195. * to fully restore any resources obtained from the new nesting
  196. * BeanContext
  197. */
  198. private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
  199. ois.defaultReadObject();
  200. }
  201. /*
  202. * fields
  203. */
  204. public BeanContextChild beanContextChildPeer;
  205. protected PropertyChangeSupport pcSupport;
  206. protected VetoableChangeSupport vcSupport;
  207. protected transient BeanContext beanContext;
  208. protected transient boolean rejectedSetBCOnce;
  209. }