BeanContextChildSupport.java 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. /* java.beans.beancontext.BeanContextChildSupport
  2. Copyright (C) 1999 Free Software Foundation, Inc.
  3. This file is part of GNU Classpath.
  4. GNU Classpath is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2, or (at your option)
  7. any later version.
  8. GNU Classpath is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GNU Classpath; see the file COPYING. If not, write to the
  14. Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  15. 02110-1301 USA.
  16. Linking this library statically or dynamically with other modules is
  17. making a combined work based on this library. Thus, the terms and
  18. conditions of the GNU General Public License cover the whole
  19. combination.
  20. As a special exception, the copyright holders of this library give you
  21. permission to link this library with independent modules to produce an
  22. executable, regardless of the license terms of these independent
  23. modules, and to copy and distribute the resulting executable under
  24. terms of your choice, provided that you also meet, for each linked
  25. independent module, the terms and conditions of the license of that
  26. module. An independent module is a module which is not derived from
  27. or based on this library. If you modify this library, you may extend
  28. this exception to your version of the library, but you are not
  29. obligated to do so. If you do not wish to do so, delete this
  30. exception statement from your version. */
  31. package java.beans.beancontext;
  32. import java.beans.PropertyChangeEvent;
  33. import java.beans.PropertyChangeListener;
  34. import java.beans.PropertyChangeSupport;
  35. import java.beans.PropertyVetoException;
  36. import java.beans.VetoableChangeListener;
  37. import java.beans.VetoableChangeSupport;
  38. import java.io.Serializable;
  39. /**
  40. * Support for creating a <code>BeanContextChild</code>.
  41. * This class contains the most common implementations of the methods in
  42. * the <code>BeanContextChild</code>
  43. *
  44. * @specnote This class is not very well specified. I had to "fill in the
  45. * blanks" in most places with what I thought was reasonable
  46. * behavior. If there are problems, let me know.
  47. *
  48. * @author John Keiser
  49. * @since 1.2
  50. * @see java.beans.beancontext.BeanContextChild
  51. */
  52. public class BeanContextChildSupport
  53. implements BeanContextChild, BeanContextServicesListener, Serializable
  54. {
  55. static final long serialVersionUID = 6328947014421475877L;
  56. /**
  57. * The peer on which to perform <code>set</code> actions.
  58. * This is here so that this class can be used as a peer.
  59. * <P>
  60. *
  61. * When extending this class, this variable will be set to
  62. * <code>this</code>.
  63. */
  64. public BeanContextChild beanContextChildPeer;
  65. /**
  66. * The parent <code>BeanContext</code>.
  67. */
  68. protected transient BeanContext beanContext;
  69. /**
  70. * If <code>setBeanContext()</code> was vetoed once before, this
  71. * is set to <code>true</code> so that the next time, vetoes will
  72. * be ignored.
  73. */
  74. protected transient boolean rejectedSetBCOnce;
  75. /**
  76. * Listeners are registered here and events are fired through here.
  77. */
  78. protected PropertyChangeSupport pcSupport;
  79. /**
  80. * Listeners are registered here and events are fired through here.
  81. */
  82. protected VetoableChangeSupport vcSupport;
  83. /**
  84. * Create a new <code>BeanContextChildSupport</code> with itself as the peer.
  85. * This is meant to be used when you subclass
  86. * <code>BeanContextChildSupport</code> to create your child.
  87. */
  88. public BeanContextChildSupport()
  89. {
  90. this (null);
  91. }
  92. /**
  93. * Create a new <code>BeanContextChildSupport</code> with the specified peer.
  94. * @param peer the peer to use, or <code>null</code> to specify
  95. * <code>this</code>.
  96. */
  97. public BeanContextChildSupport (BeanContextChild peer)
  98. {
  99. if (peer == null)
  100. {
  101. peer = this;
  102. }
  103. beanContextChildPeer = peer;
  104. pcSupport = new PropertyChangeSupport (peer);
  105. vcSupport = new VetoableChangeSupport (peer);
  106. }
  107. /**
  108. * Set the parent <code>BeanContext</code>.
  109. * <P>
  110. *
  111. * When this Object is being added to a new BeanContext or moved
  112. * from an old one, a non-null value will be passed in.
  113. * <P>
  114. *
  115. * When this Object is being removed from the current
  116. * <code>BeanContext</code>, <code>setBeanContext()</code> will
  117. * receive the parameter <code>null</code>.
  118. * <P>
  119. *
  120. * Order of events:
  121. * <OL>
  122. * <LI>
  123. * If the new <code>BeanContext</code> is the same as the old
  124. * one, nothing happens.
  125. * </LI>
  126. * <LI>
  127. * If the change has not been rejected or vetoed before, call
  128. * <code>validatePendingSetBeanContext()</code>. If this call
  129. * returns <code>false</code>, the change is rejected and a
  130. * <code>PropertyVetoException</code> is thrown.
  131. * </LI>
  132. * <LI>
  133. * If the change has not been rejected or vetoed before,
  134. * <code>VetoableChangeEvent</code>s are fired with the name
  135. * <code>"beanContext"</code>, using the
  136. * <code>fireVetoableChange()</code> method. If a veto
  137. * occurs, reversion events are fired using the same method,
  138. * the change is rejected, and the veto is rethrown.
  139. * </LI>
  140. * <LI>
  141. * <code>releaseBeanContextResources()</code> is called.
  142. * </LI>
  143. * <LI>
  144. * The change is made.
  145. * </LI>
  146. * <LI>
  147. * <code>PropertyChangeEvent</code>s are fired using the
  148. * <code>firePropertyChange()</code> method.
  149. * </LI>
  150. * <LI>
  151. * <code>initializeBeanContextResources()</code> is called.
  152. * </LI>
  153. * </OL>
  154. * <P>
  155. *
  156. * @param newBeanContext the new parent for the
  157. * <code>BeanContextChild</code>, or <code>null</code> to
  158. * signify removal from a tree.
  159. * @exception PropertyVetoException if the
  160. * <code>BeanContextChild</code> implementor does not
  161. * wish to have its parent changed.
  162. */
  163. public void setBeanContext(BeanContext newBeanContext)
  164. throws PropertyVetoException
  165. {
  166. synchronized (beanContextChildPeer)
  167. {
  168. if (newBeanContext == beanContext)
  169. return;
  170. if (!rejectedSetBCOnce)
  171. {
  172. if (!validatePendingSetBeanContext (newBeanContext))
  173. {
  174. rejectedSetBCOnce = true;
  175. throw new PropertyVetoException ("validatePendingSetBeanContext() rejected change",
  176. new PropertyChangeEvent(beanContextChildPeer, "beanContext", beanContext, newBeanContext));
  177. }
  178. try
  179. {
  180. fireVetoableChange ("beanContext", beanContext, newBeanContext);
  181. }
  182. catch (PropertyVetoException e)
  183. {
  184. rejectedSetBCOnce = true;
  185. throw e;
  186. }
  187. }
  188. releaseBeanContextResources ();
  189. beanContext = newBeanContext;
  190. rejectedSetBCOnce = false;
  191. firePropertyChange ("beanContext", beanContext, newBeanContext);
  192. initializeBeanContextResources ();
  193. }
  194. }
  195. /**
  196. * Get the parent <code>BeanContext</code>.
  197. * @return the parent <code>BeanContext</code>.
  198. */
  199. public BeanContext getBeanContext()
  200. {
  201. return beanContext;
  202. }
  203. /**
  204. * Get the peer (or <code>this</code> if there is no peer).
  205. * @return the peer, or <code>this</code> if there is no peer.
  206. */
  207. public BeanContextChild getBeanContextChildPeer() {
  208. return beanContextChildPeer;
  209. }
  210. /**
  211. * Determine whether there is a peer.
  212. * This is true iff <code>getBeanContextChildPeer() == this</code>.
  213. * @return whether there is a peer.
  214. */
  215. public boolean isDelegated() {
  216. return beanContextChildPeer == this;
  217. }
  218. /**
  219. * Add a listener that will be notified when a specific property changes.
  220. * @param propertyName the name of the property to listen on.
  221. * @param listener the listener to listen on the property.
  222. */
  223. public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
  224. pcSupport.addPropertyChangeListener(propertyName, listener);
  225. }
  226. /**
  227. * Remove a listener to a certain property.
  228. *
  229. * @param propertyName the name of the property being listened on.
  230. * @param listener the listener listening on the property.
  231. */
  232. public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
  233. pcSupport.removePropertyChangeListener(propertyName, listener);
  234. }
  235. /**
  236. * Add a listener that will be notified when a specific property
  237. * change is requested (a PropertyVetoException may be thrown) as
  238. * well as after the change is successfully made.
  239. *
  240. * @param propertyName the name of the property to listen on.
  241. * @param listener the listener to listen on the property.
  242. */
  243. public void addVetoableChangeListener(String propertyName, VetoableChangeListener listener) {
  244. vcSupport.addVetoableChangeListener(propertyName, listener);
  245. }
  246. /**
  247. * Remove a listener to a certain property.
  248. *
  249. * @param propertyName the name of the property being listened on
  250. * @param listener the listener listening on the property.
  251. */
  252. public void removeVetoableChangeListener(String propertyName, VetoableChangeListener listener) {
  253. vcSupport.removeVetoableChangeListener(propertyName, listener);
  254. }
  255. /**
  256. * Fire a property change.
  257. *
  258. * @param propertyName the name of the property that changed
  259. * @param oldVal the old value of the property
  260. * @param newVal the new value of the property
  261. */
  262. public void firePropertyChange(String propertyName, Object oldVal, Object newVal) {
  263. pcSupport.firePropertyChange(propertyName, oldVal, newVal);
  264. }
  265. /**
  266. * Fire a vetoable property change.
  267. *
  268. * @param propertyName the name of the property that changed
  269. * @param oldVal the old value of the property
  270. * @param newVal the new value of the property
  271. * @exception PropertyVetoException if the change is vetoed.
  272. */
  273. public void fireVetoableChange(String propertyName, Object oldVal, Object newVal)
  274. throws PropertyVetoException {
  275. vcSupport.fireVetoableChange(propertyName, oldVal, newVal);
  276. }
  277. /**
  278. * Called by <code>BeanContextServices.revokeService()</code> to indicate that a service has been revoked.
  279. * If you have a reference to such a service, it should be
  280. * discarded and may no longer function properly.
  281. * <code>getService()</code> will no longer work on the specified
  282. * service class after this event has been fired.
  283. * <P>
  284. *
  285. * <EM>This method is meant to be overriden.</EM>
  286. * <code>BeanContextChildSupport</code>'s implementation does
  287. * nothing.
  288. *
  289. * @param event the service revoked event.
  290. * @see java.beans.beancontext.BeanContextServices#revokeService(java.lang.Class,java.beans.beancontext.BeanContextServiceProvider,boolean)
  291. */
  292. public void serviceRevoked(BeanContextServiceRevokedEvent event) {
  293. }
  294. /**
  295. * Called by <code>BeanContextServices</code> whenever a service is made available.
  296. * <P>
  297. *
  298. * <EM>This method is meant to be overriden.</EM>
  299. * <code>BeanContextChildSupport</code>'s implementation does
  300. * nothing.
  301. *
  302. * @param event the service revoked event, with useful information
  303. * about the new service.
  304. */
  305. public void serviceAvailable(BeanContextServiceAvailableEvent event) {
  306. }
  307. /**
  308. * Called by <code>setBeanContext()</code> to determine whether the set should be rejected.
  309. * <P>
  310. *
  311. * <EM>This method is meant to be overriden.</EM>
  312. * <code>BeanContextChildSupport</code>'s implementation simply
  313. * returns <code>true</code>.
  314. *
  315. * @param newBeanContext the new parent.
  316. * @return whether to allow the parent to be changed to the new
  317. * value.
  318. */
  319. public boolean validatePendingSetBeanContext(BeanContext newBeanContext) {
  320. return true;
  321. }
  322. /**
  323. * Called by <code>setBeanContext()</code> to release resources of a what will soon no longer be the parent.
  324. * <P>
  325. *
  326. * <EM>This method is meant to be overriden.</EM>
  327. * <code>BeanContextChildSupport</code>'s implementation does
  328. * nothing.
  329. */
  330. protected void releaseBeanContextResources() {
  331. }
  332. /**
  333. * Called by <code>setBeanContext()</code> to grab resources when the parent has been set.
  334. * <P>
  335. *
  336. * <EM>This method is meant to be overriden.</EM>
  337. * <code>BeanContextChildSupport</code>'s implementation does
  338. * nothing.
  339. */
  340. protected void initializeBeanContextResources() {
  341. }
  342. }