History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/java/beans (227 of 18352 files). Show all

Unified · Split

227 files
  1. java/pkg/java/beans/AppletInitializer.class +0 −0
  2. java/pkg/java/beans/AppletInitializer.java +91 −0
  3. java/pkg/java/beans/ArrayPersistenceDelegate.class +0 −0
  4. java/pkg/java/beans/BeanDescriptor.class +0 −0
  5. java/pkg/java/beans/BeanDescriptor.java +109 −0
  6. java/pkg/java/beans/BeanInfo.class +0 −0
  7. java/pkg/java/beans/BeanInfo.java +176 −0
  8. java/pkg/java/beans/Beans$1.class +0 −0
  9. java/pkg/java/beans/Beans$2.class +0 −0
  10. java/pkg/java/beans/Beans.class +0 −0
  11. java/pkg/java/beans/Beans.java +637 −0
  12. java/pkg/java/beans/BeansAppletContext.class +0 −0
  13. java/pkg/java/beans/BeansAppletStub.class +0 −0
  14. java/pkg/java/beans/ChangeListenerMap.class +0 −0
  15. java/pkg/java/beans/ChangeListenerMap.java +247 −0
  16. java/pkg/java/beans/ConstructorProperties.class +0 −0
  17. java/pkg/java/beans/ConstructorProperties.java +76 −0
  18. java/pkg/java/beans/Customizer.class +0 −0
  19. java/pkg/java/beans/Customizer.java +65 −0
  20. java/pkg/java/beans/DefaultPersistenceDelegate.class +0 −0
  21. java/pkg/java/beans/DefaultPersistenceDelegate.java +414 −0
  22. java/pkg/java/beans/DesignMode.class +0 −0
  23. java/pkg/java/beans/DesignMode.java +89 −0
  24. java/pkg/java/beans/Encoder.class +0 −0
  25. java/pkg/java/beans/Encoder.java +345 −0
  26. java/pkg/java/beans/EnumPersistenceDelegate.class +0 −0
  27. java/pkg/java/beans/EventHandler$1.class +0 −0
  28. java/pkg/java/beans/EventHandler.class +0 −0
  29. java/pkg/java/beans/EventHandler.java +694 −0
  30. java/pkg/java/beans/EventSetDescriptor.class +0 −0
  31. java/pkg/java/beans/EventSetDescriptor.java +536 −0
  32. java/pkg/java/beans/ExceptionListener.class +0 −0
  33. java/pkg/java/beans/ExceptionListener.java +43 −0
  34. java/pkg/java/beans/Expression.class +0 −0
  35. java/pkg/java/beans/Expression.java +182 −0
  36. java/pkg/java/beans/FeatureDescriptor.class +0 −0
  37. java/pkg/java/beans/FeatureDescriptor.java +445 −0
  38. java/pkg/java/beans/GenericBeanInfo.class +0 −0
  39. java/pkg/java/beans/IndexedPropertyChangeEvent.class +0 −0
  40. java/pkg/java/beans/IndexedPropertyChangeEvent.java +78 −0
  41. java/pkg/java/beans/IndexedPropertyDescriptor.class +0 −0
  42. java/pkg/java/beans/IndexedPropertyDescriptor.java +523 −0
  43. java/pkg/java/beans/IntrospectionException.class +0 −0
  44. java/pkg/java/beans/IntrospectionException.java +50 −0
  45. java/pkg/java/beans/Introspector.class +0 −0
  46. java/pkg/java/beans/Introspector.java +1558 −0
  47. java/pkg/java/beans/MetaData$1.class +0 −0
  48. java/pkg/java/beans/MetaData.class +0 −0
  49. java/pkg/java/beans/MetaData.java +1443 −0
  50. java/pkg/java/beans/MethodDescriptor.class +0 −0
  51. java/pkg/java/beans/MethodDescriptor.java +228 −0
  52. java/pkg/java/beans/NameGenerator.class +0 −0
  53. java/pkg/java/beans/NameGenerator.java +116 −0
  54. java/pkg/java/beans/NullPersistenceDelegate.class +0 −0
  55. java/pkg/java/beans/ObjectInputStreamWithLoader.class +0 −0
  56. java/pkg/java/beans/ParameterDescriptor.class +0 −0
  57. java/pkg/java/beans/ParameterDescriptor.java +53 −0
  58. java/pkg/java/beans/PersistenceDelegate.class +0 −0
  59. java/pkg/java/beans/PersistenceDelegate.java +214 −0
  60. java/pkg/java/beans/PrimitivePersistenceDelegate.class +0 −0
  61. java/pkg/java/beans/PropertyChangeEvent.class +0 −0
  62. java/pkg/java/beans/PropertyChangeEvent.java +164 −0
  63. java/pkg/java/beans/PropertyChangeListener.class +0 −0
  64. java/pkg/java/beans/PropertyChangeListener.java +44 −0
  65. java/pkg/java/beans/PropertyChangeListenerProxy.class +0 −0
  66. java/pkg/java/beans/PropertyChangeListenerProxy.java +81 −0
  67. java/pkg/java/beans/PropertyChangeSupport$1.class +0 −0
  68. java/pkg/java/beans/PropertyChangeSupport$PropertyChangeListenerMap.class +0 −0
  69. java/pkg/java/beans/PropertyChangeSupport.class +0 −0
  70. java/pkg/java/beans/PropertyChangeSupport.java +536 −0
  71. java/pkg/java/beans/PropertyDescriptor.class +0 −0
  72. java/pkg/java/beans/PropertyDescriptor.java +719 −0
  73. java/pkg/java/beans/PropertyEditor.class +0 −0
  74. java/pkg/java/beans/PropertyEditor.java +225 −0
  75. java/pkg/java/beans/PropertyEditorManager.class +0 −0
  76. java/pkg/java/beans/PropertyEditorManager.java +141 −0
  77. java/pkg/java/beans/PropertyEditorSupport.class +0 −0
  78. java/pkg/java/beans/PropertyEditorSupport.java +302 −0
  79. java/pkg/java/beans/PropertyVetoException.class +0 −0
  80. java/pkg/java/beans/PropertyVetoException.java +64 −0
  81. java/pkg/java/beans/ProxyPersistenceDelegate.class +0 −0
  82. java/pkg/java/beans/ReflectionUtils.class +0 −0
  83. java/pkg/java/beans/ReflectionUtils.java +75 −0
  84. java/pkg/java/beans/SimpleBeanInfo$1.class +0 −0
  85. java/pkg/java/beans/SimpleBeanInfo.class +0 −0
  86. java/pkg/java/beans/SimpleBeanInfo.java +146 −0
  87. java/pkg/java/beans/Statement$1.class +0 −0
  88. java/pkg/java/beans/Statement$2.class +0 −0
  89. java/pkg/java/beans/Statement.class +0 −0
  90. java/pkg/java/beans/Statement.java +363 −0
  91. java/pkg/java/beans/StaticFieldsPersistenceDelegate.class +0 −0
  92. java/pkg/java/beans/Transient.class +0 −0
  93. java/pkg/java/beans/Transient.java +68 −0
  94. java/pkg/java/beans/VetoableChangeListener.class +0 −0
  95. java/pkg/java/beans/VetoableChangeListener.java +44 −0
  96. java/pkg/java/beans/VetoableChangeListenerProxy.class +0 −0
  97. java/pkg/java/beans/VetoableChangeListenerProxy.java +84 −0
  98. java/pkg/java/beans/VetoableChangeSupport$1.class +0 −0
  99. java/pkg/java/beans/VetoableChangeSupport$VetoableChangeListenerMap.class +0 −0
  100. java/pkg/java/beans/VetoableChangeSupport.class +0 −0
  101. java/pkg/java/beans/VetoableChangeSupport.java +525 −0
  102. java/pkg/java/beans/Visibility.class +0 −0
  103. java/pkg/java/beans/Visibility.java +67 −0
  104. java/pkg/java/beans/XMLDecoder.class +0 −0
  105. java/pkg/java/beans/XMLDecoder.java +294 −0
  106. java/pkg/java/beans/XMLEncoder$1.class +0 −0
  107. java/pkg/java/beans/XMLEncoder$ValueData.class +0 −0
  108. java/pkg/java/beans/XMLEncoder.class +0 −0
  109. java/pkg/java/beans/XMLEncoder.java +774 −0
  110. java/pkg/java/beans/beancontext/BeanContext.class +0 −0
  111. java/pkg/java/beans/beancontext/BeanContext.java +132 −0
  112. java/pkg/java/beans/beancontext/BeanContextChild.class +0 −0
  113. java/pkg/java/beans/beancontext/BeanContextChild.java +137 −0
  114. java/pkg/java/beans/beancontext/BeanContextChildComponentProxy.class +0 −0
  115. java/pkg/java/beans/beancontext/BeanContextChildComponentProxy.java +54 −0
  116. java/pkg/java/beans/beancontext/BeanContextChildSupport.class +0 −0
  117. java/pkg/java/beans/beancontext/BeanContextChildSupport.java +373 −0
  118. java/pkg/java/beans/beancontext/BeanContextContainerProxy.class +0 −0
  119. java/pkg/java/beans/beancontext/BeanContextContainerProxy.java +52 −0
  120. java/pkg/java/beans/beancontext/BeanContextEvent.class +0 −0
  121. java/pkg/java/beans/beancontext/BeanContextEvent.java +104 −0
  122. java/pkg/java/beans/beancontext/BeanContextMembershipEvent.class +0 −0
  123. java/pkg/java/beans/beancontext/BeanContextMembershipEvent.java +131 −0
  124. java/pkg/java/beans/beancontext/BeanContextMembershipListener.class +0 −0
  125. java/pkg/java/beans/beancontext/BeanContextMembershipListener.java +61 −0
  126. java/pkg/java/beans/beancontext/BeanContextProxy.class +0 −0
  127. java/pkg/java/beans/beancontext/BeanContextProxy.java +85 −0
  128. java/pkg/java/beans/beancontext/BeanContextServiceAvailableEvent.class +0 −0
  129. java/pkg/java/beans/beancontext/BeanContextServiceAvailableEvent.java +86 −0
  130. java/pkg/java/beans/beancontext/BeanContextServiceProvider.class +0 −0
  131. java/pkg/java/beans/beancontext/BeanContextServiceProvider.java +104 −0
  132. java/pkg/java/beans/beancontext/BeanContextServiceProviderBeanInfo.class +0 −0
  133. java/pkg/java/beans/beancontext/BeanContextServiceProviderBeanInfo.java +47 −0
  134. java/pkg/java/beans/beancontext/BeanContextServiceRevokedEvent.class +0 −0
  135. java/pkg/java/beans/beancontext/BeanContextServiceRevokedEvent.java +99 −0
  136. java/pkg/java/beans/beancontext/BeanContextServiceRevokedListener.class +0 −0
  137. java/pkg/java/beans/beancontext/BeanContextServiceRevokedListener.java +46 −0
  138. java/pkg/java/beans/beancontext/BeanContextServices.class +0 −0
  139. java/pkg/java/beans/beancontext/BeanContextServices.java +159 −0
  140. java/pkg/java/beans/beancontext/BeanContextServicesListener.class +0 −0
  141. java/pkg/java/beans/beancontext/BeanContextServicesListener.java +46 −0
  142. java/pkg/java/beans/beancontext/BeanContextServicesSupport$BCSSChild$BCSSCServiceClassRef.class +0 −0
  143. java/pkg/java/beans/beancontext/BeanContextServicesSupport$BCSSChild$BCSSCServiceRef.class +0 −0
  144. java/pkg/java/beans/beancontext/BeanContextServicesSupport$BCSSChild.class +0 −0
  145. java/pkg/java/beans/beancontext/BeanContextServicesSupport$BCSSProxyServiceProvider.class +0 −0
  146. java/pkg/java/beans/beancontext/BeanContextServicesSupport$BCSSServiceProvider.class +0 −0
  147. java/pkg/java/beans/beancontext/BeanContextServicesSupport.class +0 −0
  148. java/pkg/java/beans/beancontext/BeanContextServicesSupport.java +1238 −0
  149. java/pkg/java/beans/beancontext/BeanContextSupport$1.class +0 −0
  150. java/pkg/java/beans/beancontext/BeanContextSupport$2.class +0 −0
  151. java/pkg/java/beans/beancontext/BeanContextSupport$BCSChild.class +0 −0
  152. java/pkg/java/beans/beancontext/BeanContextSupport$BCSIterator.class +0 −0
  153. java/pkg/java/beans/beancontext/BeanContextSupport.class +0 −0
  154. java/pkg/java/beans/beancontext/BeanContextSupport.java +1393 −0
  155. java/pkg/java/beans/beancontext/mkfile +25 −0
  156. java/pkg/java/beans/beancontext/package.html +55 −0
  157. java/pkg/java/beans/java_awt_AWTKeyStroke_PersistenceDelegate.class +0 −0
  158. java/pkg/java/beans/java_awt_BorderLayout_PersistenceDelegate.class +0 −0
  159. java/pkg/java/beans/java_awt_CardLayout_PersistenceDelegate.class +0 −0
  160. java/pkg/java/beans/java_awt_Choice_PersistenceDelegate.class +0 −0
  161. java/pkg/java/beans/java_awt_Component_PersistenceDelegate.class +0 −0
  162. java/pkg/java/beans/java_awt_Container_PersistenceDelegate.class +0 −0
  163. java/pkg/java/beans/java_awt_Font_PersistenceDelegate.class +0 −0
  164. java/pkg/java/beans/java_awt_GridBagLayout_PersistenceDelegate.class +0 −0
  165. java/pkg/java/beans/java_awt_Insets_PersistenceDelegate.class +0 −0
  166. java/pkg/java/beans/java_awt_List_PersistenceDelegate.class +0 −0
  167. java/pkg/java/beans/java_awt_MenuBar_PersistenceDelegate.class +0 −0
  168. java/pkg/java/beans/java_awt_MenuShortcut_PersistenceDelegate.class +0 −0
  169. java/pkg/java/beans/java_awt_Menu_PersistenceDelegate.class +0 −0
  170. java/pkg/java/beans/java_awt_SystemColor_PersistenceDelegate.class +0 −0
  171. java/pkg/java/beans/java_awt_font_TextAttribute_PersistenceDelegate.class +0 −0
  172. java/pkg/java/beans/java_beans_beancontext_BeanContextSupport_PersistenceDelegate.class +0 −0
  173. java/pkg/java/beans/java_lang_Class_PersistenceDelegate.class +0 −0
  174. java/pkg/java/beans/java_lang_String_PersistenceDelegate.class +0 −0
  175. java/pkg/java/beans/java_lang_reflect_Field_PersistenceDelegate.class +0 −0
  176. java/pkg/java/beans/java_lang_reflect_Method_PersistenceDelegate.class +0 −0
  177. java/pkg/java/beans/java_sql_Timestamp_PersistenceDelegate.class +0 −0
  178. java/pkg/java/beans/java_util_AbstractCollection_PersistenceDelegate.class +0 −0
  179. java/pkg/java/beans/java_util_AbstractList_PersistenceDelegate.class +0 −0
  180. java/pkg/java/beans/java_util_AbstractMap_PersistenceDelegate.class +0 −0
  181. java/pkg/java/beans/java_util_Collection_PersistenceDelegate.class +0 −0
  182. java/pkg/java/beans/java_util_Collections$CheckedCollection_PersistenceDelegate.class +0 −0
  183. java/pkg/java/beans/java_util_Collections$CheckedList_PersistenceDelegate.class +0 −0
  184. java/pkg/java/beans/java_util_Collections$CheckedMap_PersistenceDelegate.class +0 −0
  185. java/pkg/java/beans/java_util_Collections$CheckedRandomAccessList_PersistenceDelegate.class +0 −0
  186. java/pkg/java/beans/java_util_Collections$CheckedSet_PersistenceDelegate.class +0 −0
  187. java/pkg/java/beans/java_util_Collections$CheckedSortedMap_PersistenceDelegate.class +0 −0
  188. java/pkg/java/beans/java_util_Collections$CheckedSortedSet_PersistenceDelegate.class +0 −0
  189. java/pkg/java/beans/java_util_Collections$EmptyList_PersistenceDelegate.class +0 −0
  190. java/pkg/java/beans/java_util_Collections$EmptyMap_PersistenceDelegate.class +0 −0
  191. java/pkg/java/beans/java_util_Collections$EmptySet_PersistenceDelegate.class +0 −0
  192. java/pkg/java/beans/java_util_Collections$SingletonList_PersistenceDelegate.class +0 −0
  193. java/pkg/java/beans/java_util_Collections$SingletonMap_PersistenceDelegate.class +0 −0
  194. java/pkg/java/beans/java_util_Collections$SingletonSet_PersistenceDelegate.class +0 −0
  195. java/pkg/java/beans/java_util_Collections$SynchronizedCollection_PersistenceDelegate.class +0 −0
  196. java/pkg/java/beans/java_util_Collections$SynchronizedList_PersistenceDelegate.class +0 −0
  197. java/pkg/java/beans/java_util_Collections$SynchronizedMap_PersistenceDelegate.class +0 −0
  198. java/pkg/java/beans/java_util_Collections$SynchronizedRandomAccessList_PersistenceDelegate.class +0 −0
  199. java/pkg/java/beans/java_util_Collections$SynchronizedSet_PersistenceDelegate.class +0 −0
  200. java/pkg/java/beans/java_util_Collections$SynchronizedSortedMap_PersistenceDelegate.class +0 −0
  201. java/pkg/java/beans/java_util_Collections$SynchronizedSortedSet_PersistenceDelegate.class +0 −0
  202. java/pkg/java/beans/java_util_Collections$UnmodifiableCollection_PersistenceDelegate.class +0 −0
  203. java/pkg/java/beans/java_util_Collections$UnmodifiableList_PersistenceDelegate.class +0 −0
  204. java/pkg/java/beans/java_util_Collections$UnmodifiableMap_PersistenceDelegate.class +0 −0
  205. java/pkg/java/beans/java_util_Collections$UnmodifiableRandomAccessList_PersistenceDelegate.class +0 −0
  206. java/pkg/java/beans/java_util_Collections$UnmodifiableSet_PersistenceDelegate.class +0 −0
  207. java/pkg/java/beans/java_util_Collections$UnmodifiableSortedMap_PersistenceDelegate.class +0 −0
  208. java/pkg/java/beans/java_util_Collections$UnmodifiableSortedSet_PersistenceDelegate.class +0 −0
  209. java/pkg/java/beans/java_util_Collections.class +0 −0
  210. java/pkg/java/beans/java_util_Date_PersistenceDelegate.class +0 −0
  211. java/pkg/java/beans/java_util_EnumMap_PersistenceDelegate.class +0 −0
  212. java/pkg/java/beans/java_util_EnumSet_PersistenceDelegate.class +0 −0
  213. java/pkg/java/beans/java_util_Hashtable_PersistenceDelegate.class +0 −0
  214. java/pkg/java/beans/java_util_List_PersistenceDelegate.class +0 −0
  215. java/pkg/java/beans/java_util_Map_PersistenceDelegate.class +0 −0
  216. java/pkg/java/beans/javax_swing_Box_PersistenceDelegate.class +0 −0
  217. java/pkg/java/beans/javax_swing_DefaultComboBoxModel_PersistenceDelegate.class +0 −0
  218. java/pkg/java/beans/javax_swing_DefaultListModel_PersistenceDelegate.class +0 −0
  219. java/pkg/java/beans/javax_swing_JFrame_PersistenceDelegate.class +0 −0
  220. java/pkg/java/beans/javax_swing_JMenu_PersistenceDelegate.class +0 −0
  221. java/pkg/java/beans/javax_swing_JTabbedPane_PersistenceDelegate.class +0 −0
  222. java/pkg/java/beans/javax_swing_ToolTipManager_PersistenceDelegate.class +0 −0
  223. java/pkg/java/beans/javax_swing_border_MatteBorder_PersistenceDelegate.class +0 −0
  224. java/pkg/java/beans/javax_swing_tree_DefaultMutableTreeNode_PersistenceDelegate.class +0 −0
  225. java/pkg/java/beans/mkfile +54 −0
  226. java/pkg/java/beans/package.html +156 −0
  227. java/pkg/java/beans/sun_swing_PrintColorUIResource_PersistenceDelegate.class +0 −0
java/pkg/java/beans/AppletInitializer.class+0−0

Binary file not shown.

java/pkg/java/beans/AppletInitializer.java+91−0
@@ -0,0 +1,91 @@
1/*
2 * Copyright (c) 1997, 2000, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.beans;
27
28import java.applet.Applet;
29
30import java.beans.beancontext.BeanContext;
31
32/**
33 * <p>
34 * This interface is designed to work in collusion with java.beans.Beans.instantiate.
35 * The interafce is intended to provide mechanism to allow the proper
36 * initialization of JavaBeans that are also Applets, during their
37 * instantiation by java.beans.Beans.instantiate().
38 * </p>
39 *
40 * @see java.beans.Beans#instantiate
41 *
42 * @since 1.2
43 *
44 */
45
46
47public interface AppletInitializer {
48
49 /**
50 * <p>
51 * If passed to the appropriate variant of java.beans.Beans.instantiate
52 * this method will be called in order to associate the newly instantiated
53 * Applet (JavaBean) with its AppletContext, AppletStub, and Container.
54 * </p>
55 * <p>
56 * Conformant implementations shall:
57 * <ol>
58 * <li> Associate the newly instantiated Applet with the appropriate
59 * AppletContext.
60 *
61 * <li> Instantiate an AppletStub() and associate that AppletStub with
62 * the Applet via an invocation of setStub().
63 *
64 * <li> If BeanContext parameter is null, then it shall associate the
65 * Applet with its appropriate Container by adding that Applet to its
66 * Container via an invocation of add(). If the BeanContext parameter is
67 * non-null, then it is the responsibility of the BeanContext to associate
68 * the Applet with its Container during the subsequent invocation of its
69 * addChildren() method.
70 * </ol>
71 * </p>
72 *
73 * @param newAppletBean The newly instantiated JavaBean
74 * @param bCtxt The BeanContext intended for this Applet, or
75 * null.
76 */
77
78 void initialize(Applet newAppletBean, BeanContext bCtxt);
79
80 /**
81 * <p>
82 * Activate, and/or mark Applet active. Implementors of this interface
83 * shall mark this Applet as active, and optionally invoke its start()
84 * method.
85 * </p>
86 *
87 * @param newApplet The newly instantiated JavaBean
88 */
89
90 void activate(Applet newApplet);
91}
java/pkg/java/beans/ArrayPersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/BeanDescriptor.class+0−0

Binary file not shown.

java/pkg/java/beans/BeanDescriptor.java+109−0
@@ -0,0 +1,109 @@
1/*
2 * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.beans;
27
28import java.lang.ref.Reference;
29
30/**
31 * A BeanDescriptor provides global information about a "bean",
32 * including its Java class, its displayName, etc.
33 * <p>
34 * This is one of the kinds of descriptor returned by a BeanInfo object,
35 * which also returns descriptors for properties, method, and events.
36 */
37
38public class BeanDescriptor extends FeatureDescriptor {
39
40 private Reference<Class> beanClassRef;
41 private Reference<Class> customizerClassRef;
42
43 /**
44 * Create a BeanDescriptor for a bean that doesn't have a customizer.
45 *
46 * @param beanClass The Class object of the Java class that implements
47 * the bean. For example sun.beans.OurButton.class.
48 */
49 public BeanDescriptor(Class<?> beanClass) {
50 this(beanClass, null);
51 }
52
53 /**
54 * Create a BeanDescriptor for a bean that has a customizer.
55 *
56 * @param beanClass The Class object of the Java class that implements
57 * the bean. For example sun.beans.OurButton.class.
58 * @param customizerClass The Class object of the Java class that implements
59 * the bean's Customizer. For example sun.beans.OurButtonCustomizer.class.
60 */
61 public BeanDescriptor(Class<?> beanClass, Class<?> customizerClass) {
62 this.beanClassRef = getWeakReference((Class)beanClass);
63 this.customizerClassRef = getWeakReference((Class)customizerClass);
64
65 String name = beanClass.getName();
66 while (name.indexOf('.') >= 0) {
67 name = name.substring(name.indexOf('.')+1);
68 }
69 setName(name);
70 }
71
72 /**
73 * Gets the bean's Class object.
74 *
75 * @return The Class object for the bean.
76 */
77 public Class<?> getBeanClass() {
78 return (this.beanClassRef != null)
79 ? this.beanClassRef.get()
80 : null;
81 }
82
83 /**
84 * Gets the Class object for the bean's customizer.
85 *
86 * @return The Class object for the bean's customizer. This may
87 * be null if the bean doesn't have a customizer.
88 */
89 public Class<?> getCustomizerClass() {
90 return (this.customizerClassRef != null)
91 ? this.customizerClassRef.get()
92 : null;
93 }
94
95 /*
96 * Package-private dup constructor
97 * This must isolate the new object from any changes to the old object.
98 */
99 BeanDescriptor(BeanDescriptor old) {
100 super(old);
101 beanClassRef = old.beanClassRef;
102 customizerClassRef = old.customizerClassRef;
103 }
104
105 void appendTo(StringBuilder sb) {
106 appendTo(sb, "beanClass", this.beanClassRef);
107 appendTo(sb, "customizerClass", this.customizerClassRef);
108 }
109}
java/pkg/java/beans/BeanInfo.class+0−0

Binary file not shown.

java/pkg/java/beans/BeanInfo.java+176−0
@@ -0,0 +1,176 @@
1/*
2 * Copyright (c) 1996, 1999, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.beans;
27
28/**
29 * A bean implementor who wishes to provide explicit information about
30 * their bean may provide a BeanInfo class that implements this BeanInfo
31 * interface and provides explicit information about the methods,
32 * properties, events, etc, of their bean.
33 * <p>
34 * A bean implementor doesn't need to provide a complete set of
35 * explicit information. You can pick and choose which information
36 * you want to provide and the rest will be obtained by automatic
37 * analysis using low-level reflection of the bean classes' methods
38 * and applying standard design patterns.
39 * <p>
40 * You get the opportunity to provide lots and lots of different
41 * information as part of the various XyZDescriptor classes. But
42 * don't panic, you only really need to provide the minimal core
43 * information required by the various constructors.
44 * <P>
45 * See also the SimpleBeanInfo class which provides a convenient
46 * "noop" base class for BeanInfo classes, which you can override
47 * for those specific places where you want to return explicit info.
48 * <P>
49 * To learn about all the behaviour of a bean see the Introspector class.
50 */
51
52public interface BeanInfo {
53
54 /**
55 * Gets the beans <code>BeanDescriptor</code>.
56 *
57 * @return A BeanDescriptor providing overall information about
58 * the bean, such as its displayName, its customizer, etc. May
59 * return null if the information should be obtained by automatic
60 * analysis.
61 */
62 BeanDescriptor getBeanDescriptor();
63
64 /**
65 * Gets the beans <code>EventSetDescriptor</code>s.
66 *
67 * @return An array of EventSetDescriptors describing the kinds of
68 * events fired by this bean. May return null if the information
69 * should be obtained by automatic analysis.
70 */
71 EventSetDescriptor[] getEventSetDescriptors();
72
73 /**
74 * A bean may have a "default" event that is the event that will
75 * mostly commonly be used by humans when using the bean.
76 * @return Index of default event in the EventSetDescriptor array
77 * returned by getEventSetDescriptors.
78 * <P> Returns -1 if there is no default event.
79 */
80 int getDefaultEventIndex();
81
82 /**
83 * Returns descriptors for all properties of the bean.
84 * May return {@code null} if the information
85 * should be obtained by automatic analysis.
86 * <p>
87 * If a property is indexed, then its entry in the result array
88 * will belong to the {@link IndexedPropertyDescriptor} subclass
89 * of the {@link PropertyDescriptor} class.
90 * A client of the {@code getPropertyDescriptors} method
91 * can use "{@code instanceof}" to check
92 * whether a given {@code PropertyDescriptor}
93 * is an {@code IndexedPropertyDescriptor}.
94 *
95 * @return an array of {@code PropertyDescriptor}s
96 * describing all properties supported by the bean
97 * or {@code null}
98 */
99 PropertyDescriptor[] getPropertyDescriptors();
100
101 /**
102 * A bean may have a "default" property that is the property that will
103 * mostly commonly be initially chosen for update by human's who are
104 * customizing the bean.
105 * @return Index of default property in the PropertyDescriptor array
106 * returned by getPropertyDescriptors.
107 * <P> Returns -1 if there is no default property.
108 */
109 int getDefaultPropertyIndex();
110
111 /**
112 * Gets the beans <code>MethodDescriptor</code>s.
113 *
114 * @return An array of MethodDescriptors describing the externally
115 * visible methods supported by this bean. May return null if
116 * the information should be obtained by automatic analysis.
117 */
118 MethodDescriptor[] getMethodDescriptors();
119
120 /**
121 * This method allows a BeanInfo object to return an arbitrary collection
122 * of other BeanInfo objects that provide additional information on the
123 * current bean.
124 * <P>
125 * If there are conflicts or overlaps between the information provided
126 * by different BeanInfo objects, then the current BeanInfo takes precedence
127 * over the getAdditionalBeanInfo objects, and later elements in the array
128 * take precedence over earlier ones.
129 *
130 * @return an array of BeanInfo objects. May return null.
131 */
132 BeanInfo[] getAdditionalBeanInfo();
133
134 /**
135 * This method returns an image object that can be used to
136 * represent the bean in toolboxes, toolbars, etc. Icon images
137 * will typically be GIFs, but may in future include other formats.
138 * <p>
139 * Beans aren't required to provide icons and may return null from
140 * this method.
141 * <p>
142 * There are four possible flavors of icons (16x16 color,
143 * 32x32 color, 16x16 mono, 32x32 mono). If a bean choses to only
144 * support a single icon we recommend supporting 16x16 color.
145 * <p>
146 * We recommend that icons have a "transparent" background
147 * so they can be rendered onto an existing background.
148 *
149 * @param iconKind The kind of icon requested. This should be
150 * one of the constant values ICON_COLOR_16x16, ICON_COLOR_32x32,
151 * ICON_MONO_16x16, or ICON_MONO_32x32.
152 * @return An image object representing the requested icon. May
153 * return null if no suitable icon is available.
154 */
155 java.awt.Image getIcon(int iconKind);
156
157 /**
158 * Constant to indicate a 16 x 16 color icon.
159 */
160 final static int ICON_COLOR_16x16 = 1;
161
162 /**
163 * Constant to indicate a 32 x 32 color icon.
164 */
165 final static int ICON_COLOR_32x32 = 2;
166
167 /**
168 * Constant to indicate a 16 x 16 monochrome icon.
169 */
170 final static int ICON_MONO_16x16 = 3;
171
172 /**
173 * Constant to indicate a 32 x 32 monochrome icon.
174 */
175 final static int ICON_MONO_32x32 = 4;
176}
java/pkg/java/beans/Beans$1.class+0−0

Binary file not shown.

java/pkg/java/beans/Beans$2.class+0−0

Binary file not shown.

java/pkg/java/beans/Beans.class+0−0

Binary file not shown.

java/pkg/java/beans/Beans.java+637−0
@@ -0,0 +1,637 @@
1/*
2 * Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.beans;
27
28import com.sun.beans.finder.ClassFinder;
29
30import java.applet.Applet;
31import java.applet.AppletContext;
32import java.applet.AppletStub;
33import java.applet.AudioClip;
34
35import java.awt.GraphicsEnvironment;
36import java.awt.Image;
37
38import java.beans.beancontext.BeanContext;
39
40import java.io.IOException;
41import java.io.InputStream;
42import java.io.ObjectInputStream;
43import java.io.ObjectStreamClass;
44import java.io.StreamCorruptedException;
45
46import java.net.URL;
47
48import java.security.AccessController;
49import java.security.PrivilegedAction;
50
51import java.util.Enumeration;
52import java.util.Hashtable;
53import java.util.Iterator;
54import java.util.Vector;
55
56import sun.awt.AppContext;
57
58/**
59 * This class provides some general purpose beans control methods.
60 */
61
62public class Beans {
63 private static final Object DESIGN_TIME = new Object();
64 private static final Object GUI_AVAILABLE = new Object();
65
66 /**
67 * <p>
68 * Instantiate a JavaBean.
69 * </p>
70 *
71 * @param cls the class-loader from which we should create
72 * the bean. If this is null, then the system
73 * class-loader is used.
74 * @param beanName the name of the bean within the class-loader.
75 * For example "sun.beanbox.foobah"
76 *
77 * @exception ClassNotFoundException if the class of a serialized
78 * object could not be found.
79 * @exception IOException if an I/O error occurs.
80 */
81
82 public static Object instantiate(ClassLoader cls, String beanName) throws IOException, ClassNotFoundException {
83 return Beans.instantiate(cls, beanName, null, null);
84 }
85
86 /**
87 * <p>
88 * Instantiate a JavaBean.
89 * </p>
90 *
91 * @param cls the class-loader from which we should create
92 * the bean. If this is null, then the system
93 * class-loader is used.
94 * @param beanName the name of the bean within the class-loader.
95 * For example "sun.beanbox.foobah"
96 * @param beanContext The BeanContext in which to nest the new bean
97 *
98 * @exception ClassNotFoundException if the class of a serialized
99 * object could not be found.
100 * @exception IOException if an I/O error occurs.
101 */
102
103 public static Object instantiate(ClassLoader cls, String beanName, BeanContext beanContext) throws IOException, ClassNotFoundException {
104 return Beans.instantiate(cls, beanName, beanContext, null);
105 }
106
107 /**
108 * Instantiate a bean.
109 * <p>
110 * The bean is created based on a name relative to a class-loader.
111 * This name should be a dot-separated name such as "a.b.c".
112 * <p>
113 * In Beans 1.0 the given name can indicate either a serialized object
114 * or a class. Other mechanisms may be added in the future. In
115 * beans 1.0 we first try to treat the beanName as a serialized object
116 * name then as a class name.
117 * <p>
118 * When using the beanName as a serialized object name we convert the
119 * given beanName to a resource pathname and add a trailing ".ser" suffix.
120 * We then try to load a serialized object from that resource.
121 * <p>
122 * For example, given a beanName of "x.y", Beans.instantiate would first
123 * try to read a serialized object from the resource "x/y.ser" and if
124 * that failed it would try to load the class "x.y" and create an
125 * instance of that class.
126 * <p>
127 * If the bean is a subtype of java.applet.Applet, then it is given
128 * some special initialization. First, it is supplied with a default
129 * AppletStub and AppletContext. Second, if it was instantiated from
130 * a classname the applet's "init" method is called. (If the bean was
131 * deserialized this step is skipped.)
132 * <p>
133 * Note that for beans which are applets, it is the caller's responsiblity
134 * to call "start" on the applet. For correct behaviour, this should be done
135 * after the applet has been added into a visible AWT container.
136 * <p>
137 * Note that applets created via beans.instantiate run in a slightly
138 * different environment than applets running inside browsers. In
139 * particular, bean applets have no access to "parameters", so they may
140 * wish to provide property get/set methods to set parameter values. We
141 * advise bean-applet developers to test their bean-applets against both
142 * the JDK appletviewer (for a reference browser environment) and the
143 * BDK BeanBox (for a reference bean container).
144 *
145 * @param cls the class-loader from which we should create
146 * the bean. If this is null, then the system
147 * class-loader is used.
148 * @param beanName the name of the bean within the class-loader.
149 * For example "sun.beanbox.foobah"
150 * @param beanContext The BeanContext in which to nest the new bean
151 * @param initializer The AppletInitializer for the new bean
152 *
153 * @exception ClassNotFoundException if the class of a serialized
154 * object could not be found.
155 * @exception IOException if an I/O error occurs.
156 */
157
158 public static Object instantiate(ClassLoader cls, String beanName, BeanContext beanContext, AppletInitializer initializer)
159 throws IOException, ClassNotFoundException {
160
161 InputStream ins;
162 ObjectInputStream oins = null;
163 Object result = null;
164 boolean serialized = false;
165 IOException serex = null;
166
167 // If the given classloader is null, we check if an
168 // system classloader is available and (if so)
169 // use that instead.
170 // Note that calls on the system class loader will
171 // look in the bootstrap class loader first.
172 if (cls == null) {
173 try {
174 cls = ClassLoader.getSystemClassLoader();
175 } catch (SecurityException ex) {
176 // We're not allowed to access the system class loader.
177 // Drop through.
178 }
179 }
180
181 // Try to find a serialized object with this name
182 final String serName = beanName.replace('.','/').concat(".ser");
183 final ClassLoader loader = cls;
184 ins = (InputStream)AccessController.doPrivileged
185 (new PrivilegedAction() {
186 public Object run() {
187 if (loader == null)
188 return ClassLoader.getSystemResourceAsStream(serName);
189 else
190 return loader.getResourceAsStream(serName);
191 }
192 });
193 if (ins != null) {
194 try {
195 if (cls == null) {
196 oins = new ObjectInputStream(ins);
197 } else {
198 oins = new ObjectInputStreamWithLoader(ins, cls);
199 }
200 result = oins.readObject();
201 serialized = true;
202 oins.close();
203 } catch (IOException ex) {
204 ins.close();
205 // Drop through and try opening the class. But remember
206 // the exception in case we can't find the class either.
207 serex = ex;
208 } catch (ClassNotFoundException ex) {
209 ins.close();
210 throw ex;
211 }
212 }
213
214 if (result == null) {
215 // No serialized object, try just instantiating the class
216 Class cl;
217
218 try {
219 cl = ClassFinder.findClass(beanName, cls);
220 } catch (ClassNotFoundException ex) {
221 // There is no appropriate class. If we earlier tried to
222 // deserialize an object and got an IO exception, throw that,
223 // otherwise rethrow the ClassNotFoundException.
224 if (serex != null) {
225 throw serex;
226 }
227 throw ex;
228 }
229
230 /*
231 * Try to instantiate the class.
232 */
233
234 try {
235 result = cl.newInstance();
236 } catch (Exception ex) {
237 // We have to remap the exception to one in our signature.
238 // But we pass extra information in the detail message.
239 throw new ClassNotFoundException("" + cl + " : " + ex, ex);
240 }
241 }
242
243 if (result != null) {
244
245 // Ok, if the result is an applet initialize it.
246
247 AppletStub stub = null;
248
249 if (result instanceof Applet) {
250 Applet applet = (Applet) result;
251 boolean needDummies = initializer == null;
252
253 if (needDummies) {
254
255 // Figure our the codebase and docbase URLs. We do this
256 // by locating the URL for a known resource, and then
257 // massaging the URL.
258
259 // First find the "resource name" corresponding to the bean
260 // itself. So a serialzied bean "a.b.c" would imply a
261 // resource name of "a/b/c.ser" and a classname of "x.y"
262 // would imply a resource name of "x/y.class".
263
264 final String resourceName;
265
266 if (serialized) {
267 // Serialized bean
268 resourceName = beanName.replace('.','/').concat(".ser");
269 } else {
270 // Regular class
271 resourceName = beanName.replace('.','/').concat(".class");
272 }
273
274 URL objectUrl = null;
275 URL codeBase = null;
276 URL docBase = null;
277
278 // Now get the URL correponding to the resource name.
279
280 final ClassLoader cloader = cls;
281 objectUrl = (URL)
282 AccessController.doPrivileged
283 (new PrivilegedAction() {
284 public Object run() {
285 if (cloader == null)
286 return ClassLoader.getSystemResource
287 (resourceName);
288 else
289 return cloader.getResource(resourceName);
290 }
291 });
292
293 // If we found a URL, we try to locate the docbase by taking
294 // of the final path name component, and the code base by taking
295 // of the complete resourceName.
296 // So if we had a resourceName of "a/b/c.class" and we got an
297 // objectURL of "file://bert/classes/a/b/c.class" then we would
298 // want to set the codebase to "file://bert/classes/" and the
299 // docbase to "file://bert/classes/a/b/"
300
301 if (objectUrl != null) {
302 String s = objectUrl.toExternalForm();
303
304 if (s.endsWith(resourceName)) {
305 int ix = s.length() - resourceName.length();
306 codeBase = new URL(s.substring(0,ix));
307 docBase = codeBase;
308
309 ix = s.lastIndexOf('/');
310
311 if (ix >= 0) {
312 docBase = new URL(s.substring(0,ix+1));
313 }
314 }
315 }
316
317 // Setup a default context and stub.
318 BeansAppletContext context = new BeansAppletContext(applet);
319
320 stub = (AppletStub)new BeansAppletStub(applet, context, codeBase, docBase);
321 applet.setStub(stub);
322 } else {
323 initializer.initialize(applet, beanContext);
324 }
325
326 // now, if there is a BeanContext, add the bean, if applicable.
327
328 if (beanContext != null) {
329 beanContext.add(result);
330 }
331
332 // If it was deserialized then it was already init-ed.
333 // Otherwise we need to initialize it.
334
335 if (!serialized) {
336 // We need to set a reasonable initial size, as many
337 // applets are unhappy if they are started without
338 // having been explicitly sized.
339 applet.setSize(100,100);
340 applet.init();
341 }
342
343 if (needDummies) {
344 ((BeansAppletStub)stub).active = true;
345 } else initializer.activate(applet);
346
347 } else if (beanContext != null) beanContext.add(result);
348 }
349
350 return result;
351 }
352
353
354 /**
355 * From a given bean, obtain an object representing a specified
356 * type view of that source object.
357 * <p>
358 * The result may be the same object or a different object. If
359 * the requested target view isn't available then the given
360 * bean is returned.
361 * <p>
362 * This method is provided in Beans 1.0 as a hook to allow the
363 * addition of more flexible bean behaviour in the future.
364 *
365 * @param bean Object from which we want to obtain a view.
366 * @param targetType The type of view we'd like to get.
367 *
368 */
369 public static Object getInstanceOf(Object bean, Class<?> targetType) {
370 return bean;
371 }
372
373 /**
374 * Check if a bean can be viewed as a given target type.
375 * The result will be true if the Beans.getInstanceof method
376 * can be used on the given bean to obtain an object that
377 * represents the specified targetType type view.
378 *
379 * @param bean Bean from which we want to obtain a view.
380 * @param targetType The type of view we'd like to get.
381 * @return "true" if the given bean supports the given targetType.
382 *
383 */
384 public static boolean isInstanceOf(Object bean, Class<?> targetType) {
385 return Introspector.isSubclass(bean.getClass(), targetType);
386 }
387
388
389 /**
390 * Test if we are in design-mode.
391 *
392 * @return True if we are running in an application construction
393 * environment.
394 *
395 * @see DesignMode
396 */
397 public static boolean isDesignTime() {
398 Object value = AppContext.getAppContext().get(DESIGN_TIME);
399 return (value instanceof Boolean) && (Boolean) value;
400 }
401
402 /**
403 * Determines whether beans can assume a GUI is available.
404 *
405 * @return True if we are running in an environment where beans
406 * can assume that an interactive GUI is available, so they
407 * can pop up dialog boxes, etc. This will normally return
408 * true in a windowing environment, and will normally return
409 * false in a server environment or if an application is
410 * running as part of a batch job.
411 *
412 * @see Visibility
413 *
414 */
415 public static boolean isGuiAvailable() {
416 Object value = AppContext.getAppContext().get(GUI_AVAILABLE);
417 return (value instanceof Boolean) ? (Boolean) value : !GraphicsEnvironment.isHeadless();
418 }
419
420 /**
421 * Used to indicate whether of not we are running in an application
422 * builder environment.
423 *
424 * <p>Note that this method is security checked
425 * and is not available to (for example) untrusted applets.
426 * More specifically, if there is a security manager,
427 * its <code>checkPropertiesAccess</code>
428 * method is called. This could result in a SecurityException.
429 *
430 * @param isDesignTime True if we're in an application builder tool.
431 * @exception SecurityException if a security manager exists and its
432 * <code>checkPropertiesAccess</code> method doesn't allow setting
433 * of system properties.
434 * @see SecurityManager#checkPropertiesAccess
435 */
436
437 public static void setDesignTime(boolean isDesignTime)
438 throws SecurityException {
439 SecurityManager sm = System.getSecurityManager();
440 if (sm != null) {
441 sm.checkPropertiesAccess();
442 }
443 AppContext.getAppContext().put(DESIGN_TIME, Boolean.valueOf(isDesignTime));
444 }
445
446 /**
447 * Used to indicate whether of not we are running in an environment
448 * where GUI interaction is available.
449 *
450 * <p>Note that this method is security checked
451 * and is not available to (for example) untrusted applets.
452 * More specifically, if there is a security manager,
453 * its <code>checkPropertiesAccess</code>
454 * method is called. This could result in a SecurityException.
455 *
456 * @param isGuiAvailable True if GUI interaction is available.
457 * @exception SecurityException if a security manager exists and its
458 * <code>checkPropertiesAccess</code> method doesn't allow setting
459 * of system properties.
460 * @see SecurityManager#checkPropertiesAccess
461 */
462
463 public static void setGuiAvailable(boolean isGuiAvailable)
464 throws SecurityException {
465 SecurityManager sm = System.getSecurityManager();
466 if (sm != null) {
467 sm.checkPropertiesAccess();
468 }
469 AppContext.getAppContext().put(GUI_AVAILABLE, Boolean.valueOf(isGuiAvailable));
470 }
471}
472
473/**
474 * This subclass of ObjectInputStream delegates loading of classes to
475 * an existing ClassLoader.
476 */
477
478class ObjectInputStreamWithLoader extends ObjectInputStream
479{
480 private ClassLoader loader;
481
482 /**
483 * Loader must be non-null;
484 */
485
486 public ObjectInputStreamWithLoader(InputStream in, ClassLoader loader)
487 throws IOException, StreamCorruptedException {
488
489 super(in);
490 if (loader == null) {
491 throw new IllegalArgumentException("Illegal null argument to ObjectInputStreamWithLoader");
492 }
493 this.loader = loader;
494 }
495
496 /**
497 * Use the given ClassLoader rather than using the system class
498 */
499 protected Class resolveClass(ObjectStreamClass classDesc)
500 throws IOException, ClassNotFoundException {
501
502 String cname = classDesc.getName();
503 return ClassFinder.resolveClass(cname, this.loader);
504 }
505}
506
507/**
508 * Package private support class. This provides a default AppletContext
509 * for beans which are applets.
510 */
511
512class BeansAppletContext implements AppletContext {
513 Applet target;
514 Hashtable imageCache = new Hashtable();
515
516 BeansAppletContext(Applet target) {
517 this.target = target;
518 }
519
520 public AudioClip getAudioClip(URL url) {
521 // We don't currently support audio clips in the Beans.instantiate
522 // applet context, unless by some luck there exists a URL content
523 // class that can generate an AudioClip from the audio URL.
524 try {
525 return (AudioClip) url.getContent();
526 } catch (Exception ex) {
527 return null;
528 }
529 }
530
531 public synchronized Image getImage(URL url) {
532 Object o = imageCache.get(url);
533 if (o != null) {
534 return (Image)o;
535 }
536 try {
537 o = url.getContent();
538 if (o == null) {
539 return null;
540 }
541 if (o instanceof Image) {
542 imageCache.put(url, o);
543 return (Image) o;
544 }
545 // Otherwise it must be an ImageProducer.
546 Image img = target.createImage((java.awt.image.ImageProducer)o);
547 imageCache.put(url, img);
548 return img;
549
550 } catch (Exception ex) {
551 return null;
552 }
553 }
554
555 public Applet getApplet(String name) {
556 return null;
557 }
558
559 public Enumeration getApplets() {
560 Vector applets = new Vector();
561 applets.addElement(target);
562 return applets.elements();
563 }
564
565 public void showDocument(URL url) {
566 // We do nothing.
567 }
568
569 public void showDocument(URL url, String target) {
570 // We do nothing.
571 }
572
573 public void showStatus(String status) {
574 // We do nothing.
575 }
576
577 public void setStream(String key, InputStream stream)throws IOException{
578 // We do nothing.
579 }
580
581 public InputStream getStream(String key){
582 // We do nothing.
583 return null;
584 }
585
586 public Iterator getStreamKeys(){
587 // We do nothing.
588 return null;
589 }
590}
591
592/**
593 * Package private support class. This provides an AppletStub
594 * for beans which are applets.
595 */
596class BeansAppletStub implements AppletStub {
597 transient boolean active;
598 transient Applet target;
599 transient AppletContext context;
600 transient URL codeBase;
601 transient URL docBase;
602
603 BeansAppletStub(Applet target,
604 AppletContext context, URL codeBase,
605 URL docBase) {
606 this.target = target;
607 this.context = context;
608 this.codeBase = codeBase;
609 this.docBase = docBase;
610 }
611
612 public boolean isActive() {
613 return active;
614 }
615
616 public URL getDocumentBase() {
617 // use the root directory of the applet's class-loader
618 return docBase;
619 }
620
621 public URL getCodeBase() {
622 // use the directory where we found the class or serialized object.
623 return codeBase;
624 }
625
626 public String getParameter(String name) {
627 return null;
628 }
629
630 public AppletContext getAppletContext() {
631 return context;
632 }
633
634 public void appletResize(int width, int height) {
635 // we do nothing.
636 }
637}
java/pkg/java/beans/BeansAppletContext.class+0−0

Binary file not shown.

java/pkg/java/beans/BeansAppletStub.class+0−0

Binary file not shown.

java/pkg/java/beans/ChangeListenerMap.class+0−0

Binary file not shown.

java/pkg/java/beans/ChangeListenerMap.java+247−0
@@ -0,0 +1,247 @@
1/*
2 * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25package java.beans;
26
27import java.util.ArrayList;
28import java.util.Collections;
29import java.util.EventListener;
30import java.util.EventListenerProxy;
31import java.util.HashMap;
32import java.util.List;
33import java.util.Map;
34import java.util.Map.Entry;
35import java.util.Set;
36
37/**
38 * This is an abstract class that provides base functionality
39 * for the {@link PropertyChangeSupport PropertyChangeSupport} class
40 * and the {@link VetoableChangeSupport VetoableChangeSupport} class.
41 *
42 * @see PropertyChangeListenerMap
43 * @see VetoableChangeListenerMap
44 *
45 * @author Sergey A. Malenkov
46 */
47abstract class ChangeListenerMap<L extends EventListener> {
48 private Map<String, L[]> map;
49
50 /**
51 * Creates an array of listeners.
52 * This method can be optimized by using
53 * the same instance of the empty array
54 * when {@code length} is equal to {@code 0}.
55 *
56 * @param length the array length
57 * @return an array with specified length
58 */
59 protected abstract L[] newArray(int length);
60
61 /**
62 * Creates a proxy listener for the specified property.
63 *
64 * @param name the name of the property to listen on
65 * @param listener the listener to process events
66 * @return a proxy listener
67 */
68 protected abstract L newProxy(String name, L listener);
69
70 /**
71 * Adds a listener to the list of listeners for the specified property.
72 * This listener is called as many times as it was added.
73 *
74 * @param name the name of the property to listen on
75 * @param listener the listener to process events
76 */
77 public final synchronized void add(String name, L listener) {
78 if (this.map == null) {
79 this.map = new HashMap<String, L[]>();
80 }
81 L[] array = this.map.get(name);
82 int size = (array != null)
83 ? array.length
84 : 0;
85
86 L[] clone = newArray(size + 1);
87 clone[size] = listener;
88 if (array != null) {
89 System.arraycopy(array, 0, clone, 0, size);
90 }
91 this.map.put(name, clone);
92 }
93
94 /**
95 * Removes a listener from the list of listeners for the specified property.
96 * If the listener was added more than once to the same event source,
97 * this listener will be notified one less time after being removed.
98 *
99 * @param name the name of the property to listen on
100 * @param listener the listener to process events
101 */
102 public final synchronized void remove(String name, L listener) {
103 if (this.map != null) {
104 L[] array = this.map.get(name);
105 if (array != null) {
106 for (int i = 0; i < array.length; i++) {
107 if (listener.equals(array[i])) {
108 int size = array.length - 1;
109 if (size > 0) {
110 L[] clone = newArray(size);
111 System.arraycopy(array, 0, clone, 0, i);
112 System.arraycopy(array, i + 1, clone, i, size - i);
113 this.map.put(name, clone);
114 }
115 else {
116 this.map.remove(name);
117 if (this.map.isEmpty()) {
118 this.map = null;
119 }
120 }
121 break;
122 }
123 }
124 }
125 }
126 }
127
128 /**
129 * Returns the list of listeners for the specified property.
130 *
131 * @param name the name of the property
132 * @return the corresponding list of listeners
133 */
134 public final synchronized L[] get(String name) {
135 return (this.map != null)
136 ? this.map.get(name)
137 : null;
138 }
139
140 /**
141 * Sets new list of listeners for the specified property.
142 *
143 * @param name the name of the property
144 * @param listeners new list of listeners
145 */
146 public final void set(String name, L[] listeners) {
147 if (listeners != null) {
148 if (this.map == null) {
149 this.map = new HashMap<String, L[]>();
150 }
151 this.map.put(name, listeners);
152 }
153 else if (this.map != null) {
154 this.map.remove(name);
155 if (this.map.isEmpty()) {
156 this.map = null;
157 }
158 }
159 }
160
161 /**
162 * Returns all listeners in the map.
163 *
164 * @return an array of all listeners
165 */
166 public final synchronized L[] getListeners() {
167 if (this.map == null) {
168 return newArray(0);
169 }
170 List<L> list = new ArrayList<L>();
171
172 L[] listeners = this.map.get(null);
173 if (listeners != null) {
174 for (L listener : listeners) {
175 list.add(listener);
176 }
177 }
178 for (Entry<String, L[]> entry : this.map.entrySet()) {
179 String name = entry.getKey();
180 if (name != null) {
181 for (L listener : entry.getValue()) {
182 list.add(newProxy(name, listener));
183 }
184 }
185 }
186 return list.toArray(newArray(list.size()));
187 }
188
189 /**
190 * Returns listeners that have been associated with the named property.
191 *
192 * @param name the name of the property
193 * @return an array of listeners for the named property
194 */
195 public final L[] getListeners(String name) {
196 if (name != null) {
197 L[] listeners = get(name);
198 if (listeners != null) {
199 return listeners.clone();
200 }
201 }
202 return newArray(0);
203 }
204
205 /**
206 * Indicates whether the map contains
207 * at least one listener to be notified.
208 *
209 * @param name the name of the property
210 * @return {@code true} if at least one listener exists or
211 * {@code false} otherwise
212 */
213 public final synchronized boolean hasListeners(String name) {
214 if (this.map == null) {
215 return false;
216 }
217 L[] array = this.map.get(null);
218 return (array != null) || ((name != null) && (null != this.map.get(name)));
219 }
220
221 /**
222 * Returns a set of entries from the map.
223 * Each entry is a pair consisted of the property name
224 * and the corresponding list of listeners.
225 *
226 * @return a set of entries from the map
227 */
228 public final Set<Entry<String, L[]>> getEntries() {
229 return (this.map != null)
230 ? this.map.entrySet()
231 : Collections.<Entry<String, L[]>>emptySet();
232 }
233
234 /**
235 * Extracts a real listener from the proxy listener.
236 * It is necessary because default proxy class is not serializable.
237 *
238 * @return a real listener
239 */
240 public final L extract(L listener) {
241 while (listener instanceof EventListenerProxy) {
242 EventListenerProxy<L> proxy = (EventListenerProxy<L>) listener;
243 listener = proxy.getListener();
244 }
245 return listener;
246 }
247}
java/pkg/java/beans/ConstructorProperties.class+0−0

Binary file not shown.

java/pkg/java/beans/ConstructorProperties.java+76−0
@@ -0,0 +1,76 @@
1/*
2 * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.beans;
27
28import java.lang.annotation.*;
29import static java.lang.annotation.ElementType.*;
30import static java.lang.annotation.RetentionPolicy.*;
31
32/**
33 <p>An annotation on a constructor that shows how the parameters of
34 that constructor correspond to the constructed object's getter
35 methods. For example:
36
37 <blockquote>
38<pre>
39 public class Point {
40 &#64;ConstructorProperties({"x", "y"})
41 public Point(int x, int y) {
42 this.x = x;
43 this.y = y;
44 }
45
46 public int getX() {
47 return x;
48 }
49
50 public int getY() {
51 return y;
52 }
53
54 private final int x, y;
55 }
56</pre>
57</blockquote>
58
59 The annotation shows that the first parameter of the constructor
60 can be retrieved with the {@code getX()} method and the second with
61 the {@code getY()} method. Since parameter names are not in
62 general available at runtime, without the annotation there would be
63 no way to know whether the parameters correspond to {@code getX()}
64 and {@code getY()} or the other way around.</p>
65
66 @since 1.6
67*/
68@Documented @Target(CONSTRUCTOR) @Retention(RUNTIME)
69public @interface ConstructorProperties {
70 /**
71 <p>The getter names.</p>
72 @return the getter names corresponding to the parameters in the
73 annotated constructor.
74 */
75 String[] value();
76}
java/pkg/java/beans/Customizer.class+0−0

Binary file not shown.

java/pkg/java/beans/Customizer.java+65−0
@@ -0,0 +1,65 @@
1/*
2 * Copyright (c) 1996, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.beans;
27
28/**
29 * A customizer class provides a complete custom GUI for customizing
30 * a target Java Bean.
31 * <P>
32 * Each customizer should inherit from the java.awt.Component class so
33 * it can be instantiated inside an AWT dialog or panel.
34 * <P>
35 * Each customizer should have a null constructor.
36 */
37
38public interface Customizer {
39
40 /**
41 * Set the object to be customized. This method should be called only
42 * once, before the Customizer has been added to any parent AWT container.
43 * @param bean The object to be customized.
44 */
45 void setObject(Object bean);
46
47 /**
48 * Register a listener for the PropertyChange event. The customizer
49 * should fire a PropertyChange event whenever it changes the target
50 * bean in a way that might require the displayed properties to be
51 * refreshed.
52 *
53 * @param listener An object to be invoked when a PropertyChange
54 * event is fired.
55 */
56 void addPropertyChangeListener(PropertyChangeListener listener);
57
58 /**
59 * Remove a listener for the PropertyChange event.
60 *
61 * @param listener The PropertyChange listener to be removed.
62 */
63 void removePropertyChangeListener(PropertyChangeListener listener);
64
65}
java/pkg/java/beans/DefaultPersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/DefaultPersistenceDelegate.java+414−0
@@ -0,0 +1,414 @@
1/*
2 * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25package java.beans;
26
27import java.util.*;
28import java.lang.reflect.*;
29import java.util.Objects;
30import sun.reflect.misc.*;
31
32
33/**
34 * The <code>DefaultPersistenceDelegate</code> is a concrete implementation of
35 * the abstract <code>PersistenceDelegate</code> class and
36 * is the delegate used by default for classes about
37 * which no information is available. The <code>DefaultPersistenceDelegate</code>
38 * provides, version resilient, public API-based persistence for
39 * classes that follow the JavaBeans&trade; conventions without any class specific
40 * configuration.
41 * <p>
42 * The key assumptions are that the class has a nullary constructor
43 * and that its state is accurately represented by matching pairs
44 * of "setter" and "getter" methods in the order they are returned
45 * by the Introspector.
46 * In addition to providing code-free persistence for JavaBeans,
47 * the <code>DefaultPersistenceDelegate</code> provides a convenient means
48 * to effect persistent storage for classes that have a constructor
49 * that, while not nullary, simply requires some property values
50 * as arguments.
51 *
52 * @see #DefaultPersistenceDelegate(String[])
53 * @see java.beans.Introspector
54 *
55 * @since 1.4
56 *
57 * @author Philip Milne
58 */
59
60public class DefaultPersistenceDelegate extends PersistenceDelegate {
61 private String[] constructor;
62 private Boolean definesEquals;
63
64 /**
65 * Creates a persistence delegate for a class with a nullary constructor.
66 *
67 * @see #DefaultPersistenceDelegate(java.lang.String[])
68 */
69 public DefaultPersistenceDelegate() {
70 this(new String[0]);
71 }
72
73 /**
74 * Creates a default persistence delegate for a class with a
75 * constructor whose arguments are the values of the property
76 * names as specified by <code>constructorPropertyNames</code>.
77 * The constructor arguments are created by
78 * evaluating the property names in the order they are supplied.
79 * To use this class to specify a single preferred constructor for use
80 * in the serialization of a particular type, we state the
81 * names of the properties that make up the constructor's
82 * arguments. For example, the <code>Font</code> class which
83 * does not define a nullary constructor can be handled
84 * with the following persistence delegate:
85 *
86 * <pre>
87 * new DefaultPersistenceDelegate(new String[]{"name", "style", "size"});
88 * </pre>
89 *
90 * @param constructorPropertyNames The property names for the arguments of this constructor.
91 *
92 * @see #instantiate
93 */
94 public DefaultPersistenceDelegate(String[] constructorPropertyNames) {
95 this.constructor = constructorPropertyNames;
96 }
97
98 private static boolean definesEquals(Class type) {
99 try {
100 return type == type.getMethod("equals", Object.class).getDeclaringClass();
101 }
102 catch(NoSuchMethodException e) {
103 return false;
104 }
105 }
106
107 private boolean definesEquals(Object instance) {
108 if (definesEquals != null) {
109 return (definesEquals == Boolean.TRUE);
110 }
111 else {
112 boolean result = definesEquals(instance.getClass());
113 definesEquals = result ? Boolean.TRUE : Boolean.FALSE;
114 return result;
115 }
116 }
117
118 /**
119 * If the number of arguments in the specified constructor is non-zero and
120 * the class of <code>oldInstance</code> explicitly declares an "equals" method
121 * this method returns the value of <code>oldInstance.equals(newInstance)</code>.
122 * Otherwise, this method uses the superclass's definition which returns true if the
123 * classes of the two instances are equal.
124 *
125 * @param oldInstance The instance to be copied.
126 * @param newInstance The instance that is to be modified.
127 * @return True if an equivalent copy of <code>newInstance</code> may be
128 * created by applying a series of mutations to <code>oldInstance</code>.
129 *
130 * @see #DefaultPersistenceDelegate(String[])
131 */
132 protected boolean mutatesTo(Object oldInstance, Object newInstance) {
133 // Assume the instance is either mutable or a singleton
134 // if it has a nullary constructor.
135 return (constructor.length == 0) || !definesEquals(oldInstance) ?
136 super.mutatesTo(oldInstance, newInstance) :
137 oldInstance.equals(newInstance);
138 }
139
140 /**
141 * This default implementation of the <code>instantiate</code> method returns
142 * an expression containing the predefined method name "new" which denotes a
143 * call to a constructor with the arguments as specified in
144 * the <code>DefaultPersistenceDelegate</code>'s constructor.
145 *
146 * @param oldInstance The instance to be instantiated.
147 * @param out The code output stream.
148 * @return An expression whose value is <code>oldInstance</code>.
149 *
150 * @throws NullPointerException if {@code out} is {@code null}
151 *
152 * @see #DefaultPersistenceDelegate(String[])
153 */
154 protected Expression instantiate(Object oldInstance, Encoder out) {
155 int nArgs = constructor.length;
156 Class type = oldInstance.getClass();
157 Object[] constructorArgs = new Object[nArgs];
158 for(int i = 0; i < nArgs; i++) {
159 try {
160 Method method = findMethod(type, this.constructor[i]);
161 constructorArgs[i] = MethodUtil.invoke(method, oldInstance, new Object[0]);
162 }
163 catch (Exception e) {
164 out.getExceptionListener().exceptionThrown(e);
165 }
166 }
167 return new Expression(oldInstance, oldInstance.getClass(), "new", constructorArgs);
168 }
169
170 private Method findMethod(Class type, String property) {
171 if (property == null) {
172 throw new IllegalArgumentException("Property name is null");
173 }
174 PropertyDescriptor pd = getPropertyDescriptor(type, property);
175 if (pd == null) {
176 throw new IllegalStateException("Could not find property by the name " + property);
177 }
178 Method method = pd.getReadMethod();
179 if (method == null) {
180 throw new IllegalStateException("Could not find getter for the property " + property);
181 }
182 return method;
183 }
184
185 private void doProperty(Class type, PropertyDescriptor pd, Object oldInstance, Object newInstance, Encoder out) throws Exception {
186 Method getter = pd.getReadMethod();
187 Method setter = pd.getWriteMethod();
188
189 if (getter != null && setter != null) {
190 Expression oldGetExp = new Expression(oldInstance, getter.getName(), new Object[]{});
191 Expression newGetExp = new Expression(newInstance, getter.getName(), new Object[]{});
192 Object oldValue = oldGetExp.getValue();
193 Object newValue = newGetExp.getValue();
194 out.writeExpression(oldGetExp);
195 if (!Objects.equals(newValue, out.get(oldValue))) {
196 // Search for a static constant with this value;
197 Object e = (Object[])pd.getValue("enumerationValues");
198 if (e instanceof Object[] && Array.getLength(e) % 3 == 0) {
199 Object[] a = (Object[])e;
200 for(int i = 0; i < a.length; i = i + 3) {
201 try {
202 Field f = type.getField((String)a[i]);
203 if (f.get(null).equals(oldValue)) {
204 out.remove(oldValue);
205 out.writeExpression(new Expression(oldValue, f, "get", new Object[]{null}));
206 }
207 }
208 catch (Exception ex) {}
209 }
210 }
211 invokeStatement(oldInstance, setter.getName(), new Object[]{oldValue}, out);
212 }
213 }
214 }
215
216 static void invokeStatement(Object instance, String methodName, Object[] args, Encoder out) {
217 out.writeStatement(new Statement(instance, methodName, args));
218 }
219
220 // Write out the properties of this instance.
221 private void initBean(Class type, Object oldInstance, Object newInstance, Encoder out) {
222 for (Field field : type.getFields()) {
223 int mod = field.getModifiers();
224 if (Modifier.isFinal(mod) || Modifier.isStatic(mod) || Modifier.isTransient(mod)) {
225 continue;
226 }
227 try {
228 Expression oldGetExp = new Expression(field, "get", new Object[] { oldInstance });
229 Expression newGetExp = new Expression(field, "get", new Object[] { newInstance });
230 Object oldValue = oldGetExp.getValue();
231 Object newValue = newGetExp.getValue();
232 out.writeExpression(oldGetExp);
233 if (!Objects.equals(newValue, out.get(oldValue))) {
234 out.writeStatement(new Statement(field, "set", new Object[] { oldInstance, oldValue }));
235 }
236 }
237 catch (Exception exception) {
238 out.getExceptionListener().exceptionThrown(exception);
239 }
240 }
241 BeanInfo info;
242 try {
243 info = Introspector.getBeanInfo(type);
244 } catch (IntrospectionException exception) {
245 return;
246 }
247 // Properties
248 for (PropertyDescriptor d : info.getPropertyDescriptors()) {
249 if (d.isTransient()) {
250 continue;
251 }
252 try {
253 doProperty(type, d, oldInstance, newInstance, out);
254 }
255 catch (Exception e) {
256 out.getExceptionListener().exceptionThrown(e);
257 }
258 }
259
260 // Listeners
261 /*
262 Pending(milne). There is a general problem with the archival of
263 listeners which is unresolved as of 1.4. Many of the methods
264 which install one object inside another (typically "add" methods
265 or setters) automatically install a listener on the "child" object
266 so that its "parent" may respond to changes that are made to it.
267 For example the JTable:setModel() method automatically adds a
268 TableModelListener (the JTable itself in this case) to the supplied
269 table model.
270
271 We do not need to explictly add these listeners to the model in an
272 archive as they will be added automatically by, in the above case,
273 the JTable's "setModel" method. In some cases, we must specifically
274 avoid trying to do this since the listener may be an inner class
275 that cannot be instantiated using public API.
276
277 No general mechanism currently
278 exists for differentiating between these kind of listeners and
279 those which were added explicitly by the user. A mechanism must
280 be created to provide a general means to differentiate these
281 special cases so as to provide reliable persistence of listeners
282 for the general case.
283 */
284 if (!java.awt.Component.class.isAssignableFrom(type)) {
285 return; // Just handle the listeners of Components for now.
286 }
287 for (EventSetDescriptor d : info.getEventSetDescriptors()) {
288 if (d.isTransient()) {
289 continue;
290 }
291 Class listenerType = d.getListenerType();
292
293
294 // The ComponentListener is added automatically, when
295 // Contatiner:add is called on the parent.
296 if (listenerType == java.awt.event.ComponentListener.class) {
297 continue;
298 }
299
300 // JMenuItems have a change listener added to them in
301 // their "add" methods to enable accessibility support -
302 // see the add method in JMenuItem for details. We cannot
303 // instantiate this instance as it is a private inner class
304 // and do not need to do this anyway since it will be created
305 // and installed by the "add" method. Special case this for now,
306 // ignoring all change listeners on JMenuItems.
307 if (listenerType == javax.swing.event.ChangeListener.class &&
308 type == javax.swing.JMenuItem.class) {
309 continue;
310 }
311
312 EventListener[] oldL = new EventListener[0];
313 EventListener[] newL = new EventListener[0];
314 try {
315 Method m = d.getGetListenerMethod();
316 oldL = (EventListener[])MethodUtil.invoke(m, oldInstance, new Object[]{});
317 newL = (EventListener[])MethodUtil.invoke(m, newInstance, new Object[]{});
318 }
319 catch (Exception e2) {
320 try {
321 Method m = type.getMethod("getListeners", new Class[]{Class.class});
322 oldL = (EventListener[])MethodUtil.invoke(m, oldInstance, new Object[]{listenerType});
323 newL = (EventListener[])MethodUtil.invoke(m, newInstance, new Object[]{listenerType});
324 }
325 catch (Exception e3) {
326 return;
327 }
328 }
329
330 // Asssume the listeners are in the same order and that there are no gaps.
331 // Eventually, this may need to do true differencing.
332 String addListenerMethodName = d.getAddListenerMethod().getName();
333 for (int i = newL.length; i < oldL.length; i++) {
334 // System.out.println("Adding listener: " + addListenerMethodName + oldL[i]);
335 invokeStatement(oldInstance, addListenerMethodName, new Object[]{oldL[i]}, out);
336 }
337
338 String removeListenerMethodName = d.getRemoveListenerMethod().getName();
339 for (int i = oldL.length; i < newL.length; i++) {
340 invokeStatement(oldInstance, removeListenerMethodName, new Object[]{newL[i]}, out);
341 }
342 }
343 }
344
345 /**
346 * This default implementation of the <code>initialize</code> method assumes
347 * all state held in objects of this type is exposed via the
348 * matching pairs of "setter" and "getter" methods in the order
349 * they are returned by the Introspector. If a property descriptor
350 * defines a "transient" attribute with a value equal to
351 * <code>Boolean.TRUE</code> the property is ignored by this
352 * default implementation. Note that this use of the word
353 * "transient" is quite independent of the field modifier
354 * that is used by the <code>ObjectOutputStream</code>.
355 * <p>
356 * For each non-transient property, an expression is created
357 * in which the nullary "getter" method is applied
358 * to the <code>oldInstance</code>. The value of this
359 * expression is the value of the property in the instance that is
360 * being serialized. If the value of this expression
361 * in the cloned environment <code>mutatesTo</code> the
362 * target value, the new value is initialized to make it
363 * equivalent to the old value. In this case, because
364 * the property value has not changed there is no need to
365 * call the corresponding "setter" method and no statement
366 * is emitted. If not however, the expression for this value
367 * is replaced with another expression (normally a constructor)
368 * and the corresponding "setter" method is called to install
369 * the new property value in the object. This scheme removes
370 * default information from the output produced by streams
371 * using this delegate.
372 * <p>
373 * In passing these statements to the output stream, where they
374 * will be executed, side effects are made to the <code>newInstance</code>.
375 * In most cases this allows the problem of properties
376 * whose values depend on each other to actually help the
377 * serialization process by making the number of statements
378 * that need to be written to the output smaller. In general,
379 * the problem of handling interdependent properties is reduced to
380 * that of finding an order for the properties in
381 * a class such that no property value depends on the value of
382 * a subsequent property.
383 *
384 * @param oldInstance The instance to be copied.
385 * @param newInstance The instance that is to be modified.
386 * @param out The stream to which any initialization statements should be written.
387 *
388 * @throws NullPointerException if {@code out} is {@code null}
389 *
390 * @see java.beans.Introspector#getBeanInfo
391 * @see java.beans.PropertyDescriptor
392 */
393 protected void initialize(Class<?> type,
394 Object oldInstance, Object newInstance,
395 Encoder out)
396 {
397 // System.out.println("DefulatPD:initialize" + type);
398 super.initialize(type, oldInstance, newInstance, out);
399 if (oldInstance.getClass() == type) { // !type.isInterface()) {
400 initBean(type, oldInstance, newInstance, out);
401 }
402 }
403
404 private static PropertyDescriptor getPropertyDescriptor(Class type, String property) {
405 try {
406 for (PropertyDescriptor pd : Introspector.getBeanInfo(type).getPropertyDescriptors()) {
407 if (property.equals(pd.getName()))
408 return pd;
409 }
410 } catch (IntrospectionException exception) {
411 }
412 return null;
413 }
414}
java/pkg/java/beans/DesignMode.class+0−0

Binary file not shown.

java/pkg/java/beans/DesignMode.java+89−0
@@ -0,0 +1,89 @@
1/*
2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.beans;
27
28/**
29 * <p>
30 * This interface is intended to be implemented by, or delegated from, instances
31 * of java.beans.beancontext.BeanContext, in order to propagate to its nested hierarchy
32 * of java.beans.beancontext.BeanContextChild instances, the current "designTime" property.
33 * <p>
34 * The JavaBeans&trade; specification defines the notion of design time as is a
35 * mode in which JavaBeans instances should function during their composition
36 * and customization in a interactive design, composition or construction tool,
37 * as opposed to runtime when the JavaBean is part of an applet, application,
38 * or other live Java executable abstraction.
39 *
40 * @author Laurence P. G. Cable
41 * @since 1.2
42 *
43 * @see java.beans.beancontext.BeanContext
44 * @see java.beans.beancontext.BeanContextChild
45 * @see java.beans.beancontext.BeanContextMembershipListener
46 * @see java.beans.PropertyChangeEvent
47 */
48
49public interface DesignMode {
50
51 /**
52 * The standard value of the propertyName as fired from a BeanContext or
53 * other source of PropertyChangeEvents.
54 */
55
56 static String PROPERTYNAME = "designTime";
57
58 /**
59 * Sets the "value" of the "designTime" property.
60 * <p>
61 * If the implementing object is an instance of java.beans.beancontext.BeanContext,
62 * or a subinterface thereof, then that BeanContext should fire a
63 * PropertyChangeEvent, to its registered BeanContextMembershipListeners, with
64 * parameters:
65 * <ul>
66 * <li><code>propertyName</code> - <code>java.beans.DesignMode.PROPERTYNAME</code>
67 * <li><code>oldValue</code> - previous value of "designTime"
68 * <li><code>newValue</code> - current value of "designTime"
69 * </ul>
70 * Note it is illegal for a BeanContextChild to invoke this method
71 * associated with a BeanContext that it is nested within.
72 *
73 * @param designTime the current "value" of the "designTime" property
74 * @see java.beans.beancontext.BeanContext
75 * @see java.beans.beancontext.BeanContextMembershipListener
76 * @see java.beans.PropertyChangeEvent
77 */
78
79 void setDesignTime(boolean designTime);
80
81 /**
82 * A value of true denotes that JavaBeans should behave in design time
83 * mode, a value of false denotes runtime behavior.
84 *
85 * @return the current "value" of the "designTime" property.
86 */
87
88 boolean isDesignTime();
89}
java/pkg/java/beans/Encoder.class+0−0

Binary file not shown.

java/pkg/java/beans/Encoder.java+345−0
@@ -0,0 +1,345 @@
1/*
2 * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25package java.beans;
26
27import com.sun.beans.finder.PersistenceDelegateFinder;
28
29import java.util.HashMap;
30import java.util.IdentityHashMap;
31import java.util.Map;
32
33/**
34 * An <code>Encoder</code> is a class which can be used to create
35 * files or streams that encode the state of a collection of
36 * JavaBeans in terms of their public APIs. The <code>Encoder</code>,
37 * in conjunction with its persistence delegates, is responsible for
38 * breaking the object graph down into a series of <code>Statements</code>s
39 * and <code>Expression</code>s which can be used to create it.
40 * A subclass typically provides a syntax for these expressions
41 * using some human readable form - like Java source code or XML.
42 *
43 * @since 1.4
44 *
45 * @author Philip Milne
46 */
47
48public class Encoder {
49 private final PersistenceDelegateFinder finder = new PersistenceDelegateFinder();
50 private Map bindings = new IdentityHashMap();
51 private ExceptionListener exceptionListener;
52 boolean executeStatements = true;
53 private Map attributes;
54
55 /**
56 * Write the specified object to the output stream.
57 * The serialized form will denote a series of
58 * expressions, the combined effect of which will create
59 * an equivalent object when the input stream is read.
60 * By default, the object is assumed to be a <em>JavaBean</em>
61 * with a nullary constructor, whose state is defined by
62 * the matching pairs of "setter" and "getter" methods
63 * returned by the Introspector.
64 *
65 * @param o The object to be written to the stream.
66 *
67 * @see XMLDecoder#readObject
68 */
69 protected void writeObject(Object o) {
70 if (o == this) {
71 return;
72 }
73 PersistenceDelegate info = getPersistenceDelegate(o == null ? null : o.getClass());
74 info.writeObject(o, this);
75 }
76
77 /**
78 * Sets the exception handler for this stream to <code>exceptionListener</code>.
79 * The exception handler is notified when this stream catches recoverable
80 * exceptions.
81 *
82 * @param exceptionListener The exception handler for this stream;
83 * if <code>null</code> the default exception listener will be used.
84 *
85 * @see #getExceptionListener
86 */
87 public void setExceptionListener(ExceptionListener exceptionListener) {
88 this.exceptionListener = exceptionListener;
89 }
90
91 /**
92 * Gets the exception handler for this stream.
93 *
94 * @return The exception handler for this stream;
95 * Will return the default exception listener if this has not explicitly been set.
96 *
97 * @see #setExceptionListener
98 */
99 public ExceptionListener getExceptionListener() {
100 return (exceptionListener != null) ? exceptionListener : Statement.defaultExceptionListener;
101 }
102
103 Object getValue(Expression exp) {
104 try {
105 return (exp == null) ? null : exp.getValue();
106 }
107 catch (Exception e) {
108 getExceptionListener().exceptionThrown(e);
109 throw new RuntimeException("failed to evaluate: " + exp.toString());
110 }
111 }
112
113 /**
114 * Returns the persistence delegate for the given type.
115 * The persistence delegate is calculated by applying
116 * the following rules in order:
117 * <ol>
118 * <li>
119 * If a persistence delegate is associated with the given type
120 * by using the {@link #setPersistenceDelegate} method
121 * it is returned.
122 * <li>
123 * A persistence delegate is then looked up by the name
124 * composed of the the fully qualified name of the given type
125 * and the "PersistenceDelegate" postfix.
126 * For example, a persistence delegate for the {@code Bean} class
127 * should be named {@code BeanPersistenceDelegate}
128 * and located in the same package.
129 * <pre>
130 * public class Bean { ... }
131 * public class BeanPersistenceDelegate { ... }</pre>
132 * The instance of the {@code BeanPersistenceDelegate} class
133 * is returned for the {@code Bean} class.
134 * <li>
135 * If the type is {@code null},
136 * a shared internal persistence delegate is returned
137 * that encodes {@code null} value.
138 * <li>
139 * If the type is a {@code enum} declaration,
140 * a shared internal persistence delegate is returned
141 * that encodes constants of this enumeration
142 * by their names.
143 * <li>
144 * If the type is a primitive type or the corresponding wrapper,
145 * a shared internal persistence delegate is returned
146 * that encodes values of the given type.
147 * <li>
148 * If the type is an array,
149 * a shared internal persistence delegate is returned
150 * that encodes an array of the appropriate type and length,
151 * and each of its elements as if they are properties.
152 * <li>
153 * If the type is a proxy,
154 * a shared internal persistence delegate is returned
155 * that encodes a proxy instance by using
156 * the {@link java.lang.reflect.Proxy#newProxyInstance} method.
157 * <li>
158 * If the {@link BeanInfo} for this type has a {@link BeanDescriptor}
159 * which defined a "persistenceDelegate" attribute,
160 * the value of this named attribute is returned.
161 * <li>
162 * In all other cases the default persistence delegate is returned.
163 * The default persistence delegate assumes the type is a <em>JavaBean</em>,
164 * implying that it has a default constructor and that its state
165 * may be characterized by the matching pairs of "setter" and "getter"
166 * methods returned by the {@link Introspector} class.
167 * The default constructor is the constructor with the greatest number
168 * of parameters that has the {@link ConstructorProperties} annotation.
169 * If none of the constructors has the {@code ConstructorProperties} annotation,
170 * then the nullary constructor (constructor with no parameters) will be used.
171 * For example, in the following code fragment, the nullary constructor
172 * for the {@code Foo} class will be used,
173 * while the two-parameter constructor
174 * for the {@code Bar} class will be used.
175 * <pre>
176 * public class Foo {
177 * public Foo() { ... }
178 * public Foo(int x) { ... }
179 * }
180 * public class Bar {
181 * public Bar() { ... }
182 * &#64;ConstructorProperties({"x"})
183 * public Bar(int x) { ... }
184 * &#64;ConstructorProperties({"x", "y"})
185 * public Bar(int x, int y) { ... }
186 * }</pre>
187 * </ol>
188 *
189 * @param type the class of the objects
190 * @return the persistence delegate for the given type
191 *
192 * @see #setPersistenceDelegate
193 * @see java.beans.Introspector#getBeanInfo
194 * @see java.beans.BeanInfo#getBeanDescriptor
195 */
196 public PersistenceDelegate getPersistenceDelegate(Class<?> type) {
197 PersistenceDelegate pd = this.finder.find(type);
198 return (pd != null) ? pd : MetaData.getPersistenceDelegate(type);
199 }
200
201 /**
202 * Associates the specified persistence delegate with the given type.
203 *
204 * @param type the class of objects that the specified persistence delegate applies to
205 * @param delegate the persistence delegate for instances of the given type
206 *
207 * @see #getPersistenceDelegate
208 * @see java.beans.Introspector#getBeanInfo
209 * @see java.beans.BeanInfo#getBeanDescriptor
210 */
211 public void setPersistenceDelegate(Class<?> type, PersistenceDelegate delegate) {
212 this.finder.register(type, delegate);
213 }
214
215 /**
216 * Removes the entry for this instance, returning the old entry.
217 *
218 * @param oldInstance The entry that should be removed.
219 * @return The entry that was removed.
220 *
221 * @see #get
222 */
223 public Object remove(Object oldInstance) {
224 Expression exp = (Expression)bindings.remove(oldInstance);
225 return getValue(exp);
226 }
227
228 /**
229 * Returns a tentative value for <code>oldInstance</code> in
230 * the environment created by this stream. A persistence
231 * delegate can use its <code>mutatesTo</code> method to
232 * determine whether this value may be initialized to
233 * form the equivalent object at the output or whether
234 * a new object must be instantiated afresh. If the
235 * stream has not yet seen this value, null is returned.
236 *
237 * @param oldInstance The instance to be looked up.
238 * @return The object, null if the object has not been seen before.
239 */
240 public Object get(Object oldInstance) {
241 if (oldInstance == null || oldInstance == this ||
242 oldInstance.getClass() == String.class) {
243 return oldInstance;
244 }
245 Expression exp = (Expression)bindings.get(oldInstance);
246 return getValue(exp);
247 }
248
249 private Object writeObject1(Object oldInstance) {
250 Object o = get(oldInstance);
251 if (o == null) {
252 writeObject(oldInstance);
253 o = get(oldInstance);
254 }
255 return o;
256 }
257
258 private Statement cloneStatement(Statement oldExp) {
259 Object oldTarget = oldExp.getTarget();
260 Object newTarget = writeObject1(oldTarget);
261
262 Object[] oldArgs = oldExp.getArguments();
263 Object[] newArgs = new Object[oldArgs.length];
264 for (int i = 0; i < oldArgs.length; i++) {
265 newArgs[i] = writeObject1(oldArgs[i]);
266 }
267 Statement newExp = Statement.class.equals(oldExp.getClass())
268 ? new Statement(newTarget, oldExp.getMethodName(), newArgs)
269 : new Expression(newTarget, oldExp.getMethodName(), newArgs);
270 newExp.loader = oldExp.loader;
271 return newExp;
272 }
273
274 /**
275 * Writes statement <code>oldStm</code> to the stream.
276 * The <code>oldStm</code> should be written entirely
277 * in terms of the callers environment, i.e. the
278 * target and all arguments should be part of the
279 * object graph being written. These expressions
280 * represent a series of "what happened" expressions
281 * which tell the output stream how to produce an
282 * object graph like the original.
283 * <p>
284 * The implementation of this method will produce
285 * a second expression to represent the same expression in
286 * an environment that will exist when the stream is read.
287 * This is achieved simply by calling <code>writeObject</code>
288 * on the target and all the arguments and building a new
289 * expression with the results.
290 *
291 * @param oldStm The expression to be written to the stream.
292 */
293 public void writeStatement(Statement oldStm) {
294 // System.out.println("writeStatement: " + oldExp);
295 Statement newStm = cloneStatement(oldStm);
296 if (oldStm.getTarget() != this && executeStatements) {
297 try {
298 newStm.execute();
299 } catch (Exception e) {
300 getExceptionListener().exceptionThrown(new Exception("Encoder: discarding statement "
301 + newStm, e));
302 }
303 }
304 }
305
306 /**
307 * The implementation first checks to see if an
308 * expression with this value has already been written.
309 * If not, the expression is cloned, using
310 * the same procedure as <code>writeStatement</code>,
311 * and the value of this expression is reconciled
312 * with the value of the cloned expression
313 * by calling <code>writeObject</code>.
314 *
315 * @param oldExp The expression to be written to the stream.
316 */
317 public void writeExpression(Expression oldExp) {
318 // System.out.println("Encoder::writeExpression: " + oldExp);
319 Object oldValue = getValue(oldExp);
320 if (get(oldValue) != null) {
321 return;
322 }
323 bindings.put(oldValue, (Expression)cloneStatement(oldExp));
324 writeObject(oldValue);
325 }
326
327 void clear() {
328 bindings.clear();
329 }
330
331 // Package private method for setting an attributes table for the encoder
332 void setAttribute(Object key, Object value) {
333 if (attributes == null) {
334 attributes = new HashMap();
335 }
336 attributes.put(key, value);
337 }
338
339 Object getAttribute(Object key) {
340 if (attributes == null) {
341 return null;
342 }
343 return attributes.get(key);
344 }
345}
java/pkg/java/beans/EnumPersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/EventHandler$1.class+0−0

Binary file not shown.

java/pkg/java/beans/EventHandler.class+0−0

Binary file not shown.

java/pkg/java/beans/EventHandler.java+694−0
@@ -0,0 +1,694 @@
1/*
2 * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25package java.beans;
26
27import java.lang.reflect.InvocationHandler;
28import java.lang.reflect.InvocationTargetException;
29import java.lang.reflect.Proxy;
30import java.lang.reflect.Method;
31import java.security.AccessControlContext;
32import java.security.AccessController;
33import java.security.PrivilegedAction;
34
35import sun.reflect.misc.MethodUtil;
36
37/**
38 * The <code>EventHandler</code> class provides
39 * support for dynamically generating event listeners whose methods
40 * execute a simple statement involving an incoming event object
41 * and a target object.
42 * <p>
43 * The <code>EventHandler</code> class is intended to be used by interactive tools, such as
44 * application builders, that allow developers to make connections between
45 * beans. Typically connections are made from a user interface bean
46 * (the event <em>source</em>)
47 * to an application logic bean (the <em>target</em>). The most effective
48 * connections of this kind isolate the application logic from the user
49 * interface. For example, the <code>EventHandler</code> for a
50 * connection from a <code>JCheckBox</code> to a method
51 * that accepts a boolean value can deal with extracting the state
52 * of the check box and passing it directly to the method so that
53 * the method is isolated from the user interface layer.
54 * <p>
55 * Inner classes are another, more general way to handle events from
56 * user interfaces. The <code>EventHandler</code> class
57 * handles only a subset of what is possible using inner
58 * classes. However, <code>EventHandler</code> works better
59 * with the long-term persistence scheme than inner classes.
60 * Also, using <code>EventHandler</code> in large applications in
61 * which the same interface is implemented many times can
62 * reduce the disk and memory footprint of the application.
63 * <p>
64 * The reason that listeners created with <code>EventHandler</code>
65 * have such a small
66 * footprint is that the <code>Proxy</code> class, on which
67 * the <code>EventHandler</code> relies, shares implementations
68 * of identical
69 * interfaces. For example, if you use
70 * the <code>EventHandler</code> <code>create</code> methods to make
71 * all the <code>ActionListener</code>s in an application,
72 * all the action listeners will be instances of a single class
73 * (one created by the <code>Proxy</code> class).
74 * In general, listeners based on
75 * the <code>Proxy</code> class require one listener class
76 * to be created per <em>listener type</em> (interface),
77 * whereas the inner class
78 * approach requires one class to be created per <em>listener</em>
79 * (object that implements the interface).
80 *
81 * <p>
82 * You don't generally deal directly with <code>EventHandler</code>
83 * instances.
84 * Instead, you use one of the <code>EventHandler</code>
85 * <code>create</code> methods to create
86 * an object that implements a given listener interface.
87 * This listener object uses an <code>EventHandler</code> object
88 * behind the scenes to encapsulate information about the
89 * event, the object to be sent a message when the event occurs,
90 * the message (method) to be sent, and any argument
91 * to the method.
92 * The following section gives examples of how to create listener
93 * objects using the <code>create</code> methods.
94 *
95 * <h2>Examples of Using EventHandler</h2>
96 *
97 * The simplest use of <code>EventHandler</code> is to install
98 * a listener that calls a method on the target object with no arguments.
99 * In the following example we create an <code>ActionListener</code>
100 * that invokes the <code>toFront</code> method on an instance
101 * of <code>javax.swing.JFrame</code>.
102 *
103 * <blockquote>
104 *<pre>
105 *myButton.addActionListener(
106 * (ActionListener)EventHandler.create(ActionListener.class, frame, "toFront"));
107 *</pre>
108 * </blockquote>
109 *
110 * When <code>myButton</code> is pressed, the statement
111 * <code>frame.toFront()</code> will be executed. One could get
112 * the same effect, with some additional compile-time type safety,
113 * by defining a new implementation of the <code>ActionListener</code>
114 * interface and adding an instance of it to the button:
115 *
116 * <blockquote>
117 *<pre>
118//Equivalent code using an inner class instead of EventHandler.
119 *myButton.addActionListener(new ActionListener() {
120 * public void actionPerformed(ActionEvent e) {
121 * frame.toFront();
122 * }
123 *});
124 *</pre>
125 * </blockquote>
126 *
127 * The next simplest use of <code>EventHandler</code> is
128 * to extract a property value from the first argument
129 * of the method in the listener interface (typically an event object)
130 * and use it to set the value of a property in the target object.
131 * In the following example we create an <code>ActionListener</code> that
132 * sets the <code>nextFocusableComponent</code> property of the target
133 * (myButton) object to the value of the "source" property of the event.
134 *
135 * <blockquote>
136 *<pre>
137 *EventHandler.create(ActionListener.class, myButton, "nextFocusableComponent", "source")
138 *</pre>
139 * </blockquote>
140 *
141 * This would correspond to the following inner class implementation:
142 *
143 * <blockquote>
144 *<pre>
145//Equivalent code using an inner class instead of EventHandler.
146 *new ActionListener() {
147 * public void actionPerformed(ActionEvent e) {
148 * myButton.setNextFocusableComponent((Component)e.getSource());
149 * }
150 *}
151 *</pre>
152 * </blockquote>
153 *
154 * It's also possible to create an <code>EventHandler</code> that
155 * just passes the incoming event object to the target's action.
156 * If the fourth <code>EventHandler.create</code> argument is
157 * an empty string, then the event is just passed along:
158 *
159 * <blockquote>
160 *<pre>
161 *EventHandler.create(ActionListener.class, target, "doActionEvent", "")
162 *</pre>
163 * </blockquote>
164 *
165 * This would correspond to the following inner class implementation:
166 *
167 * <blockquote>
168 *<pre>
169//Equivalent code using an inner class instead of EventHandler.
170 *new ActionListener() {
171 * public void actionPerformed(ActionEvent e) {
172 * target.doActionEvent(e);
173 * }
174 *}
175 *</pre>
176 * </blockquote>
177 *
178 * Probably the most common use of <code>EventHandler</code>
179 * is to extract a property value from the
180 * <em>source</em> of the event object and set this value as
181 * the value of a property of the target object.
182 * In the following example we create an <code>ActionListener</code> that
183 * sets the "label" property of the target
184 * object to the value of the "text" property of the
185 * source (the value of the "source" property) of the event.
186 *
187 * <blockquote>
188 *<pre>
189 *EventHandler.create(ActionListener.class, myButton, "label", "source.text")
190 *</pre>
191 * </blockquote>
192 *
193 * This would correspond to the following inner class implementation:
194 *
195 * <blockquote>
196 *<pre>
197//Equivalent code using an inner class instead of EventHandler.
198 *new ActionListener {
199 * public void actionPerformed(ActionEvent e) {
200 * myButton.setLabel(((JTextField)e.getSource()).getText());
201 * }
202 *}
203 *</pre>
204 * </blockquote>
205 *
206 * The event property may be "qualified" with an arbitrary number
207 * of property prefixes delimited with the "." character. The "qualifying"
208 * names that appear before the "." characters are taken as the names of
209 * properties that should be applied, left-most first, to
210 * the event object.
211 * <p>
212 * For example, the following action listener
213 *
214 * <blockquote>
215 *<pre>
216 *EventHandler.create(ActionListener.class, target, "a", "b.c.d")
217 *</pre>
218 * </blockquote>
219 *
220 * might be written as the following inner class
221 * (assuming all the properties had canonical getter methods and
222 * returned the appropriate types):
223 *
224 * <blockquote>
225 *<pre>
226//Equivalent code using an inner class instead of EventHandler.
227 *new ActionListener {
228 * public void actionPerformed(ActionEvent e) {
229 * target.setA(e.getB().getC().isD());
230 * }
231 *}
232 *</pre>
233 * </blockquote>
234 * The target property may also be "qualified" with an arbitrary number
235 * of property prefixs delimited with the "." character. For example, the
236 * following action listener:
237 * <pre>
238 * EventHandler.create(ActionListener.class, target, "a.b", "c.d")
239 * </pre>
240 * might be written as the following inner class
241 * (assuming all the properties had canonical getter methods and
242 * returned the appropriate types):
243 * <pre>
244 * //Equivalent code using an inner class instead of EventHandler.
245 * new ActionListener {
246 * public void actionPerformed(ActionEvent e) {
247 * target.getA().setB(e.getC().isD());
248 * }
249 *}
250 *</pre>
251 * <p>
252 * As <code>EventHandler</code> ultimately relies on reflection to invoke
253 * a method we recommend against targeting an overloaded method. For example,
254 * if the target is an instance of the class <code>MyTarget</code> which is
255 * defined as:
256 * <pre>
257 * public class MyTarget {
258 * public void doIt(String);
259 * public void doIt(Object);
260 * }
261 * </pre>
262 * Then the method <code>doIt</code> is overloaded. EventHandler will invoke
263 * the method that is appropriate based on the source. If the source is
264 * null, then either method is appropriate and the one that is invoked is
265 * undefined. For that reason we recommend against targeting overloaded
266 * methods.
267 *
268 * @see java.lang.reflect.Proxy
269 * @see java.util.EventObject
270 *
271 * @since 1.4
272 *
273 * @author Mark Davidson
274 * @author Philip Milne
275 * @author Hans Muller
276 *
277 */
278public class EventHandler implements InvocationHandler {
279 private Object target;
280 private String action;
281 private final String eventPropertyName;
282 private final String listenerMethodName;
283 private final AccessControlContext acc = AccessController.getContext();
284
285 /**
286 * Creates a new <code>EventHandler</code> object;
287 * you generally use one of the <code>create</code> methods
288 * instead of invoking this constructor directly. Refer to
289 * {@link java.beans.EventHandler#create(Class, Object, String, String)
290 * the general version of create} for a complete description of
291 * the <code>eventPropertyName</code> and <code>listenerMethodName</code>
292 * parameter.
293 *
294 * @param target the object that will perform the action
295 * @param action the name of a (possibly qualified) property or method on
296 * the target
297 * @param eventPropertyName the (possibly qualified) name of a readable property of the incoming event
298 * @param listenerMethodName the name of the method in the listener interface that should trigger the action
299 *
300 * @throws NullPointerException if <code>target</code> is null
301 * @throws NullPointerException if <code>action</code> is null
302 *
303 * @see EventHandler
304 * @see #create(Class, Object, String, String, String)
305 * @see #getTarget
306 * @see #getAction
307 * @see #getEventPropertyName
308 * @see #getListenerMethodName
309 */
310 @ConstructorProperties({"target", "action", "eventPropertyName", "listenerMethodName"})
311 public EventHandler(Object target, String action, String eventPropertyName, String listenerMethodName) {
312 this.target = target;
313 this.action = action;
314 if (target == null) {
315 throw new NullPointerException("target must be non-null");
316 }
317 if (action == null) {
318 throw new NullPointerException("action must be non-null");
319 }
320 this.eventPropertyName = eventPropertyName;
321 this.listenerMethodName = listenerMethodName;
322 }
323
324 /**
325 * Returns the object to which this event handler will send a message.
326 *
327 * @return the target of this event handler
328 * @see #EventHandler(Object, String, String, String)
329 */
330 public Object getTarget() {
331 return target;
332 }
333
334 /**
335 * Returns the name of the target's writable property
336 * that this event handler will set,
337 * or the name of the method that this event handler
338 * will invoke on the target.
339 *
340 * @return the action of this event handler
341 * @see #EventHandler(Object, String, String, String)
342 */
343 public String getAction() {
344 return action;
345 }
346
347 /**
348 * Returns the property of the event that should be
349 * used in the action applied to the target.
350 *
351 * @return the property of the event
352 *
353 * @see #EventHandler(Object, String, String, String)
354 */
355 public String getEventPropertyName() {
356 return eventPropertyName;
357 }
358
359 /**
360 * Returns the name of the method that will trigger the action.
361 * A return value of <code>null</code> signifies that all methods in the
362 * listener interface trigger the action.
363 *
364 * @return the name of the method that will trigger the action
365 *
366 * @see #EventHandler(Object, String, String, String)
367 */
368 public String getListenerMethodName() {
369 return listenerMethodName;
370 }
371
372 private Object applyGetters(Object target, String getters) {
373 if (getters == null || getters.equals("")) {
374 return target;
375 }
376 int firstDot = getters.indexOf('.');
377 if (firstDot == -1) {
378 firstDot = getters.length();
379 }
380 String first = getters.substring(0, firstDot);
381 String rest = getters.substring(Math.min(firstDot + 1, getters.length()));
382
383 try {
384 Method getter = null;
385 if (target != null) {
386 getter = Statement.getMethod(target.getClass(),
387 "get" + NameGenerator.capitalize(first),
388 new Class[]{});
389 if (getter == null) {
390 getter = Statement.getMethod(target.getClass(),
391 "is" + NameGenerator.capitalize(first),
392 new Class[]{});
393 }
394 if (getter == null) {
395 getter = Statement.getMethod(target.getClass(), first, new Class[]{});
396 }
397 }
398 if (getter == null) {
399 throw new RuntimeException("No method called: " + first +
400 " defined on " + target);
401 }
402 Object newTarget = MethodUtil.invoke(getter, target, new Object[]{});
403 return applyGetters(newTarget, rest);
404 }
405 catch (Exception e) {
406 throw new RuntimeException("Failed to call method: " + first +
407 " on " + target, e);
408 }
409 }
410
411 /**
412 * Extract the appropriate property value from the event and
413 * pass it to the action associated with
414 * this <code>EventHandler</code>.
415 *
416 * @param proxy the proxy object
417 * @param method the method in the listener interface
418 * @return the result of applying the action to the target
419 *
420 * @see EventHandler
421 */
422 public Object invoke(final Object proxy, final Method method, final Object[] arguments) {
423 AccessControlContext acc = this.acc;
424 if ((acc == null) && (System.getSecurityManager() != null)) {
425 throw new SecurityException("AccessControlContext is not set");
426 }
427 return AccessController.doPrivileged(new PrivilegedAction<Object>() {
428 public Object run() {
429 return invokeInternal(proxy, method, arguments);
430 }
431 }, acc);
432 }
433
434 private Object invokeInternal(Object proxy, Method method, Object[] arguments) {
435 String methodName = method.getName();
436 if (method.getDeclaringClass() == Object.class) {
437 // Handle the Object public methods.
438 if (methodName.equals("hashCode")) {
439 return new Integer(System.identityHashCode(proxy));
440 } else if (methodName.equals("equals")) {
441 return (proxy == arguments[0] ? Boolean.TRUE : Boolean.FALSE);
442 } else if (methodName.equals("toString")) {
443 return proxy.getClass().getName() + '@' + Integer.toHexString(proxy.hashCode());
444 }
445 }
446
447 if (listenerMethodName == null || listenerMethodName.equals(methodName)) {
448 Class[] argTypes = null;
449 Object[] newArgs = null;
450
451 if (eventPropertyName == null) { // Nullary method.
452 newArgs = new Object[]{};
453 argTypes = new Class[]{};
454 }
455 else {
456 Object input = applyGetters(arguments[0], getEventPropertyName());
457 newArgs = new Object[]{input};
458 argTypes = new Class[]{input == null ? null :
459 input.getClass()};
460 }
461 try {
462 int lastDot = action.lastIndexOf('.');
463 if (lastDot != -1) {
464 target = applyGetters(target, action.substring(0, lastDot));
465 action = action.substring(lastDot + 1);
466 }
467 Method targetMethod = Statement.getMethod(
468 target.getClass(), action, argTypes);
469 if (targetMethod == null) {
470 targetMethod = Statement.getMethod(target.getClass(),
471 "set" + NameGenerator.capitalize(action), argTypes);
472 }
473 if (targetMethod == null) {
474 String argTypeString = (argTypes.length == 0)
475 ? " with no arguments"
476 : " with argument " + argTypes[0];
477 throw new RuntimeException(
478 "No method called " + action + " on " +
479 target.getClass() + argTypeString);
480 }
481 return MethodUtil.invoke(targetMethod, target, newArgs);
482 }
483 catch (IllegalAccessException ex) {
484 throw new RuntimeException(ex);
485 }
486 catch (InvocationTargetException ex) {
487 Throwable th = ex.getTargetException();
488 throw (th instanceof RuntimeException)
489 ? (RuntimeException) th
490 : new RuntimeException(th);
491 }
492 }
493 return null;
494 }
495
496 /**
497 * Creates an implementation of <code>listenerInterface</code> in which
498 * <em>all</em> of the methods in the listener interface apply
499 * the handler's <code>action</code> to the <code>target</code>. This
500 * method is implemented by calling the other, more general,
501 * implementation of the <code>create</code> method with both
502 * the <code>eventPropertyName</code> and the <code>listenerMethodName</code>
503 * taking the value <code>null</code>. Refer to
504 * {@link java.beans.EventHandler#create(Class, Object, String, String)
505 * the general version of create} for a complete description of
506 * the <code>action</code> parameter.
507 * <p>
508 * To create an <code>ActionListener</code> that shows a
509 * <code>JDialog</code> with <code>dialog.show()</code>,
510 * one can write:
511 *
512 *<blockquote>
513 *<pre>
514 *EventHandler.create(ActionListener.class, dialog, "show")
515 *</pre>
516 *</blockquote>
517 *
518 * @param listenerInterface the listener interface to create a proxy for
519 * @param target the object that will perform the action
520 * @param action the name of a (possibly qualified) property or method on
521 * the target
522 * @return an object that implements <code>listenerInterface</code>
523 *
524 * @throws NullPointerException if <code>listenerInterface</code> is null
525 * @throws NullPointerException if <code>target</code> is null
526 * @throws NullPointerException if <code>action</code> is null
527 *
528 * @see #create(Class, Object, String, String)
529 */
530 public static <T> T create(Class<T> listenerInterface,
531 Object target, String action)
532 {
533 return create(listenerInterface, target, action, null, null);
534 }
535
536 /**
537 /**
538 * Creates an implementation of <code>listenerInterface</code> in which
539 * <em>all</em> of the methods pass the value of the event
540 * expression, <code>eventPropertyName</code>, to the final method in the
541 * statement, <code>action</code>, which is applied to the <code>target</code>.
542 * This method is implemented by calling the
543 * more general, implementation of the <code>create</code> method with
544 * the <code>listenerMethodName</code> taking the value <code>null</code>.
545 * Refer to
546 * {@link java.beans.EventHandler#create(Class, Object, String, String)
547 * the general version of create} for a complete description of
548 * the <code>action</code> and <code>eventPropertyName</code> parameters.
549 * <p>
550 * To create an <code>ActionListener</code> that sets the
551 * the text of a <code>JLabel</code> to the text value of
552 * the <code>JTextField</code> source of the incoming event,
553 * you can use the following code:
554 *
555 *<blockquote>
556 *<pre>
557 *EventHandler.create(ActionListener.class, label, "text", "source.text");
558 *</pre>
559 *</blockquote>
560 *
561 * This is equivalent to the following code:
562 *<blockquote>
563 *<pre>
564//Equivalent code using an inner class instead of EventHandler.
565 *new ActionListener() {
566 * public void actionPerformed(ActionEvent event) {
567 * label.setText(((JTextField)(event.getSource())).getText());
568 * }
569 *};
570 *</pre>
571 *</blockquote>
572 *
573 * @param listenerInterface the listener interface to create a proxy for
574 * @param target the object that will perform the action
575 * @param action the name of a (possibly qualified) property or method on
576 * the target
577 * @param eventPropertyName the (possibly qualified) name of a readable property of the incoming event
578 *
579 * @return an object that implements <code>listenerInterface</code>
580 *
581 * @throws NullPointerException if <code>listenerInterface</code> is null
582 * @throws NullPointerException if <code>target</code> is null
583 * @throws NullPointerException if <code>action</code> is null
584 *
585 * @see #create(Class, Object, String, String, String)
586 */
587 public static <T> T create(Class<T> listenerInterface,
588 Object target, String action,
589 String eventPropertyName)
590 {
591 return create(listenerInterface, target, action, eventPropertyName, null);
592 }
593
594 /**
595 * Creates an implementation of <code>listenerInterface</code> in which
596 * the method named <code>listenerMethodName</code>
597 * passes the value of the event expression, <code>eventPropertyName</code>,
598 * to the final method in the statement, <code>action</code>, which
599 * is applied to the <code>target</code>. All of the other listener
600 * methods do nothing.
601 * <p>
602 * The <code>eventPropertyName</code> string is used to extract a value
603 * from the incoming event object that is passed to the target
604 * method. The common case is the target method takes no arguments, in
605 * which case a value of null should be used for the
606 * <code>eventPropertyName</code>. Alternatively if you want
607 * the incoming event object passed directly to the target method use
608 * the empty string.
609 * The format of the <code>eventPropertyName</code> string is a sequence of
610 * methods or properties where each method or
611 * property is applied to the value returned by the preceeding method
612 * starting from the incoming event object.
613 * The syntax is: <code>propertyName{.propertyName}*</code>
614 * where <code>propertyName</code> matches a method or
615 * property. For example, to extract the <code>point</code>
616 * property from a <code>MouseEvent</code>, you could use either
617 * <code>"point"</code> or <code>"getPoint"</code> as the
618 * <code>eventPropertyName</code>. To extract the "text" property from
619 * a <code>MouseEvent</code> with a <code>JLabel</code> source use any
620 * of the following as <code>eventPropertyName</code>:
621 * <code>"source.text"</code>,
622 * <code>"getSource.text"</code> <code>"getSource.getText"</code> or
623 * <code>"source.getText"</code>. If a method can not be found, or an
624 * exception is generated as part of invoking a method a
625 * <code>RuntimeException</code> will be thrown at dispatch time. For
626 * example, if the incoming event object is null, and
627 * <code>eventPropertyName</code> is non-null and not empty, a
628 * <code>RuntimeException</code> will be thrown.
629 * <p>
630 * The <code>action</code> argument is of the same format as the
631 * <code>eventPropertyName</code> argument where the last property name
632 * identifies either a method name or writable property.
633 * <p>
634 * If the <code>listenerMethodName</code> is <code>null</code>
635 * <em>all</em> methods in the interface trigger the <code>action</code> to be
636 * executed on the <code>target</code>.
637 * <p>
638 * For example, to create a <code>MouseListener</code> that sets the target
639 * object's <code>origin</code> property to the incoming <code>MouseEvent</code>'s
640 * location (that's the value of <code>mouseEvent.getPoint()</code>) each
641 * time a mouse button is pressed, one would write:
642 *<blockquote>
643 *<pre>
644 *EventHandler.create(MouseListener.class, target, "origin", "point", "mousePressed");
645 *</pre>
646 *</blockquote>
647 *
648 * This is comparable to writing a <code>MouseListener</code> in which all
649 * of the methods except <code>mousePressed</code> are no-ops:
650 *
651 *<blockquote>
652 *<pre>
653//Equivalent code using an inner class instead of EventHandler.
654 *new MouseAdapter() {
655 * public void mousePressed(MouseEvent e) {
656 * target.setOrigin(e.getPoint());
657 * }
658 *};
659 * </pre>
660 *</blockquote>
661 *
662 * @param listenerInterface the listener interface to create a proxy for
663 * @param target the object that will perform the action
664 * @param action the name of a (possibly qualified) property or method on
665 * the target
666 * @param eventPropertyName the (possibly qualified) name of a readable property of the incoming event
667 * @param listenerMethodName the name of the method in the listener interface that should trigger the action
668 *
669 * @return an object that implements <code>listenerInterface</code>
670 *
671 * @throws NullPointerException if <code>listenerInterface</code> is null
672 * @throws NullPointerException if <code>target</code> is null
673 * @throws NullPointerException if <code>action</code> is null
674 *
675 * @see EventHandler
676 */
677 public static <T> T create(Class<T> listenerInterface,
678 Object target, String action,
679 String eventPropertyName,
680 String listenerMethodName)
681 {
682 // Create this first to verify target/action are non-null
683 EventHandler eventHandler = new EventHandler(target, action,
684 eventPropertyName,
685 listenerMethodName);
686 if (listenerInterface == null) {
687 throw new NullPointerException(
688 "listenerInterface must be non-null");
689 }
690 return (T)Proxy.newProxyInstance(target.getClass().getClassLoader(),
691 new Class[] {listenerInterface},
692 eventHandler);
693 }
694}
java/pkg/java/beans/EventSetDescriptor.class+0−0

Binary file not shown.

java/pkg/java/beans/EventSetDescriptor.java+536−0
@@ -0,0 +1,536 @@
1/*
2 * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.beans;
27
28import java.lang.ref.Reference;
29import java.lang.reflect.Method;
30import java.lang.reflect.Modifier;
31
32/**
33 * An EventSetDescriptor describes a group of events that a given Java
34 * bean fires.
35 * <P>
36 * The given group of events are all delivered as method calls on a single
37 * event listener interface, and an event listener object can be registered
38 * via a call on a registration method supplied by the event source.
39 */
40public class EventSetDescriptor extends FeatureDescriptor {
41
42 private MethodDescriptor[] listenerMethodDescriptors;
43 private MethodDescriptor addMethodDescriptor;
44 private MethodDescriptor removeMethodDescriptor;
45 private MethodDescriptor getMethodDescriptor;
46
47 private Reference<Method[]> listenerMethodsRef;
48 private Reference<Class> listenerTypeRef;
49
50 private boolean unicast;
51 private boolean inDefaultEventSet = true;
52
53 /**
54 * Creates an <TT>EventSetDescriptor</TT> assuming that you are
55 * following the most simple standard design pattern where a named
56 * event &quot;fred&quot; is (1) delivered as a call on the single method of
57 * interface FredListener, (2) has a single argument of type FredEvent,
58 * and (3) where the FredListener may be registered with a call on an
59 * addFredListener method of the source component and removed with a
60 * call on a removeFredListener method.
61 *
62 * @param sourceClass The class firing the event.
63 * @param eventSetName The programmatic name of the event. E.g. &quot;fred&quot;.
64 * Note that this should normally start with a lower-case character.
65 * @param listenerType The target interface that events
66 * will get delivered to.
67 * @param listenerMethodName The method that will get called when the event gets
68 * delivered to its target listener interface.
69 * @exception IntrospectionException if an exception occurs during
70 * introspection.
71 */
72 public EventSetDescriptor(Class<?> sourceClass, String eventSetName,
73 Class<?> listenerType, String listenerMethodName)
74 throws IntrospectionException {
75 this(sourceClass, eventSetName, listenerType,
76 new String[] { listenerMethodName },
77 Introspector.ADD_PREFIX + getListenerClassName(listenerType),
78 Introspector.REMOVE_PREFIX + getListenerClassName(listenerType),
79 Introspector.GET_PREFIX + getListenerClassName(listenerType) + "s");
80
81 String eventName = NameGenerator.capitalize(eventSetName) + "Event";
82 Method[] listenerMethods = getListenerMethods();
83 if (listenerMethods.length > 0) {
84 Class[] args = getParameterTypes(getClass0(), listenerMethods[0]);
85 // Check for EventSet compliance. Special case for vetoableChange. See 4529996
86 if (!"vetoableChange".equals(eventSetName) && !args[0].getName().endsWith(eventName)) {
87 throw new IntrospectionException("Method \"" + listenerMethodName +
88 "\" should have argument \"" +
89 eventName + "\"");
90 }
91 }
92 }
93
94 private static String getListenerClassName(Class cls) {
95 String className = cls.getName();
96 return className.substring(className.lastIndexOf('.') + 1);
97 }
98
99 /**
100 * Creates an <TT>EventSetDescriptor</TT> from scratch using
101 * string names.
102 *
103 * @param sourceClass The class firing the event.
104 * @param eventSetName The programmatic name of the event set.
105 * Note that this should normally start with a lower-case character.
106 * @param listenerType The Class of the target interface that events
107 * will get delivered to.
108 * @param listenerMethodNames The names of the methods that will get called
109 * when the event gets delivered to its target listener interface.
110 * @param addListenerMethodName The name of the method on the event source
111 * that can be used to register an event listener object.
112 * @param removeListenerMethodName The name of the method on the event source
113 * that can be used to de-register an event listener object.
114 * @exception IntrospectionException if an exception occurs during
115 * introspection.
116 */
117 public EventSetDescriptor(Class<?> sourceClass,
118 String eventSetName,
119 Class<?> listenerType,
120 String listenerMethodNames[],
121 String addListenerMethodName,
122 String removeListenerMethodName)
123 throws IntrospectionException {
124 this(sourceClass, eventSetName, listenerType,
125 listenerMethodNames, addListenerMethodName,
126 removeListenerMethodName, null);
127 }
128
129 /**
130 * This constructor creates an EventSetDescriptor from scratch using
131 * string names.
132 *
133 * @param sourceClass The class firing the event.
134 * @param eventSetName The programmatic name of the event set.
135 * Note that this should normally start with a lower-case character.
136 * @param listenerType The Class of the target interface that events
137 * will get delivered to.
138 * @param listenerMethodNames The names of the methods that will get called
139 * when the event gets delivered to its target listener interface.
140 * @param addListenerMethodName The name of the method on the event source
141 * that can be used to register an event listener object.
142 * @param removeListenerMethodName The name of the method on the event source
143 * that can be used to de-register an event listener object.
144 * @param getListenerMethodName The method on the event source that
145 * can be used to access the array of event listener objects.
146 * @exception IntrospectionException if an exception occurs during
147 * introspection.
148 * @since 1.4
149 */
150 public EventSetDescriptor(Class<?> sourceClass,
151 String eventSetName,
152 Class<?> listenerType,
153 String listenerMethodNames[],
154 String addListenerMethodName,
155 String removeListenerMethodName,
156 String getListenerMethodName)
157 throws IntrospectionException {
158 if (sourceClass == null || eventSetName == null || listenerType == null) {
159 throw new NullPointerException();
160 }
161 setName(eventSetName);
162 setClass0(sourceClass);
163 setListenerType(listenerType);
164
165 Method[] listenerMethods = new Method[listenerMethodNames.length];
166 for (int i = 0; i < listenerMethodNames.length; i++) {
167 // Check for null names
168 if (listenerMethodNames[i] == null) {
169 throw new NullPointerException();
170 }
171 listenerMethods[i] = getMethod(listenerType, listenerMethodNames[i], 1);
172 }
173 setListenerMethods(listenerMethods);
174
175 setAddListenerMethod(getMethod(sourceClass, addListenerMethodName, 1));
176 setRemoveListenerMethod(getMethod(sourceClass, removeListenerMethodName, 1));
177
178 // Be more forgiving of not finding the getListener method.
179 Method method = Introspector.findMethod(sourceClass, getListenerMethodName, 0);
180 if (method != null) {
181 setGetListenerMethod(method);
182 }
183 }
184
185 private static Method getMethod(Class cls, String name, int args)
186 throws IntrospectionException {
187 if (name == null) {
188 return null;
189 }
190 Method method = Introspector.findMethod(cls, name, args);
191 if ((method == null) || Modifier.isStatic(method.getModifiers())) {
192 throw new IntrospectionException("Method not found: " + name +
193 " on class " + cls.getName());
194 }
195 return method;
196 }
197
198 /**
199 * Creates an <TT>EventSetDescriptor</TT> from scratch using
200 * <TT>java.lang.reflect.Method</TT> and <TT>java.lang.Class</TT> objects.
201 *
202 * @param eventSetName The programmatic name of the event set.
203 * @param listenerType The Class for the listener interface.
204 * @param listenerMethods An array of Method objects describing each
205 * of the event handling methods in the target listener.
206 * @param addListenerMethod The method on the event source
207 * that can be used to register an event listener object.
208 * @param removeListenerMethod The method on the event source
209 * that can be used to de-register an event listener object.
210 * @exception IntrospectionException if an exception occurs during
211 * introspection.
212 */
213 public EventSetDescriptor(String eventSetName,
214 Class<?> listenerType,
215 Method listenerMethods[],
216 Method addListenerMethod,
217 Method removeListenerMethod)
218 throws IntrospectionException {
219 this(eventSetName, listenerType, listenerMethods,
220 addListenerMethod, removeListenerMethod, null);
221 }
222
223 /**
224 * This constructor creates an EventSetDescriptor from scratch using
225 * java.lang.reflect.Method and java.lang.Class objects.
226 *
227 * @param eventSetName The programmatic name of the event set.
228 * @param listenerType The Class for the listener interface.
229 * @param listenerMethods An array of Method objects describing each
230 * of the event handling methods in the target listener.
231 * @param addListenerMethod The method on the event source
232 * that can be used to register an event listener object.
233 * @param removeListenerMethod The method on the event source
234 * that can be used to de-register an event listener object.
235 * @param getListenerMethod The method on the event source
236 * that can be used to access the array of event listener objects.
237 * @exception IntrospectionException if an exception occurs during
238 * introspection.
239 * @since 1.4
240 */
241 public EventSetDescriptor(String eventSetName,
242 Class<?> listenerType,
243 Method listenerMethods[],
244 Method addListenerMethod,
245 Method removeListenerMethod,
246 Method getListenerMethod)
247 throws IntrospectionException {
248 setName(eventSetName);
249 setListenerMethods(listenerMethods);
250 setAddListenerMethod(addListenerMethod);
251 setRemoveListenerMethod( removeListenerMethod);
252 setGetListenerMethod(getListenerMethod);
253 setListenerType(listenerType);
254 }
255
256 /**
257 * Creates an <TT>EventSetDescriptor</TT> from scratch using
258 * <TT>java.lang.reflect.MethodDescriptor</TT> and <TT>java.lang.Class</TT>
259 * objects.
260 *
261 * @param eventSetName The programmatic name of the event set.
262 * @param listenerType The Class for the listener interface.
263 * @param listenerMethodDescriptors An array of MethodDescriptor objects
264 * describing each of the event handling methods in the
265 * target listener.
266 * @param addListenerMethod The method on the event source
267 * that can be used to register an event listener object.
268 * @param removeListenerMethod The method on the event source
269 * that can be used to de-register an event listener object.
270 * @exception IntrospectionException if an exception occurs during
271 * introspection.
272 */
273 public EventSetDescriptor(String eventSetName,
274 Class<?> listenerType,
275 MethodDescriptor listenerMethodDescriptors[],
276 Method addListenerMethod,
277 Method removeListenerMethod)
278 throws IntrospectionException {
279 setName(eventSetName);
280 this.listenerMethodDescriptors = listenerMethodDescriptors;
281 setAddListenerMethod(addListenerMethod);
282 setRemoveListenerMethod(removeListenerMethod);
283 setListenerType(listenerType);
284 }
285
286 /**
287 * Gets the <TT>Class</TT> object for the target interface.
288 *
289 * @return The Class object for the target interface that will
290 * get invoked when the event is fired.
291 */
292 public Class<?> getListenerType() {
293 return (this.listenerTypeRef != null)
294 ? this.listenerTypeRef.get()
295 : null;
296 }
297
298 private void setListenerType(Class cls) {
299 this.listenerTypeRef = getWeakReference(cls);
300 }
301
302 /**
303 * Gets the methods of the target listener interface.
304 *
305 * @return An array of <TT>Method</TT> objects for the target methods
306 * within the target listener interface that will get called when
307 * events are fired.
308 */
309 public synchronized Method[] getListenerMethods() {
310 Method[] methods = getListenerMethods0();
311 if (methods == null) {
312 if (listenerMethodDescriptors != null) {
313 methods = new Method[listenerMethodDescriptors.length];
314 for (int i = 0; i < methods.length; i++) {
315 methods[i] = listenerMethodDescriptors[i].getMethod();
316 }
317 }
318 setListenerMethods(methods);
319 }
320 return methods;
321 }
322
323 private void setListenerMethods(Method[] methods) {
324 if (methods == null) {
325 return;
326 }
327 if (listenerMethodDescriptors == null) {
328 listenerMethodDescriptors = new MethodDescriptor[methods.length];
329 for (int i = 0; i < methods.length; i++) {
330 listenerMethodDescriptors[i] = new MethodDescriptor(methods[i]);
331 }
332 }
333 this.listenerMethodsRef = getSoftReference(methods);
334 }
335
336 private Method[] getListenerMethods0() {
337 return (this.listenerMethodsRef != null)
338 ? this.listenerMethodsRef.get()
339 : null;
340 }
341
342 /**
343 * Gets the <code>MethodDescriptor</code>s of the target listener interface.
344 *
345 * @return An array of <code>MethodDescriptor</code> objects for the target methods
346 * within the target listener interface that will get called when
347 * events are fired.
348 */
349 public synchronized MethodDescriptor[] getListenerMethodDescriptors() {
350 return listenerMethodDescriptors;
351 }
352
353 /**
354 * Gets the method used to add event listeners.
355 *
356 * @return The method used to register a listener at the event source.
357 */
358 public synchronized Method getAddListenerMethod() {
359 return getMethod(this.addMethodDescriptor);
360 }
361
362 private synchronized void setAddListenerMethod(Method method) {
363 if (method == null) {
364 return;
365 }
366 if (getClass0() == null) {
367 setClass0(method.getDeclaringClass());
368 }
369 addMethodDescriptor = new MethodDescriptor(method);
370 setTransient(method.getAnnotation(Transient.class));
371 }
372
373 /**
374 * Gets the method used to remove event listeners.
375 *
376 * @return The method used to remove a listener at the event source.
377 */
378 public synchronized Method getRemoveListenerMethod() {
379 return getMethod(this.removeMethodDescriptor);
380 }
381
382 private synchronized void setRemoveListenerMethod(Method method) {
383 if (method == null) {
384 return;
385 }
386 if (getClass0() == null) {
387 setClass0(method.getDeclaringClass());
388 }
389 removeMethodDescriptor = new MethodDescriptor(method);
390 setTransient(method.getAnnotation(Transient.class));
391 }
392
393 /**
394 * Gets the method used to access the registered event listeners.
395 *
396 * @return The method used to access the array of listeners at the event
397 * source or null if it doesn't exist.
398 * @since 1.4
399 */
400 public synchronized Method getGetListenerMethod() {
401 return getMethod(this.getMethodDescriptor);
402 }
403
404 private synchronized void setGetListenerMethod(Method method) {
405 if (method == null) {
406 return;
407 }
408 if (getClass0() == null) {
409 setClass0(method.getDeclaringClass());
410 }
411 getMethodDescriptor = new MethodDescriptor(method);
412 setTransient(method.getAnnotation(Transient.class));
413 }
414
415 /**
416 * Mark an event set as unicast (or not).
417 *
418 * @param unicast True if the event set is unicast.
419 */
420 public void setUnicast(boolean unicast) {
421 this.unicast = unicast;
422 }
423
424 /**
425 * Normally event sources are multicast. However there are some
426 * exceptions that are strictly unicast.
427 *
428 * @return <TT>true</TT> if the event set is unicast.
429 * Defaults to <TT>false</TT>.
430 */
431 public boolean isUnicast() {
432 return unicast;
433 }
434
435 /**
436 * Marks an event set as being in the &quot;default&quot; set (or not).
437 * By default this is <TT>true</TT>.
438 *
439 * @param inDefaultEventSet <code>true</code> if the event set is in
440 * the &quot;default&quot; set,
441 * <code>false</code> if not
442 */
443 public void setInDefaultEventSet(boolean inDefaultEventSet) {
444 this.inDefaultEventSet = inDefaultEventSet;
445 }
446
447 /**
448 * Reports if an event set is in the &quot;default&quot; set.
449 *
450 * @return <TT>true</TT> if the event set is in
451 * the &quot;default&quot; set. Defaults to <TT>true</TT>.
452 */
453 public boolean isInDefaultEventSet() {
454 return inDefaultEventSet;
455 }
456
457 /*
458 * Package-private constructor
459 * Merge two event set descriptors. Where they conflict, give the
460 * second argument (y) priority over the first argument (x).
461 *
462 * @param x The first (lower priority) EventSetDescriptor
463 * @param y The second (higher priority) EventSetDescriptor
464 */
465 EventSetDescriptor(EventSetDescriptor x, EventSetDescriptor y) {
466 super(x,y);
467 listenerMethodDescriptors = x.listenerMethodDescriptors;
468 if (y.listenerMethodDescriptors != null) {
469 listenerMethodDescriptors = y.listenerMethodDescriptors;
470 }
471
472 listenerTypeRef = x.listenerTypeRef;
473 if (y.listenerTypeRef != null) {
474 listenerTypeRef = y.listenerTypeRef;
475 }
476
477 addMethodDescriptor = x.addMethodDescriptor;
478 if (y.addMethodDescriptor != null) {
479 addMethodDescriptor = y.addMethodDescriptor;
480 }
481
482 removeMethodDescriptor = x.removeMethodDescriptor;
483 if (y.removeMethodDescriptor != null) {
484 removeMethodDescriptor = y.removeMethodDescriptor;
485 }
486
487 getMethodDescriptor = x.getMethodDescriptor;
488 if (y.getMethodDescriptor != null) {
489 getMethodDescriptor = y.getMethodDescriptor;
490 }
491
492 unicast = y.unicast;
493 if (!x.inDefaultEventSet || !y.inDefaultEventSet) {
494 inDefaultEventSet = false;
495 }
496 }
497
498 /*
499 * Package-private dup constructor
500 * This must isolate the new object from any changes to the old object.
501 */
502 EventSetDescriptor(EventSetDescriptor old) {
503 super(old);
504 if (old.listenerMethodDescriptors != null) {
505 int len = old.listenerMethodDescriptors.length;
506 listenerMethodDescriptors = new MethodDescriptor[len];
507 for (int i = 0; i < len; i++) {
508 listenerMethodDescriptors[i] = new MethodDescriptor(
509 old.listenerMethodDescriptors[i]);
510 }
511 }
512 listenerTypeRef = old.listenerTypeRef;
513
514 addMethodDescriptor = old.addMethodDescriptor;
515 removeMethodDescriptor = old.removeMethodDescriptor;
516 getMethodDescriptor = old.getMethodDescriptor;
517
518 unicast = old.unicast;
519 inDefaultEventSet = old.inDefaultEventSet;
520 }
521
522 void appendTo(StringBuilder sb) {
523 appendTo(sb, "unicast", this.unicast);
524 appendTo(sb, "inDefaultEventSet", this.inDefaultEventSet);
525 appendTo(sb, "listenerType", this.listenerTypeRef);
526 appendTo(sb, "getListenerMethod", getMethod(this.getMethodDescriptor));
527 appendTo(sb, "addListenerMethod", getMethod(this.addMethodDescriptor));
528 appendTo(sb, "removeListenerMethod", getMethod(this.removeMethodDescriptor));
529 }
530
531 private static Method getMethod(MethodDescriptor descriptor) {
532 return (descriptor != null)
533 ? descriptor.getMethod()
534 : null;
535 }
536}
java/pkg/java/beans/ExceptionListener.class+0−0

Binary file not shown.

java/pkg/java/beans/ExceptionListener.java+43−0
@@ -0,0 +1,43 @@
1/*
2 * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25package java.beans;
26
27/**
28 * An ExceptionListener is notified of internal exceptions.
29 *
30 * @since 1.4
31 *
32 * @author Philip Milne
33 */
34public interface ExceptionListener {
35 /**
36 * This method is called when a recoverable exception has
37 * been caught.
38 *
39 * @param e The exception that was caught.
40 *
41 */
42 public void exceptionThrown(Exception e);
43}
java/pkg/java/beans/Expression.class+0−0

Binary file not shown.

java/pkg/java/beans/Expression.java+182−0
@@ -0,0 +1,182 @@
1/*
2 * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.beans;
27
28/**
29 * An <code>Expression</code> object represents a primitive expression
30 * in which a single method is applied to a target and a set of
31 * arguments to return a result - as in <code>"a.getFoo()"</code>.
32 * <p>
33 * In addition to the properties of the super class, the
34 * <code>Expression</code> object provides a <em>value</em> which
35 * is the object returned when this expression is evaluated.
36 * The return value is typically not provided by the caller and
37 * is instead computed by dynamically finding the method and invoking
38 * it when the first call to <code>getValue</code> is made.
39 *
40 * @see #getValue
41 * @see #setValue
42 *
43 * @since 1.4
44 *
45 * @author Philip Milne
46 */
47public class Expression extends Statement {
48
49 private static Object unbound = new Object();
50
51 private Object value = unbound;
52
53 /**
54 * Creates a new {@link Expression} object
55 * for the specified target object to invoke the method
56 * specified by the name and by the array of arguments.
57 * <p>
58 * The {@code target} and the {@code methodName} values should not be {@code null}.
59 * Otherwise an attempt to execute this {@code Expression}
60 * will result in a {@code NullPointerException}.
61 * If the {@code arguments} value is {@code null},
62 * an empty array is used as the value of the {@code arguments} property.
63 *
64 * @param target the target object of this expression
65 * @param methodName the name of the method to invoke on the specified target
66 * @param arguments the array of arguments to invoke the specified method
67 *
68 * @see #getValue
69 */
70 @ConstructorProperties({"target", "methodName", "arguments"})
71 public Expression(Object target, String methodName, Object[] arguments) {
72 super(target, methodName, arguments);
73 }
74
75 /**
76 * Creates a new {@link Expression} object with the specified value
77 * for the specified target object to invoke the method
78 * specified by the name and by the array of arguments.
79 * The {@code value} value is used as the value of the {@code value} property,
80 * so the {@link #getValue} method will return it
81 * without executing this {@code Expression}.
82 * <p>
83 * The {@code target} and the {@code methodName} values should not be {@code null}.
84 * Otherwise an attempt to execute this {@code Expression}
85 * will result in a {@code NullPointerException}.
86 * If the {@code arguments} value is {@code null},
87 * an empty array is used as the value of the {@code arguments} property.
88 *
89 * @param value the value of this expression
90 * @param target the target object of this expression
91 * @param methodName the name of the method to invoke on the specified target
92 * @param arguments the array of arguments to invoke the specified method
93 *
94 * @see #setValue
95 */
96 public Expression(Object value, Object target, String methodName, Object[] arguments) {
97 this(target, methodName, arguments);
98 setValue(value);
99 }
100
101 /**
102 * {@inheritDoc}
103 * <p>
104 * If the invoked method completes normally,
105 * the value it returns is copied in the {@code value} property.
106 * Note that the {@code value} property is set to {@code null},
107 * if the return type of the underlying method is {@code void}.
108 *
109 * @throws NullPointerException if the value of the {@code target} or
110 * {@code methodName} property is {@code null}
111 * @throws NoSuchMethodException if a matching method is not found
112 * @throws SecurityException if a security manager exists and
113 * it denies the method invocation
114 * @throws Exception that is thrown by the invoked method
115 *
116 * @see java.lang.reflect.Method
117 * @since 1.7
118 */
119 @Override
120 public void execute() throws Exception {
121 setValue(invoke());
122 }
123
124 /**
125 * If the value property of this instance is not already set,
126 * this method dynamically finds the method with the specified
127 * methodName on this target with these arguments and calls it.
128 * The result of the method invocation is first copied
129 * into the value property of this expression and then returned
130 * as the result of <code>getValue</code>. If the value property
131 * was already set, either by a call to <code>setValue</code>
132 * or a previous call to <code>getValue</code> then the value
133 * property is returned without either looking up or calling the method.
134 * <p>
135 * The value property of an <code>Expression</code> is set to
136 * a unique private (non-<code>null</code>) value by default and
137 * this value is used as an internal indication that the method
138 * has not yet been called. A return value of <code>null</code>
139 * replaces this default value in the same way that any other value
140 * would, ensuring that expressions are never evaluated more than once.
141 * <p>
142 * See the <code>excecute</code> method for details on how
143 * methods are chosen using the dynamic types of the target
144 * and arguments.
145 *
146 * @see Statement#execute
147 * @see #setValue
148 *
149 * @return The result of applying this method to these arguments.
150 */
151 public Object getValue() throws Exception {
152 if (value == unbound) {
153 setValue(invoke());
154 }
155 return value;
156 }
157
158 /**
159 * Sets the value of this expression to <code>value</code>.
160 * This value will be returned by the getValue method
161 * without calling the method associated with this
162 * expression.
163 *
164 * @param value The value of this expression.
165 *
166 * @see #getValue
167 */
168 public void setValue(Object value) {
169 this.value = value;
170 }
171
172 /*pp*/ String instanceName(Object instance) {
173 return instance == unbound ? "<unbound>" : super.instanceName(instance);
174 }
175
176 /**
177 * Prints the value of this expression using a Java-style syntax.
178 */
179 public String toString() {
180 return instanceName(value) + "=" + super.toString();
181 }
182}
java/pkg/java/beans/FeatureDescriptor.class+0−0

Binary file not shown.

java/pkg/java/beans/FeatureDescriptor.java+445−0
@@ -0,0 +1,445 @@
1/*
2 * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.beans;
27
28import com.sun.beans.TypeResolver;
29
30import java.lang.ref.Reference;
31import java.lang.ref.WeakReference;
32import java.lang.ref.SoftReference;
33
34import java.lang.reflect.Method;
35
36import java.util.Enumeration;
37import java.util.Hashtable;
38import java.util.Map.Entry;
39
40/**
41 * The FeatureDescriptor class is the common baseclass for PropertyDescriptor,
42 * EventSetDescriptor, and MethodDescriptor, etc.
43 * <p>
44 * It supports some common information that can be set and retrieved for
45 * any of the introspection descriptors.
46 * <p>
47 * In addition it provides an extension mechanism so that arbitrary
48 * attribute/value pairs can be associated with a design feature.
49 */
50
51public class FeatureDescriptor {
52 private static final String TRANSIENT = "transient";
53
54 private Reference<Class> classRef;
55
56 /**
57 * Constructs a <code>FeatureDescriptor</code>.
58 */
59 public FeatureDescriptor() {
60 }
61
62 /**
63 * Gets the programmatic name of this feature.
64 *
65 * @return The programmatic name of the property/method/event
66 */
67 public String getName() {
68 return name;
69 }
70
71 /**
72 * Sets the programmatic name of this feature.
73 *
74 * @param name The programmatic name of the property/method/event
75 */
76 public void setName(String name) {
77 this.name = name;
78 }
79
80 /**
81 * Gets the localized display name of this feature.
82 *
83 * @return The localized display name for the property/method/event.
84 * This defaults to the same as its programmatic name from getName.
85 */
86 public String getDisplayName() {
87 if (displayName == null) {
88 return getName();
89 }
90 return displayName;
91 }
92
93 /**
94 * Sets the localized display name of this feature.
95 *
96 * @param displayName The localized display name for the
97 * property/method/event.
98 */
99 public void setDisplayName(String displayName) {
100 this.displayName = displayName;
101 }
102
103 /**
104 * The "expert" flag is used to distinguish between those features that are
105 * intended for expert users from those that are intended for normal users.
106 *
107 * @return True if this feature is intended for use by experts only.
108 */
109 public boolean isExpert() {
110 return expert;
111 }
112
113 /**
114 * The "expert" flag is used to distinguish between features that are
115 * intended for expert users from those that are intended for normal users.
116 *
117 * @param expert True if this feature is intended for use by experts only.
118 */
119 public void setExpert(boolean expert) {
120 this.expert = expert;
121 }
122
123 /**
124 * The "hidden" flag is used to identify features that are intended only
125 * for tool use, and which should not be exposed to humans.
126 *
127 * @return True if this feature should be hidden from human users.
128 */
129 public boolean isHidden() {
130 return hidden;
131 }
132
133 /**
134 * The "hidden" flag is used to identify features that are intended only
135 * for tool use, and which should not be exposed to humans.
136 *
137 * @param hidden True if this feature should be hidden from human users.
138 */
139 public void setHidden(boolean hidden) {
140 this.hidden = hidden;
141 }
142
143 /**
144 * The "preferred" flag is used to identify features that are particularly
145 * important for presenting to humans.
146 *
147 * @return True if this feature should be preferentially shown to human users.
148 */
149 public boolean isPreferred() {
150 return preferred;
151 }
152
153 /**
154 * The "preferred" flag is used to identify features that are particularly
155 * important for presenting to humans.
156 *
157 * @param preferred True if this feature should be preferentially shown
158 * to human users.
159 */
160 public void setPreferred(boolean preferred) {
161 this.preferred = preferred;
162 }
163
164 /**
165 * Gets the short description of this feature.
166 *
167 * @return A localized short description associated with this
168 * property/method/event. This defaults to be the display name.
169 */
170 public String getShortDescription() {
171 if (shortDescription == null) {
172 return getDisplayName();
173 }
174 return shortDescription;
175 }
176
177 /**
178 * You can associate a short descriptive string with a feature. Normally
179 * these descriptive strings should be less than about 40 characters.
180 * @param text A (localized) short description to be associated with
181 * this property/method/event.
182 */
183 public void setShortDescription(String text) {
184 shortDescription = text;
185 }
186
187 /**
188 * Associate a named attribute with this feature.
189 *
190 * @param attributeName The locale-independent name of the attribute
191 * @param value The value.
192 */
193 public void setValue(String attributeName, Object value) {
194 getTable().put(attributeName, value);
195 }
196
197 /**
198 * Retrieve a named attribute with this feature.
199 *
200 * @param attributeName The locale-independent name of the attribute
201 * @return The value of the attribute. May be null if
202 * the attribute is unknown.
203 */
204 public Object getValue(String attributeName) {
205 return (this.table != null)
206 ? this.table.get(attributeName)
207 : null;
208 }
209
210 /**
211 * Gets an enumeration of the locale-independent names of this
212 * feature.
213 *
214 * @return An enumeration of the locale-independent names of any
215 * attributes that have been registered with setValue.
216 */
217 public Enumeration<String> attributeNames() {
218 return getTable().keys();
219 }
220
221 /**
222 * Package-private constructor,
223 * Merge information from two FeatureDescriptors.
224 * The merged hidden and expert flags are formed by or-ing the values.
225 * In the event of other conflicts, the second argument (y) is
226 * given priority over the first argument (x).
227 *
228 * @param x The first (lower priority) MethodDescriptor
229 * @param y The second (higher priority) MethodDescriptor
230 */
231 FeatureDescriptor(FeatureDescriptor x, FeatureDescriptor y) {
232 expert = x.expert | y.expert;
233 hidden = x.hidden | y.hidden;
234 preferred = x.preferred | y.preferred;
235 name = y.name;
236 shortDescription = x.shortDescription;
237 if (y.shortDescription != null) {
238 shortDescription = y.shortDescription;
239 }
240 displayName = x.displayName;
241 if (y.displayName != null) {
242 displayName = y.displayName;
243 }
244 classRef = x.classRef;
245 if (y.classRef != null) {
246 classRef = y.classRef;
247 }
248 addTable(x.table);
249 addTable(y.table);
250 }
251
252 /*
253 * Package-private dup constructor
254 * This must isolate the new object from any changes to the old object.
255 */
256 FeatureDescriptor(FeatureDescriptor old) {
257 expert = old.expert;
258 hidden = old.hidden;
259 preferred = old.preferred;
260 name = old.name;
261 shortDescription = old.shortDescription;
262 displayName = old.displayName;
263 classRef = old.classRef;
264
265 addTable(old.table);
266 }
267
268 /**
269 * Copies all values from the specified attribute table.
270 * If some attribute is exist its value should be overridden.
271 *
272 * @param table the attribute table with new values
273 */
274 private void addTable(Hashtable<String, Object> table) {
275 if ((table != null) && !table.isEmpty()) {
276 getTable().putAll(table);
277 }
278 }
279
280 /**
281 * Returns the initialized attribute table.
282 *
283 * @return the initialized attribute table
284 */
285 private Hashtable<String, Object> getTable() {
286 if (this.table == null) {
287 this.table = new Hashtable<String, Object>();
288 }
289 return this.table;
290 }
291
292 /**
293 * Sets the "transient" attribute according to the annotation.
294 * If the "transient" attribute is already set
295 * it should not be changed.
296 *
297 * @param annotation the annotation of the element of the feature
298 */
299 void setTransient(Transient annotation) {
300 if ((annotation != null) && (null == getValue(TRANSIENT))) {
301 setValue(TRANSIENT, annotation.value());
302 }
303 }
304
305 /**
306 * Indicates whether the feature is transient.
307 *
308 * @return {@code true} if the feature is transient,
309 * {@code false} otherwise
310 */
311 boolean isTransient() {
312 Object value = getValue(TRANSIENT);
313 return (value instanceof Boolean)
314 ? (Boolean) value
315 : false;
316 }
317
318 // Package private methods for recreating the weak/soft referent
319
320 void setClass0(Class cls) {
321 this.classRef = getWeakReference(cls);
322 }
323
324 Class getClass0() {
325 return (this.classRef != null)
326 ? this.classRef.get()
327 : null;
328 }
329
330 /**
331 * Creates a new soft reference that refers to the given object.
332 *
333 * @return a new soft reference or <code>null</code> if object is <code>null</code>
334 *
335 * @see SoftReference
336 */
337 static <T> Reference<T> getSoftReference(T object) {
338 return (object != null)
339 ? new SoftReference<T>(object)
340 : null;
341 }
342
343 /**
344 * Creates a new weak reference that refers to the given object.
345 *
346 * @return a new weak reference or <code>null</code> if object is <code>null</code>
347 *
348 * @see WeakReference
349 */
350 static <T> Reference<T> getWeakReference(T object) {
351 return (object != null)
352 ? new WeakReference<T>(object)
353 : null;
354 }
355
356 /**
357 * Resolves the return type of the method.
358 *
359 * @param base the class that contains the method in the hierarchy
360 * @param method the object that represents the method
361 * @return a class identifying the return type of the method
362 *
363 * @see Method#getGenericReturnType
364 * @see Method#getReturnType
365 */
366 static Class getReturnType(Class base, Method method) {
367 if (base == null) {
368 base = method.getDeclaringClass();
369 }
370 return TypeResolver.erase(TypeResolver.resolveInClass(base, method.getGenericReturnType()));
371 }
372
373 /**
374 * Resolves the parameter types of the method.
375 *
376 * @param base the class that contains the method in the hierarchy
377 * @param method the object that represents the method
378 * @return an array of classes identifying the parameter types of the method
379 *
380 * @see Method#getGenericParameterTypes
381 * @see Method#getParameterTypes
382 */
383 static Class[] getParameterTypes(Class base, Method method) {
384 if (base == null) {
385 base = method.getDeclaringClass();
386 }
387 return TypeResolver.erase(TypeResolver.resolveInClass(base, method.getGenericParameterTypes()));
388 }
389
390 private boolean expert;
391 private boolean hidden;
392 private boolean preferred;
393 private String shortDescription;
394 private String name;
395 private String displayName;
396 private Hashtable<String, Object> table;
397
398 /**
399 * Returns a string representation of the object.
400 *
401 * @return a string representation of the object
402 *
403 * @since 1.7
404 */
405 public String toString() {
406 StringBuilder sb = new StringBuilder(getClass().getName());
407 sb.append("[name=").append(this.name);
408 appendTo(sb, "displayName", this.displayName);
409 appendTo(sb, "shortDescription", this.shortDescription);
410 appendTo(sb, "preferred", this.preferred);
411 appendTo(sb, "hidden", this.hidden);
412 appendTo(sb, "expert", this.expert);
413 if ((this.table != null) && !this.table.isEmpty()) {
414 sb.append("; values={");
415 for (Entry<String, Object> entry : this.table.entrySet()) {
416 sb.append(entry.getKey()).append("=").append(entry.getValue()).append("; ");
417 }
418 sb.setLength(sb.length() - 2);
419 sb.append("}");
420 }
421 appendTo(sb);
422 return sb.append("]").toString();
423 }
424
425 void appendTo(StringBuilder sb) {
426 }
427
428 static void appendTo(StringBuilder sb, String name, Reference reference) {
429 if (reference != null) {
430 appendTo(sb, name, reference.get());
431 }
432 }
433
434 static void appendTo(StringBuilder sb, String name, Object value) {
435 if (value != null) {
436 sb.append("; ").append(name).append("=").append(value);
437 }
438 }
439
440 static void appendTo(StringBuilder sb, String name, boolean value) {
441 if (value) {
442 sb.append("; ").append(name);
443 }
444 }
445}
java/pkg/java/beans/GenericBeanInfo.class+0−0

Binary file not shown.

java/pkg/java/beans/IndexedPropertyChangeEvent.class+0−0

Binary file not shown.

java/pkg/java/beans/IndexedPropertyChangeEvent.java+78−0
@@ -0,0 +1,78 @@
1/*
2 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25package java.beans;
26
27/**
28 * An "IndexedPropertyChange" event gets delivered whenever a component that
29 * conforms to the JavaBeans&trade; specification (a "bean") changes a bound
30 * indexed property. This class is an extension of <code>PropertyChangeEvent</code>
31 * but contains the index of the property that has changed.
32 * <P>
33 * Null values may be provided for the old and the new values if their
34 * true values are not known.
35 * <P>
36 * An event source may send a null object as the name to indicate that an
37 * arbitrary set of if its properties have changed. In this case the
38 * old and new values should also be null.
39 *
40 * @since 1.5
41 * @author Mark Davidson
42 */
43public class IndexedPropertyChangeEvent extends PropertyChangeEvent {
44 private static final long serialVersionUID = -320227448495806870L;
45
46 private int index;
47
48 /**
49 * Constructs a new <code>IndexedPropertyChangeEvent</code> object.
50 *
51 * @param source The bean that fired the event.
52 * @param propertyName The programmatic name of the property that
53 * was changed.
54 * @param oldValue The old value of the property.
55 * @param newValue The new value of the property.
56 * @param index index of the property element that was changed.
57 */
58 public IndexedPropertyChangeEvent(Object source, String propertyName,
59 Object oldValue, Object newValue,
60 int index) {
61 super (source, propertyName, oldValue, newValue);
62 this.index = index;
63 }
64
65 /**
66 * Gets the index of the property that was changed.
67 *
68 * @return The index specifying the property element that was
69 * changed.
70 */
71 public int getIndex() {
72 return index;
73 }
74
75 void appendTo(StringBuilder sb) {
76 sb.append("; index=").append(getIndex());
77 }
78}
java/pkg/java/beans/IndexedPropertyDescriptor.class+0−0

Binary file not shown.

java/pkg/java/beans/IndexedPropertyDescriptor.java+523−0
@@ -0,0 +1,523 @@
1/*
2 * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.beans;
27
28import java.lang.ref.Reference;
29import java.lang.reflect.Method;
30
31/**
32 * An IndexedPropertyDescriptor describes a property that acts like an
33 * array and has an indexed read and/or indexed write method to access
34 * specific elements of the array.
35 * <p>
36 * An indexed property may also provide simple non-indexed read and write
37 * methods. If these are present, they read and write arrays of the type
38 * returned by the indexed read method.
39 */
40
41public class IndexedPropertyDescriptor extends PropertyDescriptor {
42
43 private Reference<Class> indexedPropertyTypeRef;
44 private Reference<Method> indexedReadMethodRef;
45 private Reference<Method> indexedWriteMethodRef;
46
47 private String indexedReadMethodName;
48 private String indexedWriteMethodName;
49
50 /**
51 * This constructor constructs an IndexedPropertyDescriptor for a property
52 * that follows the standard Java conventions by having getFoo and setFoo
53 * accessor methods, for both indexed access and array access.
54 * <p>
55 * Thus if the argument name is "fred", it will assume that there
56 * is an indexed reader method "getFred", a non-indexed (array) reader
57 * method also called "getFred", an indexed writer method "setFred",
58 * and finally a non-indexed writer method "setFred".
59 *
60 * @param propertyName The programmatic name of the property.
61 * @param beanClass The Class object for the target bean.
62 * @exception IntrospectionException if an exception occurs during
63 * introspection.
64 */
65 public IndexedPropertyDescriptor(String propertyName, Class<?> beanClass)
66 throws IntrospectionException {
67 this(propertyName, beanClass,
68 Introspector.GET_PREFIX + NameGenerator.capitalize(propertyName),
69 Introspector.SET_PREFIX + NameGenerator.capitalize(propertyName),
70 Introspector.GET_PREFIX + NameGenerator.capitalize(propertyName),
71 Introspector.SET_PREFIX + NameGenerator.capitalize(propertyName));
72 }
73
74 /**
75 * This constructor takes the name of a simple property, and method
76 * names for reading and writing the property, both indexed
77 * and non-indexed.
78 *
79 * @param propertyName The programmatic name of the property.
80 * @param beanClass The Class object for the target bean.
81 * @param readMethodName The name of the method used for reading the property
82 * values as an array. May be null if the property is write-only
83 * or must be indexed.
84 * @param writeMethodName The name of the method used for writing the property
85 * values as an array. May be null if the property is read-only
86 * or must be indexed.
87 * @param indexedReadMethodName The name of the method used for reading
88 * an indexed property value.
89 * May be null if the property is write-only.
90 * @param indexedWriteMethodName The name of the method used for writing
91 * an indexed property value.
92 * May be null if the property is read-only.
93 * @exception IntrospectionException if an exception occurs during
94 * introspection.
95 */
96 public IndexedPropertyDescriptor(String propertyName, Class<?> beanClass,
97 String readMethodName, String writeMethodName,
98 String indexedReadMethodName, String indexedWriteMethodName)
99 throws IntrospectionException {
100 super(propertyName, beanClass, readMethodName, writeMethodName);
101
102 this.indexedReadMethodName = indexedReadMethodName;
103 if (indexedReadMethodName != null && getIndexedReadMethod() == null) {
104 throw new IntrospectionException("Method not found: " + indexedReadMethodName);
105 }
106
107 this.indexedWriteMethodName = indexedWriteMethodName;
108 if (indexedWriteMethodName != null && getIndexedWriteMethod() == null) {
109 throw new IntrospectionException("Method not found: " + indexedWriteMethodName);
110 }
111 // Implemented only for type checking.
112 findIndexedPropertyType(getIndexedReadMethod(), getIndexedWriteMethod());
113 }
114
115 /**
116 * This constructor takes the name of a simple property, and Method
117 * objects for reading and writing the property.
118 *
119 * @param propertyName The programmatic name of the property.
120 * @param readMethod The method used for reading the property values as an array.
121 * May be null if the property is write-only or must be indexed.
122 * @param writeMethod The method used for writing the property values as an array.
123 * May be null if the property is read-only or must be indexed.
124 * @param indexedReadMethod The method used for reading an indexed property value.
125 * May be null if the property is write-only.
126 * @param indexedWriteMethod The method used for writing an indexed property value.
127 * May be null if the property is read-only.
128 * @exception IntrospectionException if an exception occurs during
129 * introspection.
130 */
131 public IndexedPropertyDescriptor(String propertyName, Method readMethod, Method writeMethod,
132 Method indexedReadMethod, Method indexedWriteMethod)
133 throws IntrospectionException {
134 super(propertyName, readMethod, writeMethod);
135
136 setIndexedReadMethod0(indexedReadMethod);
137 setIndexedWriteMethod0(indexedWriteMethod);
138
139 // Type checking
140 setIndexedPropertyType(findIndexedPropertyType(indexedReadMethod, indexedWriteMethod));
141 }
142
143 /**
144 * Creates <code>PropertyDescriptor</code> for the specified bean
145 * with the specified name and methods to read/write the property value.
146 *
147 * @param bean the type of the target bean
148 * @param base the base name of the property (the rest of the method name)
149 * @param read the method used for reading the property value
150 * @param write the method used for writing the property value
151 * @param readIndexed the method used for reading an indexed property value
152 * @param writeIndexed the method used for writing an indexed property value
153 * @exception IntrospectionException if an exception occurs during introspection
154 *
155 * @since 1.7
156 */
157 IndexedPropertyDescriptor(Class<?> bean, String base, Method read, Method write, Method readIndexed, Method writeIndexed) throws IntrospectionException {
158 super(bean, base, read, write);
159
160 setIndexedReadMethod0(readIndexed);
161 setIndexedWriteMethod0(writeIndexed);
162
163 // Type checking
164 setIndexedPropertyType(findIndexedPropertyType(readIndexed, writeIndexed));
165 }
166
167 /**
168 * Gets the method that should be used to read an indexed
169 * property value.
170 *
171 * @return The method that should be used to read an indexed
172 * property value.
173 * May return null if the property isn't indexed or is write-only.
174 */
175 public synchronized Method getIndexedReadMethod() {
176 Method indexedReadMethod = getIndexedReadMethod0();
177 if (indexedReadMethod == null) {
178 Class cls = getClass0();
179 if (cls == null ||
180 (indexedReadMethodName == null && indexedReadMethodRef == null)) {
181 // the Indexed readMethod was explicitly set to null.
182 return null;
183 }
184 if (indexedReadMethodName == null) {
185 Class type = getIndexedPropertyType0();
186 if (type == boolean.class || type == null) {
187 indexedReadMethodName = Introspector.IS_PREFIX + getBaseName();
188 } else {
189 indexedReadMethodName = Introspector.GET_PREFIX + getBaseName();
190 }
191 }
192
193 Class[] args = { int.class };
194 indexedReadMethod = Introspector.findMethod(cls, indexedReadMethodName, 1, args);
195 if (indexedReadMethod == null) {
196 // no "is" method, so look for a "get" method.
197 indexedReadMethodName = Introspector.GET_PREFIX + getBaseName();
198 indexedReadMethod = Introspector.findMethod(cls, indexedReadMethodName, 1, args);
199 }
200 setIndexedReadMethod0(indexedReadMethod);
201 }
202 return indexedReadMethod;
203 }
204
205 /**
206 * Sets the method that should be used to read an indexed property value.
207 *
208 * @param readMethod The new indexed read method.
209 */
210 public synchronized void setIndexedReadMethod(Method readMethod)
211 throws IntrospectionException {
212
213 // the indexed property type is set by the reader.
214 setIndexedPropertyType(findIndexedPropertyType(readMethod,
215 getIndexedWriteMethod0()));
216 setIndexedReadMethod0(readMethod);
217 }
218
219 private void setIndexedReadMethod0(Method readMethod) {
220 if (readMethod == null) {
221 indexedReadMethodName = null;
222 indexedReadMethodRef = null;
223 return;
224 }
225 setClass0(readMethod.getDeclaringClass());
226
227 indexedReadMethodName = readMethod.getName();
228 this.indexedReadMethodRef = getSoftReference(readMethod);
229 setTransient(readMethod.getAnnotation(Transient.class));
230 }
231
232
233 /**
234 * Gets the method that should be used to write an indexed property value.
235 *
236 * @return The method that should be used to write an indexed
237 * property value.
238 * May return null if the property isn't indexed or is read-only.
239 */
240 public synchronized Method getIndexedWriteMethod() {
241 Method indexedWriteMethod = getIndexedWriteMethod0();
242 if (indexedWriteMethod == null) {
243 Class cls = getClass0();
244 if (cls == null ||
245 (indexedWriteMethodName == null && indexedWriteMethodRef == null)) {
246 // the Indexed writeMethod was explicitly set to null.
247 return null;
248 }
249
250 // We need the indexed type to ensure that we get the correct method.
251 // Cannot use the getIndexedPropertyType method since that could
252 // result in an infinite loop.
253 Class type = getIndexedPropertyType0();
254 if (type == null) {
255 try {
256 type = findIndexedPropertyType(getIndexedReadMethod(), null);
257 setIndexedPropertyType(type);
258 } catch (IntrospectionException ex) {
259 // Set iprop type to be the classic type
260 Class propType = getPropertyType();
261 if (propType.isArray()) {
262 type = propType.getComponentType();
263 }
264 }
265 }
266
267 if (indexedWriteMethodName == null) {
268 indexedWriteMethodName = Introspector.SET_PREFIX + getBaseName();
269 }
270
271 Class[] args = (type == null) ? null : new Class[] { int.class, type };
272 indexedWriteMethod = Introspector.findMethod(cls, indexedWriteMethodName, 2, args);
273 if (indexedWriteMethod != null) {
274 if (!indexedWriteMethod.getReturnType().equals(void.class)) {
275 indexedWriteMethod = null;
276 }
277 }
278 setIndexedWriteMethod0(indexedWriteMethod);
279 }
280 return indexedWriteMethod;
281 }
282
283 /**
284 * Sets the method that should be used to write an indexed property value.
285 *
286 * @param writeMethod The new indexed write method.
287 */
288 public synchronized void setIndexedWriteMethod(Method writeMethod)
289 throws IntrospectionException {
290
291 // If the indexed property type has not been set, then set it.
292 Class type = findIndexedPropertyType(getIndexedReadMethod(),
293 writeMethod);
294 setIndexedPropertyType(type);
295 setIndexedWriteMethod0(writeMethod);
296 }
297
298 private void setIndexedWriteMethod0(Method writeMethod) {
299 if (writeMethod == null) {
300 indexedWriteMethodName = null;
301 indexedWriteMethodRef = null;
302 return;
303 }
304 setClass0(writeMethod.getDeclaringClass());
305
306 indexedWriteMethodName = writeMethod.getName();
307 this.indexedWriteMethodRef = getSoftReference(writeMethod);
308 setTransient(writeMethod.getAnnotation(Transient.class));
309 }
310
311 /**
312 * Returns the Java type info for the indexed property.
313 * Note that the {@code Class} object may describe
314 * primitive Java types such as {@code int}.
315 * This type is returned by the indexed read method
316 * or is used as the parameter type of the indexed write method.
317 *
318 * @return the {@code Class} object that represents the Java type info,
319 * or {@code null} if the type cannot be determined
320 */
321 public synchronized Class<?> getIndexedPropertyType() {
322 Class type = getIndexedPropertyType0();
323 if (type == null) {
324 try {
325 type = findIndexedPropertyType(getIndexedReadMethod(),
326 getIndexedWriteMethod());
327 setIndexedPropertyType(type);
328 } catch (IntrospectionException ex) {
329 // fall
330 }
331 }
332 return type;
333 }
334
335 // Private methods which set get/set the Reference objects
336
337 private void setIndexedPropertyType(Class type) {
338 this.indexedPropertyTypeRef = getWeakReference(type);
339 }
340
341 private Class getIndexedPropertyType0() {
342 return (this.indexedPropertyTypeRef != null)
343 ? this.indexedPropertyTypeRef.get()
344 : null;
345 }
346
347 private Method getIndexedReadMethod0() {
348 return (this.indexedReadMethodRef != null)
349 ? this.indexedReadMethodRef.get()
350 : null;
351 }
352
353 private Method getIndexedWriteMethod0() {
354 return (this.indexedWriteMethodRef != null)
355 ? this.indexedWriteMethodRef.get()
356 : null;
357 }
358
359 private Class findIndexedPropertyType(Method indexedReadMethod,
360 Method indexedWriteMethod)
361 throws IntrospectionException {
362 Class indexedPropertyType = null;
363
364 if (indexedReadMethod != null) {
365 Class params[] = getParameterTypes(getClass0(), indexedReadMethod);
366 if (params.length != 1) {
367 throw new IntrospectionException("bad indexed read method arg count");
368 }
369 if (params[0] != Integer.TYPE) {
370 throw new IntrospectionException("non int index to indexed read method");
371 }
372 indexedPropertyType = getReturnType(getClass0(), indexedReadMethod);
373 if (indexedPropertyType == Void.TYPE) {
374 throw new IntrospectionException("indexed read method returns void");
375 }
376 }
377 if (indexedWriteMethod != null) {
378 Class params[] = getParameterTypes(getClass0(), indexedWriteMethod);
379 if (params.length != 2) {
380 throw new IntrospectionException("bad indexed write method arg count");
381 }
382 if (params[0] != Integer.TYPE) {
383 throw new IntrospectionException("non int index to indexed write method");
384 }
385 if (indexedPropertyType != null && indexedPropertyType != params[1]) {
386 throw new IntrospectionException(
387 "type mismatch between indexed read and indexed write methods: "
388 + getName());
389 }
390 indexedPropertyType = params[1];
391 }
392 Class propertyType = getPropertyType();
393 if (propertyType != null && (!propertyType.isArray() ||
394 propertyType.getComponentType() != indexedPropertyType)) {
395 throw new IntrospectionException("type mismatch between indexed and non-indexed methods: "
396 + getName());
397 }
398 return indexedPropertyType;
399 }
400
401 /**
402 * Compares this <code>PropertyDescriptor</code> against the specified object.
403 * Returns true if the objects are the same. Two <code>PropertyDescriptor</code>s
404 * are the same if the read, write, property types, property editor and
405 * flags are equivalent.
406 *
407 * @since 1.4
408 */
409 public boolean equals(Object obj) {
410 // Note: This would be identical to PropertyDescriptor but they don't
411 // share the same fields.
412 if (this == obj) {
413 return true;
414 }
415
416 if (obj != null && obj instanceof IndexedPropertyDescriptor) {
417 IndexedPropertyDescriptor other = (IndexedPropertyDescriptor)obj;
418 Method otherIndexedReadMethod = other.getIndexedReadMethod();
419 Method otherIndexedWriteMethod = other.getIndexedWriteMethod();
420
421 if (!compareMethods(getIndexedReadMethod(), otherIndexedReadMethod)) {
422 return false;
423 }
424
425 if (!compareMethods(getIndexedWriteMethod(), otherIndexedWriteMethod)) {
426 return false;
427 }
428
429 if (getIndexedPropertyType() != other.getIndexedPropertyType()) {
430 return false;
431 }
432 return super.equals(obj);
433 }
434 return false;
435 }
436
437 /**
438 * Package-private constructor.
439 * Merge two property descriptors. Where they conflict, give the
440 * second argument (y) priority over the first argumnnt (x).
441 *
442 * @param x The first (lower priority) PropertyDescriptor
443 * @param y The second (higher priority) PropertyDescriptor
444 */
445
446 IndexedPropertyDescriptor(PropertyDescriptor x, PropertyDescriptor y) {
447 super(x,y);
448 if (x instanceof IndexedPropertyDescriptor) {
449 IndexedPropertyDescriptor ix = (IndexedPropertyDescriptor)x;
450 try {
451 Method xr = ix.getIndexedReadMethod();
452 if (xr != null) {
453 setIndexedReadMethod(xr);
454 }
455
456 Method xw = ix.getIndexedWriteMethod();
457 if (xw != null) {
458 setIndexedWriteMethod(xw);
459 }
460 } catch (IntrospectionException ex) {
461 // Should not happen
462 throw new AssertionError(ex);
463 }
464 }
465 if (y instanceof IndexedPropertyDescriptor) {
466 IndexedPropertyDescriptor iy = (IndexedPropertyDescriptor)y;
467 try {
468 Method yr = iy.getIndexedReadMethod();
469 if (yr != null && yr.getDeclaringClass() == getClass0()) {
470 setIndexedReadMethod(yr);
471 }
472
473 Method yw = iy.getIndexedWriteMethod();
474 if (yw != null && yw.getDeclaringClass() == getClass0()) {
475 setIndexedWriteMethod(yw);
476 }
477 } catch (IntrospectionException ex) {
478 // Should not happen
479 throw new AssertionError(ex);
480 }
481 }
482 }
483
484 /*
485 * Package-private dup constructor
486 * This must isolate the new object from any changes to the old object.
487 */
488 IndexedPropertyDescriptor(IndexedPropertyDescriptor old) {
489 super(old);
490 indexedReadMethodRef = old.indexedReadMethodRef;
491 indexedWriteMethodRef = old.indexedWriteMethodRef;
492 indexedPropertyTypeRef = old.indexedPropertyTypeRef;
493 indexedWriteMethodName = old.indexedWriteMethodName;
494 indexedReadMethodName = old.indexedReadMethodName;
495 }
496
497 /**
498 * Returns a hash code value for the object.
499 * See {@link java.lang.Object#hashCode} for a complete description.
500 *
501 * @return a hash code value for this object.
502 * @since 1.5
503 */
504 public int hashCode() {
505 int result = super.hashCode();
506
507 result = 37 * result + ((indexedWriteMethodName == null) ? 0 :
508 indexedWriteMethodName.hashCode());
509 result = 37 * result + ((indexedReadMethodName == null) ? 0 :
510 indexedReadMethodName.hashCode());
511 result = 37 * result + ((getIndexedPropertyType() == null) ? 0 :
512 getIndexedPropertyType().hashCode());
513
514 return result;
515 }
516
517 void appendTo(StringBuilder sb) {
518 super.appendTo(sb);
519 appendTo(sb, "indexedPropertyType", this.indexedPropertyTypeRef);
520 appendTo(sb, "indexedReadMethod", this.indexedReadMethodRef);
521 appendTo(sb, "indexedWriteMethod", this.indexedWriteMethodRef);
522 }
523}
java/pkg/java/beans/IntrospectionException.class+0−0

Binary file not shown.

java/pkg/java/beans/IntrospectionException.java+50−0
@@ -0,0 +1,50 @@
1/*
2 * Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.beans;
27
28/**
29 * Thrown when an exception happens during Introspection.
30 * <p>
31 * Typical causes include not being able to map a string class name
32 * to a Class object, not being able to resolve a string method name,
33 * or specifying a method name that has the wrong type signature for
34 * its intended use.
35 */
36
37public
38class IntrospectionException extends Exception {
39 private static final long serialVersionUID = -3728150539969542619L;
40
41 /**
42 * Constructs an <code>IntrospectionException</code> with a
43 * detailed message.
44 *
45 * @param mess Descriptive message
46 */
47 public IntrospectionException(String mess) {
48 super(mess);
49 }
50}
java/pkg/java/beans/Introspector.class+0−0

Binary file not shown.

java/pkg/java/beans/Introspector.java+1558−0
@@ -0,0 +1,1558 @@
1/*
2 * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.beans;
27
28import com.sun.beans.WeakCache;
29import com.sun.beans.finder.BeanInfoFinder;
30import com.sun.beans.finder.ClassFinder;
31
32import java.awt.Component;
33
34import java.lang.ref.Reference;
35import java.lang.ref.SoftReference;
36import java.lang.reflect.Method;
37import java.lang.reflect.Modifier;
38
39import java.util.Map;
40import java.util.ArrayList;
41import java.util.HashMap;
42import java.util.Iterator;
43import java.util.EventListener;
44import java.util.EventObject;
45import java.util.List;
46import java.util.TreeMap;
47import java.util.WeakHashMap;
48
49import sun.awt.AppContext;
50import sun.reflect.misc.ReflectUtil;
51
52/**
53 * The Introspector class provides a standard way for tools to learn about
54 * the properties, events, and methods supported by a target Java Bean.
55 * <p>
56 * For each of those three kinds of information, the Introspector will
57 * separately analyze the bean's class and superclasses looking for
58 * either explicit or implicit information and use that information to
59 * build a BeanInfo object that comprehensively describes the target bean.
60 * <p>
61 * For each class "Foo", explicit information may be available if there exists
62 * a corresponding "FooBeanInfo" class that provides a non-null value when
63 * queried for the information. We first look for the BeanInfo class by
64 * taking the full package-qualified name of the target bean class and
65 * appending "BeanInfo" to form a new class name. If this fails, then
66 * we take the final classname component of this name, and look for that
67 * class in each of the packages specified in the BeanInfo package search
68 * path.
69 * <p>
70 * Thus for a class such as "sun.xyz.OurButton" we would first look for a
71 * BeanInfo class called "sun.xyz.OurButtonBeanInfo" and if that failed we'd
72 * look in each package in the BeanInfo search path for an OurButtonBeanInfo
73 * class. With the default search path, this would mean looking for
74 * "sun.beans.infos.OurButtonBeanInfo".
75 * <p>
76 * If a class provides explicit BeanInfo about itself then we add that to
77 * the BeanInfo information we obtained from analyzing any derived classes,
78 * but we regard the explicit information as being definitive for the current
79 * class and its base classes, and do not proceed any further up the superclass
80 * chain.
81 * <p>
82 * If we don't find explicit BeanInfo on a class, we use low-level
83 * reflection to study the methods of the class and apply standard design
84 * patterns to identify property accessors, event sources, or public
85 * methods. We then proceed to analyze the class's superclass and add
86 * in the information from it (and possibly on up the superclass chain).
87 * <p>
88 * For more information about introspection and design patterns, please
89 * consult the
90 * <a href="http://java.sun.com/products/javabeans/docs/index.html">JavaBeans&trade; specification</a>.
91 */
92
93public class Introspector {
94
95 // Flags that can be used to control getBeanInfo:
96 public final static int USE_ALL_BEANINFO = 1;
97 public final static int IGNORE_IMMEDIATE_BEANINFO = 2;
98 public final static int IGNORE_ALL_BEANINFO = 3;
99
100 // Static Caches to speed up introspection.
101 private static WeakCache<Class<?>, Method[]> declaredMethodCache =
102 new WeakCache<Class<?>, Method[]>();
103
104 private static final Object BEANINFO_CACHE = new Object();
105
106 private Class beanClass;
107 private BeanInfo explicitBeanInfo;
108 private BeanInfo superBeanInfo;
109 private BeanInfo additionalBeanInfo[];
110
111 private boolean propertyChangeSource = false;
112 private static Class eventListenerType = EventListener.class;
113
114 // These should be removed.
115 private String defaultEventName;
116 private String defaultPropertyName;
117 private int defaultEventIndex = -1;
118 private int defaultPropertyIndex = -1;
119
120 // Methods maps from Method objects to MethodDescriptors
121 private Map methods;
122
123 // properties maps from String names to PropertyDescriptors
124 private Map properties;
125
126 // events maps from String names to EventSetDescriptors
127 private Map events;
128
129 private final static EventSetDescriptor[] EMPTY_EVENTSETDESCRIPTORS = new EventSetDescriptor[0];
130
131 static final String ADD_PREFIX = "add";
132 static final String REMOVE_PREFIX = "remove";
133 static final String GET_PREFIX = "get";
134 static final String SET_PREFIX = "set";
135 static final String IS_PREFIX = "is";
136
137 private static final Object FINDER_KEY = new Object();
138
139 //======================================================================
140 // Public methods
141 //======================================================================
142
143 /**
144 * Introspect on a Java Bean and learn about all its properties, exposed
145 * methods, and events.
146 * <p>
147 * If the BeanInfo class for a Java Bean has been previously Introspected
148 * then the BeanInfo class is retrieved from the BeanInfo cache.
149 *
150 * @param beanClass The bean class to be analyzed.
151 * @return A BeanInfo object describing the target bean.
152 * @exception IntrospectionException if an exception occurs during
153 * introspection.
154 * @see #flushCaches
155 * @see #flushFromCaches
156 */
157 public static BeanInfo getBeanInfo(Class<?> beanClass)
158 throws IntrospectionException
159 {
160 if (!ReflectUtil.isPackageAccessible(beanClass)) {
161 return (new Introspector(beanClass, null, USE_ALL_BEANINFO)).getBeanInfo();
162 }
163 Map<Class<?>, BeanInfo> beanInfoCache;
164 BeanInfo beanInfo;
165 synchronized (BEANINFO_CACHE) {
166 beanInfoCache = (Map<Class<?>, BeanInfo>) AppContext.getAppContext().get(BEANINFO_CACHE);
167 if (beanInfoCache == null) {
168 beanInfoCache = new WeakHashMap<Class<?>, BeanInfo>();
169 AppContext.getAppContext().put(BEANINFO_CACHE, beanInfoCache);
170 }
171 beanInfo = beanInfoCache.get(beanClass);
172 }
173 if (beanInfo == null) {
174 beanInfo = new Introspector(beanClass, null, USE_ALL_BEANINFO).getBeanInfo();
175 synchronized (BEANINFO_CACHE) {
176 beanInfoCache.put(beanClass, beanInfo);
177 }
178 }
179 return beanInfo;
180 }
181
182 /**
183 * Introspect on a Java bean and learn about all its properties, exposed
184 * methods, and events, subject to some control flags.
185 * <p>
186 * If the BeanInfo class for a Java Bean has been previously Introspected
187 * based on the same arguments then the BeanInfo class is retrieved
188 * from the BeanInfo cache.
189 *
190 * @param beanClass The bean class to be analyzed.
191 * @param flags Flags to control the introspection.
192 * If flags == USE_ALL_BEANINFO then we use all of the BeanInfo
193 * classes we can discover.
194 * If flags == IGNORE_IMMEDIATE_BEANINFO then we ignore any
195 * BeanInfo associated with the specified beanClass.
196 * If flags == IGNORE_ALL_BEANINFO then we ignore all BeanInfo
197 * associated with the specified beanClass or any of its
198 * parent classes.
199 * @return A BeanInfo object describing the target bean.
200 * @exception IntrospectionException if an exception occurs during
201 * introspection.
202 */
203 public static BeanInfo getBeanInfo(Class<?> beanClass, int flags)
204 throws IntrospectionException {
205 return getBeanInfo(beanClass, null, flags);
206 }
207
208 /**
209 * Introspect on a Java bean and learn all about its properties, exposed
210 * methods, below a given "stop" point.
211 * <p>
212 * If the BeanInfo class for a Java Bean has been previously Introspected
213 * based on the same arguments, then the BeanInfo class is retrieved
214 * from the BeanInfo cache.
215 *
216 * @param beanClass The bean class to be analyzed.
217 * @param stopClass The baseclass at which to stop the analysis. Any
218 * methods/properties/events in the stopClass or in its baseclasses
219 * will be ignored in the analysis.
220 * @exception IntrospectionException if an exception occurs during
221 * introspection.
222 */
223 public static BeanInfo getBeanInfo(Class<?> beanClass, Class<?> stopClass)
224 throws IntrospectionException {
225 return getBeanInfo(beanClass, stopClass, USE_ALL_BEANINFO);
226 }
227
228 /**
229 * Introspect on a Java Bean and learn about all its properties,
230 * exposed methods and events, below a given {@code stopClass} point
231 * subject to some control {@code flags}.
232 * <dl>
233 * <dt>USE_ALL_BEANINFO</dt>
234 * <dd>Any BeanInfo that can be discovered will be used.</dd>
235 * <dt>IGNORE_IMMEDIATE_BEANINFO</dt>
236 * <dd>Any BeanInfo associated with the specified {@code beanClass} will be ignored.</dd>
237 * <dt>IGNORE_ALL_BEANINFO</dt>
238 * <dd>Any BeanInfo associated with the specified {@code beanClass}
239 * or any of its parent classes will be ignored.</dd>
240 * </dl>
241 * Any methods/properties/events in the {@code stopClass}
242 * or in its parent classes will be ignored in the analysis.
243 * <p>
244 * If the BeanInfo class for a Java Bean has been
245 * previously introspected based on the same arguments then
246 * the BeanInfo class is retrieved from the BeanInfo cache.
247 *
248 * @param beanClass the bean class to be analyzed
249 * @param stopClass the parent class at which to stop the analysis
250 * @param flags flags to control the introspection
251 * @return a BeanInfo object describing the target bean
252 * @exception IntrospectionException if an exception occurs during introspection
253 *
254 * @since 1.7
255 */
256 public static BeanInfo getBeanInfo(Class<?> beanClass, Class<?> stopClass,
257 int flags) throws IntrospectionException {
258 BeanInfo bi;
259 if (stopClass == null && flags == USE_ALL_BEANINFO) {
260 // Same parameters to take advantage of caching.
261 bi = getBeanInfo(beanClass);
262 } else {
263 bi = (new Introspector(beanClass, stopClass, flags)).getBeanInfo();
264 }
265 return bi;
266
267 // Old behaviour: Make an independent copy of the BeanInfo.
268 //return new GenericBeanInfo(bi);
269 }
270
271
272 /**
273 * Utility method to take a string and convert it to normal Java variable
274 * name capitalization. This normally means converting the first
275 * character from upper case to lower case, but in the (unusual) special
276 * case when there is more than one character and both the first and
277 * second characters are upper case, we leave it alone.
278 * <p>
279 * Thus "FooBah" becomes "fooBah" and "X" becomes "x", but "URL" stays
280 * as "URL".
281 *
282 * @param name The string to be decapitalized.
283 * @return The decapitalized version of the string.
284 */
285 public static String decapitalize(String name) {
286 if (name == null || name.length() == 0) {
287 return name;
288 }
289 if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) &&
290 Character.isUpperCase(name.charAt(0))){
291 return name;
292 }
293 char chars[] = name.toCharArray();
294 chars[0] = Character.toLowerCase(chars[0]);
295 return new String(chars);
296 }
297
298 /**
299 * Gets the list of package names that will be used for
300 * finding BeanInfo classes.
301 *
302 * @return The array of package names that will be searched in
303 * order to find BeanInfo classes. The default value
304 * for this array is implementation-dependent; e.g.
305 * Sun implementation initially sets to {"sun.beans.infos"}.
306 */
307
308 public static String[] getBeanInfoSearchPath() {
309 return getFinder().getPackages();
310 }
311
312 /**
313 * Change the list of package names that will be used for
314 * finding BeanInfo classes. The behaviour of
315 * this method is undefined if parameter path
316 * is null.
317 *
318 * <p>First, if there is a security manager, its <code>checkPropertiesAccess</code>
319 * method is called. This could result in a SecurityException.
320 *
321 * @param path Array of package names.
322 * @exception SecurityException if a security manager exists and its
323 * <code>checkPropertiesAccess</code> method doesn't allow setting
324 * of system properties.
325 * @see SecurityManager#checkPropertiesAccess
326 */
327
328 public static void setBeanInfoSearchPath(String[] path) {
329 SecurityManager sm = System.getSecurityManager();
330 if (sm != null) {
331 sm.checkPropertiesAccess();
332 }
333 getFinder().setPackages(path);
334 }
335
336
337 /**
338 * Flush all of the Introspector's internal caches. This method is
339 * not normally required. It is normally only needed by advanced
340 * tools that update existing "Class" objects in-place and need
341 * to make the Introspector re-analyze existing Class objects.
342 */
343
344 public static void flushCaches() {
345 synchronized (BEANINFO_CACHE) {
346 Map beanInfoCache = (Map) AppContext.getAppContext().get(BEANINFO_CACHE);
347 if (beanInfoCache != null) {
348 beanInfoCache.clear();
349 }
350 declaredMethodCache.clear();
351 }
352 }
353
354 /**
355 * Flush the Introspector's internal cached information for a given class.
356 * This method is not normally required. It is normally only needed
357 * by advanced tools that update existing "Class" objects in-place
358 * and need to make the Introspector re-analyze an existing Class object.
359 *
360 * Note that only the direct state associated with the target Class
361 * object is flushed. We do not flush state for other Class objects
362 * with the same name, nor do we flush state for any related Class
363 * objects (such as subclasses), even though their state may include
364 * information indirectly obtained from the target Class object.
365 *
366 * @param clz Class object to be flushed.
367 * @throws NullPointerException If the Class object is null.
368 */
369 public static void flushFromCaches(Class<?> clz) {
370 if (clz == null) {
371 throw new NullPointerException();
372 }
373 synchronized (BEANINFO_CACHE) {
374 Map beanInfoCache = (Map) AppContext.getAppContext().get(BEANINFO_CACHE);
375 if (beanInfoCache != null) {
376 beanInfoCache.put(clz, null);
377 }
378 declaredMethodCache.put(clz, null);
379 }
380 }
381
382 //======================================================================
383 // Private implementation methods
384 //======================================================================
385
386 private Introspector(Class beanClass, Class stopClass, int flags)
387 throws IntrospectionException {
388 this.beanClass = beanClass;
389
390 // Check stopClass is a superClass of startClass.
391 if (stopClass != null) {
392 boolean isSuper = false;
393 for (Class c = beanClass.getSuperclass(); c != null; c = c.getSuperclass()) {
394 if (c == stopClass) {
395 isSuper = true;
396 }
397 }
398 if (!isSuper) {
399 throw new IntrospectionException(stopClass.getName() + " not superclass of " +
400 beanClass.getName());
401 }
402 }
403
404 if (flags == USE_ALL_BEANINFO) {
405 explicitBeanInfo = findExplicitBeanInfo(beanClass);
406 }
407
408 Class superClass = beanClass.getSuperclass();
409 if (superClass != stopClass) {
410 int newFlags = flags;
411 if (newFlags == IGNORE_IMMEDIATE_BEANINFO) {
412 newFlags = USE_ALL_BEANINFO;
413 }
414 superBeanInfo = getBeanInfo(superClass, stopClass, newFlags);
415 }
416 if (explicitBeanInfo != null) {
417 additionalBeanInfo = explicitBeanInfo.getAdditionalBeanInfo();
418 }
419 if (additionalBeanInfo == null) {
420 additionalBeanInfo = new BeanInfo[0];
421 }
422 }
423
424 /**
425 * Constructs a GenericBeanInfo class from the state of the Introspector
426 */
427 private BeanInfo getBeanInfo() throws IntrospectionException {
428
429 // the evaluation order here is import, as we evaluate the
430 // event sets and locate PropertyChangeListeners before we
431 // look for properties.
432 BeanDescriptor bd = getTargetBeanDescriptor();
433 MethodDescriptor mds[] = getTargetMethodInfo();
434 EventSetDescriptor esds[] = getTargetEventInfo();
435 PropertyDescriptor pds[] = getTargetPropertyInfo();
436
437 int defaultEvent = getTargetDefaultEventIndex();
438 int defaultProperty = getTargetDefaultPropertyIndex();
439
440 return new GenericBeanInfo(bd, esds, defaultEvent, pds,
441 defaultProperty, mds, explicitBeanInfo);
442
443 }
444
445 /**
446 * Looks for an explicit BeanInfo class that corresponds to the Class.
447 * First it looks in the existing package that the Class is defined in,
448 * then it checks to see if the class is its own BeanInfo. Finally,
449 * the BeanInfo search path is prepended to the class and searched.
450 *
451 * @param beanClass the class type of the bean
452 * @return Instance of an explicit BeanInfo class or null if one isn't found.
453 */
454 private static BeanInfo findExplicitBeanInfo(Class beanClass) {
455 return getFinder().find(beanClass);
456 }
457
458 /**
459 * @return An array of PropertyDescriptors describing the editable
460 * properties supported by the target bean.
461 */
462
463 private PropertyDescriptor[] getTargetPropertyInfo() {
464
465 // Check if the bean has its own BeanInfo that will provide
466 // explicit information.
467 PropertyDescriptor[] explicitProperties = null;
468 if (explicitBeanInfo != null) {
469 explicitProperties = getPropertyDescriptors(this.explicitBeanInfo);
470 }
471
472 if (explicitProperties == null && superBeanInfo != null) {
473 // We have no explicit BeanInfo properties. Check with our parent.
474 addPropertyDescriptors(getPropertyDescriptors(this.superBeanInfo));
475 }
476
477 for (int i = 0; i < additionalBeanInfo.length; i++) {
478 addPropertyDescriptors(additionalBeanInfo[i].getPropertyDescriptors());
479 }
480
481 if (explicitProperties != null) {
482 // Add the explicit BeanInfo data to our results.
483 addPropertyDescriptors(explicitProperties);
484
485 } else {
486
487 // Apply some reflection to the current class.
488
489 // First get an array of all the public methods at this level
490 Method methodList[] = getPublicDeclaredMethods(beanClass);
491
492 // Now analyze each method.
493 for (int i = 0; i < methodList.length; i++) {
494 Method method = methodList[i];
495 if (method == null || method.isSynthetic()) {
496 continue;
497 }
498 // skip static methods.
499 int mods = method.getModifiers();
500 if (Modifier.isStatic(mods)) {
501 continue;
502 }
503 String name = method.getName();
504 Class argTypes[] = method.getParameterTypes();
505 Class resultType = method.getReturnType();
506 int argCount = argTypes.length;
507 PropertyDescriptor pd = null;
508
509 if (name.length() <= 3 && !name.startsWith(IS_PREFIX)) {
510 // Optimization. Don't bother with invalid propertyNames.
511 continue;
512 }
513
514 try {
515
516 if (argCount == 0) {
517 if (name.startsWith(GET_PREFIX)) {
518 // Simple getter
519 pd = new PropertyDescriptor(this.beanClass, name.substring(3), method, null);
520 } else if (resultType == boolean.class && name.startsWith(IS_PREFIX)) {
521 // Boolean getter
522 pd = new PropertyDescriptor(this.beanClass, name.substring(2), method, null);
523 }
524 } else if (argCount == 1) {
525 if (int.class.equals(argTypes[0]) && name.startsWith(GET_PREFIX)) {
526 pd = new IndexedPropertyDescriptor(this.beanClass, name.substring(3), null, null, method, null);
527 } else if (void.class.equals(resultType) && name.startsWith(SET_PREFIX)) {
528 // Simple setter
529 pd = new PropertyDescriptor(this.beanClass, name.substring(3), null, method);
530 if (throwsException(method, PropertyVetoException.class)) {
531 pd.setConstrained(true);
532 }
533 }
534 } else if (argCount == 2) {
535 if (void.class.equals(resultType) && int.class.equals(argTypes[0]) && name.startsWith(SET_PREFIX)) {
536 pd = new IndexedPropertyDescriptor(this.beanClass, name.substring(3), null, null, null, method);
537 if (throwsException(method, PropertyVetoException.class)) {
538 pd.setConstrained(true);
539 }
540 }
541 }
542 } catch (IntrospectionException ex) {
543 // This happens if a PropertyDescriptor or IndexedPropertyDescriptor
544 // constructor fins that the method violates details of the deisgn
545 // pattern, e.g. by having an empty name, or a getter returning
546 // void , or whatever.
547 pd = null;
548 }
549
550 if (pd != null) {
551 // If this class or one of its base classes is a PropertyChange
552 // source, then we assume that any properties we discover are "bound".
553 if (propertyChangeSource) {
554 pd.setBound(true);
555 }
556 addPropertyDescriptor(pd);
557 }
558 }
559 }
560 processPropertyDescriptors();
561
562 // Allocate and populate the result array.
563 PropertyDescriptor result[] = new PropertyDescriptor[properties.size()];
564 result = (PropertyDescriptor[])properties.values().toArray(result);
565
566 // Set the default index.
567 if (defaultPropertyName != null) {
568 for (int i = 0; i < result.length; i++) {
569 if (defaultPropertyName.equals(result[i].getName())) {
570 defaultPropertyIndex = i;
571 }
572 }
573 }
574
575 return result;
576 }
577
578 private HashMap pdStore = new HashMap();
579
580 /**
581 * Adds the property descriptor to the list store.
582 */
583 private void addPropertyDescriptor(PropertyDescriptor pd) {
584 String propName = pd.getName();
585 List list = (List)pdStore.get(propName);
586 if (list == null) {
587 list = new ArrayList();
588 pdStore.put(propName, list);
589 }
590 if (this.beanClass != pd.getClass0()) {
591 // replace existing property descriptor
592 // only if we have types to resolve
593 // in the context of this.beanClass
594 try {
595 String name = pd.getName();
596 Method read = pd.getReadMethod();
597 Method write = pd.getWriteMethod();
598 boolean cls = true;
599 if (read != null) cls = cls && read.getGenericReturnType() instanceof Class;
600 if (write != null) cls = cls && write.getGenericParameterTypes()[0] instanceof Class;
601 if (pd instanceof IndexedPropertyDescriptor) {
602 IndexedPropertyDescriptor ipd = (IndexedPropertyDescriptor)pd;
603 Method readI = ipd.getIndexedReadMethod();
604 Method writeI = ipd.getIndexedWriteMethod();
605 if (readI != null) cls = cls && readI.getGenericReturnType() instanceof Class;
606 if (writeI != null) cls = cls && writeI.getGenericParameterTypes()[1] instanceof Class;
607 if (!cls) {
608 pd = new IndexedPropertyDescriptor(this.beanClass, name, read, write, readI, writeI);
609 }
610 } else if (!cls) {
611 pd = new PropertyDescriptor(this.beanClass, name, read, write);
612 }
613 } catch ( IntrospectionException e ) {
614 }
615 }
616 list.add(pd);
617 }
618
619 private void addPropertyDescriptors(PropertyDescriptor[] descriptors) {
620 if (descriptors != null) {
621 for (PropertyDescriptor descriptor : descriptors) {
622 addPropertyDescriptor(descriptor);
623 }
624 }
625 }
626
627 private PropertyDescriptor[] getPropertyDescriptors(BeanInfo info) {
628 PropertyDescriptor[] descriptors = info.getPropertyDescriptors();
629 int index = info.getDefaultPropertyIndex();
630 if ((0 <= index) && (index < descriptors.length)) {
631 this.defaultPropertyName = descriptors[index].getName();
632 }
633 return descriptors;
634 }
635
636 /**
637 * Populates the property descriptor table by merging the
638 * lists of Property descriptors.
639 */
640 private void processPropertyDescriptors() {
641 if (properties == null) {
642 properties = new TreeMap();
643 }
644
645 List list;
646
647 PropertyDescriptor pd, gpd, spd;
648 IndexedPropertyDescriptor ipd, igpd, ispd;
649
650 Iterator it = pdStore.values().iterator();
651 while (it.hasNext()) {
652 pd = null; gpd = null; spd = null;
653 ipd = null; igpd = null; ispd = null;
654
655 list = (List)it.next();
656
657 // First pass. Find the latest getter method. Merge properties
658 // of previous getter methods.
659 for (int i = 0; i < list.size(); i++) {
660 pd = (PropertyDescriptor)list.get(i);
661 if (pd instanceof IndexedPropertyDescriptor) {
662 ipd = (IndexedPropertyDescriptor)pd;
663 if (ipd.getIndexedReadMethod() != null) {
664 if (igpd != null) {
665 igpd = new IndexedPropertyDescriptor(igpd, ipd);
666 } else {
667 igpd = ipd;
668 }
669 }
670 } else {
671 if (pd.getReadMethod() != null) {
672 if (gpd != null) {
673 // Don't replace the existing read
674 // method if it starts with "is"
675 Method method = gpd.getReadMethod();
676 if (!method.getName().startsWith(IS_PREFIX)) {
677 gpd = new PropertyDescriptor(gpd, pd);
678 }
679 } else {
680 gpd = pd;
681 }
682 }
683 }
684 }
685
686 // Second pass. Find the latest setter method which
687 // has the same type as the getter method.
688 for (int i = 0; i < list.size(); i++) {
689 pd = (PropertyDescriptor)list.get(i);
690 if (pd instanceof IndexedPropertyDescriptor) {
691 ipd = (IndexedPropertyDescriptor)pd;
692 if (ipd.getIndexedWriteMethod() != null) {
693 if (igpd != null) {
694 if (igpd.getIndexedPropertyType()
695 == ipd.getIndexedPropertyType()) {
696 if (ispd != null) {
697 ispd = new IndexedPropertyDescriptor(ispd, ipd);
698 } else {
699 ispd = ipd;
700 }
701 }
702 } else {
703 if (ispd != null) {
704 ispd = new IndexedPropertyDescriptor(ispd, ipd);
705 } else {
706 ispd = ipd;
707 }
708 }
709 }
710 } else {
711 if (pd.getWriteMethod() != null) {
712 if (gpd != null) {
713 if (gpd.getPropertyType() == pd.getPropertyType()) {
714 if (spd != null) {
715 spd = new PropertyDescriptor(spd, pd);
716 } else {
717 spd = pd;
718 }
719 }
720 } else {
721 if (spd != null) {
722 spd = new PropertyDescriptor(spd, pd);
723 } else {
724 spd = pd;
725 }
726 }
727 }
728 }
729 }
730
731 // At this stage we should have either PDs or IPDs for the
732 // representative getters and setters. The order at which the
733 // property descriptors are determined represent the
734 // precedence of the property ordering.
735 pd = null; ipd = null;
736
737 if (igpd != null && ispd != null) {
738 // Complete indexed properties set
739 // Merge any classic property descriptors
740 if (gpd != null) {
741 PropertyDescriptor tpd = mergePropertyDescriptor(igpd, gpd);
742 if (tpd instanceof IndexedPropertyDescriptor) {
743 igpd = (IndexedPropertyDescriptor)tpd;
744 }
745 }
746 if (spd != null) {
747 PropertyDescriptor tpd = mergePropertyDescriptor(ispd, spd);
748 if (tpd instanceof IndexedPropertyDescriptor) {
749 ispd = (IndexedPropertyDescriptor)tpd;
750 }
751 }
752 if (igpd == ispd) {
753 pd = igpd;
754 } else {
755 pd = mergePropertyDescriptor(igpd, ispd);
756 }
757 } else if (gpd != null && spd != null) {
758 // Complete simple properties set
759 if (gpd == spd) {
760 pd = gpd;
761 } else {
762 pd = mergePropertyDescriptor(gpd, spd);
763 }
764 } else if (ispd != null) {
765 // indexed setter
766 pd = ispd;
767 // Merge any classic property descriptors
768 if (spd != null) {
769 pd = mergePropertyDescriptor(ispd, spd);
770 }
771 if (gpd != null) {
772 pd = mergePropertyDescriptor(ispd, gpd);
773 }
774 } else if (igpd != null) {
775 // indexed getter
776 pd = igpd;
777 // Merge any classic property descriptors
778 if (gpd != null) {
779 pd = mergePropertyDescriptor(igpd, gpd);
780 }
781 if (spd != null) {
782 pd = mergePropertyDescriptor(igpd, spd);
783 }
784 } else if (spd != null) {
785 // simple setter
786 pd = spd;
787 } else if (gpd != null) {
788 // simple getter
789 pd = gpd;
790 }
791
792 // Very special case to ensure that an IndexedPropertyDescriptor
793 // doesn't contain less information than the enclosed
794 // PropertyDescriptor. If it does, then recreate as a
795 // PropertyDescriptor. See 4168833
796 if (pd instanceof IndexedPropertyDescriptor) {
797 ipd = (IndexedPropertyDescriptor)pd;
798 if (ipd.getIndexedReadMethod() == null && ipd.getIndexedWriteMethod() == null) {
799 pd = new PropertyDescriptor(ipd);
800 }
801 }
802
803 // Find the first property descriptor
804 // which does not have getter and setter methods.
805 // See regression bug 4984912.
806 if ( (pd == null) && (list.size() > 0) ) {
807 pd = (PropertyDescriptor) list.get(0);
808 }
809
810 if (pd != null) {
811 properties.put(pd.getName(), pd);
812 }
813 }
814 }
815
816 /**
817 * Adds the property descriptor to the indexedproperty descriptor only if the
818 * types are the same.
819 *
820 * The most specific property descriptor will take precedence.
821 */
822 private PropertyDescriptor mergePropertyDescriptor(IndexedPropertyDescriptor ipd,
823 PropertyDescriptor pd) {
824 PropertyDescriptor result = null;
825
826 Class propType = pd.getPropertyType();
827 Class ipropType = ipd.getIndexedPropertyType();
828
829 if (propType.isArray() && propType.getComponentType() == ipropType) {
830 if (pd.getClass0().isAssignableFrom(ipd.getClass0())) {
831 result = new IndexedPropertyDescriptor(pd, ipd);
832 } else {
833 result = new IndexedPropertyDescriptor(ipd, pd);
834 }
835 } else {
836 // Cannot merge the pd because of type mismatch
837 // Return the most specific pd
838 if (pd.getClass0().isAssignableFrom(ipd.getClass0())) {
839 result = ipd;
840 } else {
841 result = pd;
842 // Try to add methods which may have been lost in the type change
843 // See 4168833
844 Method write = result.getWriteMethod();
845 Method read = result.getReadMethod();
846
847 if (read == null && write != null) {
848 read = findMethod(result.getClass0(),
849 GET_PREFIX + NameGenerator.capitalize(result.getName()), 0);
850 if (read != null) {
851 try {
852 result.setReadMethod(read);
853 } catch (IntrospectionException ex) {
854 // no consequences for failure.
855 }
856 }
857 }
858 if (write == null && read != null) {
859 write = findMethod(result.getClass0(),
860 SET_PREFIX + NameGenerator.capitalize(result.getName()), 1,
861 new Class[] { FeatureDescriptor.getReturnType(result.getClass0(), read) });
862 if (write != null) {
863 try {
864 result.setWriteMethod(write);
865 } catch (IntrospectionException ex) {
866 // no consequences for failure.
867 }
868 }
869 }
870 }
871 }
872 return result;
873 }
874
875 // Handle regular pd merge
876 private PropertyDescriptor mergePropertyDescriptor(PropertyDescriptor pd1,
877 PropertyDescriptor pd2) {
878 if (pd1.getClass0().isAssignableFrom(pd2.getClass0())) {
879 return new PropertyDescriptor(pd1, pd2);
880 } else {
881 return new PropertyDescriptor(pd2, pd1);
882 }
883 }
884
885 // Handle regular ipd merge
886 private PropertyDescriptor mergePropertyDescriptor(IndexedPropertyDescriptor ipd1,
887 IndexedPropertyDescriptor ipd2) {
888 if (ipd1.getClass0().isAssignableFrom(ipd2.getClass0())) {
889 return new IndexedPropertyDescriptor(ipd1, ipd2);
890 } else {
891 return new IndexedPropertyDescriptor(ipd2, ipd1);
892 }
893 }
894
895 /**
896 * @return An array of EventSetDescriptors describing the kinds of
897 * events fired by the target bean.
898 */
899 private EventSetDescriptor[] getTargetEventInfo() throws IntrospectionException {
900 if (events == null) {
901 events = new HashMap();
902 }
903
904 // Check if the bean has its own BeanInfo that will provide
905 // explicit information.
906 EventSetDescriptor[] explicitEvents = null;
907 if (explicitBeanInfo != null) {
908 explicitEvents = explicitBeanInfo.getEventSetDescriptors();
909 int ix = explicitBeanInfo.getDefaultEventIndex();
910 if (ix >= 0 && ix < explicitEvents.length) {
911 defaultEventName = explicitEvents[ix].getName();
912 }
913 }
914
915 if (explicitEvents == null && superBeanInfo != null) {
916 // We have no explicit BeanInfo events. Check with our parent.
917 EventSetDescriptor supers[] = superBeanInfo.getEventSetDescriptors();
918 for (int i = 0 ; i < supers.length; i++) {
919 addEvent(supers[i]);
920 }
921 int ix = superBeanInfo.getDefaultEventIndex();
922 if (ix >= 0 && ix < supers.length) {
923 defaultEventName = supers[ix].getName();
924 }
925 }
926
927 for (int i = 0; i < additionalBeanInfo.length; i++) {
928 EventSetDescriptor additional[] = additionalBeanInfo[i].getEventSetDescriptors();
929 if (additional != null) {
930 for (int j = 0 ; j < additional.length; j++) {
931 addEvent(additional[j]);
932 }
933 }
934 }
935
936 if (explicitEvents != null) {
937 // Add the explicit explicitBeanInfo data to our results.
938 for (int i = 0 ; i < explicitEvents.length; i++) {
939 addEvent(explicitEvents[i]);
940 }
941
942 } else {
943
944 // Apply some reflection to the current class.
945
946 // Get an array of all the public beans methods at this level
947 Method methodList[] = getPublicDeclaredMethods(beanClass);
948
949 // Find all suitable "add", "remove" and "get" Listener methods
950 // The name of the listener type is the key for these hashtables
951 // i.e, ActionListener
952 Map adds = null;
953 Map removes = null;
954 Map gets = null;
955
956 for (int i = 0; i < methodList.length; i++) {
957 Method method = methodList[i];
958 if (method == null) {
959 continue;
960 }
961 // skip static methods.
962 int mods = method.getModifiers();
963 if (Modifier.isStatic(mods)) {
964 continue;
965 }
966 String name = method.getName();
967 // Optimization avoid getParameterTypes
968 if (!name.startsWith(ADD_PREFIX) && !name.startsWith(REMOVE_PREFIX)
969 && !name.startsWith(GET_PREFIX)) {
970 continue;
971 }
972
973 Class argTypes[] = FeatureDescriptor.getParameterTypes(beanClass, method);
974 Class resultType = FeatureDescriptor.getReturnType(beanClass, method);
975
976 if (name.startsWith(ADD_PREFIX) && argTypes.length == 1 &&
977 resultType == Void.TYPE &&
978 Introspector.isSubclass(argTypes[0], eventListenerType)) {
979 String listenerName = name.substring(3);
980 if (listenerName.length() > 0 &&
981 argTypes[0].getName().endsWith(listenerName)) {
982 if (adds == null) {
983 adds = new HashMap();
984 }
985 adds.put(listenerName, method);
986 }
987 }
988 else if (name.startsWith(REMOVE_PREFIX) && argTypes.length == 1 &&
989 resultType == Void.TYPE &&
990 Introspector.isSubclass(argTypes[0], eventListenerType)) {
991 String listenerName = name.substring(6);
992 if (listenerName.length() > 0 &&
993 argTypes[0].getName().endsWith(listenerName)) {
994 if (removes == null) {
995 removes = new HashMap();
996 }
997 removes.put(listenerName, method);
998 }
999 }
1000 else if (name.startsWith(GET_PREFIX) && argTypes.length == 0 &&
1001 resultType.isArray() &&
1002 Introspector.isSubclass(resultType.getComponentType(),
1003 eventListenerType)) {
1004 String listenerName = name.substring(3, name.length() - 1);
1005 if (listenerName.length() > 0 &&
1006 resultType.getComponentType().getName().endsWith(listenerName)) {
1007 if (gets == null) {
1008 gets = new HashMap();
1009 }
1010 gets.put(listenerName, method);
1011 }
1012 }
1013 }
1014
1015 if (adds != null && removes != null) {
1016 // Now look for matching addFooListener+removeFooListener pairs.
1017 // Bonus if there is a matching getFooListeners method as well.
1018 Iterator keys = adds.keySet().iterator();
1019 while (keys.hasNext()) {
1020 String listenerName = (String) keys.next();
1021 // Skip any "add" which doesn't have a matching "remove" or
1022 // a listener name that doesn't end with Listener
1023 if (removes.get(listenerName) == null || !listenerName.endsWith("Listener")) {
1024 continue;
1025 }
1026 String eventName = decapitalize(listenerName.substring(0, listenerName.length()-8));
1027 Method addMethod = (Method)adds.get(listenerName);
1028 Method removeMethod = (Method)removes.get(listenerName);
1029 Method getMethod = null;
1030 if (gets != null) {
1031 getMethod = (Method)gets.get(listenerName);
1032 }
1033 Class argType = FeatureDescriptor.getParameterTypes(beanClass, addMethod)[0];
1034
1035 // generate a list of Method objects for each of the target methods:
1036 Method allMethods[] = getPublicDeclaredMethods(argType);
1037 List validMethods = new ArrayList(allMethods.length);
1038 for (int i = 0; i < allMethods.length; i++) {
1039 if (allMethods[i] == null) {
1040 continue;
1041 }
1042
1043 if (isEventHandler(allMethods[i])) {
1044 validMethods.add(allMethods[i]);
1045 }
1046 }
1047 Method[] methods = (Method[])validMethods.toArray(new Method[validMethods.size()]);
1048
1049 EventSetDescriptor esd = new EventSetDescriptor(eventName, argType,
1050 methods, addMethod,
1051 removeMethod,
1052 getMethod);
1053
1054 // If the adder method throws the TooManyListenersException then it
1055 // is a Unicast event source.
1056 if (throwsException(addMethod,
1057 java.util.TooManyListenersException.class)) {
1058 esd.setUnicast(true);
1059 }
1060 addEvent(esd);
1061 }
1062 } // if (adds != null ...
1063 }
1064 EventSetDescriptor[] result;
1065 if (events.size() == 0) {
1066 result = EMPTY_EVENTSETDESCRIPTORS;
1067 } else {
1068 // Allocate and populate the result array.
1069 result = new EventSetDescriptor[events.size()];
1070 result = (EventSetDescriptor[])events.values().toArray(result);
1071
1072 // Set the default index.
1073 if (defaultEventName != null) {
1074 for (int i = 0; i < result.length; i++) {
1075 if (defaultEventName.equals(result[i].getName())) {
1076 defaultEventIndex = i;
1077 }
1078 }
1079 }
1080 }
1081 return result;
1082 }
1083
1084 private void addEvent(EventSetDescriptor esd) {
1085 String key = esd.getName();
1086 if (esd.getName().equals("propertyChange")) {
1087 propertyChangeSource = true;
1088 }
1089 EventSetDescriptor old = (EventSetDescriptor)events.get(key);
1090 if (old == null) {
1091 events.put(key, esd);
1092 return;
1093 }
1094 EventSetDescriptor composite = new EventSetDescriptor(old, esd);
1095 events.put(key, composite);
1096 }
1097
1098 /**
1099 * @return An array of MethodDescriptors describing the private
1100 * methods supported by the target bean.
1101 */
1102 private MethodDescriptor[] getTargetMethodInfo() {
1103 if (methods == null) {
1104 methods = new HashMap(100);
1105 }
1106
1107 // Check if the bean has its own BeanInfo that will provide
1108 // explicit information.
1109 MethodDescriptor[] explicitMethods = null;
1110 if (explicitBeanInfo != null) {
1111 explicitMethods = explicitBeanInfo.getMethodDescriptors();
1112 }
1113
1114 if (explicitMethods == null && superBeanInfo != null) {
1115 // We have no explicit BeanInfo methods. Check with our parent.
1116 MethodDescriptor supers[] = superBeanInfo.getMethodDescriptors();
1117 for (int i = 0 ; i < supers.length; i++) {
1118 addMethod(supers[i]);
1119 }
1120 }
1121
1122 for (int i = 0; i < additionalBeanInfo.length; i++) {
1123 MethodDescriptor additional[] = additionalBeanInfo[i].getMethodDescriptors();
1124 if (additional != null) {
1125 for (int j = 0 ; j < additional.length; j++) {
1126 addMethod(additional[j]);
1127 }
1128 }
1129 }
1130
1131 if (explicitMethods != null) {
1132 // Add the explicit explicitBeanInfo data to our results.
1133 for (int i = 0 ; i < explicitMethods.length; i++) {
1134 addMethod(explicitMethods[i]);
1135 }
1136
1137 } else {
1138
1139 // Apply some reflection to the current class.
1140
1141 // First get an array of all the beans methods at this level
1142 Method methodList[] = getPublicDeclaredMethods(beanClass);
1143
1144 // Now analyze each method.
1145 for (int i = 0; i < methodList.length; i++) {
1146 Method method = methodList[i];
1147 if (method == null) {
1148 continue;
1149 }
1150 MethodDescriptor md = new MethodDescriptor(method);
1151 addMethod(md);
1152 }
1153 }
1154
1155 // Allocate and populate the result array.
1156 MethodDescriptor result[] = new MethodDescriptor[methods.size()];
1157 result = (MethodDescriptor[])methods.values().toArray(result);
1158
1159 return result;
1160 }
1161
1162 private void addMethod(MethodDescriptor md) {
1163 // We have to be careful here to distinguish method by both name
1164 // and argument lists.
1165 // This method gets called a *lot, so we try to be efficient.
1166 String name = md.getName();
1167
1168 MethodDescriptor old = (MethodDescriptor)methods.get(name);
1169 if (old == null) {
1170 // This is the common case.
1171 methods.put(name, md);
1172 return;
1173 }
1174
1175 // We have a collision on method names. This is rare.
1176
1177 // Check if old and md have the same type.
1178 String[] p1 = md.getParamNames();
1179 String[] p2 = old.getParamNames();
1180
1181 boolean match = false;
1182 if (p1.length == p2.length) {
1183 match = true;
1184 for (int i = 0; i < p1.length; i++) {
1185 if (p1[i] != p2[i]) {
1186 match = false;
1187 break;
1188 }
1189 }
1190 }
1191 if (match) {
1192 MethodDescriptor composite = new MethodDescriptor(old, md);
1193 methods.put(name, composite);
1194 return;
1195 }
1196
1197 // We have a collision on method names with different type signatures.
1198 // This is very rare.
1199
1200 String longKey = makeQualifiedMethodName(name, p1);
1201 old = (MethodDescriptor)methods.get(longKey);
1202 if (old == null) {
1203 methods.put(longKey, md);
1204 return;
1205 }
1206 MethodDescriptor composite = new MethodDescriptor(old, md);
1207 methods.put(longKey, composite);
1208 }
1209
1210 /**
1211 * Creates a key for a method in a method cache.
1212 */
1213 private static String makeQualifiedMethodName(String name, String[] params) {
1214 StringBuffer sb = new StringBuffer(name);
1215 sb.append('=');
1216 for (int i = 0; i < params.length; i++) {
1217 sb.append(':');
1218 sb.append(params[i]);
1219 }
1220 return sb.toString();
1221 }
1222
1223 private int getTargetDefaultEventIndex() {
1224 return defaultEventIndex;
1225 }
1226
1227 private int getTargetDefaultPropertyIndex() {
1228 return defaultPropertyIndex;
1229 }
1230
1231 private BeanDescriptor getTargetBeanDescriptor() {
1232 // Use explicit info, if available,
1233 if (explicitBeanInfo != null) {
1234 BeanDescriptor bd = explicitBeanInfo.getBeanDescriptor();
1235 if (bd != null) {
1236 return (bd);
1237 }
1238 }
1239 // OK, fabricate a default BeanDescriptor.
1240 return new BeanDescriptor(this.beanClass, findCustomizerClass(this.beanClass));
1241 }
1242
1243 private static Class<?> findCustomizerClass(Class<?> type) {
1244 String name = type.getName() + "Customizer";
1245 try {
1246 type = ClassFinder.findClass(name, type.getClassLoader());
1247 // Each customizer should inherit java.awt.Component and implement java.beans.Customizer
1248 // according to the section 9.3 of JavaBeans&trade; specification
1249 if (Component.class.isAssignableFrom(type) && Customizer.class.isAssignableFrom(type)) {
1250 return type;
1251 }
1252 }
1253 catch (Exception exception) {
1254 // ignore any exceptions
1255 }
1256 return null;
1257 }
1258
1259 private boolean isEventHandler(Method m) {
1260 // We assume that a method is an event handler if it has a single
1261 // argument, whose type inherit from java.util.Event.
1262 Class argTypes[] = FeatureDescriptor.getParameterTypes(beanClass, m);
1263 if (argTypes.length != 1) {
1264 return false;
1265 }
1266 return isSubclass(argTypes[0], EventObject.class);
1267 }
1268
1269 /*
1270 * Internal method to return *public* methods within a class.
1271 */
1272 private static Method[] getPublicDeclaredMethods(Class clz) {
1273 // Looking up Class.getDeclaredMethods is relatively expensive,
1274 // so we cache the results.
1275 if (!ReflectUtil.isPackageAccessible(clz)) {
1276 return new Method[0];
1277 }
1278 synchronized (BEANINFO_CACHE) {
1279 Method[] result = declaredMethodCache.get(clz);
1280 if (result == null) {
1281 result = clz.getMethods();
1282 for (int i = 0; i < result.length; i++) {
1283 Method method = result[i];
1284 if (!method.getDeclaringClass().equals(clz)) {
1285 result[i] = null;
1286 }
1287 }
1288 declaredMethodCache.put(clz, result);
1289 }
1290 return result;
1291 }
1292 }
1293
1294 //======================================================================
1295 // Package private support methods.
1296 //======================================================================
1297
1298 /**
1299 * Internal support for finding a target methodName with a given
1300 * parameter list on a given class.
1301 */
1302 private static Method internalFindMethod(Class start, String methodName,
1303 int argCount, Class args[]) {
1304 // For overriden methods we need to find the most derived version.
1305 // So we start with the given class and walk up the superclass chain.
1306
1307 Method method = null;
1308
1309 for (Class cl = start; cl != null; cl = cl.getSuperclass()) {
1310 Method methods[] = getPublicDeclaredMethods(cl);
1311 for (int i = 0; i < methods.length; i++) {
1312 method = methods[i];
1313 if (method == null) {
1314 continue;
1315 }
1316
1317 // make sure method signature matches.
1318 Class params[] = FeatureDescriptor.getParameterTypes(start, method);
1319 if (method.getName().equals(methodName) &&
1320 params.length == argCount) {
1321 if (args != null) {
1322 boolean different = false;
1323 if (argCount > 0) {
1324 for (int j = 0; j < argCount; j++) {
1325 if (params[j] != args[j]) {
1326 different = true;
1327 continue;
1328 }
1329 }
1330 if (different) {
1331 continue;
1332 }
1333 }
1334 }
1335 return method;
1336 }
1337 }
1338 }
1339 method = null;
1340
1341 // Now check any inherited interfaces. This is necessary both when
1342 // the argument class is itself an interface, and when the argument
1343 // class is an abstract class.
1344 Class ifcs[] = start.getInterfaces();
1345 for (int i = 0 ; i < ifcs.length; i++) {
1346 // Note: The original implementation had both methods calling
1347 // the 3 arg method. This is preserved but perhaps it should
1348 // pass the args array instead of null.
1349 method = internalFindMethod(ifcs[i], methodName, argCount, null);
1350 if (method != null) {
1351 break;
1352 }
1353 }
1354 return method;
1355 }
1356
1357 /**
1358 * Find a target methodName on a given class.
1359 */
1360 static Method findMethod(Class cls, String methodName, int argCount) {
1361 return findMethod(cls, methodName, argCount, null);
1362 }
1363
1364 /**
1365 * Find a target methodName with specific parameter list on a given class.
1366 * <p>
1367 * Used in the contructors of the EventSetDescriptor,
1368 * PropertyDescriptor and the IndexedPropertyDescriptor.
1369 * <p>
1370 * @param cls The Class object on which to retrieve the method.
1371 * @param methodName Name of the method.
1372 * @param argCount Number of arguments for the desired method.
1373 * @param args Array of argument types for the method.
1374 * @return the method or null if not found
1375 */
1376 static Method findMethod(Class cls, String methodName, int argCount,
1377 Class args[]) {
1378 if (methodName == null) {
1379 return null;
1380 }
1381 return internalFindMethod(cls, methodName, argCount, args);
1382 }
1383
1384 /**
1385 * Return true if class a is either equivalent to class b, or
1386 * if class a is a subclass of class b, i.e. if a either "extends"
1387 * or "implements" b.
1388 * Note tht either or both "Class" objects may represent interfaces.
1389 */
1390 static boolean isSubclass(Class a, Class b) {
1391 // We rely on the fact that for any given java class or
1392 // primtitive type there is a unqiue Class object, so
1393 // we can use object equivalence in the comparisons.
1394 if (a == b) {
1395 return true;
1396 }
1397 if (a == null || b == null) {
1398 return false;
1399 }
1400 for (Class x = a; x != null; x = x.getSuperclass()) {
1401 if (x == b) {
1402 return true;
1403 }
1404 if (b.isInterface()) {
1405 Class interfaces[] = x.getInterfaces();
1406 for (int i = 0; i < interfaces.length; i++) {
1407 if (isSubclass(interfaces[i], b)) {
1408 return true;
1409 }
1410 }
1411 }
1412 }
1413 return false;
1414 }
1415
1416 /**
1417 * Return true iff the given method throws the given exception.
1418 */
1419 private boolean throwsException(Method method, Class exception) {
1420 Class exs[] = method.getExceptionTypes();
1421 for (int i = 0; i < exs.length; i++) {
1422 if (exs[i] == exception) {
1423 return true;
1424 }
1425 }
1426 return false;
1427 }
1428
1429 private static BeanInfoFinder getFinder() {
1430 AppContext context = AppContext.getAppContext();
1431 Object object = context.get(FINDER_KEY);
1432 if (object instanceof BeanInfoFinder) {
1433 return (BeanInfoFinder) object;
1434 }
1435 BeanInfoFinder finder = new BeanInfoFinder();
1436 context.put(FINDER_KEY, finder);
1437 return finder;
1438 }
1439
1440 /**
1441 * Try to create an instance of a named class.
1442 * First try the classloader of "sibling", then try the system
1443 * classloader then the class loader of the current Thread.
1444 */
1445 static Object instantiate(Class sibling, String className)
1446 throws InstantiationException, IllegalAccessException,
1447 ClassNotFoundException {
1448 // First check with sibling's classloader (if any).
1449 ClassLoader cl = sibling.getClassLoader();
1450 Class cls = ClassFinder.findClass(className, cl);
1451 return cls.newInstance();
1452 }
1453
1454} // end class Introspector
1455
1456//===========================================================================
1457
1458/**
1459 * Package private implementation support class for Introspector's
1460 * internal use.
1461 * <p>
1462 * Mostly this is used as a placeholder for the descriptors.
1463 */
1464
1465class GenericBeanInfo extends SimpleBeanInfo {
1466
1467 private BeanDescriptor beanDescriptor;
1468 private EventSetDescriptor[] events;
1469 private int defaultEvent;
1470 private PropertyDescriptor[] properties;
1471 private int defaultProperty;
1472 private MethodDescriptor[] methods;
1473 private final Reference<BeanInfo> targetBeanInfoRef;
1474
1475 public GenericBeanInfo(BeanDescriptor beanDescriptor,
1476 EventSetDescriptor[] events, int defaultEvent,
1477 PropertyDescriptor[] properties, int defaultProperty,
1478 MethodDescriptor[] methods, BeanInfo targetBeanInfo) {
1479 this.beanDescriptor = beanDescriptor;
1480 this.events = events;
1481 this.defaultEvent = defaultEvent;
1482 this.properties = properties;
1483 this.defaultProperty = defaultProperty;
1484 this.methods = methods;
1485 this.targetBeanInfoRef = new SoftReference<BeanInfo>(targetBeanInfo);
1486 }
1487
1488 /**
1489 * Package-private dup constructor
1490 * This must isolate the new object from any changes to the old object.
1491 */
1492 GenericBeanInfo(GenericBeanInfo old) {
1493
1494 beanDescriptor = new BeanDescriptor(old.beanDescriptor);
1495 if (old.events != null) {
1496 int len = old.events.length;
1497 events = new EventSetDescriptor[len];
1498 for (int i = 0; i < len; i++) {
1499 events[i] = new EventSetDescriptor(old.events[i]);
1500 }
1501 }
1502 defaultEvent = old.defaultEvent;
1503 if (old.properties != null) {
1504 int len = old.properties.length;
1505 properties = new PropertyDescriptor[len];
1506 for (int i = 0; i < len; i++) {
1507 PropertyDescriptor oldp = old.properties[i];
1508 if (oldp instanceof IndexedPropertyDescriptor) {
1509 properties[i] = new IndexedPropertyDescriptor(
1510 (IndexedPropertyDescriptor) oldp);
1511 } else {
1512 properties[i] = new PropertyDescriptor(oldp);
1513 }
1514 }
1515 }
1516 defaultProperty = old.defaultProperty;
1517 if (old.methods != null) {
1518 int len = old.methods.length;
1519 methods = new MethodDescriptor[len];
1520 for (int i = 0; i < len; i++) {
1521 methods[i] = new MethodDescriptor(old.methods[i]);
1522 }
1523 }
1524 this.targetBeanInfoRef = old.targetBeanInfoRef;
1525 }
1526
1527 public PropertyDescriptor[] getPropertyDescriptors() {
1528 return properties;
1529 }
1530
1531 public int getDefaultPropertyIndex() {
1532 return defaultProperty;
1533 }
1534
1535 public EventSetDescriptor[] getEventSetDescriptors() {
1536 return events;
1537 }
1538
1539 public int getDefaultEventIndex() {
1540 return defaultEvent;
1541 }
1542
1543 public MethodDescriptor[] getMethodDescriptors() {
1544 return methods;
1545 }
1546
1547 public BeanDescriptor getBeanDescriptor() {
1548 return beanDescriptor;
1549 }
1550
1551 public java.awt.Image getIcon(int iconKind) {
1552 BeanInfo targetBeanInfo = this.targetBeanInfoRef.get();
1553 if (targetBeanInfo != null) {
1554 return targetBeanInfo.getIcon(iconKind);
1555 }
1556 return super.getIcon(iconKind);
1557 }
1558}
java/pkg/java/beans/MetaData$1.class+0−0

Binary file not shown.

java/pkg/java/beans/MetaData.class+0−0

Binary file not shown.

java/pkg/java/beans/MetaData.java+1443−0
@@ -0,0 +1,1443 @@
1/*
2 * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25package java.beans;
26
27import com.sun.beans.finder.PrimitiveWrapperMap;
28
29import java.awt.AWTKeyStroke;
30import java.awt.BorderLayout;
31import java.awt.Dimension;
32import java.awt.Color;
33import java.awt.Font;
34import java.awt.GridBagConstraints;
35import java.awt.Insets;
36import java.awt.Point;
37import java.awt.Rectangle;
38import java.awt.event.KeyEvent;
39import java.awt.font.TextAttribute;
40
41import java.lang.reflect.Array;
42import java.lang.reflect.Constructor;
43import java.lang.reflect.Field;
44import java.lang.reflect.Method;
45import java.lang.reflect.InvocationTargetException;
46
47import java.security.AccessController;
48import java.security.PrivilegedAction;
49
50import java.util.*;
51
52import javax.swing.Box;
53import javax.swing.JLayeredPane;
54import javax.swing.border.MatteBorder;
55import javax.swing.plaf.ColorUIResource;
56
57import sun.swing.PrintColorUIResource;
58
59import java.util.Objects;
60
61/*
62 * Like the <code>Intropector</code>, the <code>MetaData</code> class
63 * contains <em>meta</em> objects that describe the way
64 * classes should express their state in terms of their
65 * own public APIs.
66 *
67 * @see java.beans.Intropector
68 *
69 * @author Philip Milne
70 * @author Steve Langley
71 */
72
73class NullPersistenceDelegate extends PersistenceDelegate {
74 // Note this will be called by all classes when they reach the
75 // top of their superclass chain.
76 protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) {
77 }
78 protected Expression instantiate(Object oldInstance, Encoder out) { return null; }
79
80 public void writeObject(Object oldInstance, Encoder out) {
81 // System.out.println("NullPersistenceDelegate:writeObject " + oldInstance);
82 }
83}
84
85/**
86 * The persistence delegate for <CODE>enum</CODE> classes.
87 *
88 * @author Sergey A. Malenkov
89 */
90class EnumPersistenceDelegate extends PersistenceDelegate {
91 protected boolean mutatesTo(Object oldInstance, Object newInstance) {
92 return oldInstance == newInstance;
93 }
94
95 protected Expression instantiate(Object oldInstance, Encoder out) {
96 Enum e = (Enum) oldInstance;
97 return new Expression(e, Enum.class, "valueOf", new Object[]{e.getDeclaringClass(), e.name()});
98 }
99}
100
101class PrimitivePersistenceDelegate extends PersistenceDelegate {
102 protected boolean mutatesTo(Object oldInstance, Object newInstance) {
103 return oldInstance.equals(newInstance);
104 }
105
106 protected Expression instantiate(Object oldInstance, Encoder out) {
107 return new Expression(oldInstance, oldInstance.getClass(),
108 "new", new Object[]{oldInstance.toString()});
109 }
110}
111
112class ArrayPersistenceDelegate extends PersistenceDelegate {
113 protected boolean mutatesTo(Object oldInstance, Object newInstance) {
114 return (newInstance != null &&
115 oldInstance.getClass() == newInstance.getClass() && // Also ensures the subtype is correct.
116 Array.getLength(oldInstance) == Array.getLength(newInstance));
117 }
118
119 protected Expression instantiate(Object oldInstance, Encoder out) {
120 // System.out.println("instantiate: " + type + " " + oldInstance);
121 Class oldClass = oldInstance.getClass();
122 return new Expression(oldInstance, Array.class, "newInstance",
123 new Object[]{oldClass.getComponentType(),
124 new Integer(Array.getLength(oldInstance))});
125 }
126
127 protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) {
128 int n = Array.getLength(oldInstance);
129 for (int i = 0; i < n; i++) {
130 Object index = new Integer(i);
131 // Expression oldGetExp = new Expression(Array.class, "get", new Object[]{oldInstance, index});
132 // Expression newGetExp = new Expression(Array.class, "get", new Object[]{newInstance, index});
133 Expression oldGetExp = new Expression(oldInstance, "get", new Object[]{index});
134 Expression newGetExp = new Expression(newInstance, "get", new Object[]{index});
135 try {
136 Object oldValue = oldGetExp.getValue();
137 Object newValue = newGetExp.getValue();
138 out.writeExpression(oldGetExp);
139 if (!Objects.equals(newValue, out.get(oldValue))) {
140 // System.out.println("Not equal: " + newGetExp + " != " + actualGetExp);
141 // invokeStatement(Array.class, "set", new Object[]{oldInstance, index, oldValue}, out);
142 DefaultPersistenceDelegate.invokeStatement(oldInstance, "set", new Object[]{index, oldValue}, out);
143 }
144 }
145 catch (Exception e) {
146 // System.err.println("Warning:: failed to write: " + oldGetExp);
147 out.getExceptionListener().exceptionThrown(e);
148 }
149 }
150 }
151}
152
153class ProxyPersistenceDelegate extends PersistenceDelegate {
154 protected Expression instantiate(Object oldInstance, Encoder out) {
155 Class type = oldInstance.getClass();
156 java.lang.reflect.Proxy p = (java.lang.reflect.Proxy)oldInstance;
157 // This unappealing hack is not required but makes the
158 // representation of EventHandlers much more concise.
159 java.lang.reflect.InvocationHandler ih = java.lang.reflect.Proxy.getInvocationHandler(p);
160 if (ih instanceof EventHandler) {
161 EventHandler eh = (EventHandler)ih;
162 Vector args = new Vector();
163 args.add(type.getInterfaces()[0]);
164 args.add(eh.getTarget());
165 args.add(eh.getAction());
166 if (eh.getEventPropertyName() != null) {
167 args.add(eh.getEventPropertyName());
168 }
169 if (eh.getListenerMethodName() != null) {
170 args.setSize(4);
171 args.add(eh.getListenerMethodName());
172 }
173 return new Expression(oldInstance,
174 EventHandler.class,
175 "create",
176 args.toArray());
177 }
178 return new Expression(oldInstance,
179 java.lang.reflect.Proxy.class,
180 "newProxyInstance",
181 new Object[]{type.getClassLoader(),
182 type.getInterfaces(),
183 ih});
184 }
185}
186
187// Strings
188class java_lang_String_PersistenceDelegate extends PersistenceDelegate {
189 protected Expression instantiate(Object oldInstance, Encoder out) { return null; }
190
191 public void writeObject(Object oldInstance, Encoder out) {
192 // System.out.println("NullPersistenceDelegate:writeObject " + oldInstance);
193 }
194}
195
196// Classes
197class java_lang_Class_PersistenceDelegate extends PersistenceDelegate {
198 protected boolean mutatesTo(Object oldInstance, Object newInstance) {
199 return oldInstance.equals(newInstance);
200 }
201
202 protected Expression instantiate(Object oldInstance, Encoder out) {
203 Class c = (Class)oldInstance;
204 // As of 1.3 it is not possible to call Class.forName("int"),
205 // so we have to generate different code for primitive types.
206 // This is needed for arrays whose subtype may be primitive.
207 if (c.isPrimitive()) {
208 Field field = null;
209 try {
210 field = PrimitiveWrapperMap.getType(c.getName()).getDeclaredField("TYPE");
211 } catch (NoSuchFieldException ex) {
212 System.err.println("Unknown primitive type: " + c);
213 }
214 return new Expression(oldInstance, field, "get", new Object[]{null});
215 }
216 else if (oldInstance == String.class) {
217 return new Expression(oldInstance, "", "getClass", new Object[]{});
218 }
219 else if (oldInstance == Class.class) {
220 return new Expression(oldInstance, String.class, "getClass", new Object[]{});
221 }
222 else {
223 Expression newInstance = new Expression(oldInstance, Class.class, "forName", new Object[] { c.getName() });
224 newInstance.loader = c.getClassLoader();
225 return newInstance;
226 }
227 }
228}
229
230// Fields
231class java_lang_reflect_Field_PersistenceDelegate extends PersistenceDelegate {
232 protected boolean mutatesTo(Object oldInstance, Object newInstance) {
233 return oldInstance.equals(newInstance);
234 }
235
236 protected Expression instantiate(Object oldInstance, Encoder out) {
237 Field f = (Field)oldInstance;
238 return new Expression(oldInstance,
239 f.getDeclaringClass(),
240 "getField",
241 new Object[]{f.getName()});
242 }
243}
244
245// Methods
246class java_lang_reflect_Method_PersistenceDelegate extends PersistenceDelegate {
247 protected boolean mutatesTo(Object oldInstance, Object newInstance) {
248 return oldInstance.equals(newInstance);
249 }
250
251 protected Expression instantiate(Object oldInstance, Encoder out) {
252 Method m = (Method)oldInstance;
253 return new Expression(oldInstance,
254 m.getDeclaringClass(),
255 "getMethod",
256 new Object[]{m.getName(), m.getParameterTypes()});
257 }
258}
259
260// Dates
261
262/**
263 * The persistence delegate for <CODE>java.util.Date</CODE> classes.
264 * Do not extend DefaultPersistenceDelegate to improve performance and
265 * to avoid problems with <CODE>java.sql.Date</CODE>,
266 * <CODE>java.sql.Time</CODE> and <CODE>java.sql.Timestamp</CODE>.
267 *
268 * @author Sergey A. Malenkov
269 */
270class java_util_Date_PersistenceDelegate extends PersistenceDelegate {
271 protected boolean mutatesTo(Object oldInstance, Object newInstance) {
272 if (!super.mutatesTo(oldInstance, newInstance)) {
273 return false;
274 }
275 Date oldDate = (Date)oldInstance;
276 Date newDate = (Date)newInstance;
277
278 return oldDate.getTime() == newDate.getTime();
279 }
280
281 protected Expression instantiate(Object oldInstance, Encoder out) {
282 Date date = (Date)oldInstance;
283 return new Expression(date, date.getClass(), "new", new Object[] {date.getTime()});
284 }
285}
286
287/**
288 * The persistence delegate for <CODE>java.sql.Timestamp</CODE> classes.
289 * It supports nanoseconds.
290 *
291 * @author Sergey A. Malenkov
292 */
293final class java_sql_Timestamp_PersistenceDelegate extends java_util_Date_PersistenceDelegate {
294 private static final Method getNanosMethod = getNanosMethod();
295
296 private static Method getNanosMethod() {
297 try {
298 Class<?> c = Class.forName("java.sql.Timestamp", true, null);
299 return c.getMethod("getNanos");
300 } catch (ClassNotFoundException e) {
301 return null;
302 } catch (NoSuchMethodException e) {
303 throw new AssertionError(e);
304 }
305 }
306
307 /**
308 * Invoke Timstamp getNanos.
309 */
310 private static int getNanos(Object obj) {
311 if (getNanosMethod == null)
312 throw new AssertionError("Should not get here");
313 try {
314 return (Integer)getNanosMethod.invoke(obj);
315 } catch (InvocationTargetException e) {
316 Throwable cause = e.getCause();
317 if (cause instanceof RuntimeException)
318 throw (RuntimeException)cause;
319 if (cause instanceof Error)
320 throw (Error)cause;
321 throw new AssertionError(e);
322 } catch (IllegalAccessException iae) {
323 throw new AssertionError(iae);
324 }
325 }
326
327 protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) {
328 // assumes oldInstance and newInstance are Timestamps
329 int nanos = getNanos(oldInstance);
330 if (nanos != getNanos(newInstance)) {
331 out.writeStatement(new Statement(oldInstance, "setNanos", new Object[] {nanos}));
332 }
333 }
334}
335
336// Collections
337
338/*
339The Hashtable and AbstractMap classes have no common ancestor yet may
340be handled with a single persistence delegate: one which uses the methods
341of the Map insterface exclusively. Attatching the persistence delegates
342to the interfaces themselves is fraught however since, in the case of
343the Map, both the AbstractMap and HashMap classes are declared to
344implement the Map interface, leaving the obvious implementation prone
345to repeating their initialization. These issues and questions around
346the ordering of delegates attached to interfaces have lead us to
347ignore any delegates attached to interfaces and force all persistence
348delegates to be registered with concrete classes.
349*/
350
351/**
352 * The base class for persistence delegates for inner classes
353 * that can be created using {@link Collections}.
354 *
355 * @author Sergey A. Malenkov
356 */
357abstract class java_util_Collections extends PersistenceDelegate {
358 protected boolean mutatesTo(Object oldInstance, Object newInstance) {
359 if (!super.mutatesTo(oldInstance, newInstance)) {
360 return false;
361 }
362 if ((oldInstance instanceof List) || (oldInstance instanceof Set) || (oldInstance instanceof Map)) {
363 return oldInstance.equals(newInstance);
364 }
365 Collection oldC = (Collection) oldInstance;
366 Collection newC = (Collection) newInstance;
367 return (oldC.size() == newC.size()) && oldC.containsAll(newC);
368 }
369
370 static final class EmptyList_PersistenceDelegate extends java_util_Collections {
371 protected Expression instantiate(Object oldInstance, Encoder out) {
372 return new Expression(oldInstance, Collections.class, "emptyList", null);
373 }
374 }
375
376 static final class EmptySet_PersistenceDelegate extends java_util_Collections {
377 protected Expression instantiate(Object oldInstance, Encoder out) {
378 return new Expression(oldInstance, Collections.class, "emptySet", null);
379 }
380 }
381
382 static final class EmptyMap_PersistenceDelegate extends java_util_Collections {
383 protected Expression instantiate(Object oldInstance, Encoder out) {
384 return new Expression(oldInstance, Collections.class, "emptyMap", null);
385 }
386 }
387
388 static final class SingletonList_PersistenceDelegate extends java_util_Collections {
389 protected Expression instantiate(Object oldInstance, Encoder out) {
390 List list = (List) oldInstance;
391 return new Expression(oldInstance, Collections.class, "singletonList", new Object[]{list.get(0)});
392 }
393 }
394
395 static final class SingletonSet_PersistenceDelegate extends java_util_Collections {
396 protected Expression instantiate(Object oldInstance, Encoder out) {
397 Set set = (Set) oldInstance;
398 return new Expression(oldInstance, Collections.class, "singleton", new Object[]{set.iterator().next()});
399 }
400 }
401
402 static final class SingletonMap_PersistenceDelegate extends java_util_Collections {
403 protected Expression instantiate(Object oldInstance, Encoder out) {
404 Map map = (Map) oldInstance;
405 Object key = map.keySet().iterator().next();
406 return new Expression(oldInstance, Collections.class, "singletonMap", new Object[]{key, map.get(key)});
407 }
408 }
409
410 static final class UnmodifiableCollection_PersistenceDelegate extends java_util_Collections {
411 protected Expression instantiate(Object oldInstance, Encoder out) {
412 List list = new ArrayList((Collection) oldInstance);
413 return new Expression(oldInstance, Collections.class, "unmodifiableCollection", new Object[]{list});
414 }
415 }
416
417 static final class UnmodifiableList_PersistenceDelegate extends java_util_Collections {
418 protected Expression instantiate(Object oldInstance, Encoder out) {
419 List list = new LinkedList((Collection) oldInstance);
420 return new Expression(oldInstance, Collections.class, "unmodifiableList", new Object[]{list});
421 }
422 }
423
424 static final class UnmodifiableRandomAccessList_PersistenceDelegate extends java_util_Collections {
425 protected Expression instantiate(Object oldInstance, Encoder out) {
426 List list = new ArrayList((Collection) oldInstance);
427 return new Expression(oldInstance, Collections.class, "unmodifiableList", new Object[]{list});
428 }
429 }
430
431 static final class UnmodifiableSet_PersistenceDelegate extends java_util_Collections {
432 protected Expression instantiate(Object oldInstance, Encoder out) {
433 Set set = new HashSet((Set) oldInstance);
434 return new Expression(oldInstance, Collections.class, "unmodifiableSet", new Object[]{set});
435 }
436 }
437
438 static final class UnmodifiableSortedSet_PersistenceDelegate extends java_util_Collections {
439 protected Expression instantiate(Object oldInstance, Encoder out) {
440 SortedSet set = new TreeSet((SortedSet) oldInstance);
441 return new Expression(oldInstance, Collections.class, "unmodifiableSortedSet", new Object[]{set});
442 }
443 }
444
445 static final class UnmodifiableMap_PersistenceDelegate extends java_util_Collections {
446 protected Expression instantiate(Object oldInstance, Encoder out) {
447 Map map = new HashMap((Map) oldInstance);
448 return new Expression(oldInstance, Collections.class, "unmodifiableMap", new Object[]{map});
449 }
450 }
451
452 static final class UnmodifiableSortedMap_PersistenceDelegate extends java_util_Collections {
453 protected Expression instantiate(Object oldInstance, Encoder out) {
454 SortedMap map = new TreeMap((SortedMap) oldInstance);
455 return new Expression(oldInstance, Collections.class, "unmodifiableSortedMap", new Object[]{map});
456 }
457 }
458
459 static final class SynchronizedCollection_PersistenceDelegate extends java_util_Collections {
460 protected Expression instantiate(Object oldInstance, Encoder out) {
461 List list = new ArrayList((Collection) oldInstance);
462 return new Expression(oldInstance, Collections.class, "synchronizedCollection", new Object[]{list});
463 }
464 }
465
466 static final class SynchronizedList_PersistenceDelegate extends java_util_Collections {
467 protected Expression instantiate(Object oldInstance, Encoder out) {
468 List list = new LinkedList((Collection) oldInstance);
469 return new Expression(oldInstance, Collections.class, "synchronizedList", new Object[]{list});
470 }
471 }
472
473 static final class SynchronizedRandomAccessList_PersistenceDelegate extends java_util_Collections {
474 protected Expression instantiate(Object oldInstance, Encoder out) {
475 List list = new ArrayList((Collection) oldInstance);
476 return new Expression(oldInstance, Collections.class, "synchronizedList", new Object[]{list});
477 }
478 }
479
480 static final class SynchronizedSet_PersistenceDelegate extends java_util_Collections {
481 protected Expression instantiate(Object oldInstance, Encoder out) {
482 Set set = new HashSet((Set) oldInstance);
483 return new Expression(oldInstance, Collections.class, "synchronizedSet", new Object[]{set});
484 }
485 }
486
487 static final class SynchronizedSortedSet_PersistenceDelegate extends java_util_Collections {
488 protected Expression instantiate(Object oldInstance, Encoder out) {
489 SortedSet set = new TreeSet((SortedSet) oldInstance);
490 return new Expression(oldInstance, Collections.class, "synchronizedSortedSet", new Object[]{set});
491 }
492 }
493
494 static final class SynchronizedMap_PersistenceDelegate extends java_util_Collections {
495 protected Expression instantiate(Object oldInstance, Encoder out) {
496 Map map = new HashMap((Map) oldInstance);
497 return new Expression(oldInstance, Collections.class, "synchronizedMap", new Object[]{map});
498 }
499 }
500
501 static final class SynchronizedSortedMap_PersistenceDelegate extends java_util_Collections {
502 protected Expression instantiate(Object oldInstance, Encoder out) {
503 SortedMap map = new TreeMap((SortedMap) oldInstance);
504 return new Expression(oldInstance, Collections.class, "synchronizedSortedMap", new Object[]{map});
505 }
506 }
507
508 static final class CheckedCollection_PersistenceDelegate extends java_util_Collections {
509 protected Expression instantiate(Object oldInstance, Encoder out) {
510 Object type = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedCollection.type");
511 List list = new ArrayList((Collection) oldInstance);
512 return new Expression(oldInstance, Collections.class, "checkedCollection", new Object[]{list, type});
513 }
514 }
515
516 static final class CheckedList_PersistenceDelegate extends java_util_Collections {
517 protected Expression instantiate(Object oldInstance, Encoder out) {
518 Object type = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedCollection.type");
519 List list = new LinkedList((Collection) oldInstance);
520 return new Expression(oldInstance, Collections.class, "checkedList", new Object[]{list, type});
521 }
522 }
523
524 static final class CheckedRandomAccessList_PersistenceDelegate extends java_util_Collections {
525 protected Expression instantiate(Object oldInstance, Encoder out) {
526 Object type = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedCollection.type");
527 List list = new ArrayList((Collection) oldInstance);
528 return new Expression(oldInstance, Collections.class, "checkedList", new Object[]{list, type});
529 }
530 }
531
532 static final class CheckedSet_PersistenceDelegate extends java_util_Collections {
533 protected Expression instantiate(Object oldInstance, Encoder out) {
534 Object type = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedCollection.type");
535 Set set = new HashSet((Set) oldInstance);
536 return new Expression(oldInstance, Collections.class, "checkedSet", new Object[]{set, type});
537 }
538 }
539
540 static final class CheckedSortedSet_PersistenceDelegate extends java_util_Collections {
541 protected Expression instantiate(Object oldInstance, Encoder out) {
542 Object type = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedCollection.type");
543 SortedSet set = new TreeSet((SortedSet) oldInstance);
544 return new Expression(oldInstance, Collections.class, "checkedSortedSet", new Object[]{set, type});
545 }
546 }
547
548 static final class CheckedMap_PersistenceDelegate extends java_util_Collections {
549 protected Expression instantiate(Object oldInstance, Encoder out) {
550 Object keyType = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedMap.keyType");
551 Object valueType = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedMap.valueType");
552 Map map = new HashMap((Map) oldInstance);
553 return new Expression(oldInstance, Collections.class, "checkedMap", new Object[]{map, keyType, valueType});
554 }
555 }
556
557 static final class CheckedSortedMap_PersistenceDelegate extends java_util_Collections {
558 protected Expression instantiate(Object oldInstance, Encoder out) {
559 Object keyType = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedMap.keyType");
560 Object valueType = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedMap.valueType");
561 SortedMap map = new TreeMap((SortedMap) oldInstance);
562 return new Expression(oldInstance, Collections.class, "checkedSortedMap", new Object[]{map, keyType, valueType});
563 }
564 }
565}
566
567/**
568 * The persistence delegate for <CODE>java.util.EnumMap</CODE> classes.
569 *
570 * @author Sergey A. Malenkov
571 */
572class java_util_EnumMap_PersistenceDelegate extends PersistenceDelegate {
573 protected boolean mutatesTo(Object oldInstance, Object newInstance) {
574 return super.mutatesTo(oldInstance, newInstance) && (getType(oldInstance) == getType(newInstance));
575 }
576
577 protected Expression instantiate(Object oldInstance, Encoder out) {
578 return new Expression(oldInstance, EnumMap.class, "new", new Object[] {getType(oldInstance)});
579 }
580
581 private static Object getType(Object instance) {
582 return MetaData.getPrivateFieldValue(instance, "java.util.EnumMap.keyType");
583 }
584}
585
586/**
587 * The persistence delegate for <CODE>java.util.EnumSet</CODE> classes.
588 *
589 * @author Sergey A. Malenkov
590 */
591class java_util_EnumSet_PersistenceDelegate extends PersistenceDelegate {
592 protected boolean mutatesTo(Object oldInstance, Object newInstance) {
593 return super.mutatesTo(oldInstance, newInstance) && (getType(oldInstance) == getType(newInstance));
594 }
595
596 protected Expression instantiate(Object oldInstance, Encoder out) {
597 return new Expression(oldInstance, EnumSet.class, "noneOf", new Object[] {getType(oldInstance)});
598 }
599
600 private static Object getType(Object instance) {
601 return MetaData.getPrivateFieldValue(instance, "java.util.EnumSet.elementType");
602 }
603}
604
605// Collection
606class java_util_Collection_PersistenceDelegate extends DefaultPersistenceDelegate {
607 protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) {
608 java.util.Collection oldO = (java.util.Collection)oldInstance;
609 java.util.Collection newO = (java.util.Collection)newInstance;
610
611 if (newO.size() != 0) {
612 invokeStatement(oldInstance, "clear", new Object[]{}, out);
613 }
614 for (Iterator i = oldO.iterator(); i.hasNext();) {
615 invokeStatement(oldInstance, "add", new Object[]{i.next()}, out);
616 }
617 }
618}
619
620// List
621class java_util_List_PersistenceDelegate extends DefaultPersistenceDelegate {
622 protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) {
623 java.util.List oldO = (java.util.List)oldInstance;
624 java.util.List newO = (java.util.List)newInstance;
625 int oldSize = oldO.size();
626 int newSize = (newO == null) ? 0 : newO.size();
627 if (oldSize < newSize) {
628 invokeStatement(oldInstance, "clear", new Object[]{}, out);
629 newSize = 0;
630 }
631 for (int i = 0; i < newSize; i++) {
632 Object index = new Integer(i);
633
634 Expression oldGetExp = new Expression(oldInstance, "get", new Object[]{index});
635 Expression newGetExp = new Expression(newInstance, "get", new Object[]{index});
636 try {
637 Object oldValue = oldGetExp.getValue();
638 Object newValue = newGetExp.getValue();
639 out.writeExpression(oldGetExp);
640 if (!Objects.equals(newValue, out.get(oldValue))) {
641 invokeStatement(oldInstance, "set", new Object[]{index, oldValue}, out);
642 }
643 }
644 catch (Exception e) {
645 out.getExceptionListener().exceptionThrown(e);
646 }
647 }
648 for (int i = newSize; i < oldSize; i++) {
649 invokeStatement(oldInstance, "add", new Object[]{oldO.get(i)}, out);
650 }
651 }
652}
653
654
655// Map
656class java_util_Map_PersistenceDelegate extends DefaultPersistenceDelegate {
657 protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) {
658 // System.out.println("Initializing: " + newInstance);
659 java.util.Map oldMap = (java.util.Map)oldInstance;
660 java.util.Map newMap = (java.util.Map)newInstance;
661 // Remove the new elements.
662 // Do this first otherwise we undo the adding work.
663 if (newMap != null) {
664 for (Object newKey : newMap.keySet().toArray()) {
665 // PENDING: This "key" is not in the right environment.
666 if (!oldMap.containsKey(newKey)) {
667 invokeStatement(oldInstance, "remove", new Object[]{newKey}, out);
668 }
669 }
670 }
671 // Add the new elements.
672 for ( Object oldKey : oldMap.keySet() ) {
673 Expression oldGetExp = new Expression(oldInstance, "get", new Object[]{oldKey});
674 // Pending: should use newKey.
675 Expression newGetExp = new Expression(newInstance, "get", new Object[]{oldKey});
676 try {
677 Object oldValue = oldGetExp.getValue();
678 Object newValue = newGetExp.getValue();
679 out.writeExpression(oldGetExp);
680 if (!Objects.equals(newValue, out.get(oldValue))) {
681 invokeStatement(oldInstance, "put", new Object[]{oldKey, oldValue}, out);
682 } else if ((newValue == null) && !newMap.containsKey(oldKey)) {
683 // put oldValue(=null?) if oldKey is absent in newMap
684 invokeStatement(oldInstance, "put", new Object[]{oldKey, oldValue}, out);
685 }
686 }
687 catch (Exception e) {
688 out.getExceptionListener().exceptionThrown(e);
689 }
690 }
691 }
692}
693
694class java_util_AbstractCollection_PersistenceDelegate extends java_util_Collection_PersistenceDelegate {}
695class java_util_AbstractList_PersistenceDelegate extends java_util_List_PersistenceDelegate {}
696class java_util_AbstractMap_PersistenceDelegate extends java_util_Map_PersistenceDelegate {}
697class java_util_Hashtable_PersistenceDelegate extends java_util_Map_PersistenceDelegate {}
698
699
700// Beans
701class java_beans_beancontext_BeanContextSupport_PersistenceDelegate extends java_util_Collection_PersistenceDelegate {}
702
703// AWT
704
705/**
706 * The persistence delegate for {@link Insets}.
707 * It is impossible to use {@link DefaultPersistenceDelegate}
708 * because this class does not have any properties.
709 *
710 * @author Sergey A. Malenkov
711 */
712final class java_awt_Insets_PersistenceDelegate extends PersistenceDelegate {
713 protected boolean mutatesTo(Object oldInstance, Object newInstance) {
714 return oldInstance.equals(newInstance);
715 }
716
717 protected Expression instantiate(Object oldInstance, Encoder out) {
718 Insets insets = (Insets) oldInstance;
719 Object[] args = new Object[] {
720 insets.top,
721 insets.left,
722 insets.bottom,
723 insets.right,
724 };
725 return new Expression(insets, insets.getClass(), "new", args);
726 }
727}
728
729/**
730 * The persistence delegate for {@link Font}.
731 * It is impossible to use {@link DefaultPersistenceDelegate}
732 * because size of the font can be float value.
733 *
734 * @author Sergey A. Malenkov
735 */
736final class java_awt_Font_PersistenceDelegate extends PersistenceDelegate {
737 protected boolean mutatesTo(Object oldInstance, Object newInstance) {
738 return oldInstance.equals(newInstance);
739 }
740
741 protected Expression instantiate(Object oldInstance, Encoder out) {
742 Font font = (Font) oldInstance;
743
744 int count = 0;
745 String family = null;
746 int style = Font.PLAIN;
747 int size = 12;
748
749 Map basic = font.getAttributes();
750 Map clone = new HashMap(basic.size());
751 for (Object key : basic.keySet()) {
752 Object value = basic.get(key);
753 if (value != null) {
754 clone.put(key, value);
755 }
756 if (key == TextAttribute.FAMILY) {
757 if (value instanceof String) {
758 count++;
759 family = (String) value;
760 }
761 }
762 else if (key == TextAttribute.WEIGHT) {
763 if (TextAttribute.WEIGHT_REGULAR.equals(value)) {
764 count++;
765 } else if (TextAttribute.WEIGHT_BOLD.equals(value)) {
766 count++;
767 style |= Font.BOLD;
768 }
769 }
770 else if (key == TextAttribute.POSTURE) {
771 if (TextAttribute.POSTURE_REGULAR.equals(value)) {
772 count++;
773 } else if (TextAttribute.POSTURE_OBLIQUE.equals(value)) {
774 count++;
775 style |= Font.ITALIC;
776 }
777 } else if (key == TextAttribute.SIZE) {
778 if (value instanceof Number) {
779 Number number = (Number) value;
780 size = number.intValue();
781 if (size == number.floatValue()) {
782 count++;
783 }
784 }
785 }
786 }
787 Class type = font.getClass();
788 if (count == clone.size()) {
789 return new Expression(font, type, "new", new Object[]{family, style, size});
790 }
791 if (type == Font.class) {
792 return new Expression(font, type, "getFont", new Object[]{clone});
793 }
794 return new Expression(font, type, "new", new Object[]{Font.getFont(clone)});
795 }
796}
797
798/**
799 * The persistence delegate for {@link AWTKeyStroke}.
800 * It is impossible to use {@link DefaultPersistenceDelegate}
801 * because this class have no public constructor.
802 *
803 * @author Sergey A. Malenkov
804 */
805final class java_awt_AWTKeyStroke_PersistenceDelegate extends PersistenceDelegate {
806 protected boolean mutatesTo(Object oldInstance, Object newInstance) {
807 return oldInstance.equals(newInstance);
808 }
809
810 protected Expression instantiate(Object oldInstance, Encoder out) {
811 AWTKeyStroke key = (AWTKeyStroke) oldInstance;
812
813 char ch = key.getKeyChar();
814 int code = key.getKeyCode();
815 int mask = key.getModifiers();
816 boolean onKeyRelease = key.isOnKeyRelease();
817
818 Object[] args = null;
819 if (ch == KeyEvent.CHAR_UNDEFINED) {
820 args = !onKeyRelease
821 ? new Object[]{code, mask}
822 : new Object[]{code, mask, onKeyRelease};
823 } else if (code == KeyEvent.VK_UNDEFINED) {
824 if (!onKeyRelease) {
825 args = (mask == 0)
826 ? new Object[]{ch}
827 : new Object[]{ch, mask};
828 } else if (mask == 0) {
829 args = new Object[]{ch, onKeyRelease};
830 }
831 }
832 if (args == null) {
833 throw new IllegalStateException("Unsupported KeyStroke: " + key);
834 }
835 Class type = key.getClass();
836 String name = type.getName();
837 // get short name of the class
838 int index = name.lastIndexOf('.') + 1;
839 if (index > 0) {
840 name = name.substring(index);
841 }
842 return new Expression( key, type, "get" + name, args );
843 }
844}
845
846class StaticFieldsPersistenceDelegate extends PersistenceDelegate {
847 protected void installFields(Encoder out, Class<?> cls) {
848 Field fields[] = cls.getFields();
849 for(int i = 0; i < fields.length; i++) {
850 Field field = fields[i];
851 // Don't install primitives, their identity will not be preserved
852 // by wrapping.
853 if (Object.class.isAssignableFrom(field.getType())) {
854 out.writeExpression(new Expression(field, "get", new Object[]{null}));
855 }
856 }
857 }
858
859 protected Expression instantiate(Object oldInstance, Encoder out) {
860 throw new RuntimeException("Unrecognized instance: " + oldInstance);
861 }
862
863 public void writeObject(Object oldInstance, Encoder out) {
864 if (out.getAttribute(this) == null) {
865 out.setAttribute(this, Boolean.TRUE);
866 installFields(out, oldInstance.getClass());
867 }
868 super.writeObject(oldInstance, out);
869 }
870}
871
872// SystemColor
873class java_awt_SystemColor_PersistenceDelegate extends StaticFieldsPersistenceDelegate {}
874
875// TextAttribute
876class java_awt_font_TextAttribute_PersistenceDelegate extends StaticFieldsPersistenceDelegate {}
877
878// MenuShortcut
879class java_awt_MenuShortcut_PersistenceDelegate extends PersistenceDelegate {
880 protected boolean mutatesTo(Object oldInstance, Object newInstance) {
881 return oldInstance.equals(newInstance);
882 }
883
884 protected Expression instantiate(Object oldInstance, Encoder out) {
885 java.awt.MenuShortcut m = (java.awt.MenuShortcut)oldInstance;
886 return new Expression(oldInstance, m.getClass(), "new",
887 new Object[]{new Integer(m.getKey()), Boolean.valueOf(m.usesShiftModifier())});
888 }
889}
890
891// Component
892class java_awt_Component_PersistenceDelegate extends DefaultPersistenceDelegate {
893 protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) {
894 super.initialize(type, oldInstance, newInstance, out);
895 java.awt.Component c = (java.awt.Component)oldInstance;
896 java.awt.Component c2 = (java.awt.Component)newInstance;
897 // The "background", "foreground" and "font" properties.
898 // The foreground and font properties of Windows change from
899 // null to defined values after the Windows are made visible -
900 // special case them for now.
901 if (!(oldInstance instanceof java.awt.Window)) {
902 Object oldBackground = c.isBackgroundSet() ? c.getBackground() : null;
903 Object newBackground = c2.isBackgroundSet() ? c2.getBackground() : null;
904 if (!Objects.equals(oldBackground, newBackground)) {
905 invokeStatement(oldInstance, "setBackground", new Object[] { oldBackground }, out);
906 }
907 Object oldForeground = c.isForegroundSet() ? c.getForeground() : null;
908 Object newForeground = c2.isForegroundSet() ? c2.getForeground() : null;
909 if (!Objects.equals(oldForeground, newForeground)) {
910 invokeStatement(oldInstance, "setForeground", new Object[] { oldForeground }, out);
911 }
912 Object oldFont = c.isFontSet() ? c.getFont() : null;
913 Object newFont = c2.isFontSet() ? c2.getFont() : null;
914 if (!Objects.equals(oldFont, newFont)) {
915 invokeStatement(oldInstance, "setFont", new Object[] { oldFont }, out);
916 }
917 }
918
919 // Bounds
920 java.awt.Container p = c.getParent();
921 if (p == null || p.getLayout() == null) {
922 // Use the most concise construct.
923 boolean locationCorrect = c.getLocation().equals(c2.getLocation());
924 boolean sizeCorrect = c.getSize().equals(c2.getSize());
925 if (!locationCorrect && !sizeCorrect) {
926 invokeStatement(oldInstance, "setBounds", new Object[]{c.getBounds()}, out);
927 }
928 else if (!locationCorrect) {
929 invokeStatement(oldInstance, "setLocation", new Object[]{c.getLocation()}, out);
930 }
931 else if (!sizeCorrect) {
932 invokeStatement(oldInstance, "setSize", new Object[]{c.getSize()}, out);
933 }
934 }
935 }
936}
937
938// Container
939class java_awt_Container_PersistenceDelegate extends DefaultPersistenceDelegate {
940 protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) {
941 super.initialize(type, oldInstance, newInstance, out);
942 // Ignore the children of a JScrollPane.
943 // Pending(milne) find a better way to do this.
944 if (oldInstance instanceof javax.swing.JScrollPane) {
945 return;
946 }
947 java.awt.Container oldC = (java.awt.Container)oldInstance;
948 java.awt.Component[] oldChildren = oldC.getComponents();
949 java.awt.Container newC = (java.awt.Container)newInstance;
950 java.awt.Component[] newChildren = (newC == null) ? new java.awt.Component[0] : newC.getComponents();
951
952 BorderLayout layout = ( oldC.getLayout() instanceof BorderLayout )
953 ? ( BorderLayout )oldC.getLayout()
954 : null;
955
956 JLayeredPane oldLayeredPane = (oldInstance instanceof JLayeredPane)
957 ? (JLayeredPane) oldInstance
958 : null;
959
960 // Pending. Assume all the new children are unaltered.
961 for(int i = newChildren.length; i < oldChildren.length; i++) {
962 Object[] args = ( layout != null )
963 ? new Object[] {oldChildren[i], layout.getConstraints( oldChildren[i] )}
964 : (oldLayeredPane != null)
965 ? new Object[] {oldChildren[i], oldLayeredPane.getLayer(oldChildren[i]), Integer.valueOf(-1)}
966 : new Object[] {oldChildren[i]};
967
968 invokeStatement(oldInstance, "add", args, out);
969 }
970 }
971}
972
973// Choice
974class java_awt_Choice_PersistenceDelegate extends DefaultPersistenceDelegate {
975 protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) {
976 super.initialize(type, oldInstance, newInstance, out);
977 java.awt.Choice m = (java.awt.Choice)oldInstance;
978 java.awt.Choice n = (java.awt.Choice)newInstance;
979 for (int i = n.getItemCount(); i < m.getItemCount(); i++) {
980 invokeStatement(oldInstance, "add", new Object[]{m.getItem(i)}, out);
981 }
982 }
983}
984
985// Menu
986class java_awt_Menu_PersistenceDelegate extends DefaultPersistenceDelegate {
987 protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) {
988 super.initialize(type, oldInstance, newInstance, out);
989 java.awt.Menu m = (java.awt.Menu)oldInstance;
990 java.awt.Menu n = (java.awt.Menu)newInstance;
991 for (int i = n.getItemCount(); i < m.getItemCount(); i++) {
992 invokeStatement(oldInstance, "add", new Object[]{m.getItem(i)}, out);
993 }
994 }
995}
996
997// MenuBar
998class java_awt_MenuBar_PersistenceDelegate extends DefaultPersistenceDelegate {
999 protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) {
1000 super.initialize(type, oldInstance, newInstance, out);
1001 java.awt.MenuBar m = (java.awt.MenuBar)oldInstance;
1002 java.awt.MenuBar n = (java.awt.MenuBar)newInstance;
1003 for (int i = n.getMenuCount(); i < m.getMenuCount(); i++) {
1004 invokeStatement(oldInstance, "add", new Object[]{m.getMenu(i)}, out);
1005 }
1006 }
1007}
1008
1009// List
1010class java_awt_List_PersistenceDelegate extends DefaultPersistenceDelegate {
1011 protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) {
1012 super.initialize(type, oldInstance, newInstance, out);
1013 java.awt.List m = (java.awt.List)oldInstance;
1014 java.awt.List n = (java.awt.List)newInstance;
1015 for (int i = n.getItemCount(); i < m.getItemCount(); i++) {
1016 invokeStatement(oldInstance, "add", new Object[]{m.getItem(i)}, out);
1017 }
1018 }
1019}
1020
1021
1022// LayoutManagers
1023
1024// BorderLayout
1025class java_awt_BorderLayout_PersistenceDelegate extends DefaultPersistenceDelegate {
1026 private static final String[] CONSTRAINTS = {
1027 BorderLayout.NORTH,
1028 BorderLayout.SOUTH,
1029 BorderLayout.EAST,
1030 BorderLayout.WEST,
1031 BorderLayout.CENTER,
1032 BorderLayout.PAGE_START,
1033 BorderLayout.PAGE_END,
1034 BorderLayout.LINE_START,
1035 BorderLayout.LINE_END,
1036 };
1037 @Override
1038 protected void initialize(Class<?> type, Object oldInstance,
1039 Object newInstance, Encoder out) {
1040 super.initialize(type, oldInstance, newInstance, out);
1041 BorderLayout oldLayout = (BorderLayout) oldInstance;
1042 BorderLayout newLayout = (BorderLayout) newInstance;
1043 for (String constraints : CONSTRAINTS) {
1044 Object oldC = oldLayout.getLayoutComponent(constraints);
1045 Object newC = newLayout.getLayoutComponent(constraints);
1046 // Pending, assume any existing elements are OK.
1047 if (oldC != null && newC == null) {
1048 invokeStatement(oldInstance, "addLayoutComponent",
1049 new Object[] { oldC, constraints }, out);
1050 }
1051 }
1052 }
1053}
1054
1055// CardLayout
1056class java_awt_CardLayout_PersistenceDelegate extends DefaultPersistenceDelegate {
1057 protected void initialize(Class<?> type, Object oldInstance,
1058 Object newInstance, Encoder out) {
1059 super.initialize(type, oldInstance, newInstance, out);
1060 Hashtable tab = (Hashtable)ReflectionUtils.getPrivateField(oldInstance,
1061 java.awt.CardLayout.class,
1062 "tab",
1063 out.getExceptionListener());
1064 if (tab != null) {
1065 for(Enumeration e = tab.keys(); e.hasMoreElements();) {
1066 Object child = e.nextElement();
1067 invokeStatement(oldInstance, "addLayoutComponent",
1068 new Object[]{child, (String)tab.get(child)}, out);
1069 }
1070 }
1071 }
1072}
1073
1074// GridBagLayout
1075class java_awt_GridBagLayout_PersistenceDelegate extends DefaultPersistenceDelegate {
1076 protected void initialize(Class<?> type, Object oldInstance,
1077 Object newInstance, Encoder out) {
1078 super.initialize(type, oldInstance, newInstance, out);
1079 Hashtable comptable = (Hashtable)ReflectionUtils.getPrivateField(oldInstance,
1080 java.awt.GridBagLayout.class,
1081 "comptable",
1082 out.getExceptionListener());
1083 if (comptable != null) {
1084 for(Enumeration e = comptable.keys(); e.hasMoreElements();) {
1085 Object child = e.nextElement();
1086 invokeStatement(oldInstance, "addLayoutComponent",
1087 new Object[]{child, comptable.get(child)}, out);
1088 }
1089 }
1090 }
1091}
1092
1093// Swing
1094
1095// JFrame (If we do this for Window instead of JFrame, the setVisible call
1096// will be issued before we have added all the children to the JFrame and
1097// will appear blank).
1098class javax_swing_JFrame_PersistenceDelegate extends DefaultPersistenceDelegate {
1099 protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) {
1100 super.initialize(type, oldInstance, newInstance, out);
1101 java.awt.Window oldC = (java.awt.Window)oldInstance;
1102 java.awt.Window newC = (java.awt.Window)newInstance;
1103 boolean oldV = oldC.isVisible();
1104 boolean newV = newC.isVisible();
1105 if (newV != oldV) {
1106 // false means: don't execute this statement at write time.
1107 boolean executeStatements = out.executeStatements;
1108 out.executeStatements = false;
1109 invokeStatement(oldInstance, "setVisible", new Object[]{Boolean.valueOf(oldV)}, out);
1110 out.executeStatements = executeStatements;
1111 }
1112 }
1113}
1114
1115// Models
1116
1117// DefaultListModel
1118class javax_swing_DefaultListModel_PersistenceDelegate extends DefaultPersistenceDelegate {
1119 protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) {
1120 // Note, the "size" property will be set here.
1121 super.initialize(type, oldInstance, newInstance, out);
1122 javax.swing.DefaultListModel m = (javax.swing.DefaultListModel)oldInstance;
1123 javax.swing.DefaultListModel n = (javax.swing.DefaultListModel)newInstance;
1124 for (int i = n.getSize(); i < m.getSize(); i++) {
1125 invokeStatement(oldInstance, "add", // Can also use "addElement".
1126 new Object[]{m.getElementAt(i)}, out);
1127 }
1128 }
1129}
1130
1131// DefaultComboBoxModel
1132class javax_swing_DefaultComboBoxModel_PersistenceDelegate extends DefaultPersistenceDelegate {
1133 protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) {
1134 super.initialize(type, oldInstance, newInstance, out);
1135 javax.swing.DefaultComboBoxModel m = (javax.swing.DefaultComboBoxModel)oldInstance;
1136 for (int i = 0; i < m.getSize(); i++) {
1137 invokeStatement(oldInstance, "addElement", new Object[]{m.getElementAt(i)}, out);
1138 }
1139 }
1140}
1141
1142
1143// DefaultMutableTreeNode
1144class javax_swing_tree_DefaultMutableTreeNode_PersistenceDelegate extends DefaultPersistenceDelegate {
1145 protected void initialize(Class<?> type, Object oldInstance, Object
1146 newInstance, Encoder out) {
1147 super.initialize(type, oldInstance, newInstance, out);
1148 javax.swing.tree.DefaultMutableTreeNode m =
1149 (javax.swing.tree.DefaultMutableTreeNode)oldInstance;
1150 javax.swing.tree.DefaultMutableTreeNode n =
1151 (javax.swing.tree.DefaultMutableTreeNode)newInstance;
1152 for (int i = n.getChildCount(); i < m.getChildCount(); i++) {
1153 invokeStatement(oldInstance, "add", new
1154 Object[]{m.getChildAt(i)}, out);
1155 }
1156 }
1157}
1158
1159// ToolTipManager
1160class javax_swing_ToolTipManager_PersistenceDelegate extends PersistenceDelegate {
1161 protected Expression instantiate(Object oldInstance, Encoder out) {
1162 return new Expression(oldInstance, javax.swing.ToolTipManager.class,
1163 "sharedInstance", new Object[]{});
1164 }
1165}
1166
1167// JTabbedPane
1168class javax_swing_JTabbedPane_PersistenceDelegate extends DefaultPersistenceDelegate {
1169 protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) {
1170 super.initialize(type, oldInstance, newInstance, out);
1171 javax.swing.JTabbedPane p = (javax.swing.JTabbedPane)oldInstance;
1172 for (int i = 0; i < p.getTabCount(); i++) {
1173 invokeStatement(oldInstance, "addTab",
1174 new Object[]{
1175 p.getTitleAt(i),
1176 p.getIconAt(i),
1177 p.getComponentAt(i)}, out);
1178 }
1179 }
1180}
1181
1182// Box
1183class javax_swing_Box_PersistenceDelegate extends DefaultPersistenceDelegate {
1184 protected boolean mutatesTo(Object oldInstance, Object newInstance) {
1185 return super.mutatesTo(oldInstance, newInstance) && getAxis(oldInstance).equals(getAxis(newInstance));
1186 }
1187
1188 protected Expression instantiate(Object oldInstance, Encoder out) {
1189 return new Expression(oldInstance, oldInstance.getClass(), "new", new Object[] {getAxis(oldInstance)});
1190 }
1191
1192 private Integer getAxis(Object object) {
1193 Box box = (Box) object;
1194 return (Integer) MetaData.getPrivateFieldValue(box.getLayout(), "javax.swing.BoxLayout.axis");
1195 }
1196}
1197
1198// JMenu
1199// Note that we do not need to state the initialiser for
1200// JMenuItems since the getComponents() method defined in
1201// Container will return all of the sub menu items that
1202// need to be added to the menu item.
1203// Not so for JMenu apparently.
1204class javax_swing_JMenu_PersistenceDelegate extends DefaultPersistenceDelegate {
1205 protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) {
1206 super.initialize(type, oldInstance, newInstance, out);
1207 javax.swing.JMenu m = (javax.swing.JMenu)oldInstance;
1208 java.awt.Component[] c = m.getMenuComponents();
1209 for (int i = 0; i < c.length; i++) {
1210 invokeStatement(oldInstance, "add", new Object[]{c[i]}, out);
1211 }
1212 }
1213}
1214
1215/**
1216 * The persistence delegate for {@link MatteBorder}.
1217 * It is impossible to use {@link DefaultPersistenceDelegate}
1218 * because this class does not have writable properties.
1219 *
1220 * @author Sergey A. Malenkov
1221 */
1222final class javax_swing_border_MatteBorder_PersistenceDelegate extends PersistenceDelegate {
1223 protected Expression instantiate(Object oldInstance, Encoder out) {
1224 MatteBorder border = (MatteBorder) oldInstance;
1225 Insets insets = border.getBorderInsets();
1226 Object object = border.getTileIcon();
1227 if (object == null) {
1228 object = border.getMatteColor();
1229 }
1230 Object[] args = new Object[] {
1231 insets.top,
1232 insets.left,
1233 insets.bottom,
1234 insets.right,
1235 object,
1236 };
1237 return new Expression(border, border.getClass(), "new", args);
1238 }
1239}
1240
1241/* XXX - doens't seem to work. Debug later.
1242class javax_swing_JMenu_PersistenceDelegate extends DefaultPersistenceDelegate {
1243 protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) {
1244 super.initialize(type, oldInstance, newInstance, out);
1245 javax.swing.JMenu m = (javax.swing.JMenu)oldInstance;
1246 javax.swing.JMenu n = (javax.swing.JMenu)newInstance;
1247 for (int i = n.getItemCount(); i < m.getItemCount(); i++) {
1248 invokeStatement(oldInstance, "add", new Object[]{m.getItem(i)}, out);
1249 }
1250 }
1251}
1252*/
1253
1254/**
1255 * The persistence delegate for {@link PrintColorUIResource}.
1256 * It is impossible to use {@link DefaultPersistenceDelegate}
1257 * because this class has special rule for serialization:
1258 * it should be converted to {@link ColorUIResource}.
1259 *
1260 * @see PrintColorUIResource#writeReplace
1261 *
1262 * @author Sergey A. Malenkov
1263 */
1264final class sun_swing_PrintColorUIResource_PersistenceDelegate extends PersistenceDelegate {
1265 protected boolean mutatesTo(Object oldInstance, Object newInstance) {
1266 return oldInstance.equals(newInstance);
1267 }
1268
1269 protected Expression instantiate(Object oldInstance, Encoder out) {
1270 Color color = (Color) oldInstance;
1271 Object[] args = new Object[] {color.getRGB()};
1272 return new Expression(color, ColorUIResource.class, "new", args);
1273 }
1274}
1275
1276class MetaData {
1277 private static final Map<String,Field> fields = Collections.synchronizedMap(new WeakHashMap<String, Field>());
1278 private static Hashtable internalPersistenceDelegates = new Hashtable();
1279
1280 private static PersistenceDelegate nullPersistenceDelegate = new NullPersistenceDelegate();
1281 private static PersistenceDelegate enumPersistenceDelegate = new EnumPersistenceDelegate();
1282 private static PersistenceDelegate primitivePersistenceDelegate = new PrimitivePersistenceDelegate();
1283 private static PersistenceDelegate defaultPersistenceDelegate = new DefaultPersistenceDelegate();
1284 private static PersistenceDelegate arrayPersistenceDelegate;
1285 private static PersistenceDelegate proxyPersistenceDelegate;
1286
1287 static {
1288
1289 internalPersistenceDelegates.put("java.net.URI",
1290 new PrimitivePersistenceDelegate());
1291
1292 // it is possible because MatteBorder is assignable from MatteBorderUIResource
1293 internalPersistenceDelegates.put("javax.swing.plaf.BorderUIResource$MatteBorderUIResource",
1294 new javax_swing_border_MatteBorder_PersistenceDelegate());
1295
1296 // it is possible because FontUIResource is supported by java_awt_Font_PersistenceDelegate
1297 internalPersistenceDelegates.put("javax.swing.plaf.FontUIResource",
1298 new java_awt_Font_PersistenceDelegate());
1299
1300 // it is possible because KeyStroke is supported by java_awt_AWTKeyStroke_PersistenceDelegate
1301 internalPersistenceDelegates.put("javax.swing.KeyStroke",
1302 new java_awt_AWTKeyStroke_PersistenceDelegate());
1303
1304 internalPersistenceDelegates.put("java.sql.Date", new java_util_Date_PersistenceDelegate());
1305 internalPersistenceDelegates.put("java.sql.Time", new java_util_Date_PersistenceDelegate());
1306
1307 internalPersistenceDelegates.put("java.util.JumboEnumSet", new java_util_EnumSet_PersistenceDelegate());
1308 internalPersistenceDelegates.put("java.util.RegularEnumSet", new java_util_EnumSet_PersistenceDelegate());
1309 }
1310
1311 public synchronized static PersistenceDelegate getPersistenceDelegate(Class type) {
1312 if (type == null) {
1313 return nullPersistenceDelegate;
1314 }
1315 if (Enum.class.isAssignableFrom(type)) {
1316 return enumPersistenceDelegate;
1317 }
1318 if (ReflectionUtils.isPrimitive(type)) {
1319 return primitivePersistenceDelegate;
1320 }
1321 // The persistence delegate for arrays is non-trivial; instantiate it lazily.
1322 if (type.isArray()) {
1323 if (arrayPersistenceDelegate == null) {
1324 arrayPersistenceDelegate = new ArrayPersistenceDelegate();
1325 }
1326 return arrayPersistenceDelegate;
1327 }
1328 // Handle proxies lazily for backward compatibility with 1.2.
1329 try {
1330 if (java.lang.reflect.Proxy.isProxyClass(type)) {
1331 if (proxyPersistenceDelegate == null) {
1332 proxyPersistenceDelegate = new ProxyPersistenceDelegate();
1333 }
1334 return proxyPersistenceDelegate;
1335 }
1336 }
1337 catch(Exception e) {}
1338 // else if (type.getDeclaringClass() != null) {
1339 // return new DefaultPersistenceDelegate(new String[]{"this$0"});
1340 // }
1341
1342 String typeName = type.getName();
1343 PersistenceDelegate pd = (PersistenceDelegate)getBeanAttribute(type, "persistenceDelegate");
1344 if (pd == null) {
1345 pd = (PersistenceDelegate)internalPersistenceDelegates.get(typeName);
1346 if (pd != null) {
1347 return pd;
1348 }
1349 internalPersistenceDelegates.put(typeName, defaultPersistenceDelegate);
1350 try {
1351 String name = type.getName();
1352 Class c = Class.forName("java.beans." + name.replace('.', '_')
1353 + "_PersistenceDelegate");
1354 pd = (PersistenceDelegate)c.newInstance();
1355 internalPersistenceDelegates.put(typeName, pd);
1356 }
1357 catch (ClassNotFoundException e) {
1358 String[] properties = getConstructorProperties(type);
1359 if (properties != null) {
1360 pd = new DefaultPersistenceDelegate(properties);
1361 internalPersistenceDelegates.put(typeName, pd);
1362 }
1363 }
1364 catch (Exception e) {
1365 System.err.println("Internal error: " + e);
1366 }
1367 }
1368
1369 return (pd != null) ? pd : defaultPersistenceDelegate;
1370 }
1371
1372 private static String[] getConstructorProperties(Class type) {
1373 String[] names = null;
1374 int length = 0;
1375 for (Constructor<?> constructor : type.getConstructors()) {
1376 String[] value = getAnnotationValue(constructor);
1377 if ((value != null) && (length < value.length) && isValid(constructor, value)) {
1378 names = value;
1379 length = value.length;
1380 }
1381 }
1382 return names;
1383 }
1384
1385 private static String[] getAnnotationValue(Constructor<?> constructor) {
1386 ConstructorProperties annotation = constructor.getAnnotation(ConstructorProperties.class);
1387 return (annotation != null)
1388 ? annotation.value()
1389 : null;
1390 }
1391
1392 private static boolean isValid(Constructor<?> constructor, String[] names) {
1393 Class[] parameters = constructor.getParameterTypes();
1394 if (names.length != parameters.length) {
1395 return false;
1396 }
1397 for (String name : names) {
1398 if (name == null) {
1399 return false;
1400 }
1401 }
1402 return true;
1403 }
1404
1405 private static Object getBeanAttribute(Class type, String attribute) {
1406 try {
1407 return Introspector.getBeanInfo(type).getBeanDescriptor().getValue(attribute);
1408 } catch (IntrospectionException exception) {
1409 return null;
1410 }
1411 }
1412
1413 static Object getPrivateFieldValue(Object instance, String name) {
1414 Field field = fields.get(name);
1415 if (field == null) {
1416 int index = name.lastIndexOf('.');
1417 final String className = name.substring(0, index);
1418 final String fieldName = name.substring(1 + index);
1419 field = AccessController.doPrivileged(new PrivilegedAction<Field>() {
1420 public Field run() {
1421 try {
1422 Field field = Class.forName(className).getDeclaredField(fieldName);
1423 field.setAccessible(true);
1424 return field;
1425 }
1426 catch (ClassNotFoundException exception) {
1427 throw new IllegalStateException("Could not find class", exception);
1428 }
1429 catch (NoSuchFieldException exception) {
1430 throw new IllegalStateException("Could not find field", exception);
1431 }
1432 }
1433 });
1434 fields.put(name, field);
1435 }
1436 try {
1437 return field.get(instance);
1438 }
1439 catch (IllegalAccessException exception) {
1440 throw new IllegalStateException("Could not get value of the field", exception);
1441 }
1442 }
1443}
java/pkg/java/beans/MethodDescriptor.class+0−0

Binary file not shown.

java/pkg/java/beans/MethodDescriptor.java+228−0
@@ -0,0 +1,228 @@
1/*
2 * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.beans;
27
28import java.lang.ref.Reference;
29import java.lang.ref.WeakReference;
30import java.lang.reflect.Method;
31import java.util.List;
32import java.util.ArrayList;
33
34/**
35 * A MethodDescriptor describes a particular method that a Java Bean
36 * supports for external access from other components.
37 */
38
39public class MethodDescriptor extends FeatureDescriptor {
40
41 private Reference<Method> methodRef;
42
43 private String[] paramNames;
44
45 private List params;
46
47 private ParameterDescriptor parameterDescriptors[];
48
49 /**
50 * Constructs a <code>MethodDescriptor</code> from a
51 * <code>Method</code>.
52 *
53 * @param method The low-level method information.
54 */
55 public MethodDescriptor(Method method) {
56 this(method, null);
57 }
58
59
60 /**
61 * Constructs a <code>MethodDescriptor</code> from a
62 * <code>Method</code> providing descriptive information for each
63 * of the method's parameters.
64 *
65 * @param method The low-level method information.
66 * @param parameterDescriptors Descriptive information for each of the
67 * method's parameters.
68 */
69 public MethodDescriptor(Method method,
70 ParameterDescriptor parameterDescriptors[]) {
71 setName(method.getName());
72 setMethod(method);
73 this.parameterDescriptors = parameterDescriptors;
74 }
75
76 /**
77 * Gets the method that this MethodDescriptor encapsualtes.
78 *
79 * @return The low-level description of the method
80 */
81 public synchronized Method getMethod() {
82 Method method = getMethod0();
83 if (method == null) {
84 Class cls = getClass0();
85 String name = getName();
86 if ((cls != null) && (name != null)) {
87 Class[] params = getParams();
88 if (params == null) {
89 for (int i = 0; i < 3; i++) {
90 // Find methods for up to 2 params. We are guessing here.
91 // This block should never execute unless the classloader
92 // that loaded the argument classes disappears.
93 method = Introspector.findMethod(cls, name, i, null);
94 if (method != null) {
95 break;
96 }
97 }
98 } else {
99 method = Introspector.findMethod(cls, name, params.length, params);
100 }
101 setMethod(method);
102 }
103 }
104 return method;
105 }
106
107 private synchronized void setMethod(Method method) {
108 if (method == null) {
109 return;
110 }
111 if (getClass0() == null) {
112 setClass0(method.getDeclaringClass());
113 }
114 setParams(getParameterTypes(getClass0(), method));
115 this.methodRef = getSoftReference(method);
116 }
117
118 private Method getMethod0() {
119 return (this.methodRef != null)
120 ? this.methodRef.get()
121 : null;
122 }
123
124 private synchronized void setParams(Class[] param) {
125 if (param == null) {
126 return;
127 }
128 paramNames = new String[param.length];
129 params = new ArrayList(param.length);
130 for (int i = 0; i < param.length; i++) {
131 paramNames[i] = param[i].getName();
132 params.add(new WeakReference(param[i]));
133 }
134 }
135
136 // pp getParamNames used as an optimization to avoid method.getParameterTypes.
137 String[] getParamNames() {
138 return paramNames;
139 }
140
141 private synchronized Class[] getParams() {
142 Class[] clss = new Class[params.size()];
143
144 for (int i = 0; i < params.size(); i++) {
145 Reference ref = (Reference)params.get(i);
146 Class cls = (Class)ref.get();
147 if (cls == null) {
148 return null;
149 } else {
150 clss[i] = cls;
151 }
152 }
153 return clss;
154 }
155
156 /**
157 * Gets the ParameterDescriptor for each of this MethodDescriptor's
158 * method's parameters.
159 *
160 * @return The locale-independent names of the parameters. May return
161 * a null array if the parameter names aren't known.
162 */
163 public ParameterDescriptor[] getParameterDescriptors() {
164 return parameterDescriptors;
165 }
166
167 /*
168 * Package-private constructor
169 * Merge two method descriptors. Where they conflict, give the
170 * second argument (y) priority over the first argument (x).
171 * @param x The first (lower priority) MethodDescriptor
172 * @param y The second (higher priority) MethodDescriptor
173 */
174
175 MethodDescriptor(MethodDescriptor x, MethodDescriptor y) {
176 super(x,y);
177
178 methodRef = x.methodRef;
179 if (y.methodRef != null) {
180 methodRef = y.methodRef;
181 }
182 params = x.params;
183 if (y.params != null) {
184 params = y.params;
185 }
186 paramNames = x.paramNames;
187 if (y.paramNames != null) {
188 paramNames = y.paramNames;
189 }
190
191 parameterDescriptors = x.parameterDescriptors;
192 if (y.parameterDescriptors != null) {
193 parameterDescriptors = y.parameterDescriptors;
194 }
195 }
196
197 /*
198 * Package-private dup constructor
199 * This must isolate the new object from any changes to the old object.
200 */
201 MethodDescriptor(MethodDescriptor old) {
202 super(old);
203
204 methodRef = old.methodRef;
205 params = old.params;
206 paramNames = old.paramNames;
207
208 if (old.parameterDescriptors != null) {
209 int len = old.parameterDescriptors.length;
210 parameterDescriptors = new ParameterDescriptor[len];
211 for (int i = 0; i < len ; i++) {
212 parameterDescriptors[i] = new ParameterDescriptor(old.parameterDescriptors[i]);
213 }
214 }
215 }
216
217 void appendTo(StringBuilder sb) {
218 appendTo(sb, "method", this.methodRef);
219 if (this.parameterDescriptors != null) {
220 sb.append("; parameterDescriptors={");
221 for (ParameterDescriptor pd : this.parameterDescriptors) {
222 sb.append(pd).append(", ");
223 }
224 sb.setLength(sb.length() - 2);
225 sb.append("}");
226 }
227 }
228}
java/pkg/java/beans/NameGenerator.class+0−0

Binary file not shown.

java/pkg/java/beans/NameGenerator.java+116−0
@@ -0,0 +1,116 @@
1/*
2 * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25package java.beans;
26
27import java.util.HashMap;
28import java.util.IdentityHashMap;
29import java.util.Map;
30
31import static java.util.Locale.ENGLISH;
32
33/**
34 * A utility class which generates unique names for object instances.
35 * The name will be a concatenation of the unqualified class name
36 * and an instance number.
37 * <p>
38 * For example, if the first object instance javax.swing.JButton
39 * is passed into <code>instanceName</code> then the returned
40 * string identifier will be &quot;JButton0&quot;.
41 *
42 * @author Philip Milne
43 */
44class NameGenerator {
45
46 private Map valueToName;
47 private Map nameToCount;
48
49 public NameGenerator() {
50 valueToName = new IdentityHashMap();
51 nameToCount = new HashMap();
52 }
53
54 /**
55 * Clears the name cache. Should be called to near the end of
56 * the encoding cycle.
57 */
58 public void clear() {
59 valueToName.clear();
60 nameToCount.clear();
61 }
62
63 /**
64 * Returns the root name of the class.
65 */
66 public static String unqualifiedClassName(Class type) {
67 if (type.isArray()) {
68 return unqualifiedClassName(type.getComponentType())+"Array";
69 }
70 String name = type.getName();
71 return name.substring(name.lastIndexOf('.')+1);
72 }
73
74 /**
75 * Returns a String which capitalizes the first letter of the string.
76 */
77 public static String capitalize(String name) {
78 if (name == null || name.length() == 0) {
79 return name;
80 }
81 return name.substring(0, 1).toUpperCase(ENGLISH) + name.substring(1);
82 }
83
84 /**
85 * Returns a unique string which identifies the object instance.
86 * Invocations are cached so that if an object has been previously
87 * passed into this method then the same identifier is returned.
88 *
89 * @param instance object used to generate string
90 * @return a unique string representing the object
91 */
92 public String instanceName(Object instance) {
93 if (instance == null) {
94 return "null";
95 }
96 if (instance instanceof Class) {
97 return unqualifiedClassName((Class)instance);
98 }
99 else {
100 String result = (String)valueToName.get(instance);
101 if (result != null) {
102 return result;
103 }
104 Class type = instance.getClass();
105 String className = unqualifiedClassName(type);
106
107 Object size = nameToCount.get(className);
108 int instanceNumber = (size == null) ? 0 : ((Integer)size).intValue() + 1;
109 nameToCount.put(className, new Integer(instanceNumber));
110
111 result = className + instanceNumber;
112 valueToName.put(instance, result);
113 return result;
114 }
115 }
116}
java/pkg/java/beans/NullPersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/ObjectInputStreamWithLoader.class+0−0

Binary file not shown.

java/pkg/java/beans/ParameterDescriptor.class+0−0

Binary file not shown.

java/pkg/java/beans/ParameterDescriptor.java+53−0
@@ -0,0 +1,53 @@
1/*
2 * Copyright (c) 1996, 1997, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.beans;
27
28/**
29 * The ParameterDescriptor class allows bean implementors to provide
30 * additional information on each of their parameters, beyond the
31 * low level type information provided by the java.lang.reflect.Method
32 * class.
33 * <p>
34 * Currently all our state comes from the FeatureDescriptor base class.
35 */
36
37public class ParameterDescriptor extends FeatureDescriptor {
38
39 /**
40 * Public default constructor.
41 */
42 public ParameterDescriptor() {
43 }
44
45 /**
46 * Package private dup constructor.
47 * This must isolate the new object from any changes to the old object.
48 */
49 ParameterDescriptor(ParameterDescriptor old) {
50 super(old);
51 }
52
53}
java/pkg/java/beans/PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/PersistenceDelegate.java+214−0
@@ -0,0 +1,214 @@
1/*
2 * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25package java.beans;
26
27/**
28 * The PersistenceDelegate class takes the responsibility
29 * for expressing the state of an instance of a given class
30 * in terms of the methods in the class's public API. Instead
31 * of associating the responsibility of persistence with
32 * the class itself as is done, for example, by the
33 * <code>readObject</code> and <code>writeObject</code>
34 * methods used by the <code>ObjectOutputStream</code>, streams like
35 * the <code>XMLEncoder</code> which
36 * use this delegation model can have their behavior controlled
37 * independently of the classes themselves. Normally, the class
38 * is the best place to put such information and conventions
39 * can easily be expressed in this delegation scheme to do just that.
40 * Sometimes however, it is the case that a minor problem
41 * in a single class prevents an entire object graph from
42 * being written and this can leave the application
43 * developer with no recourse but to attempt to shadow
44 * the problematic classes locally or use alternative
45 * persistence techniques. In situations like these, the
46 * delegation model gives a relatively clean mechanism for
47 * the application developer to intervene in all parts of the
48 * serialization process without requiring that modifications
49 * be made to the implementation of classes which are not part
50 * of the application itself.
51 * <p>
52 * In addition to using a delegation model, this persistence
53 * scheme differs from traditional serialization schemes
54 * in requiring an analog of the <code>writeObject</code>
55 * method without a corresponding <code>readObject</code>
56 * method. The <code>writeObject</code> analog encodes each
57 * instance in terms of its public API and there is no need to
58 * define a <code>readObject</code> analog
59 * since the procedure for reading the serialized form
60 * is defined by the semantics of method invocation as laid
61 * out in the Java Language Specification.
62 * Breaking the dependency between <code>writeObject</code>
63 * and <code>readObject</code> implementations, which may
64 * change from version to version, is the key factor
65 * in making the archives produced by this technique immune
66 * to changes in the private implementations of the classes
67 * to which they refer.
68 * <p>
69 * A persistence delegate, may take control of all
70 * aspects of the persistence of an object including:
71 * <ul>
72 * <li>
73 * Deciding whether or not an instance can be mutated
74 * into another instance of the same class.
75 * <li>
76 * Instantiating the object, either by calling a
77 * public constructor or a public factory method.
78 * <li>
79 * Performing the initialization of the object.
80 * </ul>
81 * @see XMLEncoder
82 *
83 * @since 1.4
84 *
85 * @author Philip Milne
86 */
87
88public abstract class PersistenceDelegate {
89
90 /**
91 * The <code>writeObject</code> is a single entry point to the persistence
92 * and is used by a <code>Encoder</code> in the traditional
93 * mode of delegation. Although this method is not final,
94 * it should not need to be subclassed under normal circumstances.
95 * <p>
96 * This implementation first checks to see if the stream
97 * has already encountered this object. Next the
98 * <code>mutatesTo</code> method is called to see if
99 * that candidate returned from the stream can
100 * be mutated into an accurate copy of <code>oldInstance</code>.
101 * If it can, the <code>initialize</code> method is called to
102 * perform the initialization. If not, the candidate is removed
103 * from the stream, and the <code>instantiate</code> method
104 * is called to create a new candidate for this object.
105 *
106 * @param oldInstance The instance that will be created by this expression.
107 * @param out The stream to which this expression will be written.
108 *
109 * @throws NullPointerException if {@code out} is {@code null}
110 */
111 public void writeObject(Object oldInstance, Encoder out) {
112 Object newInstance = out.get(oldInstance);
113 if (!mutatesTo(oldInstance, newInstance)) {
114 out.remove(oldInstance);
115 out.writeExpression(instantiate(oldInstance, out));
116 }
117 else {
118 initialize(oldInstance.getClass(), oldInstance, newInstance, out);
119 }
120 }
121
122 /**
123 * Returns true if an <em>equivalent</em> copy of <code>oldInstance</code> may be
124 * created by applying a series of statements to <code>newInstance</code>.
125 * In the specification of this method, we mean by equivalent that the modified instance
126 * is indistinguishable from <code>oldInstance</code> in the behavior
127 * of the relevant methods in its public API. [Note: we use the
128 * phrase <em>relevant</em> methods rather than <em>all</em> methods
129 * here only because, to be strictly correct, methods like <code>hashCode</code>
130 * and <code>toString</code> prevent most classes from producing truly
131 * indistinguishable copies of their instances].
132 * <p>
133 * The default behavior returns <code>true</code>
134 * if the classes of the two instances are the same.
135 *
136 * @param oldInstance The instance to be copied.
137 * @param newInstance The instance that is to be modified.
138 * @return True if an equivalent copy of <code>newInstance</code> may be
139 * created by applying a series of mutations to <code>oldInstance</code>.
140 */
141 protected boolean mutatesTo(Object oldInstance, Object newInstance) {
142 return (newInstance != null && oldInstance != null &&
143 oldInstance.getClass() == newInstance.getClass());
144 }
145
146 /**
147 * Returns an expression whose value is <code>oldInstance</code>.
148 * This method is used to characterize the constructor
149 * or factory method that should be used to create the given object.
150 * For example, the <code>instantiate</code> method of the persistence
151 * delegate for the <code>Field</code> class could be defined as follows:
152 * <pre>
153 * Field f = (Field)oldInstance;
154 * return new Expression(f, f.getDeclaringClass(), "getField", new Object[]{f.getName()});
155 * </pre>
156 * Note that we declare the value of the returned expression so that
157 * the value of the expression (as returned by <code>getValue</code>)
158 * will be identical to <code>oldInstance</code>.
159 *
160 * @param oldInstance The instance that will be created by this expression.
161 * @param out The stream to which this expression will be written.
162 * @return An expression whose value is <code>oldInstance</code>.
163 *
164 * @throws NullPointerException if {@code out} is {@code null}
165 */
166 protected abstract Expression instantiate(Object oldInstance, Encoder out);
167
168 /**
169 * Produce a series of statements with side effects on <code>newInstance</code>
170 * so that the new instance becomes <em>equivalent</em> to <code>oldInstance</code>.
171 * In the specification of this method, we mean by equivalent that, after the method
172 * returns, the modified instance is indistinguishable from
173 * <code>newInstance</code> in the behavior of all methods in its
174 * public API.
175 * <p>
176 * The implementation typically achieves this goal by producing a series of
177 * "what happened" statements involving the <code>oldInstance</code>
178 * and its publicly available state. These statements are sent
179 * to the output stream using its <code>writeExpression</code>
180 * method which returns an expression involving elements in
181 * a cloned environment simulating the state of an input stream during
182 * reading. Each statement returned will have had all instances
183 * the old environment replaced with objects which exist in the new
184 * one. In particular, references to the target of these statements,
185 * which start out as references to <code>oldInstance</code> are returned
186 * as references to the <code>newInstance</code> instead.
187 * Executing these statements effects an incremental
188 * alignment of the state of the two objects as a series of
189 * modifications to the objects in the new environment.
190 * By the time the initialize method returns it should be impossible
191 * to tell the two instances apart by using their public APIs.
192 * Most importantly, the sequence of steps that were used to make
193 * these objects appear equivalent will have been recorded
194 * by the output stream and will form the actual output when
195 * the stream is flushed.
196 * <p>
197 * The default implementation, calls the <code>initialize</code>
198 * method of the type's superclass.
199 *
200 * @param oldInstance The instance to be copied.
201 * @param newInstance The instance that is to be modified.
202 * @param out The stream to which any initialization statements should be written.
203 *
204 * @throws NullPointerException if {@code out} is {@code null}
205 */
206 protected void initialize(Class<?> type,
207 Object oldInstance, Object newInstance,
208 Encoder out)
209 {
210 Class superType = type.getSuperclass();
211 PersistenceDelegate info = out.getPersistenceDelegate(superType);
212 info.initialize(superType, oldInstance, newInstance, out);
213 }
214}
java/pkg/java/beans/PrimitivePersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/PropertyChangeEvent.class+0−0

Binary file not shown.

java/pkg/java/beans/PropertyChangeEvent.java+164−0
@@ -0,0 +1,164 @@
1/*
2 * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.beans;
27
28/**
29 * A "PropertyChange" event gets delivered whenever a bean changes a "bound"
30 * or "constrained" property. A PropertyChangeEvent object is sent as an
31 * argument to the PropertyChangeListener and VetoableChangeListener methods.
32 * <P>
33 * Normally PropertyChangeEvents are accompanied by the name and the old
34 * and new value of the changed property. If the new value is a primitive
35 * type (such as int or boolean) it must be wrapped as the
36 * corresponding java.lang.* Object type (such as Integer or Boolean).
37 * <P>
38 * Null values may be provided for the old and the new values if their
39 * true values are not known.
40 * <P>
41 * An event source may send a null object as the name to indicate that an
42 * arbitrary set of if its properties have changed. In this case the
43 * old and new values should also be null.
44 */
45
46public class PropertyChangeEvent extends java.util.EventObject {
47 private static final long serialVersionUID = 7042693688939648123L;
48
49 /**
50 * Constructs a new <code>PropertyChangeEvent</code>.
51 *
52 * @param source The bean that fired the event.
53 * @param propertyName The programmatic name of the property
54 * that was changed.
55 * @param oldValue The old value of the property.
56 * @param newValue The new value of the property.
57 */
58 public PropertyChangeEvent(Object source, String propertyName,
59 Object oldValue, Object newValue) {
60 super(source);
61 this.propertyName = propertyName;
62 this.newValue = newValue;
63 this.oldValue = oldValue;
64 }
65
66 /**
67 * Gets the programmatic name of the property that was changed.
68 *
69 * @return The programmatic name of the property that was changed.
70 * May be null if multiple properties have changed.
71 */
72 public String getPropertyName() {
73 return propertyName;
74 }
75
76 /**
77 * Gets the new value for the property, expressed as an Object.
78 *
79 * @return The new value for the property, expressed as an Object.
80 * May be null if multiple properties have changed.
81 */
82 public Object getNewValue() {
83 return newValue;
84 }
85
86 /**
87 * Gets the old value for the property, expressed as an Object.
88 *
89 * @return The old value for the property, expressed as an Object.
90 * May be null if multiple properties have changed.
91 */
92 public Object getOldValue() {
93 return oldValue;
94 }
95
96 /**
97 * Sets the propagationId object for the event.
98 *
99 * @param propagationId The propagationId object for the event.
100 */
101 public void setPropagationId(Object propagationId) {
102 this.propagationId = propagationId;
103 }
104
105 /**
106 * The "propagationId" field is reserved for future use. In Beans 1.0
107 * the sole requirement is that if a listener catches a PropertyChangeEvent
108 * and then fires a PropertyChangeEvent of its own, then it should
109 * make sure that it propagates the propagationId field from its
110 * incoming event to its outgoing event.
111 *
112 * @return the propagationId object associated with a bound/constrained
113 * property update.
114 */
115 public Object getPropagationId() {
116 return propagationId;
117 }
118
119 /**
120 * name of the property that changed. May be null, if not known.
121 * @serial
122 */
123 private String propertyName;
124
125 /**
126 * New value for property. May be null if not known.
127 * @serial
128 */
129 private Object newValue;
130
131 /**
132 * Previous value for property. May be null if not known.
133 * @serial
134 */
135 private Object oldValue;
136
137 /**
138 * Propagation ID. May be null.
139 * @serial
140 * @see #getPropagationId
141 */
142 private Object propagationId;
143
144 /**
145 * Returns a string representation of the object.
146 *
147 * @return a string representation of the object
148 *
149 * @since 1.7
150 */
151 public String toString() {
152 StringBuilder sb = new StringBuilder(getClass().getName());
153 sb.append("[propertyName=").append(getPropertyName());
154 appendTo(sb);
155 sb.append("; oldValue=").append(getOldValue());
156 sb.append("; newValue=").append(getNewValue());
157 sb.append("; propagationId=").append(getPropagationId());
158 sb.append("; source=").append(getSource());
159 return sb.append("]").toString();
160 }
161
162 void appendTo(StringBuilder sb) {
163 }
164}
java/pkg/java/beans/PropertyChangeListener.class+0−0

Binary file not shown.

java/pkg/java/beans/PropertyChangeListener.java+44−0
@@ -0,0 +1,44 @@
1/*
2 * Copyright (c) 1996, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.beans;
27
28/**
29 * A "PropertyChange" event gets fired whenever a bean changes a "bound"
30 * property. You can register a PropertyChangeListener with a source
31 * bean so as to be notified of any bound property updates.
32 */
33
34public interface PropertyChangeListener extends java.util.EventListener {
35
36 /**
37 * This method gets called when a bound property is changed.
38 * @param evt A PropertyChangeEvent object describing the event source
39 * and the property that has changed.
40 */
41
42 void propertyChange(PropertyChangeEvent evt);
43
44}
java/pkg/java/beans/PropertyChangeListenerProxy.class+0−0

Binary file not shown.

java/pkg/java/beans/PropertyChangeListenerProxy.java+81−0
@@ -0,0 +1,81 @@
1/*
2 * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.beans;
27
28import java.util.EventListenerProxy;
29
30/**
31 * A class which extends the {@code EventListenerProxy}
32 * specifically for adding a {@code PropertyChangeListener}
33 * with a "bound" property.
34 * Instances of this class can be added
35 * as {@code PropertyChangeListener}s to a bean
36 * which supports firing property change events.
37 * <p>
38 * If the object has a {@code getPropertyChangeListeners} method
39 * then the array returned could be a mixture of {@code PropertyChangeListener}
40 * and {@code PropertyChangeListenerProxy} objects.
41 *
42 * @see java.util.EventListenerProxy
43 * @see PropertyChangeSupport#getPropertyChangeListeners
44 * @since 1.4
45 */
46public class PropertyChangeListenerProxy
47 extends EventListenerProxy<PropertyChangeListener>
48 implements PropertyChangeListener {
49
50 private final String propertyName;
51
52 /**
53 * Constructor which binds the {@code PropertyChangeListener}
54 * to a specific property.
55 *
56 * @param propertyName the name of the property to listen on
57 * @param listener the listener object
58 */
59 public PropertyChangeListenerProxy(String propertyName, PropertyChangeListener listener) {
60 super(listener);
61 this.propertyName = propertyName;
62 }
63
64 /**
65 * Forwards the property change event to the listener delegate.
66 *
67 * @param event the property change event
68 */
69 public void propertyChange(PropertyChangeEvent event) {
70 getListener().propertyChange(event);
71 }
72
73 /**
74 * Returns the name of the named property associated with the listener.
75 *
76 * @return the name of the named property associated with the listener
77 */
78 public String getPropertyName() {
79 return this.propertyName;
80 }
81}
java/pkg/java/beans/PropertyChangeSupport$1.class+0−0

Binary file not shown.

java/pkg/java/beans/PropertyChangeSupport$PropertyChangeListenerMap.class+0−0

Binary file not shown.

java/pkg/java/beans/PropertyChangeSupport.class+0−0

Binary file not shown.

java/pkg/java/beans/PropertyChangeSupport.java+536−0
@@ -0,0 +1,536 @@
1/*
2 * Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25package java.beans;
26
27import java.io.Serializable;
28import java.io.ObjectStreamField;
29import java.io.ObjectOutputStream;
30import java.io.ObjectInputStream;
31import java.io.IOException;
32import java.util.Hashtable;
33import java.util.Map.Entry;
34
35/**
36 * This is a utility class that can be used by beans that support bound
37 * properties. It manages a list of listeners and dispatches
38 * {@link PropertyChangeEvent}s to them. You can use an instance of this class
39 * as a member field of your bean and delegate these types of work to it.
40 * The {@link PropertyChangeListener} can be registered for all properties
41 * or for a property specified by name.
42 * <p>
43 * Here is an example of {@code PropertyChangeSupport} usage that follows
44 * the rules and recommendations laid out in the JavaBeans&trade; specification:
45 * <pre>
46 * public class MyBean {
47 * private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
48 *
49 * public void addPropertyChangeListener(PropertyChangeListener listener) {
50 * this.pcs.addPropertyChangeListener(listener);
51 * }
52 *
53 * public void removePropertyChangeListener(PropertyChangeListener listener) {
54 * this.pcs.removePropertyChangeListener(listener);
55 * }
56 *
57 * private String value;
58 *
59 * public String getValue() {
60 * return this.value;
61 * }
62 *
63 * public void setValue(String newValue) {
64 * String oldValue = this.value;
65 * this.value = newValue;
66 * this.pcs.firePropertyChange("value", oldValue, newValue);
67 * }
68 *
69 * [...]
70 * }
71 * </pre>
72 * <p>
73 * A {@code PropertyChangeSupport} instance is thread-safe.
74 * <p>
75 * This class is serializable. When it is serialized it will save
76 * (and restore) any listeners that are themselves serializable. Any
77 * non-serializable listeners will be skipped during serialization.
78 *
79 * @see VetoableChangeSupport
80 */
81public class PropertyChangeSupport implements Serializable {
82 private PropertyChangeListenerMap map = new PropertyChangeListenerMap();
83
84 /**
85 * Constructs a <code>PropertyChangeSupport</code> object.
86 *
87 * @param sourceBean The bean to be given as the source for any events.
88 */
89 public PropertyChangeSupport(Object sourceBean) {
90 if (sourceBean == null) {
91 throw new NullPointerException();
92 }
93 source = sourceBean;
94 }
95
96 /**
97 * Add a PropertyChangeListener to the listener list.
98 * The listener is registered for all properties.
99 * The same listener object may be added more than once, and will be called
100 * as many times as it is added.
101 * If <code>listener</code> is null, no exception is thrown and no action
102 * is taken.
103 *
104 * @param listener The PropertyChangeListener to be added
105 */
106 public void addPropertyChangeListener(PropertyChangeListener listener) {
107 if (listener == null) {
108 return;
109 }
110 if (listener instanceof PropertyChangeListenerProxy) {
111 PropertyChangeListenerProxy proxy =
112 (PropertyChangeListenerProxy)listener;
113 // Call two argument add method.
114 addPropertyChangeListener(proxy.getPropertyName(),
115 proxy.getListener());
116 } else {
117 this.map.add(null, listener);
118 }
119 }
120
121 /**
122 * Remove a PropertyChangeListener from the listener list.
123 * This removes a PropertyChangeListener that was registered
124 * for all properties.
125 * If <code>listener</code> was added more than once to the same event
126 * source, it will be notified one less time after being removed.
127 * If <code>listener</code> is null, or was never added, no exception is
128 * thrown and no action is taken.
129 *
130 * @param listener The PropertyChangeListener to be removed
131 */
132 public void removePropertyChangeListener(PropertyChangeListener listener) {
133 if (listener == null) {
134 return;
135 }
136 if (listener instanceof PropertyChangeListenerProxy) {
137 PropertyChangeListenerProxy proxy =
138 (PropertyChangeListenerProxy)listener;
139 // Call two argument remove method.
140 removePropertyChangeListener(proxy.getPropertyName(),
141 proxy.getListener());
142 } else {
143 this.map.remove(null, listener);
144 }
145 }
146
147 /**
148 * Returns an array of all the listeners that were added to the
149 * PropertyChangeSupport object with addPropertyChangeListener().
150 * <p>
151 * If some listeners have been added with a named property, then
152 * the returned array will be a mixture of PropertyChangeListeners
153 * and <code>PropertyChangeListenerProxy</code>s. If the calling
154 * method is interested in distinguishing the listeners then it must
155 * test each element to see if it's a
156 * <code>PropertyChangeListenerProxy</code>, perform the cast, and examine
157 * the parameter.
158 *
159 * <pre>
160 * PropertyChangeListener[] listeners = bean.getPropertyChangeListeners();
161 * for (int i = 0; i < listeners.length; i++) {
162 * if (listeners[i] instanceof PropertyChangeListenerProxy) {
163 * PropertyChangeListenerProxy proxy =
164 * (PropertyChangeListenerProxy)listeners[i];
165 * if (proxy.getPropertyName().equals("foo")) {
166 * // proxy is a PropertyChangeListener which was associated
167 * // with the property named "foo"
168 * }
169 * }
170 * }
171 *</pre>
172 *
173 * @see PropertyChangeListenerProxy
174 * @return all of the <code>PropertyChangeListeners</code> added or an
175 * empty array if no listeners have been added
176 * @since 1.4
177 */
178 public PropertyChangeListener[] getPropertyChangeListeners() {
179 return this.map.getListeners();
180 }
181
182 /**
183 * Add a PropertyChangeListener for a specific property. The listener
184 * will be invoked only when a call on firePropertyChange names that
185 * specific property.
186 * The same listener object may be added more than once. For each
187 * property, the listener will be invoked the number of times it was added
188 * for that property.
189 * If <code>propertyName</code> or <code>listener</code> is null, no
190 * exception is thrown and no action is taken.
191 *
192 * @param propertyName The name of the property to listen on.
193 * @param listener The PropertyChangeListener to be added
194 */
195 public void addPropertyChangeListener(
196 String propertyName,
197 PropertyChangeListener listener) {
198 if (listener == null || propertyName == null) {
199 return;
200 }
201 listener = this.map.extract(listener);
202 if (listener != null) {
203 this.map.add(propertyName, listener);
204 }
205 }
206
207 /**
208 * Remove a PropertyChangeListener for a specific property.
209 * If <code>listener</code> was added more than once to the same event
210 * source for the specified property, it will be notified one less time
211 * after being removed.
212 * If <code>propertyName</code> is null, no exception is thrown and no
213 * action is taken.
214 * If <code>listener</code> is null, or was never added for the specified
215 * property, no exception is thrown and no action is taken.
216 *
217 * @param propertyName The name of the property that was listened on.
218 * @param listener The PropertyChangeListener to be removed
219 */
220 public void removePropertyChangeListener(
221 String propertyName,
222 PropertyChangeListener listener) {
223 if (listener == null || propertyName == null) {
224 return;
225 }
226 listener = this.map.extract(listener);
227 if (listener != null) {
228 this.map.remove(propertyName, listener);
229 }
230 }
231
232 /**
233 * Returns an array of all the listeners which have been associated
234 * with the named property.
235 *
236 * @param propertyName The name of the property being listened to
237 * @return all of the <code>PropertyChangeListeners</code> associated with
238 * the named property. If no such listeners have been added,
239 * or if <code>propertyName</code> is null, an empty array is
240 * returned.
241 * @since 1.4
242 */
243 public PropertyChangeListener[] getPropertyChangeListeners(String propertyName) {
244 return this.map.getListeners(propertyName);
245 }
246
247 /**
248 * Reports a bound property update to listeners
249 * that have been registered to track updates of
250 * all properties or a property with the specified name.
251 * <p>
252 * No event is fired if old and new values are equal and non-null.
253 * <p>
254 * This is merely a convenience wrapper around the more general
255 * {@link #firePropertyChange(PropertyChangeEvent)} method.
256 *
257 * @param propertyName the programmatic name of the property that was changed
258 * @param oldValue the old value of the property
259 * @param newValue the new value of the property
260 */
261 public void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
262 if (oldValue == null || newValue == null || !oldValue.equals(newValue)) {
263 firePropertyChange(new PropertyChangeEvent(this.source, propertyName, oldValue, newValue));
264 }
265 }
266
267 /**
268 * Reports an integer bound property update to listeners
269 * that have been registered to track updates of
270 * all properties or a property with the specified name.
271 * <p>
272 * No event is fired if old and new values are equal.
273 * <p>
274 * This is merely a convenience wrapper around the more general
275 * {@link #firePropertyChange(String, Object, Object)} method.
276 *
277 * @param propertyName the programmatic name of the property that was changed
278 * @param oldValue the old value of the property
279 * @param newValue the new value of the property
280 */
281 public void firePropertyChange(String propertyName, int oldValue, int newValue) {
282 if (oldValue != newValue) {
283 firePropertyChange(propertyName, Integer.valueOf(oldValue), Integer.valueOf(newValue));
284 }
285 }
286
287 /**
288 * Reports a boolean bound property update to listeners
289 * that have been registered to track updates of
290 * all properties or a property with the specified name.
291 * <p>
292 * No event is fired if old and new values are equal.
293 * <p>
294 * This is merely a convenience wrapper around the more general
295 * {@link #firePropertyChange(String, Object, Object)} method.
296 *
297 * @param propertyName the programmatic name of the property that was changed
298 * @param oldValue the old value of the property
299 * @param newValue the new value of the property
300 */
301 public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) {
302 if (oldValue != newValue) {
303 firePropertyChange(propertyName, Boolean.valueOf(oldValue), Boolean.valueOf(newValue));
304 }
305 }
306
307 /**
308 * Fires a property change event to listeners
309 * that have been registered to track updates of
310 * all properties or a property with the specified name.
311 * <p>
312 * No event is fired if the given event's old and new values are equal and non-null.
313 *
314 * @param event the {@code PropertyChangeEvent} to be fired
315 */
316 public void firePropertyChange(PropertyChangeEvent event) {
317 Object oldValue = event.getOldValue();
318 Object newValue = event.getNewValue();
319 if (oldValue == null || newValue == null || !oldValue.equals(newValue)) {
320 String name = event.getPropertyName();
321
322 PropertyChangeListener[] common = this.map.get(null);
323 PropertyChangeListener[] named = (name != null)
324 ? this.map.get(name)
325 : null;
326
327 fire(common, event);
328 fire(named, event);
329 }
330 }
331
332 private static void fire(PropertyChangeListener[] listeners, PropertyChangeEvent event) {
333 if (listeners != null) {
334 for (PropertyChangeListener listener : listeners) {
335 listener.propertyChange(event);
336 }
337 }
338 }
339
340 /**
341 * Reports a bound indexed property update to listeners
342 * that have been registered to track updates of
343 * all properties or a property with the specified name.
344 * <p>
345 * No event is fired if old and new values are equal and non-null.
346 * <p>
347 * This is merely a convenience wrapper around the more general
348 * {@link #firePropertyChange(PropertyChangeEvent)} method.
349 *
350 * @param propertyName the programmatic name of the property that was changed
351 * @param index the index of the property element that was changed
352 * @param oldValue the old value of the property
353 * @param newValue the new value of the property
354 * @since 1.5
355 */
356 public void fireIndexedPropertyChange(String propertyName, int index, Object oldValue, Object newValue) {
357 if (oldValue == null || newValue == null || !oldValue.equals(newValue)) {
358 firePropertyChange(new IndexedPropertyChangeEvent(source, propertyName, oldValue, newValue, index));
359 }
360 }
361
362 /**
363 * Reports an integer bound indexed property update to listeners
364 * that have been registered to track updates of
365 * all properties or a property with the specified name.
366 * <p>
367 * No event is fired if old and new values are equal.
368 * <p>
369 * This is merely a convenience wrapper around the more general
370 * {@link #fireIndexedPropertyChange(String, int, Object, Object)} method.
371 *
372 * @param propertyName the programmatic name of the property that was changed
373 * @param index the index of the property element that was changed
374 * @param oldValue the old value of the property
375 * @param newValue the new value of the property
376 * @since 1.5
377 */
378 public void fireIndexedPropertyChange(String propertyName, int index, int oldValue, int newValue) {
379 if (oldValue != newValue) {
380 fireIndexedPropertyChange(propertyName, index, Integer.valueOf(oldValue), Integer.valueOf(newValue));
381 }
382 }
383
384 /**
385 * Reports a boolean bound indexed property update to listeners
386 * that have been registered to track updates of
387 * all properties or a property with the specified name.
388 * <p>
389 * No event is fired if old and new values are equal.
390 * <p>
391 * This is merely a convenience wrapper around the more general
392 * {@link #fireIndexedPropertyChange(String, int, Object, Object)} method.
393 *
394 * @param propertyName the programmatic name of the property that was changed
395 * @param index the index of the property element that was changed
396 * @param oldValue the old value of the property
397 * @param newValue the new value of the property
398 * @since 1.5
399 */
400 public void fireIndexedPropertyChange(String propertyName, int index, boolean oldValue, boolean newValue) {
401 if (oldValue != newValue) {
402 fireIndexedPropertyChange(propertyName, index, Boolean.valueOf(oldValue), Boolean.valueOf(newValue));
403 }
404 }
405
406 /**
407 * Check if there are any listeners for a specific property, including
408 * those registered on all properties. If <code>propertyName</code>
409 * is null, only check for listeners registered on all properties.
410 *
411 * @param propertyName the property name.
412 * @return true if there are one or more listeners for the given property
413 */
414 public boolean hasListeners(String propertyName) {
415 return this.map.hasListeners(propertyName);
416 }
417
418 /**
419 * @serialData Null terminated list of <code>PropertyChangeListeners</code>.
420 * <p>
421 * At serialization time we skip non-serializable listeners and
422 * only serialize the serializable listeners.
423 */
424 private void writeObject(ObjectOutputStream s) throws IOException {
425 Hashtable<String, PropertyChangeSupport> children = null;
426 PropertyChangeListener[] listeners = null;
427 synchronized (this.map) {
428 for (Entry<String, PropertyChangeListener[]> entry : this.map.getEntries()) {
429 String property = entry.getKey();
430 if (property == null) {
431 listeners = entry.getValue();
432 } else {
433 if (children == null) {
434 children = new Hashtable<String, PropertyChangeSupport>();
435 }
436 PropertyChangeSupport pcs = new PropertyChangeSupport(this.source);
437 pcs.map.set(null, entry.getValue());
438 children.put(property, pcs);
439 }
440 }
441 }
442 ObjectOutputStream.PutField fields = s.putFields();
443 fields.put("children", children);
444 fields.put("source", this.source);
445 fields.put("propertyChangeSupportSerializedDataVersion", 2);
446 s.writeFields();
447
448 if (listeners != null) {
449 for (PropertyChangeListener l : listeners) {
450 if (l instanceof Serializable) {
451 s.writeObject(l);
452 }
453 }
454 }
455 s.writeObject(null);
456 }
457
458 private void readObject(ObjectInputStream s) throws ClassNotFoundException, IOException {
459 this.map = new PropertyChangeListenerMap();
460
461 ObjectInputStream.GetField fields = s.readFields();
462
463 Hashtable<String, PropertyChangeSupport> children = (Hashtable<String, PropertyChangeSupport>) fields.get("children", null);
464 this.source = fields.get("source", null);
465 fields.get("propertyChangeSupportSerializedDataVersion", 2);
466
467 Object listenerOrNull;
468 while (null != (listenerOrNull = s.readObject())) {
469 this.map.add(null, (PropertyChangeListener)listenerOrNull);
470 }
471 if (children != null) {
472 for (Entry<String, PropertyChangeSupport> entry : children.entrySet()) {
473 for (PropertyChangeListener listener : entry.getValue().getPropertyChangeListeners()) {
474 this.map.add(entry.getKey(), listener);
475 }
476 }
477 }
478 }
479
480 /**
481 * The object to be provided as the "source" for any generated events.
482 */
483 private Object source;
484
485 /**
486 * @serialField children Hashtable
487 * @serialField source Object
488 * @serialField propertyChangeSupportSerializedDataVersion int
489 */
490 private static final ObjectStreamField[] serialPersistentFields = {
491 new ObjectStreamField("children", Hashtable.class),
492 new ObjectStreamField("source", Object.class),
493 new ObjectStreamField("propertyChangeSupportSerializedDataVersion", Integer.TYPE)
494 };
495
496 /**
497 * Serialization version ID, so we're compatible with JDK 1.1
498 */
499 static final long serialVersionUID = 6401253773779951803L;
500
501 /**
502 * This is a {@link ChangeListenerMap ChangeListenerMap} implementation
503 * that works with {@link PropertyChangeListener PropertyChangeListener} objects.
504 */
505 private static final class PropertyChangeListenerMap extends ChangeListenerMap<PropertyChangeListener> {
506 private static final PropertyChangeListener[] EMPTY = {};
507
508 /**
509 * Creates an array of {@link PropertyChangeListener PropertyChangeListener} objects.
510 * This method uses the same instance of the empty array
511 * when {@code length} equals {@code 0}.
512 *
513 * @param length the array length
514 * @return an array with specified length
515 */
516 @Override
517 protected PropertyChangeListener[] newArray(int length) {
518 return (0 < length)
519 ? new PropertyChangeListener[length]
520 : EMPTY;
521 }
522
523 /**
524 * Creates a {@link PropertyChangeListenerProxy PropertyChangeListenerProxy}
525 * object for the specified property.
526 *
527 * @param name the name of the property to listen on
528 * @param listener the listener to process events
529 * @return a {@code PropertyChangeListenerProxy} object
530 */
531 @Override
532 protected PropertyChangeListener newProxy(String name, PropertyChangeListener listener) {
533 return new PropertyChangeListenerProxy(name, listener);
534 }
535 }
536}
java/pkg/java/beans/PropertyDescriptor.class+0−0

Binary file not shown.

java/pkg/java/beans/PropertyDescriptor.java+719−0
@@ -0,0 +1,719 @@
1/*
2 * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.beans;
27
28import java.lang.ref.Reference;
29import java.lang.reflect.Method;
30import java.lang.reflect.Constructor;
31
32/**
33 * A PropertyDescriptor describes one property that a Java Bean
34 * exports via a pair of accessor methods.
35 */
36public class PropertyDescriptor extends FeatureDescriptor {
37
38 private Reference<Class> propertyTypeRef;
39 private Reference<Method> readMethodRef;
40 private Reference<Method> writeMethodRef;
41 private Reference<Class> propertyEditorClassRef;
42
43 private boolean bound;
44 private boolean constrained;
45
46 // The base name of the method name which will be prefixed with the
47 // read and write method. If name == "foo" then the baseName is "Foo"
48 private String baseName;
49
50 private String writeMethodName;
51 private String readMethodName;
52
53 /**
54 * Constructs a PropertyDescriptor for a property that follows
55 * the standard Java convention by having getFoo and setFoo
56 * accessor methods. Thus if the argument name is "fred", it will
57 * assume that the writer method is "setFred" and the reader method
58 * is "getFred" (or "isFred" for a boolean property). Note that the
59 * property name should start with a lower case character, which will
60 * be capitalized in the method names.
61 *
62 * @param propertyName The programmatic name of the property.
63 * @param beanClass The Class object for the target bean. For
64 * example sun.beans.OurButton.class.
65 * @exception IntrospectionException if an exception occurs during
66 * introspection.
67 */
68 public PropertyDescriptor(String propertyName, Class<?> beanClass)
69 throws IntrospectionException {
70 this(propertyName, beanClass,
71 Introspector.IS_PREFIX + NameGenerator.capitalize(propertyName),
72 Introspector.SET_PREFIX + NameGenerator.capitalize(propertyName));
73 }
74
75 /**
76 * This constructor takes the name of a simple property, and method
77 * names for reading and writing the property.
78 *
79 * @param propertyName The programmatic name of the property.
80 * @param beanClass The Class object for the target bean. For
81 * example sun.beans.OurButton.class.
82 * @param readMethodName The name of the method used for reading the property
83 * value. May be null if the property is write-only.
84 * @param writeMethodName The name of the method used for writing the property
85 * value. May be null if the property is read-only.
86 * @exception IntrospectionException if an exception occurs during
87 * introspection.
88 */
89 public PropertyDescriptor(String propertyName, Class<?> beanClass,
90 String readMethodName, String writeMethodName)
91 throws IntrospectionException {
92 if (beanClass == null) {
93 throw new IntrospectionException("Target Bean class is null");
94 }
95 if (propertyName == null || propertyName.length() == 0) {
96 throw new IntrospectionException("bad property name");
97 }
98 if ("".equals(readMethodName) || "".equals(writeMethodName)) {
99 throw new IntrospectionException("read or write method name should not be the empty string");
100 }
101 setName(propertyName);
102 setClass0(beanClass);
103
104 this.readMethodName = readMethodName;
105 if (readMethodName != null && getReadMethod() == null) {
106 throw new IntrospectionException("Method not found: " + readMethodName);
107 }
108 this.writeMethodName = writeMethodName;
109 if (writeMethodName != null && getWriteMethod() == null) {
110 throw new IntrospectionException("Method not found: " + writeMethodName);
111 }
112 // If this class or one of its base classes allow PropertyChangeListener,
113 // then we assume that any properties we discover are "bound".
114 // See Introspector.getTargetPropertyInfo() method.
115 Class[] args = { PropertyChangeListener.class };
116 this.bound = null != Introspector.findMethod(beanClass, "addPropertyChangeListener", args.length, args);
117 }
118
119 /**
120 * This constructor takes the name of a simple property, and Method
121 * objects for reading and writing the property.
122 *
123 * @param propertyName The programmatic name of the property.
124 * @param readMethod The method used for reading the property value.
125 * May be null if the property is write-only.
126 * @param writeMethod The method used for writing the property value.
127 * May be null if the property is read-only.
128 * @exception IntrospectionException if an exception occurs during
129 * introspection.
130 */
131 public PropertyDescriptor(String propertyName, Method readMethod, Method writeMethod)
132 throws IntrospectionException {
133 if (propertyName == null || propertyName.length() == 0) {
134 throw new IntrospectionException("bad property name");
135 }
136 setName(propertyName);
137 setReadMethod(readMethod);
138 setWriteMethod(writeMethod);
139 }
140
141 /**
142 * Creates <code>PropertyDescriptor</code> for the specified bean
143 * with the specified name and methods to read/write the property value.
144 *
145 * @param bean the type of the target bean
146 * @param base the base name of the property (the rest of the method name)
147 * @param read the method used for reading the property value
148 * @param write the method used for writing the property value
149 * @exception IntrospectionException if an exception occurs during introspection
150 *
151 * @since 1.7
152 */
153 PropertyDescriptor(Class<?> bean, String base, Method read, Method write) throws IntrospectionException {
154 if (bean == null) {
155 throw new IntrospectionException("Target Bean class is null");
156 }
157 setClass0(bean);
158 setName(Introspector.decapitalize(base));
159 setReadMethod(read);
160 setWriteMethod(write);
161 this.baseName = base;
162 }
163
164 /**
165 * Returns the Java type info for the property.
166 * Note that the {@code Class} object may describe
167 * primitive Java types such as {@code int}.
168 * This type is returned by the read method
169 * or is used as the parameter type of the write method.
170 * Returns {@code null} if the type is an indexed property
171 * that does not support non-indexed access.
172 *
173 * @return the {@code Class} object that represents the Java type info,
174 * or {@code null} if the type cannot be determined
175 */
176 public synchronized Class<?> getPropertyType() {
177 Class type = getPropertyType0();
178 if (type == null) {
179 try {
180 type = findPropertyType(getReadMethod(), getWriteMethod());
181 setPropertyType(type);
182 } catch (IntrospectionException ex) {
183 // Fall
184 }
185 }
186 return type;
187 }
188
189 private void setPropertyType(Class type) {
190 this.propertyTypeRef = getWeakReference(type);
191 }
192
193 private Class getPropertyType0() {
194 return (this.propertyTypeRef != null)
195 ? this.propertyTypeRef.get()
196 : null;
197 }
198
199 /**
200 * Gets the method that should be used to read the property value.
201 *
202 * @return The method that should be used to read the property value.
203 * May return null if the property can't be read.
204 */
205 public synchronized Method getReadMethod() {
206 Method readMethod = getReadMethod0();
207 if (readMethod == null) {
208 Class cls = getClass0();
209 if (cls == null || (readMethodName == null && readMethodRef == null)) {
210 // The read method was explicitly set to null.
211 return null;
212 }
213 if (readMethodName == null) {
214 Class type = getPropertyType0();
215 if (type == boolean.class || type == null) {
216 readMethodName = Introspector.IS_PREFIX + getBaseName();
217 } else {
218 readMethodName = Introspector.GET_PREFIX + getBaseName();
219 }
220 }
221
222 // Since there can be multiple write methods but only one getter
223 // method, find the getter method first so that you know what the
224 // property type is. For booleans, there can be "is" and "get"
225 // methods. If an "is" method exists, this is the official
226 // reader method so look for this one first.
227 readMethod = Introspector.findMethod(cls, readMethodName, 0);
228 if (readMethod == null) {
229 readMethodName = Introspector.GET_PREFIX + getBaseName();
230 readMethod = Introspector.findMethod(cls, readMethodName, 0);
231 }
232 try {
233 setReadMethod(readMethod);
234 } catch (IntrospectionException ex) {
235 // fall
236 }
237 }
238 return readMethod;
239 }
240
241 /**
242 * Sets the method that should be used to read the property value.
243 *
244 * @param readMethod The new read method.
245 */
246 public synchronized void setReadMethod(Method readMethod)
247 throws IntrospectionException {
248 if (readMethod == null) {
249 readMethodName = null;
250 readMethodRef = null;
251 return;
252 }
253 // The property type is determined by the read method.
254 setPropertyType(findPropertyType(readMethod, getWriteMethod0()));
255 setClass0(readMethod.getDeclaringClass());
256
257 readMethodName = readMethod.getName();
258 this.readMethodRef = getSoftReference(readMethod);
259 setTransient(readMethod.getAnnotation(Transient.class));
260 }
261
262 /**
263 * Gets the method that should be used to write the property value.
264 *
265 * @return The method that should be used to write the property value.
266 * May return null if the property can't be written.
267 */
268 public synchronized Method getWriteMethod() {
269 Method writeMethod = getWriteMethod0();
270 if (writeMethod == null) {
271 Class cls = getClass0();
272 if (cls == null || (writeMethodName == null && writeMethodRef == null)) {
273 // The write method was explicitly set to null.
274 return null;
275 }
276
277 // We need the type to fetch the correct method.
278 Class type = getPropertyType0();
279 if (type == null) {
280 try {
281 // Can't use getPropertyType since it will lead to recursive loop.
282 type = findPropertyType(getReadMethod(), null);
283 setPropertyType(type);
284 } catch (IntrospectionException ex) {
285 // Without the correct property type we can't be guaranteed
286 // to find the correct method.
287 return null;
288 }
289 }
290
291 if (writeMethodName == null) {
292 writeMethodName = Introspector.SET_PREFIX + getBaseName();
293 }
294
295 Class[] args = (type == null) ? null : new Class[] { type };
296 writeMethod = Introspector.findMethod(cls, writeMethodName, 1, args);
297 if (writeMethod != null) {
298 if (!writeMethod.getReturnType().equals(void.class)) {
299 writeMethod = null;
300 }
301 }
302 try {
303 setWriteMethod(writeMethod);
304 } catch (IntrospectionException ex) {
305 // fall through
306 }
307 }
308 return writeMethod;
309 }
310
311 /**
312 * Sets the method that should be used to write the property value.
313 *
314 * @param writeMethod The new write method.
315 */
316 public synchronized void setWriteMethod(Method writeMethod)
317 throws IntrospectionException {
318 if (writeMethod == null) {
319 writeMethodName = null;
320 writeMethodRef = null;
321 return;
322 }
323 // Set the property type - which validates the method
324 setPropertyType(findPropertyType(getReadMethod(), writeMethod));
325 setClass0(writeMethod.getDeclaringClass());
326
327 writeMethodName = writeMethod.getName();
328 this.writeMethodRef = getSoftReference(writeMethod);
329 setTransient(writeMethod.getAnnotation(Transient.class));
330 }
331
332 private Method getReadMethod0() {
333 return (this.readMethodRef != null)
334 ? this.readMethodRef.get()
335 : null;
336 }
337
338 private Method getWriteMethod0() {
339 return (this.writeMethodRef != null)
340 ? this.writeMethodRef.get()
341 : null;
342 }
343
344 /**
345 * Overridden to ensure that a super class doesn't take precedent
346 */
347 void setClass0(Class clz) {
348 if (getClass0() != null && clz.isAssignableFrom(getClass0())) {
349 // dont replace a subclass with a superclass
350 return;
351 }
352 super.setClass0(clz);
353 }
354
355 /**
356 * Updates to "bound" properties will cause a "PropertyChange" event to
357 * get fired when the property is changed.
358 *
359 * @return True if this is a bound property.
360 */
361 public boolean isBound() {
362 return bound;
363 }
364
365 /**
366 * Updates to "bound" properties will cause a "PropertyChange" event to
367 * get fired when the property is changed.
368 *
369 * @param bound True if this is a bound property.
370 */
371 public void setBound(boolean bound) {
372 this.bound = bound;
373 }
374
375 /**
376 * Attempted updates to "Constrained" properties will cause a "VetoableChange"
377 * event to get fired when the property is changed.
378 *
379 * @return True if this is a constrained property.
380 */
381 public boolean isConstrained() {
382 return constrained;
383 }
384
385 /**
386 * Attempted updates to "Constrained" properties will cause a "VetoableChange"
387 * event to get fired when the property is changed.
388 *
389 * @param constrained True if this is a constrained property.
390 */
391 public void setConstrained(boolean constrained) {
392 this.constrained = constrained;
393 }
394
395
396 /**
397 * Normally PropertyEditors will be found using the PropertyEditorManager.
398 * However if for some reason you want to associate a particular
399 * PropertyEditor with a given property, then you can do it with
400 * this method.
401 *
402 * @param propertyEditorClass The Class for the desired PropertyEditor.
403 */
404 public void setPropertyEditorClass(Class<?> propertyEditorClass) {
405 this.propertyEditorClassRef = getWeakReference((Class)propertyEditorClass);
406 }
407
408 /**
409 * Gets any explicit PropertyEditor Class that has been registered
410 * for this property.
411 *
412 * @return Any explicit PropertyEditor Class that has been registered
413 * for this property. Normally this will return "null",
414 * indicating that no special editor has been registered,
415 * so the PropertyEditorManager should be used to locate
416 * a suitable PropertyEditor.
417 */
418 public Class<?> getPropertyEditorClass() {
419 return (this.propertyEditorClassRef != null)
420 ? this.propertyEditorClassRef.get()
421 : null;
422 }
423
424 /**
425 * Constructs an instance of a property editor using the current
426 * property editor class.
427 * <p>
428 * If the property editor class has a public constructor that takes an
429 * Object argument then it will be invoked using the bean parameter
430 * as the argument. Otherwise, the default constructor will be invoked.
431 *
432 * @param bean the source object
433 * @return a property editor instance or null if a property editor has
434 * not been defined or cannot be created
435 * @since 1.5
436 */
437 public PropertyEditor createPropertyEditor(Object bean) {
438 Object editor = null;
439
440 Class cls = getPropertyEditorClass();
441 if (cls != null) {
442 Constructor ctor = null;
443 if (bean != null) {
444 try {
445 ctor = cls.getConstructor(new Class[] { Object.class });
446 } catch (Exception ex) {
447 // Fall through
448 }
449 }
450 try {
451 if (ctor == null) {
452 editor = cls.newInstance();
453 } else {
454 editor = ctor.newInstance(new Object[] { bean });
455 }
456 } catch (Exception ex) {
457 // A serious error has occured.
458 // Proably due to an invalid property editor.
459 throw new RuntimeException("PropertyEditor not instantiated",
460 ex);
461 }
462 }
463 return (PropertyEditor)editor;
464 }
465
466
467 /**
468 * Compares this <code>PropertyDescriptor</code> against the specified object.
469 * Returns true if the objects are the same. Two <code>PropertyDescriptor</code>s
470 * are the same if the read, write, property types, property editor and
471 * flags are equivalent.
472 *
473 * @since 1.4
474 */
475 public boolean equals(Object obj) {
476 if (this == obj) {
477 return true;
478 }
479 if (obj != null && obj instanceof PropertyDescriptor) {
480 PropertyDescriptor other = (PropertyDescriptor)obj;
481 Method otherReadMethod = other.getReadMethod();
482 Method otherWriteMethod = other.getWriteMethod();
483
484 if (!compareMethods(getReadMethod(), otherReadMethod)) {
485 return false;
486 }
487
488 if (!compareMethods(getWriteMethod(), otherWriteMethod)) {
489 return false;
490 }
491
492 if (getPropertyType() == other.getPropertyType() &&
493 getPropertyEditorClass() == other.getPropertyEditorClass() &&
494 bound == other.isBound() && constrained == other.isConstrained() &&
495 writeMethodName == other.writeMethodName &&
496 readMethodName == other.readMethodName) {
497 return true;
498 }
499 }
500 return false;
501 }
502
503 /**
504 * Package private helper method for Descriptor .equals methods.
505 *
506 * @param a first method to compare
507 * @param b second method to compare
508 * @return boolean to indicate that the methods are equivalent
509 */
510 boolean compareMethods(Method a, Method b) {
511 // Note: perhaps this should be a protected method in FeatureDescriptor
512 if ((a == null) != (b == null)) {
513 return false;
514 }
515
516 if (a != null && b != null) {
517 if (!a.equals(b)) {
518 return false;
519 }
520 }
521 return true;
522 }
523
524 /**
525 * Package-private constructor.
526 * Merge two property descriptors. Where they conflict, give the
527 * second argument (y) priority over the first argument (x).
528 *
529 * @param x The first (lower priority) PropertyDescriptor
530 * @param y The second (higher priority) PropertyDescriptor
531 */
532 PropertyDescriptor(PropertyDescriptor x, PropertyDescriptor y) {
533 super(x,y);
534
535 if (y.baseName != null) {
536 baseName = y.baseName;
537 } else {
538 baseName = x.baseName;
539 }
540
541 if (y.readMethodName != null) {
542 readMethodName = y.readMethodName;
543 } else {
544 readMethodName = x.readMethodName;
545 }
546
547 if (y.writeMethodName != null) {
548 writeMethodName = y.writeMethodName;
549 } else {
550 writeMethodName = x.writeMethodName;
551 }
552
553 if (y.propertyTypeRef != null) {
554 propertyTypeRef = y.propertyTypeRef;
555 } else {
556 propertyTypeRef = x.propertyTypeRef;
557 }
558
559 // Figure out the merged read method.
560 Method xr = x.getReadMethod();
561 Method yr = y.getReadMethod();
562
563 // Normally give priority to y's readMethod.
564 try {
565 if (yr != null && yr.getDeclaringClass() == getClass0()) {
566 setReadMethod(yr);
567 } else {
568 setReadMethod(xr);
569 }
570 } catch (IntrospectionException ex) {
571 // fall through
572 }
573
574 // However, if both x and y reference read methods in the same class,
575 // give priority to a boolean "is" method over a boolean "get" method.
576 if (xr != null && yr != null &&
577 xr.getDeclaringClass() == yr.getDeclaringClass() &&
578 getReturnType(getClass0(), xr) == boolean.class &&
579 getReturnType(getClass0(), yr) == boolean.class &&
580 xr.getName().indexOf(Introspector.IS_PREFIX) == 0 &&
581 yr.getName().indexOf(Introspector.GET_PREFIX) == 0) {
582 try {
583 setReadMethod(xr);
584 } catch (IntrospectionException ex) {
585 // fall through
586 }
587 }
588
589 Method xw = x.getWriteMethod();
590 Method yw = y.getWriteMethod();
591
592 try {
593 if (yw != null && yw.getDeclaringClass() == getClass0()) {
594 setWriteMethod(yw);
595 } else {
596 setWriteMethod(xw);
597 }
598 } catch (IntrospectionException ex) {
599 // Fall through
600 }
601
602 if (y.getPropertyEditorClass() != null) {
603 setPropertyEditorClass(y.getPropertyEditorClass());
604 } else {
605 setPropertyEditorClass(x.getPropertyEditorClass());
606 }
607
608
609 bound = x.bound | y.bound;
610 constrained = x.constrained | y.constrained;
611 }
612
613 /*
614 * Package-private dup constructor.
615 * This must isolate the new object from any changes to the old object.
616 */
617 PropertyDescriptor(PropertyDescriptor old) {
618 super(old);
619 propertyTypeRef = old.propertyTypeRef;
620 readMethodRef = old.readMethodRef;
621 writeMethodRef = old.writeMethodRef;
622 propertyEditorClassRef = old.propertyEditorClassRef;
623
624 writeMethodName = old.writeMethodName;
625 readMethodName = old.readMethodName;
626 baseName = old.baseName;
627
628 bound = old.bound;
629 constrained = old.constrained;
630 }
631
632 /**
633 * Returns the property type that corresponds to the read and write method.
634 * The type precedence is given to the readMethod.
635 *
636 * @return the type of the property descriptor or null if both
637 * read and write methods are null.
638 * @throws IntrospectionException if the read or write method is invalid
639 */
640 private Class findPropertyType(Method readMethod, Method writeMethod)
641 throws IntrospectionException {
642 Class propertyType = null;
643 try {
644 if (readMethod != null) {
645 Class[] params = getParameterTypes(getClass0(), readMethod);
646 if (params.length != 0) {
647 throw new IntrospectionException("bad read method arg count: "
648 + readMethod);
649 }
650 propertyType = getReturnType(getClass0(), readMethod);
651 if (propertyType == Void.TYPE) {
652 throw new IntrospectionException("read method " +
653 readMethod.getName() + " returns void");
654 }
655 }
656 if (writeMethod != null) {
657 Class params[] = getParameterTypes(getClass0(), writeMethod);
658 if (params.length != 1) {
659 throw new IntrospectionException("bad write method arg count: "
660 + writeMethod);
661 }
662 if (propertyType != null && propertyType != params[0]) {
663 throw new IntrospectionException("type mismatch between read and write methods");
664 }
665 propertyType = params[0];
666 }
667 } catch (IntrospectionException ex) {
668 throw ex;
669 }
670 return propertyType;
671 }
672
673
674 /**
675 * Returns a hash code value for the object.
676 * See {@link java.lang.Object#hashCode} for a complete description.
677 *
678 * @return a hash code value for this object.
679 * @since 1.5
680 */
681 public int hashCode() {
682 int result = 7;
683
684 result = 37 * result + ((getPropertyType() == null) ? 0 :
685 getPropertyType().hashCode());
686 result = 37 * result + ((getReadMethod() == null) ? 0 :
687 getReadMethod().hashCode());
688 result = 37 * result + ((getWriteMethod() == null) ? 0 :
689 getWriteMethod().hashCode());
690 result = 37 * result + ((getPropertyEditorClass() == null) ? 0 :
691 getPropertyEditorClass().hashCode());
692 result = 37 * result + ((writeMethodName == null) ? 0 :
693 writeMethodName.hashCode());
694 result = 37 * result + ((readMethodName == null) ? 0 :
695 readMethodName.hashCode());
696 result = 37 * result + getName().hashCode();
697 result = 37 * result + ((bound == false) ? 0 : 1);
698 result = 37 * result + ((constrained == false) ? 0 : 1);
699
700 return result;
701 }
702
703 // Calculate once since capitalize() is expensive.
704 String getBaseName() {
705 if (baseName == null) {
706 baseName = NameGenerator.capitalize(getName());
707 }
708 return baseName;
709 }
710
711 void appendTo(StringBuilder sb) {
712 appendTo(sb, "bound", this.bound);
713 appendTo(sb, "constrained", this.constrained);
714 appendTo(sb, "propertyEditorClass", this.propertyEditorClassRef);
715 appendTo(sb, "propertyType", this.propertyTypeRef);
716 appendTo(sb, "readMethod", this.readMethodRef);
717 appendTo(sb, "writeMethod", this.writeMethodRef);
718 }
719}
java/pkg/java/beans/PropertyEditor.class+0−0

Binary file not shown.

java/pkg/java/beans/PropertyEditor.java+225−0
@@ -0,0 +1,225 @@
1/*
2 * Copyright (c) 1996, 2003, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.beans;
27
28/**
29 * A PropertyEditor class provides support for GUIs that want to
30 * allow users to edit a property value of a given type.
31 * <p>
32 * PropertyEditor supports a variety of different kinds of ways of
33 * displaying and updating property values. Most PropertyEditors will
34 * only need to support a subset of the different options available in
35 * this API.
36 * <P>
37 * Simple PropertyEditors may only support the getAsText and setAsText
38 * methods and need not support (say) paintValue or getCustomEditor. More
39 * complex types may be unable to support getAsText and setAsText but will
40 * instead support paintValue and getCustomEditor.
41 * <p>
42 * Every propertyEditor must support one or more of the three simple
43 * display styles. Thus it can either (1) support isPaintable or (2)
44 * both return a non-null String[] from getTags() and return a non-null
45 * value from getAsText or (3) simply return a non-null String from
46 * getAsText().
47 * <p>
48 * Every property editor must support a call on setValue when the argument
49 * object is of the type for which this is the corresponding propertyEditor.
50 * In addition, each property editor must either support a custom editor,
51 * or support setAsText.
52 * <p>
53 * Each PropertyEditor should have a null constructor.
54 */
55
56public interface PropertyEditor {
57
58 /**
59 * Set (or change) the object that is to be edited. Primitive types such
60 * as "int" must be wrapped as the corresponding object type such as
61 * "java.lang.Integer".
62 *
63 * @param value The new target object to be edited. Note that this
64 * object should not be modified by the PropertyEditor, rather
65 * the PropertyEditor should create a new object to hold any
66 * modified value.
67 */
68 void setValue(Object value);
69
70 /**
71 * Gets the property value.
72 *
73 * @return The value of the property. Primitive types such as "int" will
74 * be wrapped as the corresponding object type such as "java.lang.Integer".
75 */
76
77 Object getValue();
78
79 //----------------------------------------------------------------------
80
81 /**
82 * Determines whether this property editor is paintable.
83 *
84 * @return True if the class will honor the paintValue method.
85 */
86
87 boolean isPaintable();
88
89 /**
90 * Paint a representation of the value into a given area of screen
91 * real estate. Note that the propertyEditor is responsible for doing
92 * its own clipping so that it fits into the given rectangle.
93 * <p>
94 * If the PropertyEditor doesn't honor paint requests (see isPaintable)
95 * this method should be a silent noop.
96 * <p>
97 * The given Graphics object will have the default font, color, etc of
98 * the parent container. The PropertyEditor may change graphics attributes
99 * such as font and color and doesn't need to restore the old values.
100 *
101 * @param gfx Graphics object to paint into.
102 * @param box Rectangle within graphics object into which we should paint.
103 */
104 void paintValue(java.awt.Graphics gfx, java.awt.Rectangle box);
105
106 //----------------------------------------------------------------------
107
108 /**
109 * Returns a fragment of Java code that can be used to set a property
110 * to match the editors current state. This method is intended
111 * for use when generating Java code to reflect changes made through the
112 * property editor.
113 * <p>
114 * The code fragment should be context free and must be a legal Java
115 * expression as specified by the JLS.
116 * <p>
117 * Specifically, if the expression represents a computation then all
118 * classes and static members should be fully qualified. This rule
119 * applies to constructors, static methods and non primitive arguments.
120 * <p>
121 * Caution should be used when evaluating the expression as it may throw
122 * exceptions. In particular, code generators must ensure that generated
123 * code will compile in the presence of an expression that can throw
124 * checked exceptions.
125 * <p>
126 * Example results are:
127 * <ul>
128 * <li>Primitive expresssion: <code>2</code>
129 * <li>Class constructor: <code>new java.awt.Color(127,127,34)</code>
130 * <li>Static field: <code>java.awt.Color.orange</code>
131 * <li>Static method: <code>javax.swing.Box.createRigidArea(new
132 * java.awt.Dimension(0, 5))</code>
133 * </ul>
134 *
135 * @return a fragment of Java code representing an initializer for the
136 * current value. It should not contain a semi-colon
137 * ('<code>;</code>') to end the expression.
138 */
139 String getJavaInitializationString();
140
141 //----------------------------------------------------------------------
142
143 /**
144 * Gets the property value as text.
145 *
146 * @return The property value as a human editable string.
147 * <p> Returns null if the value can't be expressed as an editable string.
148 * <p> If a non-null value is returned, then the PropertyEditor should
149 * be prepared to parse that string back in setAsText().
150 */
151 String getAsText();
152
153 /**
154 * Set the property value by parsing a given String. May raise
155 * java.lang.IllegalArgumentException if either the String is
156 * badly formatted or if this kind of property can't be expressed
157 * as text.
158 * @param text The string to be parsed.
159 */
160 void setAsText(String text) throws java.lang.IllegalArgumentException;
161
162 //----------------------------------------------------------------------
163
164 /**
165 * If the property value must be one of a set of known tagged values,
166 * then this method should return an array of the tags. This can
167 * be used to represent (for example) enum values. If a PropertyEditor
168 * supports tags, then it should support the use of setAsText with
169 * a tag value as a way of setting the value and the use of getAsText
170 * to identify the current value.
171 *
172 * @return The tag values for this property. May be null if this
173 * property cannot be represented as a tagged value.
174 *
175 */
176 String[] getTags();
177
178 //----------------------------------------------------------------------
179
180 /**
181 * A PropertyEditor may choose to make available a full custom Component
182 * that edits its property value. It is the responsibility of the
183 * PropertyEditor to hook itself up to its editor Component itself and
184 * to report property value changes by firing a PropertyChange event.
185 * <P>
186 * The higher-level code that calls getCustomEditor may either embed
187 * the Component in some larger property sheet, or it may put it in
188 * its own individual dialog, or ...
189 *
190 * @return A java.awt.Component that will allow a human to directly
191 * edit the current property value. May be null if this is
192 * not supported.
193 */
194
195 java.awt.Component getCustomEditor();
196
197 /**
198 * Determines whether this property editor supports a custom editor.
199 *
200 * @return True if the propertyEditor can provide a custom editor.
201 */
202 boolean supportsCustomEditor();
203
204 //----------------------------------------------------------------------
205
206 /**
207 * Adds a listener for the value change.
208 * When the property editor changes its value
209 * it should fire a {@link PropertyChangeEvent}
210 * on all registered {@link PropertyChangeListener}s,
211 * specifying the {@code null} value for the property name
212 * and itself as the source.
213 *
214 * @param listener the {@link PropertyChangeListener} to add
215 */
216 void addPropertyChangeListener(PropertyChangeListener listener);
217
218 /**
219 * Removes a listener for the value change.
220 *
221 * @param listener the {@link PropertyChangeListener} to remove
222 */
223 void removePropertyChangeListener(PropertyChangeListener listener);
224
225}
java/pkg/java/beans/PropertyEditorManager.class+0−0

Binary file not shown.

java/pkg/java/beans/PropertyEditorManager.java+141−0
@@ -0,0 +1,141 @@
1/*
2 * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.beans;
27
28import com.sun.beans.finder.PropertyEditorFinder;
29import sun.awt.AppContext;
30
31/**
32 * The PropertyEditorManager can be used to locate a property editor for
33 * any given type name. This property editor must support the
34 * java.beans.PropertyEditor interface for editing a given object.
35 * <P>
36 * The PropertyEditorManager uses three techniques for locating an editor
37 * for a given type. First, it provides a registerEditor method to allow
38 * an editor to be specifically registered for a given type. Second it
39 * tries to locate a suitable class by adding "Editor" to the full
40 * qualified classname of the given type (e.g. "foo.bah.FozEditor").
41 * Finally it takes the simple classname (without the package name) adds
42 * "Editor" to it and looks in a search-path of packages for a matching
43 * class.
44 * <P>
45 * So for an input class foo.bah.Fred, the PropertyEditorManager would
46 * first look in its tables to see if an editor had been registered for
47 * foo.bah.Fred and if so use that. Then it will look for a
48 * foo.bah.FredEditor class. Then it will look for (say)
49 * standardEditorsPackage.FredEditor class.
50 * <p>
51 * Default PropertyEditors will be provided for the Java primitive types
52 * "boolean", "byte", "short", "int", "long", "float", and "double"; and
53 * for the classes java.lang.String. java.awt.Color, and java.awt.Font.
54 */
55
56public class PropertyEditorManager {
57
58 private static final Object FINDER_KEY = new Object();
59
60 /**
61 * Registers an editor class to edit values of the given target class.
62 * If the editor class is {@code null},
63 * then any existing definition will be removed.
64 * Thus this method can be used to cancel the registration.
65 * The registration is canceled automatically
66 * if either the target or editor class is unloaded.
67 * <p>
68 * If there is a security manager, its {@code checkPropertiesAccess}
69 * method is called. This could result in a {@linkplain SecurityException}.
70 *
71 * @param targetType the class object of the type to be edited
72 * @param editorClass the class object of the editor class
73 * @throws SecurityException if a security manager exists and
74 * its {@code checkPropertiesAccess} method
75 * doesn't allow setting of system properties
76 *
77 * @see SecurityManager#checkPropertiesAccess
78 */
79 public static void registerEditor(Class<?> targetType, Class<?> editorClass) {
80 SecurityManager sm = System.getSecurityManager();
81 if (sm != null) {
82 sm.checkPropertiesAccess();
83 }
84 getFinder().register(targetType, editorClass);
85 }
86
87 /**
88 * Locate a value editor for a given target type.
89 *
90 * @param targetType The Class object for the type to be edited
91 * @return An editor object for the given target class.
92 * The result is null if no suitable editor can be found.
93 */
94 public static PropertyEditor findEditor(Class<?> targetType) {
95 return getFinder().find(targetType);
96 }
97
98 /**
99 * Gets the package names that will be searched for property editors.
100 *
101 * @return The array of package names that will be searched in
102 * order to find property editors.
103 * <p> The default value for this array is implementation-dependent,
104 * e.g. Sun implementation initially sets to {"sun.beans.editors"}.
105 */
106 public static String[] getEditorSearchPath() {
107 return getFinder().getPackages();
108 }
109
110 /**
111 * Change the list of package names that will be used for
112 * finding property editors.
113 *
114 * <p>First, if there is a security manager, its <code>checkPropertiesAccess</code>
115 * method is called. This could result in a SecurityException.
116 *
117 * @param path Array of package names.
118 * @exception SecurityException if a security manager exists and its
119 * <code>checkPropertiesAccess</code> method doesn't allow setting
120 * of system properties.
121 * @see SecurityManager#checkPropertiesAccess
122 */
123 public static void setEditorSearchPath(String[] path) {
124 SecurityManager sm = System.getSecurityManager();
125 if (sm != null) {
126 sm.checkPropertiesAccess();
127 }
128 getFinder().setPackages(path);
129 }
130
131 private static PropertyEditorFinder getFinder() {
132 AppContext context = AppContext.getAppContext();
133 Object object = context.get(FINDER_KEY);
134 if (object instanceof PropertyEditorFinder) {
135 return (PropertyEditorFinder) object;
136 }
137 PropertyEditorFinder finder = new PropertyEditorFinder();
138 context.put(FINDER_KEY, finder);
139 return finder;
140 }
141}
java/pkg/java/beans/PropertyEditorSupport.class+0−0

Binary file not shown.

java/pkg/java/beans/PropertyEditorSupport.java+302−0
@@ -0,0 +1,302 @@
1/*
2 * Copyright (c) 1996, 2007, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.beans;
27
28import java.beans.*;
29
30/**
31 * This is a support class to help build property editors.
32 * <p>
33 * It can be used either as a base class or as a delagatee.
34 */
35
36public class PropertyEditorSupport implements PropertyEditor {
37
38 /**
39 * Constructs a <code>PropertyEditorSupport</code> object.
40 *
41 * @since 1.5
42 */
43 public PropertyEditorSupport() {
44 setSource(this);
45 }
46
47 /**
48 * Constructs a <code>PropertyEditorSupport</code> object.
49 *
50 * @param source the source used for event firing
51 * @since 1.5
52 */
53 public PropertyEditorSupport(Object source) {
54 if (source == null) {
55 throw new NullPointerException();
56 }
57 setSource(source);
58 }
59
60 /**
61 * Returns the bean that is used as the
62 * source of events. If the source has not
63 * been explicitly set then this instance of
64 * <code>PropertyEditorSupport</code> is returned.
65 *
66 * @return the source object or this instance
67 * @since 1.5
68 */
69 public Object getSource() {
70 return source;
71 }
72
73 /**
74 * Sets the source bean.
75 * <p>
76 * The source bean is used as the source of events
77 * for the property changes. This source should be used for information
78 * purposes only and should not be modified by the PropertyEditor.
79 *
80 * @param source source object to be used for events
81 * @since 1.5
82 */
83 public void setSource(Object source) {
84 this.source = source;
85 }
86
87 /**
88 * Set (or change) the object that is to be edited.
89 *
90 * @param value The new target object to be edited. Note that this
91 * object should not be modified by the PropertyEditor, rather
92 * the PropertyEditor should create a new object to hold any
93 * modified value.
94 */
95 public void setValue(Object value) {
96 this.value = value;
97 firePropertyChange();
98 }
99
100 /**
101 * Gets the value of the property.
102 *
103 * @return The value of the property.
104 */
105 public Object getValue() {
106 return value;
107 }
108
109 //----------------------------------------------------------------------
110
111 /**
112 * Determines whether the class will honor the paintValue method.
113 *
114 * @return True if the class will honor the paintValue method.
115 */
116
117 public boolean isPaintable() {
118 return false;
119 }
120
121 /**
122 * Paint a representation of the value into a given area of screen
123 * real estate. Note that the propertyEditor is responsible for doing
124 * its own clipping so that it fits into the given rectangle.
125 * <p>
126 * If the PropertyEditor doesn't honor paint requests (see isPaintable)
127 * this method should be a silent noop.
128 *
129 * @param gfx Graphics object to paint into.
130 * @param box Rectangle within graphics object into which we should paint.
131 */
132 public void paintValue(java.awt.Graphics gfx, java.awt.Rectangle box) {
133 }
134
135 //----------------------------------------------------------------------
136
137 /**
138 * This method is intended for use when generating Java code to set
139 * the value of the property. It should return a fragment of Java code
140 * that can be used to initialize a variable with the current property
141 * value.
142 * <p>
143 * Example results are "2", "new Color(127,127,34)", "Color.orange", etc.
144 *
145 * @return A fragment of Java code representing an initializer for the
146 * current value.
147 */
148 public String getJavaInitializationString() {
149 return "???";
150 }
151
152 //----------------------------------------------------------------------
153
154 /**
155 * Gets the property value as a string suitable for presentation
156 * to a human to edit.
157 *
158 * @return The property value as a string suitable for presentation
159 * to a human to edit.
160 * <p> Returns null if the value can't be expressed as a string.
161 * <p> If a non-null value is returned, then the PropertyEditor should
162 * be prepared to parse that string back in setAsText().
163 */
164 public String getAsText() {
165 return (this.value != null)
166 ? this.value.toString()
167 : null;
168 }
169
170 /**
171 * Sets the property value by parsing a given String. May raise
172 * java.lang.IllegalArgumentException if either the String is
173 * badly formatted or if this kind of property can't be expressed
174 * as text.
175 *
176 * @param text The string to be parsed.
177 */
178 public void setAsText(String text) throws java.lang.IllegalArgumentException {
179 if (value instanceof String) {
180 setValue(text);
181 return;
182 }
183 throw new java.lang.IllegalArgumentException(text);
184 }
185
186 //----------------------------------------------------------------------
187
188 /**
189 * If the property value must be one of a set of known tagged values,
190 * then this method should return an array of the tag values. This can
191 * be used to represent (for example) enum values. If a PropertyEditor
192 * supports tags, then it should support the use of setAsText with
193 * a tag value as a way of setting the value.
194 *
195 * @return The tag values for this property. May be null if this
196 * property cannot be represented as a tagged value.
197 *
198 */
199 public String[] getTags() {
200 return null;
201 }
202
203 //----------------------------------------------------------------------
204
205 /**
206 * A PropertyEditor may chose to make available a full custom Component
207 * that edits its property value. It is the responsibility of the
208 * PropertyEditor to hook itself up to its editor Component itself and
209 * to report property value changes by firing a PropertyChange event.
210 * <P>
211 * The higher-level code that calls getCustomEditor may either embed
212 * the Component in some larger property sheet, or it may put it in
213 * its own individual dialog, or ...
214 *
215 * @return A java.awt.Component that will allow a human to directly
216 * edit the current property value. May be null if this is
217 * not supported.
218 */
219
220 public java.awt.Component getCustomEditor() {
221 return null;
222 }
223
224 /**
225 * Determines whether the propertyEditor can provide a custom editor.
226 *
227 * @return True if the propertyEditor can provide a custom editor.
228 */
229 public boolean supportsCustomEditor() {
230 return false;
231 }
232
233 //----------------------------------------------------------------------
234
235 /**
236 * Adds a listener for the value change.
237 * When the property editor changes its value
238 * it should fire a {@link PropertyChangeEvent}
239 * on all registered {@link PropertyChangeListener}s,
240 * specifying the {@code null} value for the property name.
241 * If the source property is set,
242 * it should be used as the source of the event.
243 * <p>
244 * The same listener object may be added more than once,
245 * and will be called as many times as it is added.
246 * If {@code listener} is {@code null},
247 * no exception is thrown and no action is taken.
248 *
249 * @param listener the {@link PropertyChangeListener} to add
250 */
251 public synchronized void addPropertyChangeListener(
252 PropertyChangeListener listener) {
253 if (listeners == null) {
254 listeners = new java.util.Vector();
255 }
256 listeners.addElement(listener);
257 }
258
259 /**
260 * Removes a listener for the value change.
261 * <p>
262 * If the same listener was added more than once,
263 * it will be notified one less time after being removed.
264 * If {@code listener} is {@code null}, or was never added,
265 * no exception is thrown and no action is taken.
266 *
267 * @param listener the {@link PropertyChangeListener} to remove
268 */
269 public synchronized void removePropertyChangeListener(
270 PropertyChangeListener listener) {
271 if (listeners == null) {
272 return;
273 }
274 listeners.removeElement(listener);
275 }
276
277 /**
278 * Report that we have been modified to any interested listeners.
279 */
280 public void firePropertyChange() {
281 java.util.Vector targets;
282 synchronized (this) {
283 if (listeners == null) {
284 return;
285 }
286 targets = (java.util.Vector) listeners.clone();
287 }
288 // Tell our listeners that "everything" has changed.
289 PropertyChangeEvent evt = new PropertyChangeEvent(source, null, null, null);
290
291 for (int i = 0; i < targets.size(); i++) {
292 PropertyChangeListener target = (PropertyChangeListener)targets.elementAt(i);
293 target.propertyChange(evt);
294 }
295 }
296
297 //----------------------------------------------------------------------
298
299 private Object value;
300 private Object source;
301 private java.util.Vector listeners;
302}
java/pkg/java/beans/PropertyVetoException.class+0−0

Binary file not shown.

java/pkg/java/beans/PropertyVetoException.java+64−0
@@ -0,0 +1,64 @@
1/*
2 * Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.beans;
27
28
29/**
30 * A PropertyVetoException is thrown when a proposed change to a
31 * property represents an unacceptable value.
32 */
33
34public
35class PropertyVetoException extends Exception {
36 private static final long serialVersionUID = 129596057694162164L;
37
38 /**
39 * Constructs a <code>PropertyVetoException</code> with a
40 * detailed message.
41 *
42 * @param mess Descriptive message
43 * @param evt A PropertyChangeEvent describing the vetoed change.
44 */
45 public PropertyVetoException(String mess, PropertyChangeEvent evt) {
46 super(mess);
47 this.evt = evt;
48 }
49
50 /**
51 * Gets the vetoed <code>PropertyChangeEvent</code>.
52 *
53 * @return A PropertyChangeEvent describing the vetoed change.
54 */
55 public PropertyChangeEvent getPropertyChangeEvent() {
56 return evt;
57 }
58
59 /**
60 * A PropertyChangeEvent describing the vetoed change.
61 * @serial
62 */
63 private PropertyChangeEvent evt;
64}
java/pkg/java/beans/ProxyPersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/ReflectionUtils.class+0−0

Binary file not shown.

java/pkg/java/beans/ReflectionUtils.java+75−0
@@ -0,0 +1,75 @@
1/*
2 * Copyright (c) 2003, 2009, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25package java.beans;
26
27import java.lang.reflect.Field;
28
29/**
30 * A utility class for reflectively finding methods, constuctors and fields
31 * using reflection.
32 */
33class ReflectionUtils {
34
35 public static boolean isPrimitive(Class type) {
36 return primitiveTypeFor(type) != null;
37 }
38
39 public static Class primitiveTypeFor(Class wrapper) {
40 if (wrapper == Boolean.class) return Boolean.TYPE;
41 if (wrapper == Byte.class) return Byte.TYPE;
42 if (wrapper == Character.class) return Character.TYPE;
43 if (wrapper == Short.class) return Short.TYPE;
44 if (wrapper == Integer.class) return Integer.TYPE;
45 if (wrapper == Long.class) return Long.TYPE;
46 if (wrapper == Float.class) return Float.TYPE;
47 if (wrapper == Double.class) return Double.TYPE;
48 if (wrapper == Void.class) return Void.TYPE;
49 return null;
50 }
51
52 /**
53 * Returns the value of a private field.
54 *
55 * @param instance object instance
56 * @param cls class
57 * @param name name of the field
58 * @param el an exception listener to handle exceptions; or null
59 * @return value of the field; null if not found or an error is encountered
60 */
61 public static Object getPrivateField(Object instance, Class cls,
62 String name, ExceptionListener el) {
63 try {
64 Field f = cls.getDeclaredField(name);
65 f.setAccessible(true);
66 return f.get(instance);
67 }
68 catch (Exception e) {
69 if (el != null) {
70 el.exceptionThrown(e);
71 }
72 }
73 return null;
74 }
75}
java/pkg/java/beans/SimpleBeanInfo$1.class+0−0

Binary file not shown.

java/pkg/java/beans/SimpleBeanInfo.class+0−0

Binary file not shown.

java/pkg/java/beans/SimpleBeanInfo.java+146−0
@@ -0,0 +1,146 @@
1/*
2 * Copyright (c) 1996, 1998, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.beans;
27
28/**
29 * This is a support class to make it easier for people to provide
30 * BeanInfo classes.
31 * <p>
32 * It defaults to providing "noop" information, and can be selectively
33 * overriden to provide more explicit information on chosen topics.
34 * When the introspector sees the "noop" values, it will apply low
35 * level introspection and design patterns to automatically analyze
36 * the target bean.
37 */
38
39public class SimpleBeanInfo implements BeanInfo {
40
41 /**
42 * Deny knowledge about the class and customizer of the bean.
43 * You can override this if you wish to provide explicit info.
44 */
45 public BeanDescriptor getBeanDescriptor() {
46 return null;
47 }
48
49 /**
50 * Deny knowledge of properties. You can override this
51 * if you wish to provide explicit property info.
52 */
53 public PropertyDescriptor[] getPropertyDescriptors() {
54 return null;
55 }
56
57 /**
58 * Deny knowledge of a default property. You can override this
59 * if you wish to define a default property for the bean.
60 */
61 public int getDefaultPropertyIndex() {
62 return -1;
63 }
64
65 /**
66 * Deny knowledge of event sets. You can override this
67 * if you wish to provide explicit event set info.
68 */
69 public EventSetDescriptor[] getEventSetDescriptors() {
70 return null;
71 }
72
73 /**
74 * Deny knowledge of a default event. You can override this
75 * if you wish to define a default event for the bean.
76 */
77 public int getDefaultEventIndex() {
78 return -1;
79 }
80
81 /**
82 * Deny knowledge of methods. You can override this
83 * if you wish to provide explicit method info.
84 */
85 public MethodDescriptor[] getMethodDescriptors() {
86 return null;
87 }
88
89 /**
90 * Claim there are no other relevant BeanInfo objects. You
91 * may override this if you want to (for example) return a
92 * BeanInfo for a base class.
93 */
94 public BeanInfo[] getAdditionalBeanInfo() {
95 return null;
96 }
97
98 /**
99 * Claim there are no icons available. You can override
100 * this if you want to provide icons for your bean.
101 */
102 public java.awt.Image getIcon(int iconKind) {
103 return null;
104 }
105
106 /**
107 * This is a utility method to help in loading icon images.
108 * It takes the name of a resource file associated with the
109 * current object's class file and loads an image object
110 * from that file. Typically images will be GIFs.
111 * <p>
112 * @param resourceName A pathname relative to the directory
113 * holding the class file of the current class. For example,
114 * "wombat.gif".
115 * @return an image object. May be null if the load failed.
116 */
117 public java.awt.Image loadImage(final String resourceName) {
118 try {
119 final Class c = getClass();
120 java.awt.image.ImageProducer ip = (java.awt.image.ImageProducer)
121 java.security.AccessController.doPrivileged(
122 new java.security.PrivilegedAction() {
123 public Object run() {
124 java.net.URL url;
125 if ((url = c.getResource(resourceName)) == null) {
126 return null;
127 } else {
128 try {
129 return url.getContent();
130 } catch (java.io.IOException ioe) {
131 return null;
132 }
133 }
134 }
135 });
136
137 if (ip == null)
138 return null;
139 java.awt.Toolkit tk = java.awt.Toolkit.getDefaultToolkit();
140 return tk.createImage(ip);
141 } catch (Exception ex) {
142 return null;
143 }
144 }
145
146}
java/pkg/java/beans/Statement$1.class+0−0

Binary file not shown.

java/pkg/java/beans/Statement$2.class+0−0

Binary file not shown.

java/pkg/java/beans/Statement.class+0−0

Binary file not shown.

java/pkg/java/beans/Statement.java+363−0
@@ -0,0 +1,363 @@
1/*
2 * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25package java.beans;
26
27import java.lang.reflect.AccessibleObject;
28import java.lang.reflect.Array;
29import java.lang.reflect.Constructor;
30import java.lang.reflect.InvocationTargetException;
31import java.lang.reflect.Method;
32import java.security.AccessControlContext;
33import java.security.AccessController;
34import java.security.PrivilegedActionException;
35import java.security.PrivilegedExceptionAction;
36
37import com.sun.beans.finder.ClassFinder;
38import com.sun.beans.finder.ConstructorFinder;
39import com.sun.beans.finder.MethodFinder;
40import sun.reflect.misc.MethodUtil;
41
42/**
43 * A <code>Statement</code> object represents a primitive statement
44 * in which a single method is applied to a target and
45 * a set of arguments - as in <code>"a.setFoo(b)"</code>.
46 * Note that where this example uses names
47 * to denote the target and its argument, a statement
48 * object does not require a name space and is constructed with
49 * the values themselves.
50 * The statement object associates the named method
51 * with its environment as a simple set of values:
52 * the target and an array of argument values.
53 *
54 * @since 1.4
55 *
56 * @author Philip Milne
57 */
58public class Statement {
59
60 private static Object[] emptyArray = new Object[]{};
61
62 static ExceptionListener defaultExceptionListener = new ExceptionListener() {
63 public void exceptionThrown(Exception e) {
64 System.err.println(e);
65 // e.printStackTrace();
66 System.err.println("Continuing ...");
67 }
68 };
69
70 private final AccessControlContext acc = AccessController.getContext();
71 private final Object target;
72 private final String methodName;
73 private final Object[] arguments;
74 ClassLoader loader;
75
76 /**
77 * Creates a new {@link Statement} object
78 * for the specified target object to invoke the method
79 * specified by the name and by the array of arguments.
80 * <p>
81 * The {@code target} and the {@code methodName} values should not be {@code null}.
82 * Otherwise an attempt to execute this {@code Expression}
83 * will result in a {@code NullPointerException}.
84 * If the {@code arguments} value is {@code null},
85 * an empty array is used as the value of the {@code arguments} property.
86 *
87 * @param target the target object of this statement
88 * @param methodName the name of the method to invoke on the specified target
89 * @param arguments the array of arguments to invoke the specified method
90 */
91 @ConstructorProperties({"target", "methodName", "arguments"})
92 public Statement(Object target, String methodName, Object[] arguments) {
93 this.target = target;
94 this.methodName = methodName;
95 this.arguments = (arguments == null) ? emptyArray : arguments;
96 }
97
98 /**
99 * Returns the target object of this statement.
100 * If this method returns {@code null},
101 * the {@link #execute} method
102 * throws a {@code NullPointerException}.
103 *
104 * @return the target object of this statement
105 */
106 public Object getTarget() {
107 return target;
108 }
109
110 /**
111 * Returns the name of the method to invoke.
112 * If this method returns {@code null},
113 * the {@link #execute} method
114 * throws a {@code NullPointerException}.
115 *
116 * @return the name of the method
117 */
118 public String getMethodName() {
119 return methodName;
120 }
121
122 /**
123 * Returns the arguments for the method to invoke.
124 * The number of arguments and their types
125 * must match the method being called.
126 * {@code null} can be used as a synonym of an empty array.
127 *
128 * @return the array of arguments
129 */
130 public Object[] getArguments() {
131 return arguments;
132 }
133
134 /**
135 * The {@code execute} method finds a method whose name is the same
136 * as the {@code methodName} property, and invokes the method on
137 * the target.
138 *
139 * When the target's class defines many methods with the given name
140 * the implementation should choose the most specific method using
141 * the algorithm specified in the Java Language Specification
142 * (15.11). The dynamic class of the target and arguments are used
143 * in place of the compile-time type information and, like the
144 * {@link java.lang.reflect.Method} class itself, conversion between
145 * primitive values and their associated wrapper classes is handled
146 * internally.
147 * <p>
148 * The following method types are handled as special cases:
149 * <ul>
150 * <li>
151 * Static methods may be called by using a class object as the target.
152 * <li>
153 * The reserved method name "new" may be used to call a class's constructor
154 * as if all classes defined static "new" methods. Constructor invocations
155 * are typically considered {@code Expression}s rather than {@code Statement}s
156 * as they return a value.
157 * <li>
158 * The method names "get" and "set" defined in the {@link java.util.List}
159 * interface may also be applied to array instances, mapping to
160 * the static methods of the same name in the {@code Array} class.
161 * </ul>
162 *
163 * @throws NullPointerException if the value of the {@code target} or
164 * {@code methodName} property is {@code null}
165 * @throws NoSuchMethodException if a matching method is not found
166 * @throws SecurityException if a security manager exists and
167 * it denies the method invocation
168 * @throws Exception that is thrown by the invoked method
169 *
170 * @see java.lang.reflect.Method
171 */
172 public void execute() throws Exception {
173 invoke();
174 }
175
176 Object invoke() throws Exception {
177 AccessControlContext acc = this.acc;
178 if ((acc == null) && (System.getSecurityManager() != null)) {
179 throw new SecurityException("AccessControlContext is not set");
180 }
181 try {
182 return AccessController.doPrivileged(
183 new PrivilegedExceptionAction<Object>() {
184 public Object run() throws Exception {
185 return invokeInternal();
186 }
187 },
188 acc
189 );
190 }
191 catch (PrivilegedActionException exception) {
192 throw exception.getException();
193 }
194 }
195
196 private Object invokeInternal() throws Exception {
197 Object target = getTarget();
198 String methodName = getMethodName();
199
200 if (target == null || methodName == null) {
201 throw new NullPointerException((target == null ? "target" :
202 "methodName") + " should not be null");
203 }
204
205 Object[] arguments = getArguments();
206 if (arguments == null) {
207 arguments = emptyArray;
208 }
209 // Class.forName() won't load classes outside
210 // of core from a class inside core. Special
211 // case this method.
212 if (target == Class.class && methodName.equals("forName")) {
213 return ClassFinder.resolveClass((String)arguments[0], this.loader);
214 }
215 Class[] argClasses = new Class[arguments.length];
216 for(int i = 0; i < arguments.length; i++) {
217 argClasses[i] = (arguments[i] == null) ? null : arguments[i].getClass();
218 }
219
220 AccessibleObject m = null;
221 if (target instanceof Class) {
222 /*
223 For class methods, simluate the effect of a meta class
224 by taking the union of the static methods of the
225 actual class, with the instance methods of "Class.class"
226 and the overloaded "newInstance" methods defined by the
227 constructors.
228 This way "System.class", for example, will perform both
229 the static method getProperties() and the instance method
230 getSuperclass() defined in "Class.class".
231 */
232 if (methodName.equals("new")) {
233 methodName = "newInstance";
234 }
235 // Provide a short form for array instantiation by faking an nary-constructor.
236 if (methodName.equals("newInstance") && ((Class)target).isArray()) {
237 Object result = Array.newInstance(((Class)target).getComponentType(), arguments.length);
238 for(int i = 0; i < arguments.length; i++) {
239 Array.set(result, i, arguments[i]);
240 }
241 return result;
242 }
243 if (methodName.equals("newInstance") && arguments.length != 0) {
244 // The Character class, as of 1.4, does not have a constructor
245 // which takes a String. All of the other "wrapper" classes
246 // for Java's primitive types have a String constructor so we
247 // fake such a constructor here so that this special case can be
248 // ignored elsewhere.
249 if (target == Character.class && arguments.length == 1 &&
250 argClasses[0] == String.class) {
251 return new Character(((String)arguments[0]).charAt(0));
252 }
253 try {
254 m = ConstructorFinder.findConstructor((Class)target, argClasses);
255 }
256 catch (NoSuchMethodException exception) {
257 m = null;
258 }
259 }
260 if (m == null && target != Class.class) {
261 m = getMethod((Class)target, methodName, argClasses);
262 }
263 if (m == null) {
264 m = getMethod(Class.class, methodName, argClasses);
265 }
266 }
267 else {
268 /*
269 This special casing of arrays is not necessary, but makes files
270 involving arrays much shorter and simplifies the archiving infrastrcure.
271 The Array.set() method introduces an unusual idea - that of a static method
272 changing the state of an instance. Normally statements with side
273 effects on objects are instance methods of the objects themselves
274 and we reinstate this rule (perhaps temporarily) by special-casing arrays.
275 */
276 if (target.getClass().isArray() &&
277 (methodName.equals("set") || methodName.equals("get"))) {
278 int index = ((Integer)arguments[0]).intValue();
279 if (methodName.equals("get")) {
280 return Array.get(target, index);
281 }
282 else {
283 Array.set(target, index, arguments[1]);
284 return null;
285 }
286 }
287 m = getMethod(target.getClass(), methodName, argClasses);
288 }
289 if (m != null) {
290 try {
291 if (m instanceof Method) {
292 return MethodUtil.invoke((Method)m, target, arguments);
293 }
294 else {
295 return ((Constructor)m).newInstance(arguments);
296 }
297 }
298 catch (IllegalAccessException iae) {
299 throw new Exception("Statement cannot invoke: " +
300 methodName + " on " + target.getClass(),
301 iae);
302 }
303 catch (InvocationTargetException ite) {
304 Throwable te = ite.getTargetException();
305 if (te instanceof Exception) {
306 throw (Exception)te;
307 }
308 else {
309 throw ite;
310 }
311 }
312 }
313 throw new NoSuchMethodException(toString());
314 }
315
316 String instanceName(Object instance) {
317 if (instance == null) {
318 return "null";
319 } else if (instance.getClass() == String.class) {
320 return "\""+(String)instance + "\"";
321 } else {
322 // Note: there is a minor problem with using the non-caching
323 // NameGenerator method. The return value will not have
324 // specific information about the inner class name. For example,
325 // In 1.4.2 an inner class would be represented as JList$1 now
326 // would be named Class.
327
328 return NameGenerator.unqualifiedClassName(instance.getClass());
329 }
330 }
331
332 /**
333 * Prints the value of this statement using a Java-style syntax.
334 */
335 public String toString() {
336 // Respect a subclass's implementation here.
337 Object target = getTarget();
338 String methodName = getMethodName();
339 Object[] arguments = getArguments();
340 if (arguments == null) {
341 arguments = emptyArray;
342 }
343 StringBuffer result = new StringBuffer(instanceName(target) + "." + methodName + "(");
344 int n = arguments.length;
345 for(int i = 0; i < n; i++) {
346 result.append(instanceName(arguments[i]));
347 if (i != n -1) {
348 result.append(", ");
349 }
350 }
351 result.append(");");
352 return result.toString();
353 }
354
355 static Method getMethod(Class<?> type, String name, Class<?>... args) {
356 try {
357 return MethodFinder.findMethod(type, name, args);
358 }
359 catch (NoSuchMethodException exception) {
360 return null;
361 }
362 }
363}
java/pkg/java/beans/StaticFieldsPersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/Transient.class+0−0

Binary file not shown.

java/pkg/java/beans/Transient.java+68−0
@@ -0,0 +1,68 @@
1/*
2 * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.beans;
27
28import java.lang.annotation.Retention;
29import java.lang.annotation.Target;
30
31import static java.lang.annotation.ElementType.METHOD;
32import static java.lang.annotation.RetentionPolicy.RUNTIME;
33
34/**
35 * Indicates that an attribute called "transient"
36 * should be declared with the given {@code value}
37 * when the {@link Introspector} constructs
38 * a {@link PropertyDescriptor} or {@link EventSetDescriptor}
39 * classes associated with the annotated code element.
40 * A {@code true} value for the "transient" attribute
41 * indicates to encoders derived from {@link Encoder}
42 * that this feature should be ignored.
43 * <p/>
44 * The {@code Transient} annotation may be be used
45 * in any of the methods that are involved
46 * in a {@link FeatureDescriptor} subclass
47 * to identify the transient feature in the annotated class and its subclasses.
48 * Normally, the method that starts with "get" is the best place
49 * to put the annotation and it is this declaration
50 * that takes precedence in the case of multiple annotations
51 * being defined for the same feature.
52 * <p/>
53 * To declare a feature non-transient in a class
54 * whose superclass declares it transient,
55 * use {@code @Transient(false)}.
56 * In all cases, the {@link Introspector} decides
57 * if a feature is transient by referring to the annotation
58 * on the most specific superclass.
59 * If no {@code Transient} annotation is present
60 * in any superclass the feature is not transient.
61 *
62 * @since 1.7
63 */
64@Target({METHOD})
65@Retention(RUNTIME)
66public @interface Transient {
67 boolean value() default true;
68}
java/pkg/java/beans/VetoableChangeListener.class+0−0

Binary file not shown.

java/pkg/java/beans/VetoableChangeListener.java+44−0
@@ -0,0 +1,44 @@
1/*
2 * Copyright (c) 1996, 1997, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.beans;
27
28/**
29 * A VetoableChange event gets fired whenever a bean changes a "constrained"
30 * property. You can register a VetoableChangeListener with a source bean
31 * so as to be notified of any constrained property updates.
32 */
33public interface VetoableChangeListener extends java.util.EventListener {
34 /**
35 * This method gets called when a constrained property is changed.
36 *
37 * @param evt a <code>PropertyChangeEvent</code> object describing the
38 * event source and the property that has changed.
39 * @exception PropertyVetoException if the recipient wishes the property
40 * change to be rolled back.
41 */
42 void vetoableChange(PropertyChangeEvent evt)
43 throws PropertyVetoException;
44}
java/pkg/java/beans/VetoableChangeListenerProxy.class+0−0

Binary file not shown.

java/pkg/java/beans/VetoableChangeListenerProxy.java+84−0
@@ -0,0 +1,84 @@
1/*
2 * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.beans;
27
28import java.util.EventListenerProxy;
29
30/**
31 * A class which extends the {@code EventListenerProxy}
32 * specifically for adding a {@code VetoableChangeListener}
33 * with a "constrained" property.
34 * Instances of this class can be added
35 * as {@code VetoableChangeListener}s to a bean
36 * which supports firing vetoable change events.
37 * <p>
38 * If the object has a {@code getVetoableChangeListeners} method
39 * then the array returned could be a mixture of {@code VetoableChangeListener}
40 * and {@code VetoableChangeListenerProxy} objects.
41 *
42 * @see java.util.EventListenerProxy
43 * @see VetoableChangeSupport#getVetoableChangeListeners
44 * @since 1.4
45 */
46public class VetoableChangeListenerProxy
47 extends EventListenerProxy<VetoableChangeListener>
48 implements VetoableChangeListener {
49
50 private final String propertyName;
51
52 /**
53 * Constructor which binds the {@code VetoableChangeListener}
54 * to a specific property.
55 *
56 * @param propertyName the name of the property to listen on
57 * @param listener the listener object
58 */
59 public VetoableChangeListenerProxy(String propertyName, VetoableChangeListener listener) {
60 super(listener);
61 this.propertyName = propertyName;
62 }
63
64 /**
65 * Forwards the property change event to the listener delegate.
66 *
67 * @param event the property change event
68 *
69 * @exception PropertyVetoException if the recipient wishes the property
70 * change to be rolled back
71 */
72 public void vetoableChange(PropertyChangeEvent event) throws PropertyVetoException{
73 getListener().vetoableChange(event);
74 }
75
76 /**
77 * Returns the name of the named property associated with the listener.
78 *
79 * @return the name of the named property associated with the listener
80 */
81 public String getPropertyName() {
82 return this.propertyName;
83 }
84}
java/pkg/java/beans/VetoableChangeSupport$1.class+0−0

Binary file not shown.

java/pkg/java/beans/VetoableChangeSupport$VetoableChangeListenerMap.class+0−0

Binary file not shown.

java/pkg/java/beans/VetoableChangeSupport.class+0−0

Binary file not shown.

java/pkg/java/beans/VetoableChangeSupport.java+525−0
@@ -0,0 +1,525 @@
1/*
2 * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25package java.beans;
26
27import java.io.Serializable;
28import java.io.ObjectStreamField;
29import java.io.ObjectOutputStream;
30import java.io.ObjectInputStream;
31import java.io.IOException;
32import java.util.Hashtable;
33import java.util.Map.Entry;
34
35/**
36 * This is a utility class that can be used by beans that support constrained
37 * properties. It manages a list of listeners and dispatches
38 * {@link PropertyChangeEvent}s to them. You can use an instance of this class
39 * as a member field of your bean and delegate these types of work to it.
40 * The {@link VetoableChangeListener} can be registered for all properties
41 * or for a property specified by name.
42 * <p>
43 * Here is an example of {@code VetoableChangeSupport} usage that follows
44 * the rules and recommendations laid out in the JavaBeans&trade; specification:
45 * <pre>
46 * public class MyBean {
47 * private final VetoableChangeSupport vcs = new VetoableChangeSupport(this);
48 *
49 * public void addVetoableChangeListener(VetoableChangeListener listener) {
50 * this.vcs.addVetoableChangeListener(listener);
51 * }
52 *
53 * public void removeVetoableChangeListener(VetoableChangeListener listener) {
54 * this.vcs.removeVetoableChangeListener(listener);
55 * }
56 *
57 * private String value;
58 *
59 * public String getValue() {
60 * return this.value;
61 * }
62 *
63 * public void setValue(String newValue) throws PropertyVetoException {
64 * String oldValue = this.value;
65 * this.vcs.fireVetoableChange("value", oldValue, newValue);
66 * this.value = newValue;
67 * }
68 *
69 * [...]
70 * }
71 * </pre>
72 * <p>
73 * A {@code VetoableChangeSupport} instance is thread-safe.
74 * <p>
75 * This class is serializable. When it is serialized it will save
76 * (and restore) any listeners that are themselves serializable. Any
77 * non-serializable listeners will be skipped during serialization.
78 *
79 * @see PropertyChangeSupport
80 */
81public class VetoableChangeSupport implements Serializable {
82 private VetoableChangeListenerMap map = new VetoableChangeListenerMap();
83
84 /**
85 * Constructs a <code>VetoableChangeSupport</code> object.
86 *
87 * @param sourceBean The bean to be given as the source for any events.
88 */
89 public VetoableChangeSupport(Object sourceBean) {
90 if (sourceBean == null) {
91 throw new NullPointerException();
92 }
93 source = sourceBean;
94 }
95
96 /**
97 * Add a VetoableChangeListener to the listener list.
98 * The listener is registered for all properties.
99 * The same listener object may be added more than once, and will be called
100 * as many times as it is added.
101 * If <code>listener</code> is null, no exception is thrown and no action
102 * is taken.
103 *
104 * @param listener The VetoableChangeListener to be added
105 */
106 public void addVetoableChangeListener(VetoableChangeListener listener) {
107 if (listener == null) {
108 return;
109 }
110 if (listener instanceof VetoableChangeListenerProxy) {
111 VetoableChangeListenerProxy proxy =
112 (VetoableChangeListenerProxy)listener;
113 // Call two argument add method.
114 addVetoableChangeListener(proxy.getPropertyName(),
115 proxy.getListener());
116 } else {
117 this.map.add(null, listener);
118 }
119 }
120
121 /**
122 * Remove a VetoableChangeListener from the listener list.
123 * This removes a VetoableChangeListener that was registered
124 * for all properties.
125 * If <code>listener</code> was added more than once to the same event
126 * source, it will be notified one less time after being removed.
127 * If <code>listener</code> is null, or was never added, no exception is
128 * thrown and no action is taken.
129 *
130 * @param listener The VetoableChangeListener to be removed
131 */
132 public void removeVetoableChangeListener(VetoableChangeListener listener) {
133 if (listener == null) {
134 return;
135 }
136 if (listener instanceof VetoableChangeListenerProxy) {
137 VetoableChangeListenerProxy proxy =
138 (VetoableChangeListenerProxy)listener;
139 // Call two argument remove method.
140 removeVetoableChangeListener(proxy.getPropertyName(),
141 proxy.getListener());
142 } else {
143 this.map.remove(null, listener);
144 }
145 }
146
147 /**
148 * Returns an array of all the listeners that were added to the
149 * VetoableChangeSupport object with addVetoableChangeListener().
150 * <p>
151 * If some listeners have been added with a named property, then
152 * the returned array will be a mixture of VetoableChangeListeners
153 * and <code>VetoableChangeListenerProxy</code>s. If the calling
154 * method is interested in distinguishing the listeners then it must
155 * test each element to see if it's a
156 * <code>VetoableChangeListenerProxy</code>, perform the cast, and examine
157 * the parameter.
158 *
159 * <pre>
160 * VetoableChangeListener[] listeners = bean.getVetoableChangeListeners();
161 * for (int i = 0; i < listeners.length; i++) {
162 * if (listeners[i] instanceof VetoableChangeListenerProxy) {
163 * VetoableChangeListenerProxy proxy =
164 * (VetoableChangeListenerProxy)listeners[i];
165 * if (proxy.getPropertyName().equals("foo")) {
166 * // proxy is a VetoableChangeListener which was associated
167 * // with the property named "foo"
168 * }
169 * }
170 * }
171 *</pre>
172 *
173 * @see VetoableChangeListenerProxy
174 * @return all of the <code>VetoableChangeListeners</code> added or an
175 * empty array if no listeners have been added
176 * @since 1.4
177 */
178 public VetoableChangeListener[] getVetoableChangeListeners(){
179 return this.map.getListeners();
180 }
181
182 /**
183 * Add a VetoableChangeListener for a specific property. The listener
184 * will be invoked only when a call on fireVetoableChange names that
185 * specific property.
186 * The same listener object may be added more than once. For each
187 * property, the listener will be invoked the number of times it was added
188 * for that property.
189 * If <code>propertyName</code> or <code>listener</code> is null, no
190 * exception is thrown and no action is taken.
191 *
192 * @param propertyName The name of the property to listen on.
193 * @param listener The VetoableChangeListener to be added
194 */
195 public void addVetoableChangeListener(
196 String propertyName,
197 VetoableChangeListener listener) {
198 if (listener == null || propertyName == null) {
199 return;
200 }
201 listener = this.map.extract(listener);
202 if (listener != null) {
203 this.map.add(propertyName, listener);
204 }
205 }
206
207 /**
208 * Remove a VetoableChangeListener for a specific property.
209 * If <code>listener</code> was added more than once to the same event
210 * source for the specified property, it will be notified one less time
211 * after being removed.
212 * If <code>propertyName</code> is null, no exception is thrown and no
213 * action is taken.
214 * If <code>listener</code> is null, or was never added for the specified
215 * property, no exception is thrown and no action is taken.
216 *
217 * @param propertyName The name of the property that was listened on.
218 * @param listener The VetoableChangeListener to be removed
219 */
220 public void removeVetoableChangeListener(
221 String propertyName,
222 VetoableChangeListener listener) {
223 if (listener == null || propertyName == null) {
224 return;
225 }
226 listener = this.map.extract(listener);
227 if (listener != null) {
228 this.map.remove(propertyName, listener);
229 }
230 }
231
232 /**
233 * Returns an array of all the listeners which have been associated
234 * with the named property.
235 *
236 * @param propertyName The name of the property being listened to
237 * @return all the <code>VetoableChangeListeners</code> associated with
238 * the named property. If no such listeners have been added,
239 * or if <code>propertyName</code> is null, an empty array is
240 * returned.
241 * @since 1.4
242 */
243 public VetoableChangeListener[] getVetoableChangeListeners(String propertyName) {
244 return this.map.getListeners(propertyName);
245 }
246
247 /**
248 * Reports a constrained property update to listeners
249 * that have been registered to track updates of
250 * all properties or a property with the specified name.
251 * <p>
252 * Any listener can throw a {@code PropertyVetoException} to veto the update.
253 * If one of the listeners vetoes the update, this method passes
254 * a new "undo" {@code PropertyChangeEvent} that reverts to the old value
255 * to all listeners that already confirmed this update
256 * and throws the {@code PropertyVetoException} again.
257 * <p>
258 * No event is fired if old and new values are equal and non-null.
259 * <p>
260 * This is merely a convenience wrapper around the more general
261 * {@link #fireVetoableChange(PropertyChangeEvent)} method.
262 *
263 * @param propertyName the programmatic name of the property that is about to change
264 * @param oldValue the old value of the property
265 * @param newValue the new value of the property
266 * @throws PropertyVetoException if one of listeners vetoes the property update
267 */
268 public void fireVetoableChange(String propertyName, Object oldValue, Object newValue)
269 throws PropertyVetoException {
270 if (oldValue == null || newValue == null || !oldValue.equals(newValue)) {
271 fireVetoableChange(new PropertyChangeEvent(this.source, propertyName, oldValue, newValue));
272 }
273 }
274
275 /**
276 * Reports an integer constrained property update to listeners
277 * that have been registered to track updates of
278 * all properties or a property with the specified name.
279 * <p>
280 * Any listener can throw a {@code PropertyVetoException} to veto the update.
281 * If one of the listeners vetoes the update, this method passes
282 * a new "undo" {@code PropertyChangeEvent} that reverts to the old value
283 * to all listeners that already confirmed this update
284 * and throws the {@code PropertyVetoException} again.
285 * <p>
286 * No event is fired if old and new values are equal.
287 * <p>
288 * This is merely a convenience wrapper around the more general
289 * {@link #fireVetoableChange(String, Object, Object)} method.
290 *
291 * @param propertyName the programmatic name of the property that is about to change
292 * @param oldValue the old value of the property
293 * @param newValue the new value of the property
294 * @throws PropertyVetoException if one of listeners vetoes the property update
295 */
296 public void fireVetoableChange(String propertyName, int oldValue, int newValue)
297 throws PropertyVetoException {
298 if (oldValue != newValue) {
299 fireVetoableChange(propertyName, Integer.valueOf(oldValue), Integer.valueOf(newValue));
300 }
301 }
302
303 /**
304 * Reports a boolean constrained property update to listeners
305 * that have been registered to track updates of
306 * all properties or a property with the specified name.
307 * <p>
308 * Any listener can throw a {@code PropertyVetoException} to veto the update.
309 * If one of the listeners vetoes the update, this method passes
310 * a new "undo" {@code PropertyChangeEvent} that reverts to the old value
311 * to all listeners that already confirmed this update
312 * and throws the {@code PropertyVetoException} again.
313 * <p>
314 * No event is fired if old and new values are equal.
315 * <p>
316 * This is merely a convenience wrapper around the more general
317 * {@link #fireVetoableChange(String, Object, Object)} method.
318 *
319 * @param propertyName the programmatic name of the property that is about to change
320 * @param oldValue the old value of the property
321 * @param newValue the new value of the property
322 * @throws PropertyVetoException if one of listeners vetoes the property update
323 */
324 public void fireVetoableChange(String propertyName, boolean oldValue, boolean newValue)
325 throws PropertyVetoException {
326 if (oldValue != newValue) {
327 fireVetoableChange(propertyName, Boolean.valueOf(oldValue), Boolean.valueOf(newValue));
328 }
329 }
330
331 /**
332 * Fires a property change event to listeners
333 * that have been registered to track updates of
334 * all properties or a property with the specified name.
335 * <p>
336 * Any listener can throw a {@code PropertyVetoException} to veto the update.
337 * If one of the listeners vetoes the update, this method passes
338 * a new "undo" {@code PropertyChangeEvent} that reverts to the old value
339 * to all listeners that already confirmed this update
340 * and throws the {@code PropertyVetoException} again.
341 * <p>
342 * No event is fired if the given event's old and new values are equal and non-null.
343 *
344 * @param event the {@code PropertyChangeEvent} to be fired
345 * @throws PropertyVetoException if one of listeners vetoes the property update
346 */
347 public void fireVetoableChange(PropertyChangeEvent event)
348 throws PropertyVetoException {
349 Object oldValue = event.getOldValue();
350 Object newValue = event.getNewValue();
351 if (oldValue == null || newValue == null || !oldValue.equals(newValue)) {
352 String name = event.getPropertyName();
353
354 VetoableChangeListener[] common = this.map.get(null);
355 VetoableChangeListener[] named = (name != null)
356 ? this.map.get(name)
357 : null;
358
359 VetoableChangeListener[] listeners;
360 if (common == null) {
361 listeners = named;
362 }
363 else if (named == null) {
364 listeners = common;
365 }
366 else {
367 listeners = new VetoableChangeListener[common.length + named.length];
368 System.arraycopy(common, 0, listeners, 0, common.length);
369 System.arraycopy(named, 0, listeners, common.length, named.length);
370 }
371 if (listeners != null) {
372 int current = 0;
373 try {
374 while (current < listeners.length) {
375 listeners[current].vetoableChange(event);
376 current++;
377 }
378 }
379 catch (PropertyVetoException veto) {
380 event = new PropertyChangeEvent(this.source, name, newValue, oldValue);
381 for (int i = 0; i < current; i++) {
382 try {
383 listeners[i].vetoableChange(event);
384 }
385 catch (PropertyVetoException exception) {
386 // ignore exceptions that occur during rolling back
387 }
388 }
389 throw veto; // rethrow the veto exception
390 }
391 }
392 }
393 }
394
395 /**
396 * Check if there are any listeners for a specific property, including
397 * those registered on all properties. If <code>propertyName</code>
398 * is null, only check for listeners registered on all properties.
399 *
400 * @param propertyName the property name.
401 * @return true if there are one or more listeners for the given property
402 */
403 public boolean hasListeners(String propertyName) {
404 return this.map.hasListeners(propertyName);
405 }
406
407 /**
408 * @serialData Null terminated list of <code>VetoableChangeListeners</code>.
409 * <p>
410 * At serialization time we skip non-serializable listeners and
411 * only serialize the serializable listeners.
412 */
413 private void writeObject(ObjectOutputStream s) throws IOException {
414 Hashtable<String, VetoableChangeSupport> children = null;
415 VetoableChangeListener[] listeners = null;
416 synchronized (this.map) {
417 for (Entry<String, VetoableChangeListener[]> entry : this.map.getEntries()) {
418 String property = entry.getKey();
419 if (property == null) {
420 listeners = entry.getValue();
421 } else {
422 if (children == null) {
423 children = new Hashtable<String, VetoableChangeSupport>();
424 }
425 VetoableChangeSupport vcs = new VetoableChangeSupport(this.source);
426 vcs.map.set(null, entry.getValue());
427 children.put(property, vcs);
428 }
429 }
430 }
431 ObjectOutputStream.PutField fields = s.putFields();
432 fields.put("children", children);
433 fields.put("source", this.source);
434 fields.put("vetoableChangeSupportSerializedDataVersion", 2);
435 s.writeFields();
436
437 if (listeners != null) {
438 for (VetoableChangeListener l : listeners) {
439 if (l instanceof Serializable) {
440 s.writeObject(l);
441 }
442 }
443 }
444 s.writeObject(null);
445 }
446
447 private void readObject(ObjectInputStream s) throws ClassNotFoundException, IOException {
448 this.map = new VetoableChangeListenerMap();
449
450 ObjectInputStream.GetField fields = s.readFields();
451
452 Hashtable<String, VetoableChangeSupport> children = (Hashtable<String, VetoableChangeSupport>) fields.get("children", null);
453 this.source = fields.get("source", null);
454 fields.get("vetoableChangeSupportSerializedDataVersion", 2);
455
456 Object listenerOrNull;
457 while (null != (listenerOrNull = s.readObject())) {
458 this.map.add(null, (VetoableChangeListener)listenerOrNull);
459 }
460 if (children != null) {
461 for (Entry<String, VetoableChangeSupport> entry : children.entrySet()) {
462 for (VetoableChangeListener listener : entry.getValue().getVetoableChangeListeners()) {
463 this.map.add(entry.getKey(), listener);
464 }
465 }
466 }
467 }
468
469 /**
470 * The object to be provided as the "source" for any generated events.
471 */
472 private Object source;
473
474 /**
475 * @serialField children Hashtable
476 * @serialField source Object
477 * @serialField vetoableChangeSupportSerializedDataVersion int
478 */
479 private static final ObjectStreamField[] serialPersistentFields = {
480 new ObjectStreamField("children", Hashtable.class),
481 new ObjectStreamField("source", Object.class),
482 new ObjectStreamField("vetoableChangeSupportSerializedDataVersion", Integer.TYPE)
483 };
484
485 /**
486 * Serialization version ID, so we're compatible with JDK 1.1
487 */
488 static final long serialVersionUID = -5090210921595982017L;
489
490 /**
491 * This is a {@link ChangeListenerMap ChangeListenerMap} implementation
492 * that works with {@link VetoableChangeListener VetoableChangeListener} objects.
493 */
494 private static final class VetoableChangeListenerMap extends ChangeListenerMap<VetoableChangeListener> {
495 private static final VetoableChangeListener[] EMPTY = {};
496
497 /**
498 * Creates an array of {@link VetoableChangeListener VetoableChangeListener} objects.
499 * This method uses the same instance of the empty array
500 * when {@code length} equals {@code 0}.
501 *
502 * @param length the array length
503 * @return an array with specified length
504 */
505 @Override
506 protected VetoableChangeListener[] newArray(int length) {
507 return (0 < length)
508 ? new VetoableChangeListener[length]
509 : EMPTY;
510 }
511
512 /**
513 * Creates a {@link VetoableChangeListenerProxy VetoableChangeListenerProxy}
514 * object for the specified property.
515 *
516 * @param name the name of the property to listen on
517 * @param listener the listener to process events
518 * @return a {@code VetoableChangeListenerProxy} object
519 */
520 @Override
521 protected VetoableChangeListener newProxy(String name, VetoableChangeListener listener) {
522 return new VetoableChangeListenerProxy(name, listener);
523 }
524 }
525}
java/pkg/java/beans/Visibility.class+0−0

Binary file not shown.

java/pkg/java/beans/Visibility.java+67−0
@@ -0,0 +1,67 @@
1/*
2 * Copyright (c) 1996, 1998, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.beans;
27
28/**
29 * Under some circumstances a bean may be run on servers where a GUI
30 * is not available. This interface can be used to query a bean to
31 * determine whether it absolutely needs a gui, and to advise the
32 * bean whether a GUI is available.
33 * <p>
34 * This interface is for expert developers, and is not needed
35 * for normal simple beans. To avoid confusing end-users we
36 * avoid using getXXX setXXX design patterns for these methods.
37 */
38
39public interface Visibility {
40
41 /**
42 * Determines whether this bean needs a GUI.
43 *
44 * @return True if the bean absolutely needs a GUI available in
45 * order to get its work done.
46 */
47 boolean needsGui();
48
49 /**
50 * This method instructs the bean that it should not use the Gui.
51 */
52 void dontUseGui();
53
54 /**
55 * This method instructs the bean that it is OK to use the Gui.
56 */
57 void okToUseGui();
58
59 /**
60 * Determines whether this bean is avoiding using a GUI.
61 *
62 * @return true if the bean is currently avoiding use of the Gui.
63 * e.g. due to a call on dontUseGui().
64 */
65 boolean avoidingGui();
66
67}
java/pkg/java/beans/XMLDecoder.class+0−0

Binary file not shown.

java/pkg/java/beans/XMLDecoder.java+294−0
@@ -0,0 +1,294 @@
1/*
2 * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25package java.beans;
26
27import com.sun.beans.decoder.DocumentHandler;
28
29import java.io.Closeable;
30import java.io.InputStream;
31import java.io.IOException;
32
33import org.xml.sax.InputSource;
34import org.xml.sax.helpers.DefaultHandler;
35
36/**
37 * The <code>XMLDecoder</code> class is used to read XML documents
38 * created using the <code>XMLEncoder</code> and is used just like
39 * the <code>ObjectInputStream</code>. For example, one can use
40 * the following fragment to read the first object defined
41 * in an XML document written by the <code>XMLEncoder</code>
42 * class:
43 * <pre>
44 * XMLDecoder d = new XMLDecoder(
45 * new BufferedInputStream(
46 * new FileInputStream("Test.xml")));
47 * Object result = d.readObject();
48 * d.close();
49 * </pre>
50 *
51 *<p>
52 * For more information you might also want to check out
53 * <a
54 href="http://java.sun.com/products/jfc/tsc/articles/persistence3">Long Term Persistence of JavaBeans Components: XML Schema</a>,
55 * an article in <em>The Swing Connection.</em>
56 * @see XMLEncoder
57 * @see java.io.ObjectInputStream
58 *
59 * @since 1.4
60 *
61 * @author Philip Milne
62 */
63public class XMLDecoder implements AutoCloseable {
64 private final DocumentHandler handler = new DocumentHandler();
65 private final InputSource input;
66 private Object owner;
67 private Object[] array;
68 private int index;
69
70 /**
71 * Creates a new input stream for reading archives
72 * created by the <code>XMLEncoder</code> class.
73 *
74 * @param in The underlying stream.
75 *
76 * @see XMLEncoder#XMLEncoder(java.io.OutputStream)
77 */
78 public XMLDecoder(InputStream in) {
79 this(in, null);
80 }
81
82 /**
83 * Creates a new input stream for reading archives
84 * created by the <code>XMLEncoder</code> class.
85 *
86 * @param in The underlying stream.
87 * @param owner The owner of this stream.
88 *
89 */
90 public XMLDecoder(InputStream in, Object owner) {
91 this(in, owner, null);
92 }
93
94 /**
95 * Creates a new input stream for reading archives
96 * created by the <code>XMLEncoder</code> class.
97 *
98 * @param in the underlying stream.
99 * @param owner the owner of this stream.
100 * @param exceptionListener the exception handler for the stream;
101 * if <code>null</code> the default exception listener will be used.
102 */
103 public XMLDecoder(InputStream in, Object owner, ExceptionListener exceptionListener) {
104 this(in, owner, exceptionListener, null);
105 }
106
107 /**
108 * Creates a new input stream for reading archives
109 * created by the <code>XMLEncoder</code> class.
110 *
111 * @param in the underlying stream. <code>null</code> may be passed without
112 * error, though the resulting XMLDecoder will be useless
113 * @param owner the owner of this stream. <code>null</code> is a legal
114 * value
115 * @param exceptionListener the exception handler for the stream, or
116 * <code>null</code> to use the default
117 * @param cl the class loader used for instantiating objects.
118 * <code>null</code> indicates that the default class loader should
119 * be used
120 * @since 1.5
121 */
122 public XMLDecoder(InputStream in, Object owner,
123 ExceptionListener exceptionListener, ClassLoader cl) {
124 this(new InputSource(in), owner, exceptionListener, cl);
125 }
126
127
128 /**
129 * Creates a new decoder to parse XML archives
130 * created by the {@code XMLEncoder} class.
131 * If the input source {@code is} is {@code null},
132 * no exception is thrown and no parsing is performed.
133 * This behavior is similar to behavior of other constructors
134 * that use {@code InputStream} as a parameter.
135 *
136 * @param is the input source to parse
137 *
138 * @since 1.7
139 */
140 public XMLDecoder(InputSource is) {
141 this(is, null, null, null);
142 }
143
144 /**
145 * Creates a new decoder to parse XML archives
146 * created by the {@code XMLEncoder} class.
147 *
148 * @param is the input source to parse
149 * @param owner the owner of this decoder
150 * @param el the exception handler for the parser,
151 * or {@code null} to use the default exception handler
152 * @param cl the class loader used for instantiating objects,
153 * or {@code null} to use the default class loader
154 *
155 * @since 1.7
156 */
157 private XMLDecoder(InputSource is, Object owner, ExceptionListener el, ClassLoader cl) {
158 this.input = is;
159 this.owner = owner;
160 setExceptionListener(el);
161 this.handler.setClassLoader(cl);
162 this.handler.setOwner(this);
163 }
164
165 /**
166 * This method closes the input stream associated
167 * with this stream.
168 */
169 public void close() {
170 if (parsingComplete()) {
171 close(this.input.getCharacterStream());
172 close(this.input.getByteStream());
173 }
174 }
175
176 private void close(Closeable in) {
177 if (in != null) {
178 try {
179 in.close();
180 }
181 catch (IOException e) {
182 getExceptionListener().exceptionThrown(e);
183 }
184 }
185 }
186
187 private boolean parsingComplete() {
188 if (this.input == null) {
189 return false;
190 }
191 if (this.array == null) {
192 this.handler.parse(this.input);
193 this.array = this.handler.getObjects();
194 }
195 return true;
196 }
197
198 /**
199 * Sets the exception handler for this stream to <code>exceptionListener</code>.
200 * The exception handler is notified when this stream catches recoverable
201 * exceptions.
202 *
203 * @param exceptionListener The exception handler for this stream;
204 * if <code>null</code> the default exception listener will be used.
205 *
206 * @see #getExceptionListener
207 */
208 public void setExceptionListener(ExceptionListener exceptionListener) {
209 if (exceptionListener == null) {
210 exceptionListener = Statement.defaultExceptionListener;
211 }
212 this.handler.setExceptionListener(exceptionListener);
213 }
214
215 /**
216 * Gets the exception handler for this stream.
217 *
218 * @return The exception handler for this stream.
219 * Will return the default exception listener if this has not explicitly been set.
220 *
221 * @see #setExceptionListener
222 */
223 public ExceptionListener getExceptionListener() {
224 return this.handler.getExceptionListener();
225 }
226
227 /**
228 * Reads the next object from the underlying input stream.
229 *
230 * @return the next object read
231 *
232 * @throws ArrayIndexOutOfBoundsException if the stream contains no objects
233 * (or no more objects)
234 *
235 * @see XMLEncoder#writeObject
236 */
237 public Object readObject() {
238 return (parsingComplete())
239 ? this.array[this.index++]
240 : null;
241 }
242
243 /**
244 * Sets the owner of this decoder to <code>owner</code>.
245 *
246 * @param owner The owner of this decoder.
247 *
248 * @see #getOwner
249 */
250 public void setOwner(Object owner) {
251 this.owner = owner;
252 }
253
254 /**
255 * Gets the owner of this decoder.
256 *
257 * @return The owner of this decoder.
258 *
259 * @see #setOwner
260 */
261 public Object getOwner() {
262 return owner;
263 }
264
265 /**
266 * Creates a new handler for SAX parser
267 * that can be used to parse embedded XML archives
268 * created by the {@code XMLEncoder} class.
269 *
270 * The {@code owner} should be used if parsed XML document contains
271 * the method call within context of the &lt;java&gt; element.
272 * The {@code null} value may cause illegal parsing in such case.
273 * The same problem may occur, if the {@code owner} class
274 * does not contain expected method to call. See details <a
275 * href="http://java.sun.com/products/jfc/tsc/articles/persistence3/">here</a>.
276 *
277 * @param owner the owner of the default handler
278 * that can be used as a value of &lt;java&gt; element
279 * @param el the exception handler for the parser,
280 * or {@code null} to use the default exception handler
281 * @param cl the class loader used for instantiating objects,
282 * or {@code null} to use the default class loader
283 * @return an instance of {@code DefaultHandler} for SAX parser
284 *
285 * @since 1.7
286 */
287 public static DefaultHandler createHandler(Object owner, ExceptionListener el, ClassLoader cl) {
288 DocumentHandler handler = new DocumentHandler();
289 handler.setOwner(owner);
290 handler.setExceptionListener(el);
291 handler.setClassLoader(cl);
292 return handler;
293 }
294}
java/pkg/java/beans/XMLEncoder$1.class+0−0

Binary file not shown.

java/pkg/java/beans/XMLEncoder$ValueData.class+0−0

Binary file not shown.

java/pkg/java/beans/XMLEncoder.class+0−0

Binary file not shown.

java/pkg/java/beans/XMLEncoder.java+774−0
@@ -0,0 +1,774 @@
1/*
2 * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25package java.beans;
26
27import java.io.*;
28import java.util.*;
29import java.lang.reflect.*;
30import java.nio.charset.Charset;
31import java.nio.charset.CharsetEncoder;
32import java.nio.charset.IllegalCharsetNameException;
33import java.nio.charset.UnsupportedCharsetException;
34
35/**
36 * The <code>XMLEncoder</code> class is a complementary alternative to
37 * the <code>ObjectOutputStream</code> and can used to generate
38 * a textual representation of a <em>JavaBean</em> in the same
39 * way that the <code>ObjectOutputStream</code> can
40 * be used to create binary representation of <code>Serializable</code>
41 * objects. For example, the following fragment can be used to create
42 * a textual representation the supplied <em>JavaBean</em>
43 * and all its properties:
44 * <pre>
45 * XMLEncoder e = new XMLEncoder(
46 * new BufferedOutputStream(
47 * new FileOutputStream("Test.xml")));
48 * e.writeObject(new JButton("Hello, world"));
49 * e.close();
50 * </pre>
51 * Despite the similarity of their APIs, the <code>XMLEncoder</code>
52 * class is exclusively designed for the purpose of archiving graphs
53 * of <em>JavaBean</em>s as textual representations of their public
54 * properties. Like Java source files, documents written this way
55 * have a natural immunity to changes in the implementations of the classes
56 * involved. The <code>ObjectOutputStream</code> continues to be recommended
57 * for interprocess communication and general purpose serialization.
58 * <p>
59 * The <code>XMLEncoder</code> class provides a default denotation for
60 * <em>JavaBean</em>s in which they are represented as XML documents
61 * complying with version 1.0 of the XML specification and the
62 * UTF-8 character encoding of the Unicode/ISO 10646 character set.
63 * The XML documents produced by the <code>XMLEncoder</code> class are:
64 * <ul>
65 * <li>
66 * <em>Portable and version resilient</em>: they have no dependencies
67 * on the private implementation of any class and so, like Java source
68 * files, they may be exchanged between environments which may have
69 * different versions of some of the classes and between VMs from
70 * different vendors.
71 * <li>
72 * <em>Structurally compact</em>: The <code>XMLEncoder</code> class
73 * uses a <em>redundancy elimination</em> algorithm internally so that the
74 * default values of a Bean's properties are not written to the stream.
75 * <li>
76 * <em>Fault tolerant</em>: Non-structural errors in the file,
77 * caused either by damage to the file or by API changes
78 * made to classes in an archive remain localized
79 * so that a reader can report the error and continue to load the parts
80 * of the document which were not affected by the error.
81 * </ul>
82 * <p>
83 * Below is an example of an XML archive containing
84 * some user interface components from the <em>swing</em> toolkit:
85 * <pre>
86 * &lt;?xml version="1.0" encoding="UTF-8"?&gt;
87 * &lt;java version="1.0" class="java.beans.XMLDecoder"&gt;
88 * &lt;object class="javax.swing.JFrame"&gt;
89 * &lt;void property="name"&gt;
90 * &lt;string&gt;frame1&lt;/string&gt;
91 * &lt;/void&gt;
92 * &lt;void property="bounds"&gt;
93 * &lt;object class="java.awt.Rectangle"&gt;
94 * &lt;int&gt;0&lt;/int&gt;
95 * &lt;int&gt;0&lt;/int&gt;
96 * &lt;int&gt;200&lt;/int&gt;
97 * &lt;int&gt;200&lt;/int&gt;
98 * &lt;/object&gt;
99 * &lt;/void&gt;
100 * &lt;void property="contentPane"&gt;
101 * &lt;void method="add"&gt;
102 * &lt;object class="javax.swing.JButton"&gt;
103 * &lt;void property="label"&gt;
104 * &lt;string&gt;Hello&lt;/string&gt;
105 * &lt;/void&gt;
106 * &lt;/object&gt;
107 * &lt;/void&gt;
108 * &lt;/void&gt;
109 * &lt;void property="visible"&gt;
110 * &lt;boolean&gt;true&lt;/boolean&gt;
111 * &lt;/void&gt;
112 * &lt;/object&gt;
113 * &lt;/java&gt;
114 * </pre>
115 * The XML syntax uses the following conventions:
116 * <ul>
117 * <li>
118 * Each element represents a method call.
119 * <li>
120 * The "object" tag denotes an <em>expression</em> whose value is
121 * to be used as the argument to the enclosing element.
122 * <li>
123 * The "void" tag denotes a <em>statement</em> which will
124 * be executed, but whose result will not be used as an
125 * argument to the enclosing method.
126 * <li>
127 * Elements which contain elements use those elements as arguments,
128 * unless they have the tag: "void".
129 * <li>
130 * The name of the method is denoted by the "method" attribute.
131 * <li>
132 * XML's standard "id" and "idref" attributes are used to make
133 * references to previous expressions - so as to deal with
134 * circularities in the object graph.
135 * <li>
136 * The "class" attribute is used to specify the target of a static
137 * method or constructor explicitly; its value being the fully
138 * qualified name of the class.
139 * <li>
140 * Elements with the "void" tag are executed using
141 * the outer context as the target if no target is defined
142 * by a "class" attribute.
143 * <li>
144 * Java's String class is treated specially and is
145 * written &lt;string&gt;Hello, world&lt;/string&gt; where
146 * the characters of the string are converted to bytes
147 * using the UTF-8 character encoding.
148 * </ul>
149 * <p>
150 * Although all object graphs may be written using just these three
151 * tags, the following definitions are included so that common
152 * data structures can be expressed more concisely:
153 * <p>
154 * <ul>
155 * <li>
156 * The default method name is "new".
157 * <li>
158 * A reference to a java class is written in the form
159 * &lt;class&gt;javax.swing.JButton&lt;/class&gt;.
160 * <li>
161 * Instances of the wrapper classes for Java's primitive types are written
162 * using the name of the primitive type as the tag. For example, an
163 * instance of the <code>Integer</code> class could be written:
164 * &lt;int&gt;123&lt;/int&gt;. Note that the <code>XMLEncoder</code> class
165 * uses Java's reflection package in which the conversion between
166 * Java's primitive types and their associated "wrapper classes"
167 * is handled internally. The API for the <code>XMLEncoder</code> class
168 * itself deals only with <code>Object</code>s.
169 * <li>
170 * In an element representing a nullary method whose name
171 * starts with "get", the "method" attribute is replaced
172 * with a "property" attribute whose value is given by removing
173 * the "get" prefix and decapitalizing the result.
174 * <li>
175 * In an element representing a monadic method whose name
176 * starts with "set", the "method" attribute is replaced
177 * with a "property" attribute whose value is given by removing
178 * the "set" prefix and decapitalizing the result.
179 * <li>
180 * In an element representing a method named "get" taking one
181 * integer argument, the "method" attribute is replaced
182 * with an "index" attribute whose value the value of the
183 * first argument.
184 * <li>
185 * In an element representing a method named "set" taking two arguments,
186 * the first of which is an integer, the "method" attribute is replaced
187 * with an "index" attribute whose value the value of the
188 * first argument.
189 * <li>
190 * A reference to an array is written using the "array"
191 * tag. The "class" and "length" attributes specify the
192 * sub-type of the array and its length respectively.
193 * </ul>
194 *
195 *<p>
196 * For more information you might also want to check out
197 * <a
198 href="http://java.sun.com/products/jfc/tsc/articles/persistence4">Using XMLEncoder</a>,
199 * an article in <em>The Swing Connection.</em>
200 * @see XMLDecoder
201 * @see java.io.ObjectOutputStream
202 *
203 * @since 1.4
204 *
205 * @author Philip Milne
206 */
207public class XMLEncoder extends Encoder implements AutoCloseable {
208
209 private final CharsetEncoder encoder;
210 private final String charset;
211 private final boolean declaration;
212
213 private OutputStreamWriter out;
214 private Object owner;
215 private int indentation = 0;
216 private boolean internal = false;
217 private Map<Object, ValueData> valueToExpression;
218 private Map<Object, List<Statement>> targetToStatementList;
219 private boolean preambleWritten = false;
220 private NameGenerator nameGenerator;
221
222 private class ValueData {
223 public int refs = 0;
224 public boolean marked = false; // Marked -> refs > 0 unless ref was a target.
225 public String name = null;
226 public Expression exp = null;
227 }
228
229 /**
230 * Creates a new XML encoder to write out <em>JavaBeans</em>
231 * to the stream <code>out</code> using an XML encoding.
232 *
233 * @param out the stream to which the XML representation of
234 * the objects will be written
235 *
236 * @throws IllegalArgumentException
237 * if <code>out</code> is <code>null</code>
238 *
239 * @see XMLDecoder#XMLDecoder(InputStream)
240 */
241 public XMLEncoder(OutputStream out) {
242 this(out, "UTF-8", true, 0);
243 }
244
245 /**
246 * Creates a new XML encoder to write out <em>JavaBeans</em>
247 * to the stream <code>out</code> using the given <code>charset</code>
248 * starting from the given <code>indentation</code>.
249 *
250 * @param out the stream to which the XML representation of
251 * the objects will be written
252 * @param charset the name of the requested charset;
253 * may be either a canonical name or an alias
254 * @param declaration whether the XML declaration should be generated;
255 * set this to <code>false</code>
256 * when embedding the contents in another XML document
257 * @param indentation the number of space characters to indent the entire XML document by
258 *
259 * @throws IllegalArgumentException
260 * if <code>out</code> or <code>charset</code> is <code>null</code>,
261 * or if <code>indentation</code> is less than 0
262 *
263 * @throws IllegalCharsetNameException
264 * if <code>charset</code> name is illegal
265 *
266 * @throws UnsupportedCharsetException
267 * if no support for the named charset is available
268 * in this instance of the Java virtual machine
269 *
270 * @throws UnsupportedOperationException
271 * if loaded charset does not support encoding
272 *
273 * @see Charset#forName(String)
274 *
275 * @since 1.7
276 */
277 public XMLEncoder(OutputStream out, String charset, boolean declaration, int indentation) {
278 if (out == null) {
279 throw new IllegalArgumentException("the output stream cannot be null");
280 }
281 if (indentation < 0) {
282 throw new IllegalArgumentException("the indentation must be >= 0");
283 }
284 Charset cs = Charset.forName(charset);
285 this.encoder = cs.newEncoder();
286 this.charset = charset;
287 this.declaration = declaration;
288 this.indentation = indentation;
289 this.out = new OutputStreamWriter(out, cs.newEncoder());
290 valueToExpression = new IdentityHashMap<Object, ValueData>();
291 targetToStatementList = new IdentityHashMap<Object, List<Statement>>();
292 nameGenerator = new NameGenerator();
293 }
294
295 /**
296 * Sets the owner of this encoder to <code>owner</code>.
297 *
298 * @param owner The owner of this encoder.
299 *
300 * @see #getOwner
301 */
302 public void setOwner(Object owner) {
303 this.owner = owner;
304 writeExpression(new Expression(this, "getOwner", new Object[0]));
305 }
306
307 /**
308 * Gets the owner of this encoder.
309 *
310 * @return The owner of this encoder.
311 *
312 * @see #setOwner
313 */
314 public Object getOwner() {
315 return owner;
316 }
317
318 /**
319 * Write an XML representation of the specified object to the output.
320 *
321 * @param o The object to be written to the stream.
322 *
323 * @see XMLDecoder#readObject
324 */
325 public void writeObject(Object o) {
326 if (internal) {
327 super.writeObject(o);
328 }
329 else {
330 writeStatement(new Statement(this, "writeObject", new Object[]{o}));
331 }
332 }
333
334 private List<Statement> statementList(Object target) {
335 List<Statement> list = targetToStatementList.get(target);
336 if (list == null) {
337 list = new ArrayList<Statement>();
338 targetToStatementList.put(target, list);
339 }
340 return list;
341 }
342
343
344 private void mark(Object o, boolean isArgument) {
345 if (o == null || o == this) {
346 return;
347 }
348 ValueData d = getValueData(o);
349 Expression exp = d.exp;
350 // Do not mark liternal strings. Other strings, which might,
351 // for example, come from resource bundles should still be marked.
352 if (o.getClass() == String.class && exp == null) {
353 return;
354 }
355
356 // Bump the reference counts of all arguments
357 if (isArgument) {
358 d.refs++;
359 }
360 if (d.marked) {
361 return;
362 }
363 d.marked = true;
364 Object target = exp.getTarget();
365 mark(exp);
366 if (!(target instanceof Class)) {
367 statementList(target).add(exp);
368 // Pending: Why does the reference count need to
369 // be incremented here?
370 d.refs++;
371 }
372 }
373
374 private void mark(Statement stm) {
375 Object[] args = stm.getArguments();
376 for (int i = 0; i < args.length; i++) {
377 Object arg = args[i];
378 mark(arg, true);
379 }
380 mark(stm.getTarget(), false);
381 }
382
383
384 /**
385 * Records the Statement so that the Encoder will
386 * produce the actual output when the stream is flushed.
387 * <P>
388 * This method should only be invoked within the context
389 * of initializing a persistence delegate.
390 *
391 * @param oldStm The statement that will be written
392 * to the stream.
393 * @see java.beans.PersistenceDelegate#initialize
394 */
395 public void writeStatement(Statement oldStm) {
396 // System.out.println("XMLEncoder::writeStatement: " + oldStm);
397 boolean internal = this.internal;
398 this.internal = true;
399 try {
400 super.writeStatement(oldStm);
401 /*
402 Note we must do the mark first as we may
403 require the results of previous values in
404 this context for this statement.
405 Test case is:
406 os.setOwner(this);
407 os.writeObject(this);
408 */
409 mark(oldStm);
410 Object target = oldStm.getTarget();
411 if (target instanceof Field) {
412 String method = oldStm.getMethodName();
413 Object[] args = oldStm.getArguments();
414 if ((method == null) || (args == null)) {
415 }
416 else if (method.equals("get") && (args.length == 1)) {
417 target = args[0];
418 }
419 else if (method.equals("set") && (args.length == 2)) {
420 target = args[0];
421 }
422 }
423 statementList(target).add(oldStm);
424 }
425 catch (Exception e) {
426 getExceptionListener().exceptionThrown(new Exception("XMLEncoder: discarding statement " + oldStm, e));
427 }
428 this.internal = internal;
429 }
430
431
432 /**
433 * Records the Expression so that the Encoder will
434 * produce the actual output when the stream is flushed.
435 * <P>
436 * This method should only be invoked within the context of
437 * initializing a persistence delegate or setting up an encoder to
438 * read from a resource bundle.
439 * <P>
440 * For more information about using resource bundles with the
441 * XMLEncoder, see
442 * http://java.sun.com/products/jfc/tsc/articles/persistence4/#i18n
443 *
444 * @param oldExp The expression that will be written
445 * to the stream.
446 * @see java.beans.PersistenceDelegate#initialize
447 */
448 public void writeExpression(Expression oldExp) {
449 boolean internal = this.internal;
450 this.internal = true;
451 Object oldValue = getValue(oldExp);
452 if (get(oldValue) == null || (oldValue instanceof String && !internal)) {
453 getValueData(oldValue).exp = oldExp;
454 super.writeExpression(oldExp);
455 }
456 this.internal = internal;
457 }
458
459 /**
460 * This method writes out the preamble associated with the
461 * XML encoding if it has not been written already and
462 * then writes out all of the values that been
463 * written to the stream since the last time <code>flush</code>
464 * was called. After flushing, all internal references to the
465 * values that were written to this stream are cleared.
466 */
467 public void flush() {
468 if (!preambleWritten) { // Don't do this in constructor - it throws ... pending.
469 if (this.declaration) {
470 writeln("<?xml version=" + quote("1.0") +
471 " encoding=" + quote(this.charset) + "?>");
472 }
473 writeln("<java version=" + quote(System.getProperty("java.version")) +
474 " class=" + quote(XMLDecoder.class.getName()) + ">");
475 preambleWritten = true;
476 }
477 indentation++;
478 List<Statement> statements = statementList(this);
479 while (!statements.isEmpty()) {
480 Statement s = statements.remove(0);
481 if ("writeObject".equals(s.getMethodName())) {
482 outputValue(s.getArguments()[0], this, true);
483 }
484 else {
485 outputStatement(s, this, false);
486 }
487 }
488 indentation--;
489
490 try {
491 out.flush();
492 }
493 catch (IOException e) {
494 getExceptionListener().exceptionThrown(e);
495 }
496 clear();
497 }
498
499 void clear() {
500 super.clear();
501 nameGenerator.clear();
502 valueToExpression.clear();
503 targetToStatementList.clear();
504 }
505
506
507 /**
508 * This method calls <code>flush</code>, writes the closing
509 * postamble and then closes the output stream associated
510 * with this stream.
511 */
512 public void close() {
513 flush();
514 writeln("</java>");
515 try {
516 out.close();
517 }
518 catch (IOException e) {
519 getExceptionListener().exceptionThrown(e);
520 }
521 }
522
523 private String quote(String s) {
524 return "\"" + s + "\"";
525 }
526
527 private ValueData getValueData(Object o) {
528 ValueData d = valueToExpression.get(o);
529 if (d == null) {
530 d = new ValueData();
531 valueToExpression.put(o, d);
532 }
533 return d;
534 }
535
536 /**
537 * Returns <code>true</code> if the argument,
538 * a Unicode code point, is valid in XML documents.
539 * Unicode characters fit into the low sixteen bits of a Unicode code point,
540 * and pairs of Unicode <em>surrogate characters</em> can be combined
541 * to encode Unicode code point in documents containing only Unicode.
542 * (The <code>char</code> datatype in the Java Programming Language
543 * represents Unicode characters, including unpaired surrogates.)
544 * <par>
545 * [2] Char ::= #x0009 | #x000A | #x000D
546 * | [#x0020-#xD7FF]
547 * | [#xE000-#xFFFD]
548 * | [#x10000-#x10ffff]
549 * </par>
550 *
551 * @param code the 32-bit Unicode code point being tested
552 * @return <code>true</code> if the Unicode code point is valid,
553 * <code>false</code> otherwise
554 */
555 private static boolean isValidCharCode(int code) {
556 return (0x0020 <= code && code <= 0xD7FF)
557 || (0x000A == code)
558 || (0x0009 == code)
559 || (0x000D == code)
560 || (0xE000 <= code && code <= 0xFFFD)
561 || (0x10000 <= code && code <= 0x10ffff);
562 }
563
564 private void writeln(String exp) {
565 try {
566 StringBuilder sb = new StringBuilder();
567 for(int i = 0; i < indentation; i++) {
568 sb.append(' ');
569 }
570 sb.append(exp);
571 sb.append('\n');
572 this.out.write(sb.toString());
573 }
574 catch (IOException e) {
575 getExceptionListener().exceptionThrown(e);
576 }
577 }
578
579 private void outputValue(Object value, Object outer, boolean isArgument) {
580 if (value == null) {
581 writeln("<null/>");
582 return;
583 }
584
585 if (value instanceof Class) {
586 writeln("<class>" + ((Class)value).getName() + "</class>");
587 return;
588 }
589
590 ValueData d = getValueData(value);
591 if (d.exp != null) {
592 Object target = d.exp.getTarget();
593 String methodName = d.exp.getMethodName();
594
595 if (target == null || methodName == null) {
596 throw new NullPointerException((target == null ? "target" :
597 "methodName") + " should not be null");
598 }
599
600 if (target instanceof Field && methodName.equals("get")) {
601 Field f = (Field)target;
602 writeln("<object class=" + quote(f.getDeclaringClass().getName()) +
603 " field=" + quote(f.getName()) + "/>");
604 return;
605 }
606
607 Class primitiveType = ReflectionUtils.primitiveTypeFor(value.getClass());
608 if (primitiveType != null && target == value.getClass() &&
609 methodName.equals("new")) {
610 String primitiveTypeName = primitiveType.getName();
611 // Make sure that character types are quoted correctly.
612 if (primitiveType == Character.TYPE) {
613 char code = ((Character) value).charValue();
614 if (!isValidCharCode(code)) {
615 writeln(createString(code));
616 return;
617 }
618 value = quoteCharCode(code);
619 if (value == null) {
620 value = Character.valueOf(code);
621 }
622 }
623 writeln("<" + primitiveTypeName + ">" + value + "</" +
624 primitiveTypeName + ">");
625 return;
626 }
627
628 } else if (value instanceof String) {
629 writeln(createString((String) value));
630 return;
631 }
632
633 if (d.name != null) {
634 outputXML(isArgument ? "object" : "void", " idref=" + quote(d.name), value);
635 }
636 else if (d.exp != null) {
637 outputStatement(d.exp, outer, isArgument);
638 }
639 }
640
641 private static String quoteCharCode(int code) {
642 switch(code) {
643 case '&': return "&amp;";
644 case '<': return "&lt;";
645 case '>': return "&gt;";
646 case '"': return "&quot;";
647 case '\'': return "&apos;";
648 case '\r': return "&#13;";
649 default: return null;
650 }
651 }
652
653 private static String createString(int code) {
654 return "<char code=\"#" + Integer.toString(code, 16) + "\"/>";
655 }
656
657 private String createString(String string) {
658 StringBuilder sb = new StringBuilder();
659 sb.append("<string>");
660 int index = 0;
661 while (index < string.length()) {
662 int point = string.codePointAt(index);
663 int count = Character.charCount(point);
664
665 if (isValidCharCode(point) && this.encoder.canEncode(string.substring(index, index + count))) {
666 String value = quoteCharCode(point);
667 if (value != null) {
668 sb.append(value);
669 } else {
670 sb.appendCodePoint(point);
671 }
672 index += count;
673 } else {
674 sb.append(createString(string.charAt(index)));
675 index++;
676 }
677 }
678 sb.append("</string>");
679 return sb.toString();
680 }
681
682 private void outputStatement(Statement exp, Object outer, boolean isArgument) {
683 Object target = exp.getTarget();
684 String methodName = exp.getMethodName();
685
686 if (target == null || methodName == null) {
687 throw new NullPointerException((target == null ? "target" :
688 "methodName") + " should not be null");
689 }
690
691 Object[] args = exp.getArguments();
692 boolean expression = exp.getClass() == Expression.class;
693 Object value = (expression) ? getValue((Expression)exp) : null;
694
695 String tag = (expression && isArgument) ? "object" : "void";
696 String attributes = "";
697 ValueData d = getValueData(value);
698
699 // Special cases for targets.
700 if (target == outer) {
701 }
702 else if (target == Array.class && methodName.equals("newInstance")) {
703 tag = "array";
704 attributes = attributes + " class=" + quote(((Class)args[0]).getName());
705 attributes = attributes + " length=" + quote(args[1].toString());
706 args = new Object[]{};
707 }
708 else if (target.getClass() == Class.class) {
709 attributes = attributes + " class=" + quote(((Class)target).getName());
710 }
711 else {
712 d.refs = 2;
713 getValueData(target).refs++;
714 List<Statement> statements = statementList(target);
715 if (!statements.contains(exp)) {
716 statements.add(exp);
717 }
718 outputValue(target, outer, false);
719 if (expression) {
720 outputValue(value, outer, isArgument);
721 }
722 return;
723 }
724 if (expression && (d.refs > 1)) {
725 String instanceName = nameGenerator.instanceName(value);
726 d.name = instanceName;
727 attributes = attributes + " id=" + quote(instanceName);
728 }
729
730 // Special cases for methods.
731 if ((!expression && methodName.equals("set") && args.length == 2 &&
732 args[0] instanceof Integer) ||
733 (expression && methodName.equals("get") && args.length == 1 &&
734 args[0] instanceof Integer)) {
735 attributes = attributes + " index=" + quote(args[0].toString());
736 args = (args.length == 1) ? new Object[]{} : new Object[]{args[1]};
737 }
738 else if ((!expression && methodName.startsWith("set") && args.length == 1) ||
739 (expression && methodName.startsWith("get") && args.length == 0)) {
740 if (3 < methodName.length()) {
741 attributes = attributes + " property=" +
742 quote(Introspector.decapitalize(methodName.substring(3)));
743 }
744 }
745 else if (!methodName.equals("new") && !methodName.equals("newInstance")) {
746 attributes = attributes + " method=" + quote(methodName);
747 }
748 outputXML(tag, attributes, value, args);
749 }
750
751 private void outputXML(String tag, String attributes, Object value, Object... args) {
752 List<Statement> statements = statementList(value);
753 // Use XML's short form when there is no body.
754 if (args.length == 0 && statements.size() == 0) {
755 writeln("<" + tag + attributes + "/>");
756 return;
757 }
758
759 writeln("<" + tag + attributes + ">");
760 indentation++;
761
762 for(int i = 0; i < args.length; i++) {
763 outputValue(args[i], null, true);
764 }
765
766 while (!statements.isEmpty()) {
767 Statement s = statements.remove(0);
768 outputStatement(s, value, false);
769 }
770
771 indentation--;
772 writeln("</" + tag + ">");
773 }
774}
java/pkg/java/beans/beancontext/BeanContext.class+0−0

Binary file not shown.

java/pkg/java/beans/beancontext/BeanContext.java+132−0
@@ -0,0 +1,132 @@
1/*
2 * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.beans.beancontext;
27
28import java.beans.DesignMode;
29import java.beans.Visibility;
30
31import java.io.InputStream;
32import java.io.IOException;
33
34import java.net.URL;
35
36import java.util.Collection;
37import java.util.Locale;
38
39/**
40 * <p>
41 * The BeanContext acts a logical hierarchical container for JavaBeans.
42 * </p>
43 *
44 * @author Laurence P. G. Cable
45 * @since 1.2
46 *
47 * @see java.beans.Beans
48 * @see java.beans.beancontext.BeanContextChild
49 * @see java.beans.beancontext.BeanContextMembershipListener
50 * @see java.beans.PropertyChangeEvent
51 * @see java.beans.DesignMode
52 * @see java.beans.Visibility
53 * @see java.util.Collection
54 */
55
56public interface BeanContext extends BeanContextChild, Collection, DesignMode, Visibility {
57
58 /**
59 * Instantiate the javaBean named as a
60 * child of this <code>BeanContext</code>.
61 * The implementation of the JavaBean is
62 * derived from the value of the beanName parameter,
63 * and is defined by the
64 * <code>java.beans.Beans.instantiate()</code> method.
65 *
66 * @param beanName The name of the JavaBean to instantiate
67 * as a child of this <code>BeanContext</code>
68 * @throws <code>IOException</code>
69 * @throws <code>ClassNotFoundException</code> if the class identified
70 * by the beanName parameter is not found
71 */
72 Object instantiateChild(String beanName) throws IOException, ClassNotFoundException;
73
74 /**
75 * Analagous to <code>java.lang.ClassLoader.getResourceAsStream()</code>,
76 * this method allows a <code>BeanContext</code> implementation
77 * to interpose behavior between the child <code>Component</code>
78 * and underlying <code>ClassLoader</code>.
79 *
80 * @param name the resource name
81 * @param bcc the specified child
82 * @return an <code>InputStream</code> for reading the resource,
83 * or <code>null</code> if the resource could not
84 * be found.
85 * @throws <code>IllegalArgumentException</code> if
86 * the resource is not valid
87 */
88 InputStream getResourceAsStream(String name, BeanContextChild bcc) throws IllegalArgumentException;
89
90 /**
91 * Analagous to <code>java.lang.ClassLoader.getResource()</code>, this
92 * method allows a <code>BeanContext</code> implementation to interpose
93 * behavior between the child <code>Component</code>
94 * and underlying <code>ClassLoader</code>.
95 *
96 * @param name the resource name
97 * @param bcc the specified child
98 * @return a <code>URL</code> for the named
99 * resource for the specified child
100 * @throws <code>IllegalArgumentException</code>
101 * if the resource is not valid
102 */
103 URL getResource(String name, BeanContextChild bcc) throws IllegalArgumentException;
104
105 /**
106 * Adds the specified <code>BeanContextMembershipListener</code>
107 * to receive <code>BeanContextMembershipEvents</code> from
108 * this <code>BeanContext</code> whenever it adds
109 * or removes a child <code>Component</code>(s).
110 *
111 * @param bcml the <code>BeanContextMembershipListener</code> to be added
112 */
113 void addBeanContextMembershipListener(BeanContextMembershipListener bcml);
114
115 /**
116 * Removes the specified <code>BeanContextMembershipListener</code>
117 * so that it no longer receives <code>BeanContextMembershipEvent</code>s
118 * when the child <code>Component</code>(s) are added or removed.
119 *
120 * @param bcml the <code>BeanContextMembershipListener</code>
121 * to be removed
122 */
123 void removeBeanContextMembershipListener(BeanContextMembershipListener bcml);
124
125 /**
126 * This global lock is used by both <code>BeanContext</code>
127 * and <code>BeanContextServices</code> implementors
128 * to serialize changes in a <code>BeanContext</code>
129 * hierarchy and any service requests etc.
130 */
131 public static final Object globalHierarchyLock = new Object();
132}
java/pkg/java/beans/beancontext/BeanContextChild.class+0−0

Binary file not shown.

java/pkg/java/beans/beancontext/BeanContextChild.java+137−0
@@ -0,0 +1,137 @@
1/*
2 * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.beans.beancontext;
27
28import java.beans.PropertyChangeListener;
29import java.beans.VetoableChangeListener;
30import java.beans.PropertyVetoException;
31
32import java.beans.beancontext.BeanContext;
33
34/**
35 * <p>
36 * JavaBeans wishing to be nested within, and obtain a reference to their
37 * execution environment, or context, as defined by the BeanContext
38 * sub-interface shall implement this interface.
39 * </p>
40 * <p>
41 * Conformant BeanContexts shall as a side effect of adding a BeanContextChild
42 * object shall pass a reference to itself via the setBeanContext() method of
43 * this interface.
44 * </p>
45 * <p>
46 * Note that a BeanContextChild may refuse a change in state by throwing
47 * PropertyVetoedException in response.
48 * </p>
49 * <p>
50 * In order for persistence mechanisms to function properly on BeanContextChild
51 * instances across a broad variety of scenarios, implementing classes of this
52 * interface are required to define as transient, any or all fields, or
53 * instance variables, that may contain, or represent, references to the
54 * nesting BeanContext instance or other resources obtained
55 * from the BeanContext via any unspecified mechanisms.
56 * </p>
57 *
58 * @author Laurence P. G. Cable
59 * @since 1.2
60 *
61 * @see java.beans.beancontext.BeanContext
62 * @see java.beans.PropertyChangeEvent
63 * @see java.beans.PropertyChangeListener
64 * @see java.beans.PropertyVetoException
65 * @see java.beans.VetoableChangeListener
66 */
67
68public interface BeanContextChild {
69
70 /**
71 * <p>
72 * Objects that implement this interface,
73 * shall fire a java.beans.PropertyChangeEvent, with parameters:
74 *
75 * propertyName "beanContext", oldValue (the previous nesting
76 * <code>BeanContext</code> instance, or <code>null</code>),
77 * newValue (the current nesting
78 * <code>BeanContext</code> instance, or <code>null</code>).
79 * <p>
80 * A change in the value of the nesting BeanContext property of this
81 * BeanContextChild may be vetoed by throwing the appropriate exception.
82 * </p>
83 * @param bc The <code>BeanContext</code> with which
84 * to associate this <code>BeanContextChild</code>.
85 * @throws <code>PropertyVetoException</code> if the
86 * addition of the specified <code>BeanContext</code> is refused.
87 */
88 void setBeanContext(BeanContext bc) throws PropertyVetoException;
89
90 /**
91 * Gets the <code>BeanContext</code> associated
92 * with this <code>BeanContextChild</code>.
93 * @return the <code>BeanContext</code> associated
94 * with this <code>BeanContextChild</code>.
95 */
96 BeanContext getBeanContext();
97
98 /**
99 * Adds a <code>PropertyChangeListener</code>
100 * to this <code>BeanContextChild</code>
101 * in order to receive a <code>PropertyChangeEvent</code>
102 * whenever the specified property has changed.
103 * @param name the name of the property to listen on
104 * @param pcl the <code>PropertyChangeListener</code> to add
105 */
106 void addPropertyChangeListener(String name, PropertyChangeListener pcl);
107
108 /**
109 * Removes a <code>PropertyChangeListener</code> from this
110 * <code>BeanContextChild</code> so that it no longer
111 * receives <code>PropertyChangeEvents</code> when the
112 * specified property is changed.
113 *
114 * @param name the name of the property that was listened on
115 * @param pcl the <code>PropertyChangeListener</code> to remove
116 */
117 void removePropertyChangeListener(String name, PropertyChangeListener pcl);
118
119 /**
120 * Adds a <code>VetoableChangeListener</code> to
121 * this <code>BeanContextChild</code>
122 * to receive events whenever the specified property changes.
123 * @param name the name of the property to listen on
124 * @param vcl the <code>VetoableChangeListener</code> to add
125 */
126 void addVetoableChangeListener(String name, VetoableChangeListener vcl);
127
128 /**
129 * Removes a <code>VetoableChangeListener</code> from this
130 * <code>BeanContextChild</code> so that it no longer receives
131 * events when the specified property changes.
132 * @param name the name of the property that was listened on.
133 * @param vcl the <code>VetoableChangeListener</code> to remove.
134 */
135 void removeVetoableChangeListener(String name, VetoableChangeListener vcl);
136
137}
java/pkg/java/beans/beancontext/BeanContextChildComponentProxy.class+0−0

Binary file not shown.

java/pkg/java/beans/beancontext/BeanContextChildComponentProxy.java+54−0
@@ -0,0 +1,54 @@
1/*
2 * Copyright (c) 1998, 2002, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.beans.beancontext;
27
28import java.awt.Component;
29
30/**
31 * <p>
32 * This interface is implemented by
33 * <code>BeanContextChildren</code> that have an AWT <code>Component</code>
34 * associated with them.
35 * </p>
36 *
37 * @author Laurence P. G. Cable
38 * @since 1.2
39 *
40 * @see java.beans.beancontext.BeanContext
41 * @see java.beans.beancontext.BeanContextSupport
42 */
43
44public interface BeanContextChildComponentProxy {
45
46 /**
47 * Gets the <code>java.awt.Component</code> associated with
48 * this <code>BeanContextChild</code>.
49 * @return the AWT <code>Component</code> associated with
50 * this <code>BeanContextChild</code>
51 */
52
53 Component getComponent();
54}
java/pkg/java/beans/beancontext/BeanContextChildSupport.class+0−0

Binary file not shown.

java/pkg/java/beans/beancontext/BeanContextChildSupport.java+373−0
@@ -0,0 +1,373 @@
1/*
2 * Copyright (c) 1998, 2004, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.beans.beancontext;
27
28import java.beans.PropertyChangeEvent;
29import java.beans.PropertyChangeListener;
30import java.beans.PropertyChangeSupport;
31
32import java.beans.VetoableChangeListener;
33import java.beans.VetoableChangeSupport;
34
35import java.beans.PropertyVetoException;
36
37import java.io.IOException;
38import java.io.ObjectInputStream;
39import java.io.ObjectOutputStream;
40import java.io.Serializable;
41
42/**
43 * <p>
44 * This is a general support class to provide support for implementing the
45 * BeanContextChild protocol.
46 *
47 * This class may either be directly subclassed, or encapsulated and delegated
48 * to in order to implement this interface for a given component.
49 * </p>
50 *
51 * @author Laurence P. G. Cable
52 * @since 1.2
53 *
54 * @see java.beans.beancontext.BeanContext
55 * @see java.beans.beancontext.BeanContextServices
56 * @see java.beans.beancontext.BeanContextChild
57 */
58
59public class BeanContextChildSupport implements BeanContextChild, BeanContextServicesListener, Serializable {
60
61 static final long serialVersionUID = 6328947014421475877L;
62
63 /**
64 * construct a BeanContextChildSupport where this class has been
65 * subclassed in order to implement the JavaBean component itself.
66 */
67
68 public BeanContextChildSupport() {
69 super();
70
71 beanContextChildPeer = this;
72
73 pcSupport = new PropertyChangeSupport(beanContextChildPeer);
74 vcSupport = new VetoableChangeSupport(beanContextChildPeer);
75 }
76
77 /**
78 * construct a BeanContextChildSupport where the JavaBean component
79 * itself implements BeanContextChild, and encapsulates this, delegating
80 * that interface to this implementation
81 */
82
83 public BeanContextChildSupport(BeanContextChild bcc) {
84 super();
85
86 beanContextChildPeer = (bcc != null) ? bcc : this;
87
88 pcSupport = new PropertyChangeSupport(beanContextChildPeer);
89 vcSupport = new VetoableChangeSupport(beanContextChildPeer);
90 }
91
92 /**
93 * Sets the <code>BeanContext</code> for
94 * this <code>BeanContextChildSupport</code>.
95 * @param bc the new value to be assigned to the <code>BeanContext</code>
96 * property
97 * @throws <code>PropertyVetoException</code> if the change is rejected
98 */
99 public synchronized void setBeanContext(BeanContext bc) throws PropertyVetoException {
100 if (bc == beanContext) return;
101
102 BeanContext oldValue = beanContext;
103 BeanContext newValue = bc;
104
105 if (!rejectedSetBCOnce) {
106 if (rejectedSetBCOnce = !validatePendingSetBeanContext(bc)) {
107 throw new PropertyVetoException(
108 "setBeanContext() change rejected:",
109 new PropertyChangeEvent(beanContextChildPeer, "beanContext", oldValue, newValue)
110 );
111 }
112
113 try {
114 fireVetoableChange("beanContext",
115 oldValue,
116 newValue
117 );
118 } catch (PropertyVetoException pve) {
119 rejectedSetBCOnce = true;
120
121 throw pve; // re-throw
122 }
123 }
124
125 if (beanContext != null) releaseBeanContextResources();
126
127 beanContext = newValue;
128 rejectedSetBCOnce = false;
129
130 firePropertyChange("beanContext",
131 oldValue,
132 newValue
133 );
134
135 if (beanContext != null) initializeBeanContextResources();
136 }
137
138 /**
139 * Gets the nesting <code>BeanContext</code>
140 * for this <code>BeanContextChildSupport</code>.
141 * @return the nesting <code>BeanContext</code> for
142 * this <code>BeanContextChildSupport</code>.
143 */
144 public synchronized BeanContext getBeanContext() { return beanContext; }
145
146 /**
147 * Add a PropertyChangeListener for a specific property.
148 * The same listener object may be added more than once. For each
149 * property, the listener will be invoked the number of times it was added
150 * for that property.
151 * If <code>name</code> or <code>pcl</code> is null, no exception is thrown
152 * and no action is taken.
153 *
154 * @param name The name of the property to listen on
155 * @param pcl The <code>PropertyChangeListener</code> to be added
156 */
157 public void addPropertyChangeListener(String name, PropertyChangeListener pcl) {
158 pcSupport.addPropertyChangeListener(name, pcl);
159 }
160
161 /**
162 * Remove a PropertyChangeListener for a specific property.
163 * If <code>pcl</code> was added more than once to the same event
164 * source for the specified property, it will be notified one less time
165 * after being removed.
166 * If <code>name</code> is null, no exception is thrown
167 * and no action is taken.
168 * If <code>pcl</code> is null, or was never added for the specified
169 * property, no exception is thrown and no action is taken.
170 *
171 * @param name The name of the property that was listened on
172 * @param pcl The PropertyChangeListener to be removed
173 */
174 public void removePropertyChangeListener(String name, PropertyChangeListener pcl) {
175 pcSupport.removePropertyChangeListener(name, pcl);
176 }
177
178 /**
179 * Add a VetoableChangeListener for a specific property.
180 * The same listener object may be added more than once. For each
181 * property, the listener will be invoked the number of times it was added
182 * for that property.
183 * If <code>name</code> or <code>vcl</code> is null, no exception is thrown
184 * and no action is taken.
185 *
186 * @param name The name of the property to listen on
187 * @param vcl The <code>VetoableChangeListener</code> to be added
188 */
189 public void addVetoableChangeListener(String name, VetoableChangeListener vcl) {
190 vcSupport.addVetoableChangeListener(name, vcl);
191 }
192
193 /**
194 * Removes a <code>VetoableChangeListener</code>.
195 * If <code>pcl</code> was added more than once to the same event
196 * source for the specified property, it will be notified one less time
197 * after being removed.
198 * If <code>name</code> is null, no exception is thrown
199 * and no action is taken.
200 * If <code>vcl</code> is null, or was never added for the specified
201 * property, no exception is thrown and no action is taken.
202 *
203 * @param name The name of the property that was listened on
204 * @param vcl The <code>VetoableChangeListener</code> to be removed
205 */
206 public void removeVetoableChangeListener(String name, VetoableChangeListener vcl) {
207 vcSupport.removeVetoableChangeListener(name, vcl);
208 }
209
210 /**
211 * A service provided by the nesting BeanContext has been revoked.
212 *
213 * Subclasses may override this method in order to implement their own
214 * behaviors.
215 * @param bcsre The <code>BeanContextServiceRevokedEvent</code> fired as a
216 * result of a service being revoked
217 */
218 public void serviceRevoked(BeanContextServiceRevokedEvent bcsre) { }
219
220 /**
221 * A new service is available from the nesting BeanContext.
222 *
223 * Subclasses may override this method in order to implement their own
224 * behaviors
225 * @param bcsae The BeanContextServiceAvailableEvent fired as a
226 * result of a service becoming available
227 *
228 */
229 public void serviceAvailable(BeanContextServiceAvailableEvent bcsae) { }
230
231 /**
232 * Gets the <tt>BeanContextChild</tt> associated with this
233 * <tt>BeanContextChildSupport</tt>.
234 *
235 * @return the <tt>BeanContextChild</tt> peer of this class
236 */
237 public BeanContextChild getBeanContextChildPeer() { return beanContextChildPeer; }
238
239 /**
240 * Reports whether or not this class is a delegate of another.
241 *
242 * @return true if this class is a delegate of another
243 */
244 public boolean isDelegated() { return !this.equals(beanContextChildPeer); }
245
246 /**
247 * Report a bound property update to any registered listeners. No event is
248 * fired if old and new are equal and non-null.
249 * @param name The programmatic name of the property that was changed
250 * @param oldValue The old value of the property
251 * @param newValue The new value of the property
252 */
253 public void firePropertyChange(String name, Object oldValue, Object newValue) {
254 pcSupport.firePropertyChange(name, oldValue, newValue);
255 }
256
257 /**
258 * Report a vetoable property update to any registered listeners.
259 * If anyone vetos the change, then fire a new event
260 * reverting everyone to the old value and then rethrow
261 * the PropertyVetoException. <P>
262 *
263 * No event is fired if old and new are equal and non-null.
264 * <P>
265 * @param name The programmatic name of the property that is about to
266 * change
267 *
268 * @param oldValue The old value of the property
269 * @param newValue - The new value of the property
270 *
271 * @throws PropertyVetoException if the recipient wishes the property
272 * change to be rolled back.
273 */
274 public void fireVetoableChange(String name, Object oldValue, Object newValue) throws PropertyVetoException {
275 vcSupport.fireVetoableChange(name, oldValue, newValue);
276 }
277
278 /**
279 * Called from setBeanContext to validate (or otherwise) the
280 * pending change in the nesting BeanContext property value.
281 * Returning false will cause setBeanContext to throw
282 * PropertyVetoException.
283 * @param newValue the new value that has been requested for
284 * the BeanContext property
285 * @return <code>true</code> if the change operation is to be vetoed
286 */
287 public boolean validatePendingSetBeanContext(BeanContext newValue) {
288 return true;
289 }
290
291 /**
292 * This method may be overridden by subclasses to provide their own
293 * release behaviors. When invoked any resources held by this instance
294 * obtained from its current BeanContext property should be released
295 * since the object is no longer nested within that BeanContext.
296 */
297
298 protected void releaseBeanContextResources() {
299 // do nothing
300 }
301
302 /**
303 * This method may be overridden by subclasses to provide their own
304 * initialization behaviors. When invoked any resources requried by the
305 * BeanContextChild should be obtained from the current BeanContext.
306 */
307
308 protected void initializeBeanContextResources() {
309 // do nothing
310 }
311
312 /**
313 * Write the persistence state of the object.
314 */
315
316 private void writeObject(ObjectOutputStream oos) throws IOException {
317
318 /*
319 * dont serialize if we are delegated and the delegator isnt also
320 * serializable.
321 */
322
323 if (!equals(beanContextChildPeer) && !(beanContextChildPeer instanceof Serializable))
324 throw new IOException("BeanContextChildSupport beanContextChildPeer not Serializable");
325
326 else
327 oos.defaultWriteObject();
328
329 }
330
331
332 /**
333 * Restore a persistent object, must wait for subsequent setBeanContext()
334 * to fully restore any resources obtained from the new nesting
335 * BeanContext
336 */
337
338 private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
339 ois.defaultReadObject();
340 }
341
342 /*
343 * fields
344 */
345
346 /**
347 * The <code>BeanContext</code> in which
348 * this <code>BeanContextChild</code> is nested.
349 */
350 public BeanContextChild beanContextChildPeer;
351
352 /**
353 * The <tt>PropertyChangeSupport</tt> associated with this
354 * <tt>BeanContextChildSupport</tt>.
355 */
356 protected PropertyChangeSupport pcSupport;
357
358 /**
359 * The <tt>VetoableChangeSupport</tt> associated with this
360 * <tt>BeanContextChildSupport</tt>.
361 */
362 protected VetoableChangeSupport vcSupport;
363
364 protected transient BeanContext beanContext;
365
366 /**
367 * A flag indicating that there has been
368 * at least one <code>PropertyChangeVetoException</code>
369 * thrown for the attempted setBeanContext operation.
370 */
371 protected transient boolean rejectedSetBCOnce;
372
373}
java/pkg/java/beans/beancontext/BeanContextContainerProxy.class+0−0

Binary file not shown.

java/pkg/java/beans/beancontext/BeanContextContainerProxy.java+52−0
@@ -0,0 +1,52 @@
1/*
2 * Copyright (c) 1998, 2002, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.beans.beancontext;
27
28import java.awt.Container;
29
30/**
31 * <p>
32 * This interface is implemented by BeanContexts' that have an AWT Container
33 * associated with them.
34 * </p>
35 *
36 * @author Laurence P. G. Cable
37 * @since 1.2
38 *
39 * @see java.beans.beancontext.BeanContext
40 * @see java.beans.beancontext.BeanContextSupport
41 */
42
43public interface BeanContextContainerProxy {
44
45 /**
46 * Gets the <code>java.awt.Container</code> associated
47 * with this <code>BeanContext</code>.
48 * @return the <code>java.awt.Container</code> associated
49 * with this <code>BeanContext</code>.
50 */
51 Container getContainer();
52}
java/pkg/java/beans/beancontext/BeanContextEvent.class+0−0

Binary file not shown.

java/pkg/java/beans/beancontext/BeanContextEvent.java+104−0
@@ -0,0 +1,104 @@
1/*
2 * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.beans.beancontext;
27
28import java.util.EventObject;
29
30import java.beans.beancontext.BeanContext;
31
32/**
33 * <p>
34 * <code>BeanContextEvent</code> is the abstract root event class
35 * for all events emitted
36 * from, and pertaining to the semantics of, a <code>BeanContext</code>.
37 * This class introduces a mechanism to allow the propagation of
38 * <code>BeanContextEvent</code> subclasses through a hierarchy of
39 * <code>BeanContext</code>s. The <code>setPropagatedFrom()</code>
40 * and <code>getPropagatedFrom()</code> methods allow a
41 * <code>BeanContext</code> to identify itself as the source
42 * of a propagated event.
43 * </p>
44 *
45 * @author Laurence P. G. Cable
46 * @since 1.2
47 * @see java.beans.beancontext.BeanContext
48 */
49
50public abstract class BeanContextEvent extends EventObject {
51 private static final long serialVersionUID = 7267998073569045052L;
52
53 /**
54 * Contruct a BeanContextEvent
55 *
56 * @param bc The BeanContext source
57 */
58 protected BeanContextEvent(BeanContext bc) {
59 super(bc);
60 }
61
62 /**
63 * Gets the <code>BeanContext</code> associated with this event.
64 * @return the <code>BeanContext</code> associated with this event.
65 */
66 public BeanContext getBeanContext() { return (BeanContext)getSource(); }
67
68 /**
69 * Sets the <code>BeanContext</code> from which this event was propagated.
70 * @param bc the <code>BeanContext</code> from which this event
71 * was propagated
72 */
73 public synchronized void setPropagatedFrom(BeanContext bc) {
74 propagatedFrom = bc;
75 }
76
77 /**
78 * Gets the <code>BeanContext</code> from which this event was propagated.
79 * @return the <code>BeanContext</code> from which this
80 * event was propagated
81 */
82 public synchronized BeanContext getPropagatedFrom() {
83 return propagatedFrom;
84 }
85
86 /**
87 * Reports whether or not this event is
88 * propagated from some other <code>BeanContext</code>.
89 * @return <code>true</code> if propagated, <code>false</code>
90 * if not
91 */
92 public synchronized boolean isPropagated() {
93 return propagatedFrom != null;
94 }
95
96 /*
97 * fields
98 */
99
100 /**
101 * The <code>BeanContext</code> from which this event was propagated
102 */
103 protected BeanContext propagatedFrom;
104}
java/pkg/java/beans/beancontext/BeanContextMembershipEvent.class+0−0

Binary file not shown.

java/pkg/java/beans/beancontext/BeanContextMembershipEvent.java+131−0
@@ -0,0 +1,131 @@
1/*
2 * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.beans.beancontext;
27
28import java.util.EventObject;
29
30import java.beans.beancontext.BeanContext;
31import java.beans.beancontext.BeanContextEvent;
32
33import java.util.Arrays;
34import java.util.Collection;
35import java.util.Iterator;
36
37/**
38 * A <code>BeanContextMembershipEvent</code> encapsulates
39 * the list of children added to, or removed from,
40 * the membership of a particular <code>BeanContext</code>.
41 * An instance of this event is fired whenever a successful
42 * add(), remove(), retainAll(), removeAll(), or clear() is
43 * invoked on a given <code>BeanContext</code> instance.
44 * Objects interested in receiving events of this type must
45 * implement the <code>BeanContextMembershipListener</code>
46 * interface, and must register their intent via the
47 * <code>BeanContext</code>'s
48 * <code>addBeanContextMembershipListener(BeanContextMembershipListener bcml)
49 * </code> method.
50 *
51 * @author Laurence P. G. Cable
52 * @since 1.2
53 * @see java.beans.beancontext.BeanContext
54 * @see java.beans.beancontext.BeanContextEvent
55 * @see java.beans.beancontext.BeanContextMembershipListener
56 */
57public class BeanContextMembershipEvent extends BeanContextEvent {
58 private static final long serialVersionUID = 3499346510334590959L;
59
60 /**
61 * Contruct a BeanContextMembershipEvent
62 *
63 * @param bc The BeanContext source
64 * @param changes The Children affected
65 * @throws NullPointerException if <CODE>changes</CODE> is <CODE>null</CODE>
66 */
67
68 public BeanContextMembershipEvent(BeanContext bc, Collection changes) {
69 super(bc);
70
71 if (changes == null) throw new NullPointerException(
72 "BeanContextMembershipEvent constructor: changes is null.");
73
74 children = changes;
75 }
76
77 /**
78 * Contruct a BeanContextMembershipEvent
79 *
80 * @param bc The BeanContext source
81 * @param changes The Children effected
82 * @exception NullPointerException if changes associated with this
83 * event are null.
84 */
85
86 public BeanContextMembershipEvent(BeanContext bc, Object[] changes) {
87 super(bc);
88
89 if (changes == null) throw new NullPointerException(
90 "BeanContextMembershipEvent: changes is null.");
91
92 children = Arrays.asList(changes);
93 }
94
95 /**
96 * Gets the number of children affected by the notification.
97 * @return the number of children affected by the notification
98 */
99 public int size() { return children.size(); }
100
101 /**
102 * Is the child specified affected by the event?
103 * @return <code>true</code> if affected, <code>false</code>
104 * if not
105 */
106 public boolean contains(Object child) {
107 return children.contains(child);
108 }
109
110 /**
111 * Gets the array of children affected by this event.
112 * @return the array of children affected
113 */
114 public Object[] toArray() { return children.toArray(); }
115
116 /**
117 * Gets the array of children affected by this event.
118 * @return the array of children effected
119 */
120 public Iterator iterator() { return children.iterator(); }
121
122 /*
123 * fields
124 */
125
126 /**
127 * The list of children affected by this
128 * event notification.
129 */
130 protected Collection children;
131}
java/pkg/java/beans/beancontext/BeanContextMembershipListener.class+0−0

Binary file not shown.

java/pkg/java/beans/beancontext/BeanContextMembershipListener.java+61−0
@@ -0,0 +1,61 @@
1/*
2 * Copyright (c) 1997, 1999, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.beans.beancontext;
27
28import java.beans.beancontext.BeanContextMembershipEvent;
29
30import java.util.EventListener;
31
32/**
33 * <p>
34 * Compliant BeanContexts fire events on this interface when the state of
35 * the membership of the BeanContext changes.
36 * </p>
37 *
38 * @author Laurence P. G. Cable
39 * @since 1.2
40 * @see java.beans.beancontext.BeanContext
41 */
42
43public interface BeanContextMembershipListener extends EventListener {
44
45 /**
46 * Called when a child or list of children is added to a
47 * <code>BeanContext</code> that this listener is registered with.
48 * @param bcme The <code>BeanContextMembershipEvent</code>
49 * describing the change that occurred.
50 */
51 void childrenAdded(BeanContextMembershipEvent bcme);
52
53 /**
54 * Called when a child or list of children is removed
55 * from a <code>BeanContext</code> that this listener
56 * is registered with.
57 * @param bcme The <code>BeanContextMembershipEvent</code>
58 * describing the change that occurred.
59 */
60 void childrenRemoved(BeanContextMembershipEvent bcme);
61}
java/pkg/java/beans/beancontext/BeanContextProxy.class+0−0

Binary file not shown.

java/pkg/java/beans/beancontext/BeanContextProxy.java+85−0
@@ -0,0 +1,85 @@
1/*
2 * Copyright (c) 1998, 2002, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.beans.beancontext;
27
28/**
29 * <p>
30 * This interface is implemented by a JavaBean that does
31 * not directly have a BeanContext(Child) associated with
32 * it (via implementing that interface or a subinterface thereof),
33 * but has a public BeanContext(Child) delegated from it.
34 * For example, a subclass of java.awt.Container may have a BeanContext
35 * associated with it that all Component children of that Container shall
36 * be contained within.
37 * </p>
38 * <p>
39 * An Object may not implement this interface and the
40 * BeanContextChild interface
41 * (or any subinterfaces thereof) they are mutually exclusive.
42 * </p>
43 * <p>
44 * Callers of this interface shall examine the return type in order to
45 * obtain a particular subinterface of BeanContextChild as follows:
46 * <code>
47 * BeanContextChild bcc = o.getBeanContextProxy();
48 *
49 * if (bcc instanceof BeanContext) {
50 * // ...
51 * }
52 * </code>
53 * or
54 * <code>
55 * BeanContextChild bcc = o.getBeanContextProxy();
56 * BeanContext bc = null;
57 *
58 * try {
59 * bc = (BeanContext)bcc;
60 * } catch (ClassCastException cce) {
61 * // cast failed, bcc is not an instanceof BeanContext
62 * }
63 * </code>
64 * </p>
65 * <p>
66 * The return value is a constant for the lifetime of the implementing
67 * instance
68 * </p>
69 * @author Laurence P. G. Cable
70 * @since 1.2
71 *
72 * @see java.beans.beancontext.BeanContextChild
73 * @see java.beans.beancontext.BeanContextChildSupport
74 */
75
76public interface BeanContextProxy {
77
78 /**
79 * Gets the <code>BeanContextChild</code> (or subinterface)
80 * associated with this object.
81 * @return the <code>BeanContextChild</code> (or subinterface)
82 * associated with this object
83 */
84 BeanContextChild getBeanContextProxy();
85}
java/pkg/java/beans/beancontext/BeanContextServiceAvailableEvent.class+0−0

Binary file not shown.

java/pkg/java/beans/beancontext/BeanContextServiceAvailableEvent.java+86−0
@@ -0,0 +1,86 @@
1/*
2 * Copyright (c) 1998, 2009, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.beans.beancontext;
27
28import java.beans.beancontext.BeanContextChild;
29import java.beans.beancontext.BeanContextEvent;
30
31import java.beans.beancontext.BeanContextServices;
32
33import java.util.Iterator;
34
35/**
36 * <p>
37 * This event type is used by the BeanContextServicesListener in order to
38 * identify the service being registered.
39 * </p>
40 */
41
42public class BeanContextServiceAvailableEvent extends BeanContextEvent {
43 private static final long serialVersionUID = -5333985775656400778L;
44
45 /**
46 * Construct a <code>BeanContextAvailableServiceEvent</code>.
47 * @param bcs The context in which the service has become available
48 * @param sc A <code>Class</code> reference to the newly available service
49 */
50 public BeanContextServiceAvailableEvent(BeanContextServices bcs, Class sc) {
51 super((BeanContext)bcs);
52
53 serviceClass = sc;
54 }
55
56 /**
57 * Gets the source as a reference of type <code>BeanContextServices</code>.
58 * @return The context in which the service has become available
59 */
60 public BeanContextServices getSourceAsBeanContextServices() {
61 return (BeanContextServices)getBeanContext();
62 }
63
64 /**
65 * Gets the service class that is the subject of this notification.
66 * @return A <code>Class</code> reference to the newly available service
67 */
68 public Class getServiceClass() { return serviceClass; }
69
70 /**
71 * Gets the list of service dependent selectors.
72 * @return the current selectors available from the service
73 */
74 public Iterator getCurrentServiceSelectors() {
75 return ((BeanContextServices)getSource()).getCurrentServiceSelectors(serviceClass);
76 }
77
78 /*
79 * fields
80 */
81
82 /**
83 * A <code>Class</code> reference to the newly available service
84 */
85 protected Class serviceClass;
86}
java/pkg/java/beans/beancontext/BeanContextServiceProvider.class+0−0

Binary file not shown.

java/pkg/java/beans/beancontext/BeanContextServiceProvider.java+104−0
@@ -0,0 +1,104 @@
1/*
2 * Copyright (c) 1998, 2004, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.beans.beancontext;
27
28import java.util.Iterator;
29
30/**
31 * <p>
32 * One of the primary functions of a BeanContext is to act a as rendezvous
33 * between JavaBeans, and BeanContextServiceProviders.
34 * </p>
35 * <p>
36 * A JavaBean nested within a BeanContext, may ask that BeanContext to
37 * provide an instance of a "service", based upon a reference to a Java
38 * Class object that represents that service.
39 * </p>
40 * <p>
41 * If such a service has been registered with the context, or one of its
42 * nesting context's, in the case where a context delegate to its context
43 * to satisfy a service request, then the BeanContextServiceProvider associated with
44 * the service is asked to provide an instance of that service.
45 * </p>
46 * <p>
47 * The ServcieProvider may always return the same instance, or it may
48 * construct a new instance for each request.
49 * </p>
50 */
51
52public interface BeanContextServiceProvider {
53
54 /**
55 * Invoked by <code>BeanContextServices</code>, this method
56 * requests an instance of a
57 * service from this <code>BeanContextServiceProvider</code>.
58 *
59 * @param bcs The <code>BeanContextServices</code> associated with this
60 * particular request. This parameter enables the
61 * <code>BeanContextServiceProvider</code> to distinguish service
62 * requests from multiple sources.
63 *
64 * @param requestor The object requesting the service
65 *
66 * @param serviceClass The service requested
67 *
68 * @param serviceSelector the service dependent parameter
69 * for a particular service, or <code>null</code> if not applicable.
70 *
71 * @return a reference to the requested service
72 */
73 Object getService(BeanContextServices bcs, Object requestor, Class serviceClass, Object serviceSelector);
74
75 /**
76 * Invoked by <code>BeanContextServices</code>,
77 * this method releases a nested <code>BeanContextChild</code>'s
78 * (or any arbitrary object associated with a
79 * <code>BeanContextChild</code>) reference to the specified service.
80 *
81 * @param bcs the <code>BeanContextServices</code> associated with this
82 * particular release request
83 *
84 * @param requestor the object requesting the service to be released
85 *
86 * @param service the service that is to be released
87 */
88 public void releaseService(BeanContextServices bcs, Object requestor, Object service);
89
90 /**
91 * Invoked by <code>BeanContextServices</code>, this method
92 * gets the current service selectors for the specified service.
93 * A service selector is a service specific parameter,
94 * typical examples of which could include: a
95 * parameter to a constructor for the service implementation class,
96 * a value for a particular service's property, or a key into a
97 * map of existing implementations.
98 *
99 * @param bcs the <code>BeanContextServices</code> for this request
100 * @param serviceClass the specified service
101 * @return the current service selectors for the specified serviceClass
102 */
103 Iterator getCurrentServiceSelectors(BeanContextServices bcs, Class serviceClass);
104}
java/pkg/java/beans/beancontext/BeanContextServiceProviderBeanInfo.class+0−0

Binary file not shown.

java/pkg/java/beans/beancontext/BeanContextServiceProviderBeanInfo.java+47−0
@@ -0,0 +1,47 @@
1/*
2 * Copyright (c) 1998, 1999, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.beans.beancontext;
27
28import java.beans.BeanInfo;
29
30/**
31 * A BeanContextServiceProvider implementor who wishes to provide explicit
32 * information about the services their bean may provide shall implement a
33 * BeanInfo class that implements this BeanInfo subinterface and provides
34 * explicit information about the methods, properties, events, etc, of their
35 * services.
36 */
37
38public interface BeanContextServiceProviderBeanInfo extends BeanInfo {
39
40 /**
41 * Gets a <code>BeanInfo</code> array, one for each
42 * service class or interface statically available
43 * from this ServiceProvider.
44 * @return the <code>BeanInfo</code> array
45 */
46 BeanInfo[] getServicesBeanInfo();
47}
java/pkg/java/beans/beancontext/BeanContextServiceRevokedEvent.class+0−0

Binary file not shown.

java/pkg/java/beans/beancontext/BeanContextServiceRevokedEvent.java+99−0
@@ -0,0 +1,99 @@
1/*
2 * Copyright (c) 1998, 2009, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.beans.beancontext;
27
28import java.beans.beancontext.BeanContextEvent;
29
30import java.beans.beancontext.BeanContextServices;
31
32/**
33 * <p>
34 * This event type is used by the
35 * <code>BeanContextServiceRevokedListener</code> in order to
36 * identify the service being revoked.
37 * </p>
38 */
39public class BeanContextServiceRevokedEvent extends BeanContextEvent {
40 private static final long serialVersionUID = -1295543154724961754L;
41
42 /**
43 * Construct a <code>BeanContextServiceEvent</code>.
44 * @param bcs the <code>BeanContextServices</code>
45 * from which this service is being revoked
46 * @param sc the service that is being revoked
47 * @param invalidate <code>true</code> for immediate revocation
48 */
49 public BeanContextServiceRevokedEvent(BeanContextServices bcs, Class sc, boolean invalidate) {
50 super((BeanContext)bcs);
51
52 serviceClass = sc;
53 invalidateRefs = invalidate;
54 }
55
56 /**
57 * Gets the source as a reference of type <code>BeanContextServices</code>
58 * @return the <code>BeanContextServices</code> from which
59 * this service is being revoked
60 */
61 public BeanContextServices getSourceAsBeanContextServices() {
62 return (BeanContextServices)getBeanContext();
63 }
64
65 /**
66 * Gets the service class that is the subject of this notification
67 * @return A <code>Class</code> reference to the
68 * service that is being revoked
69 */
70 public Class getServiceClass() { return serviceClass; }
71
72 /**
73 * Checks this event to determine whether or not
74 * the service being revoked is of a particular class.
75 * @param service the service of interest (should be non-null)
76 * @return <code>true</code> if the service being revoked is of the
77 * same class as the specified service
78 */
79 public boolean isServiceClass(Class service) {
80 return serviceClass.equals(service);
81 }
82
83 /**
84 * Reports if the current service is being forcibly revoked,
85 * in which case the references are now invalidated and unusable.
86 * @return <code>true</code> if current service is being forcibly revoked
87 */
88 public boolean isCurrentServiceInvalidNow() { return invalidateRefs; }
89
90 /**
91 * fields
92 */
93
94 /**
95 * A <code>Class</code> reference to the service that is being revoked.
96 */
97 protected Class serviceClass;
98 private boolean invalidateRefs;
99}
java/pkg/java/beans/beancontext/BeanContextServiceRevokedListener.class+0−0

Binary file not shown.

java/pkg/java/beans/beancontext/BeanContextServiceRevokedListener.java+46−0
@@ -0,0 +1,46 @@
1/*
2 * Copyright (c) 1998, 1999, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25package java.beans.beancontext;
26
27import java.beans.beancontext.BeanContextServiceRevokedEvent;
28
29import java.util.EventListener;
30
31/**
32 * The listener interface for receiving
33 * <code>BeanContextServiceRevokedEvent</code> objects. A class that is
34 * interested in processing a <code>BeanContextServiceRevokedEvent</code>
35 * implements this interface.
36 */
37public interface BeanContextServiceRevokedListener extends EventListener {
38
39 /**
40 * The service named has been revoked. getService requests for
41 * this service will no longer be satisifed.
42 * @param bcsre the <code>BeanContextServiceRevokedEvent</code> received
43 * by this listener.
44 */
45 void serviceRevoked(BeanContextServiceRevokedEvent bcsre);
46}
java/pkg/java/beans/beancontext/BeanContextServices.class+0−0

Binary file not shown.

java/pkg/java/beans/beancontext/BeanContextServices.java+159−0
@@ -0,0 +1,159 @@
1/*
2 * Copyright (c) 1998, 2004, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.beans.beancontext;
27
28import java.util.Iterator;
29
30import java.util.TooManyListenersException;
31
32import java.beans.beancontext.BeanContext;
33
34import java.beans.beancontext.BeanContextServiceProvider;
35
36import java.beans.beancontext.BeanContextServicesListener;
37
38
39/**
40 * <p>
41 * The BeanContextServices interface provides a mechanism for a BeanContext
42 * to expose generic "services" to the BeanContextChild objects within.
43 * </p>
44 */
45public interface BeanContextServices extends BeanContext, BeanContextServicesListener {
46
47 /**
48 * Adds a service to this BeanContext.
49 * <code>BeanContextServiceProvider</code>s call this method
50 * to register a particular service with this context.
51 * If the service has not previously been added, the
52 * <code>BeanContextServices</code> associates
53 * the service with the <code>BeanContextServiceProvider</code> and
54 * fires a <code>BeanContextServiceAvailableEvent</code> to all
55 * currently registered <code>BeanContextServicesListeners</code>.
56 * The method then returns <code>true</code>, indicating that
57 * the addition of the service was successful.
58 * If the given service has already been added, this method
59 * simply returns <code>false</code>.
60 * @param serviceClass the service to add
61 * @param serviceProvider the <code>BeanContextServiceProvider</code>
62 * associated with the service
63 */
64 boolean addService(Class serviceClass, BeanContextServiceProvider serviceProvider);
65
66 /**
67 * BeanContextServiceProviders wishing to remove
68 * a currently registered service from this context
69 * may do so via invocation of this method. Upon revocation of
70 * the service, the <code>BeanContextServices</code> fires a
71 * <code>BeanContextServiceRevokedEvent</code> to its
72 * list of currently registered
73 * <code>BeanContextServiceRevokedListeners</code> and
74 * <code>BeanContextServicesListeners</code>.
75 * @param serviceClass the service to revoke from this BeanContextServices
76 * @param serviceProvider the BeanContextServiceProvider associated with
77 * this particular service that is being revoked
78 * @param revokeCurrentServicesNow a value of <code>true</code>
79 * indicates an exceptional circumstance where the
80 * <code>BeanContextServiceProvider</code> or
81 * <code>BeanContextServices</code> wishes to immediately
82 * terminate service to all currently outstanding references
83 * to the specified service.
84 */
85 void revokeService(Class serviceClass, BeanContextServiceProvider serviceProvider, boolean revokeCurrentServicesNow);
86
87 /**
88 * Reports whether or not a given service is
89 * currently available from this context.
90 * @param serviceClass the service in question
91 * @return true if the service is available
92 */
93 boolean hasService(Class serviceClass);
94
95 /**
96 * A <code>BeanContextChild</code>, or any arbitrary object
97 * associated with a <code>BeanContextChild</code>, may obtain
98 * a reference to a currently registered service from its
99 * nesting <code>BeanContextServices</code>
100 * via invocation of this method. When invoked, this method
101 * gets the service by calling the getService() method on the
102 * underlying <code>BeanContextServiceProvider</code>.
103 * @param child the <code>BeanContextChild</code>
104 * associated with this request
105 * @param requestor the object requesting the service
106 * @param serviceClass class of the requested service
107 * @param serviceSelector the service dependent parameter
108 * @param bcsrl the
109 * <code>BeanContextServiceRevokedListener</code> to notify
110 * if the service should later become revoked
111 * @throws TooManyListenersException
112 * @return a reference to this context's named
113 * Service as requested or <code>null</code>
114 */
115 Object getService(BeanContextChild child, Object requestor, Class serviceClass, Object serviceSelector, BeanContextServiceRevokedListener bcsrl) throws TooManyListenersException;
116
117 /**
118 * Releases a <code>BeanContextChild</code>'s
119 * (or any arbitrary object associated with a BeanContextChild)
120 * reference to the specified service by calling releaseService()
121 * on the underlying <code>BeanContextServiceProvider</code>.
122 * @param child the <code>BeanContextChild</code>
123 * @param requestor the requestor
124 * @param service the service
125 */
126 void releaseService(BeanContextChild child, Object requestor, Object service);
127
128 /**
129 * Gets the currently available services for this context.
130 * @return an <code>Iterator</code> consisting of the
131 * currently available services
132 */
133 Iterator getCurrentServiceClasses();
134
135 /**
136 * Gets the list of service dependent service parameters
137 * (Service Selectors) for the specified service, by
138 * calling getCurrentServiceSelectors() on the
139 * underlying BeanContextServiceProvider.
140 * @param serviceClass the specified service
141 * @return the currently available service selectors
142 * for the named serviceClass
143 */
144 Iterator getCurrentServiceSelectors(Class serviceClass);
145
146 /**
147 * Adds a <code>BeanContextServicesListener</code> to this BeanContext
148 * @param bcsl the <code>BeanContextServicesListener</code> to add
149 */
150 void addBeanContextServicesListener(BeanContextServicesListener bcsl);
151
152 /**
153 * Removes a <code>BeanContextServicesListener</code>
154 * from this <code>BeanContext</code>
155 * @param bcsl the <code>BeanContextServicesListener</code>
156 * to remove from this context
157 */
158 void removeBeanContextServicesListener(BeanContextServicesListener bcsl);
159}
java/pkg/java/beans/beancontext/BeanContextServicesListener.class+0−0

Binary file not shown.

java/pkg/java/beans/beancontext/BeanContextServicesListener.java+46−0
@@ -0,0 +1,46 @@
1/*
2 * Copyright (c) 1998, 1999, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.beans.beancontext;
27
28import java.beans.beancontext.BeanContextServiceAvailableEvent;
29import java.beans.beancontext.BeanContextServiceRevokedEvent;
30import java.beans.beancontext.BeanContextServiceRevokedListener;
31
32/**
33 * The listener interface for receiving
34 * <code>BeanContextServiceAvailableEvent</code> objects.
35 * A class that is interested in processing a
36 * <code>BeanContextServiceAvailableEvent</code> implements this interface.
37 */
38public interface BeanContextServicesListener extends BeanContextServiceRevokedListener {
39
40 /**
41 * The service named has been registered. getService requests for
42 * this service may now be made.
43 * @param bcsae the <code>BeanContextServiceAvailableEvent</code>
44 */
45 void serviceAvailable(BeanContextServiceAvailableEvent bcsae);
46}
java/pkg/java/beans/beancontext/BeanContextServicesSupport$BCSSChild$BCSSCServiceClassRef.class+0−0

Binary file not shown.

java/pkg/java/beans/beancontext/BeanContextServicesSupport$BCSSChild$BCSSCServiceRef.class+0−0

Binary file not shown.

java/pkg/java/beans/beancontext/BeanContextServicesSupport$BCSSChild.class+0−0

Binary file not shown.

java/pkg/java/beans/beancontext/BeanContextServicesSupport$BCSSProxyServiceProvider.class+0−0

Binary file not shown.

java/pkg/java/beans/beancontext/BeanContextServicesSupport$BCSSServiceProvider.class+0−0

Binary file not shown.

java/pkg/java/beans/beancontext/BeanContextServicesSupport.class+0−0

Binary file not shown.

java/pkg/java/beans/beancontext/BeanContextServicesSupport.java+1238−0
@@ -0,0 +1,1238 @@
1/*
2 * Copyright (c) 1998, 2009, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.beans.beancontext;
27
28import java.util.ArrayList;
29import java.util.Collection;
30import java.util.HashMap;
31import java.util.HashSet;
32import java.util.Iterator;
33import java.util.Map;
34import java.util.Map.Entry;
35
36import java.io.IOException;
37import java.io.ObjectInputStream;
38import java.io.ObjectOutputStream;
39import java.io.Serializable;
40
41import java.util.TooManyListenersException;
42
43import java.util.Locale;
44
45/**
46 * <p>
47 * This helper class provides a utility implementation of the
48 * java.beans.beancontext.BeanContextServices interface.
49 * </p>
50 * <p>
51 * Since this class directly implements the BeanContextServices interface,
52 * the class can, and is intended to be used either by subclassing this
53 * implementation, or via delegation of an instance of this class
54 * from another through the BeanContextProxy interface.
55 * </p>
56 *
57 * @author Laurence P. G. Cable
58 * @since 1.2
59 */
60
61public class BeanContextServicesSupport extends BeanContextSupport
62 implements BeanContextServices {
63 private static final long serialVersionUID = -8494482757288719206L;
64
65 /**
66 * <p>
67 * Construct a BeanContextServicesSupport instance
68 * </p>
69 *
70 * @param peer The peer BeanContext we are supplying an implementation for, if null the this object is its own peer
71 * @param lcle The current Locale for this BeanContext.
72 * @param dTime The initial state, true if in design mode, false if runtime.
73 * @param visible The initial visibility.
74 *
75 */
76
77 public BeanContextServicesSupport(BeanContextServices peer, Locale lcle, boolean dTime, boolean visible) {
78 super(peer, lcle, dTime, visible);
79 }
80
81 /**
82 * Create an instance using the specified Locale and design mode.
83 *
84 * @param peer The peer BeanContext we are supplying an implementation for, if null the this object is its own peer
85 * @param lcle The current Locale for this BeanContext.
86 * @param dtime The initial state, true if in design mode, false if runtime.
87 */
88
89 public BeanContextServicesSupport(BeanContextServices peer, Locale lcle, boolean dtime) {
90 this (peer, lcle, dtime, true);
91 }
92
93 /**
94 * Create an instance using the specified locale
95 *
96 * @param peer The peer BeanContext we are supplying an implementation for, if null the this object is its own peer
97 * @param lcle The current Locale for this BeanContext.
98 */
99
100 public BeanContextServicesSupport(BeanContextServices peer, Locale lcle) {
101 this (peer, lcle, false, true);
102 }
103
104 /**
105 * Create an instance with a peer
106 *
107 * @param peer The peer BeanContext we are supplying an implementation for, if null the this object is its own peer
108 */
109
110 public BeanContextServicesSupport(BeanContextServices peer) {
111 this (peer, null, false, true);
112 }
113
114 /**
115 * Create an instance that is not a delegate of another object
116 */
117
118 public BeanContextServicesSupport() {
119 this (null, null, false, true);
120 }
121
122 /**
123 * called by BeanContextSupport superclass during construction and
124 * deserialization to initialize subclass transient state.
125 *
126 * subclasses may envelope this method, but should not override it or
127 * call it directly.
128 */
129
130 public void initialize() {
131 super.initialize();
132
133 services = new HashMap(serializable + 1);
134 bcsListeners = new ArrayList(1);
135 }
136
137 /**
138 * Gets the <tt>BeanContextServices</tt> associated with this
139 * <tt>BeanContextServicesSupport</tt>.
140 *
141 * @return the instance of <tt>BeanContext</tt>
142 * this object is providing the implementation for.
143 */
144 public BeanContextServices getBeanContextServicesPeer() {
145 return (BeanContextServices)getBeanContextChildPeer();
146 }
147
148 /************************************************************************/
149
150 /*
151 * protected nested class containing per child information, an instance
152 * of which is associated with each child in the "children" hashtable.
153 * subclasses can extend this class to include their own per-child state.
154 *
155 * Note that this 'value' is serialized with the corresponding child 'key'
156 * when the BeanContextSupport is serialized.
157 */
158
159 protected class BCSSChild extends BeanContextSupport.BCSChild {
160
161 private static final long serialVersionUID = -3263851306889194873L;
162
163 /*
164 * private nested class to map serviceClass to Provider and requestors
165 * listeners.
166 */
167
168 class BCSSCServiceClassRef {
169
170 // create an instance of a service ref
171
172 BCSSCServiceClassRef(Class sc, BeanContextServiceProvider bcsp, boolean delegated) {
173 super();
174
175 serviceClass = sc;
176
177 if (delegated)
178 delegateProvider = bcsp;
179 else
180 serviceProvider = bcsp;
181 }
182
183 // add a requestor and assoc listener
184
185 void addRequestor(Object requestor, BeanContextServiceRevokedListener bcsrl) throws TooManyListenersException {
186 BeanContextServiceRevokedListener cbcsrl = (BeanContextServiceRevokedListener)requestors.get(requestor);
187
188 if (cbcsrl != null && !cbcsrl.equals(bcsrl))
189 throw new TooManyListenersException();
190
191 requestors.put(requestor, bcsrl);
192 }
193
194 // remove a requestor
195
196 void removeRequestor(Object requestor) {
197 requestors.remove(requestor);
198 }
199
200 // check a requestors listener
201
202 void verifyRequestor(Object requestor, BeanContextServiceRevokedListener bcsrl) throws TooManyListenersException {
203 BeanContextServiceRevokedListener cbcsrl = (BeanContextServiceRevokedListener)requestors.get(requestor);
204
205 if (cbcsrl != null && !cbcsrl.equals(bcsrl))
206 throw new TooManyListenersException();
207 }
208
209 void verifyAndMaybeSetProvider(BeanContextServiceProvider bcsp, boolean isDelegated) {
210 BeanContextServiceProvider current;
211
212 if (isDelegated) { // the provider is delegated
213 current = delegateProvider;
214
215 if (current == null || bcsp == null) {
216 delegateProvider = bcsp;
217 return;
218 }
219 } else { // the provider is registered with this BCS
220 current = serviceProvider;
221
222 if (current == null || bcsp == null) {
223 serviceProvider = bcsp;
224 return;
225 }
226 }
227
228 if (!current.equals(bcsp))
229 throw new UnsupportedOperationException("existing service reference obtained from different BeanContextServiceProvider not supported");
230
231 }
232
233 Iterator cloneOfEntries() {
234 return ((HashMap)requestors.clone()).entrySet().iterator();
235 }
236
237 Iterator entries() { return requestors.entrySet().iterator(); }
238
239 boolean isEmpty() { return requestors.isEmpty(); }
240
241 Class getServiceClass() { return serviceClass; }
242
243 BeanContextServiceProvider getServiceProvider() {
244 return serviceProvider;
245 }
246
247 BeanContextServiceProvider getDelegateProvider() {
248 return delegateProvider;
249 }
250
251 boolean isDelegated() { return delegateProvider != null; }
252
253 void addRef(boolean delegated) {
254 if (delegated) {
255 delegateRefs++;
256 } else {
257 serviceRefs++;
258 }
259 }
260
261
262 void releaseRef(boolean delegated) {
263 if (delegated) {
264 if (--delegateRefs == 0) {
265 delegateProvider = null;
266 }
267 } else {
268 if (--serviceRefs <= 0) {
269 serviceProvider = null;
270 }
271 }
272 }
273
274 int getRefs() { return serviceRefs + delegateRefs; }
275
276 int getDelegateRefs() { return delegateRefs; }
277
278 int getServiceRefs() { return serviceRefs; }
279
280 /*
281 * fields
282 */
283
284 Class serviceClass;
285
286 BeanContextServiceProvider serviceProvider;
287 int serviceRefs;
288
289 BeanContextServiceProvider delegateProvider; // proxy
290 int delegateRefs;
291
292 HashMap requestors = new HashMap(1);
293 }
294
295 /*
296 * per service reference info ...
297 */
298
299 class BCSSCServiceRef {
300 BCSSCServiceRef(BCSSCServiceClassRef scref, boolean isDelegated) {
301 serviceClassRef = scref;
302 delegated = isDelegated;
303 }
304
305 void addRef() { refCnt++; }
306 int release() { return --refCnt; }
307
308 BCSSCServiceClassRef getServiceClassRef() { return serviceClassRef; }
309
310 boolean isDelegated() { return delegated; }
311
312 /*
313 * fields
314 */
315
316 BCSSCServiceClassRef serviceClassRef;
317 int refCnt = 1;
318 boolean delegated = false;
319 }
320
321 BCSSChild(Object bcc, Object peer) { super(bcc, peer); }
322
323 // note usage of service per requestor, per service
324
325 synchronized void usingService(Object requestor, Object service, Class serviceClass, BeanContextServiceProvider bcsp, boolean isDelegated, BeanContextServiceRevokedListener bcsrl) throws TooManyListenersException, UnsupportedOperationException {
326
327 // first, process mapping from serviceClass to requestor(s)
328
329 BCSSCServiceClassRef serviceClassRef = null;
330
331 if (serviceClasses == null)
332 serviceClasses = new HashMap(1);
333 else
334 serviceClassRef = (BCSSCServiceClassRef)serviceClasses.get(serviceClass);
335
336 if (serviceClassRef == null) { // new service being used ...
337 serviceClassRef = new BCSSCServiceClassRef(serviceClass, bcsp, isDelegated);
338 serviceClasses.put(serviceClass, serviceClassRef);
339
340 } else { // existing service ...
341 serviceClassRef.verifyAndMaybeSetProvider(bcsp, isDelegated); // throws
342 serviceClassRef.verifyRequestor(requestor, bcsrl); // throws
343 }
344
345 serviceClassRef.addRequestor(requestor, bcsrl);
346 serviceClassRef.addRef(isDelegated);
347
348 // now handle mapping from requestor to service(s)
349
350 BCSSCServiceRef serviceRef = null;
351 Map services = null;
352
353 if (serviceRequestors == null) {
354 serviceRequestors = new HashMap(1);
355 } else {
356 services = (Map)serviceRequestors.get(requestor);
357 }
358
359 if (services == null) {
360 services = new HashMap(1);
361
362 serviceRequestors.put(requestor, services);
363 } else
364 serviceRef = (BCSSCServiceRef)services.get(service);
365
366 if (serviceRef == null) {
367 serviceRef = new BCSSCServiceRef(serviceClassRef, isDelegated);
368
369 services.put(service, serviceRef);
370 } else {
371 serviceRef.addRef();
372 }
373 }
374
375 // release a service reference
376
377 synchronized void releaseService(Object requestor, Object service) {
378 if (serviceRequestors == null) return;
379
380 Map services = (Map)serviceRequestors.get(requestor);
381
382 if (services == null) return; // oops its not there anymore!
383
384 BCSSCServiceRef serviceRef = (BCSSCServiceRef)services.get(service);
385
386 if (serviceRef == null) return; // oops its not there anymore!
387
388 BCSSCServiceClassRef serviceClassRef = serviceRef.getServiceClassRef();
389 boolean isDelegated = serviceRef.isDelegated();
390 BeanContextServiceProvider bcsp = isDelegated ? serviceClassRef.getDelegateProvider() : serviceClassRef.getServiceProvider();
391
392 bcsp.releaseService(BeanContextServicesSupport.this.getBeanContextServicesPeer(), requestor, service);
393
394 serviceClassRef.releaseRef(isDelegated);
395 serviceClassRef.removeRequestor(requestor);
396
397 if (serviceRef.release() == 0) {
398
399 services.remove(service);
400
401 if (services.isEmpty()) {
402 serviceRequestors.remove(requestor);
403 serviceClassRef.removeRequestor(requestor);
404 }
405
406 if (serviceRequestors.isEmpty()) {
407 serviceRequestors = null;
408 }
409
410 if (serviceClassRef.isEmpty()) {
411 serviceClasses.remove(serviceClassRef.getServiceClass());
412 }
413
414 if (serviceClasses.isEmpty())
415 serviceClasses = null;
416 }
417 }
418
419 // revoke a service
420
421 synchronized void revokeService(Class serviceClass, boolean isDelegated, boolean revokeNow) {
422 if (serviceClasses == null) return;
423
424 BCSSCServiceClassRef serviceClassRef = (BCSSCServiceClassRef)serviceClasses.get(serviceClass);
425
426 if (serviceClassRef == null) return;
427
428 Iterator i = serviceClassRef.cloneOfEntries();
429
430 BeanContextServiceRevokedEvent bcsre = new BeanContextServiceRevokedEvent(BeanContextServicesSupport.this.getBeanContextServicesPeer(), serviceClass, revokeNow);
431 boolean noMoreRefs = false;
432
433 while (i.hasNext() && serviceRequestors != null) {
434 Map.Entry entry = (Map.Entry)i.next();
435 BeanContextServiceRevokedListener listener = (BeanContextServiceRevokedListener)entry.getValue();
436
437 if (revokeNow) {
438 Object requestor = entry.getKey();
439 Map services = (Map)serviceRequestors.get(requestor);
440
441 if (services != null) {
442 Iterator i1 = services.entrySet().iterator();
443
444 while (i1.hasNext()) {
445 Map.Entry tmp = (Map.Entry)i1.next();
446
447 BCSSCServiceRef serviceRef = (BCSSCServiceRef)tmp.getValue();
448 if (serviceRef.getServiceClassRef().equals(serviceClassRef) && isDelegated == serviceRef.isDelegated()) {
449 i1.remove();
450 }
451 }
452
453 if (noMoreRefs = services.isEmpty()) {
454 serviceRequestors.remove(requestor);
455 }
456 }
457
458 if (noMoreRefs) serviceClassRef.removeRequestor(requestor);
459 }
460
461 listener.serviceRevoked(bcsre);
462 }
463
464 if (revokeNow && serviceClasses != null) {
465 if (serviceClassRef.isEmpty())
466 serviceClasses.remove(serviceClass);
467
468 if (serviceClasses.isEmpty())
469 serviceClasses = null;
470 }
471
472 if (serviceRequestors != null && serviceRequestors.isEmpty())
473 serviceRequestors = null;
474 }
475
476 // release all references for this child since it has been unnested.
477
478 void cleanupReferences() {
479
480 if (serviceRequestors == null) return;
481
482 Iterator requestors = serviceRequestors.entrySet().iterator();
483
484 while(requestors.hasNext()) {
485 Map.Entry tmp = (Map.Entry)requestors.next();
486 Object requestor = tmp.getKey();
487 Iterator services = ((Map)tmp.getValue()).entrySet().iterator();
488
489 requestors.remove();
490
491 while (services.hasNext()) {
492 Map.Entry entry = (Map.Entry)services.next();
493 Object service = entry.getKey();
494 BCSSCServiceRef sref = (BCSSCServiceRef)entry.getValue();
495
496 BCSSCServiceClassRef scref = sref.getServiceClassRef();
497
498 BeanContextServiceProvider bcsp = sref.isDelegated() ? scref.getDelegateProvider() : scref.getServiceProvider();
499
500 scref.removeRequestor(requestor);
501 services.remove();
502
503 while (sref.release() >= 0) {
504 bcsp.releaseService(BeanContextServicesSupport.this.getBeanContextServicesPeer(), requestor, service);
505 }
506 }
507 }
508
509 serviceRequestors = null;
510 serviceClasses = null;
511 }
512
513 void revokeAllDelegatedServicesNow() {
514 if (serviceClasses == null) return;
515
516 Iterator serviceClassRefs =
517 new HashSet(serviceClasses.values()).iterator();
518
519 while (serviceClassRefs.hasNext()) {
520 BCSSCServiceClassRef serviceClassRef = (BCSSCServiceClassRef)serviceClassRefs.next();
521
522 if (!serviceClassRef.isDelegated()) continue;
523
524 Iterator i = serviceClassRef.cloneOfEntries();
525 BeanContextServiceRevokedEvent bcsre = new BeanContextServiceRevokedEvent(BeanContextServicesSupport.this.getBeanContextServicesPeer(), serviceClassRef.getServiceClass(), true);
526 boolean noMoreRefs = false;
527
528 while (i.hasNext()) {
529 Map.Entry entry = (Map.Entry)i.next();
530 BeanContextServiceRevokedListener listener = (BeanContextServiceRevokedListener)entry.getValue();
531
532 Object requestor = entry.getKey();
533 Map services = (Map)serviceRequestors.get(requestor);
534
535 if (services != null) {
536 Iterator i1 = services.entrySet().iterator();
537
538 while (i1.hasNext()) {
539 Map.Entry tmp = (Map.Entry)i1.next();
540
541 BCSSCServiceRef serviceRef = (BCSSCServiceRef)tmp.getValue();
542 if (serviceRef.getServiceClassRef().equals(serviceClassRef) && serviceRef.isDelegated()) {
543 i1.remove();
544 }
545 }
546
547 if (noMoreRefs = services.isEmpty()) {
548 serviceRequestors.remove(requestor);
549 }
550 }
551
552 if (noMoreRefs) serviceClassRef.removeRequestor(requestor);
553
554 listener.serviceRevoked(bcsre);
555
556 if (serviceClassRef.isEmpty())
557 serviceClasses.remove(serviceClassRef.getServiceClass());
558 }
559 }
560
561 if (serviceClasses.isEmpty()) serviceClasses = null;
562
563 if (serviceRequestors != null && serviceRequestors.isEmpty())
564 serviceRequestors = null;
565 }
566
567 /*
568 * fields
569 */
570
571 private transient HashMap serviceClasses;
572 private transient HashMap serviceRequestors;
573 }
574
575 /**
576 * <p>
577 * Subclasses can override this method to insert their own subclass
578 * of Child without having to override add() or the other Collection
579 * methods that add children to the set.
580 * </p>
581 *
582 * @param targetChild the child to create the Child on behalf of
583 * @param peer the peer if the targetChild and peer are related by BeanContextProxy
584 */
585
586 protected BCSChild createBCSChild(Object targetChild, Object peer) {
587 return new BCSSChild(targetChild, peer);
588 }
589
590 /************************************************************************/
591
592 /**
593 * subclasses may subclass this nested class to add behaviors for
594 * each BeanContextServicesProvider.
595 */
596
597 protected static class BCSSServiceProvider implements Serializable {
598 private static final long serialVersionUID = 861278251667444782L;
599
600 BCSSServiceProvider(Class sc, BeanContextServiceProvider bcsp) {
601 super();
602
603 serviceProvider = bcsp;
604 }
605
606 protected BeanContextServiceProvider getServiceProvider() {
607 return serviceProvider;
608 }
609
610 /*
611 * fields
612 */
613
614 protected BeanContextServiceProvider serviceProvider;
615 }
616
617 /**
618 * subclasses can override this method to create new subclasses of
619 * BCSSServiceProvider without having to overrride addService() in
620 * order to instantiate.
621 */
622
623 protected BCSSServiceProvider createBCSSServiceProvider(Class sc, BeanContextServiceProvider bcsp) {
624 return new BCSSServiceProvider(sc, bcsp);
625 }
626
627 /************************************************************************/
628
629 /**
630 * add a BeanContextServicesListener
631 *
632 * @throws NullPointerException
633 */
634
635 public void addBeanContextServicesListener(BeanContextServicesListener bcsl) {
636 if (bcsl == null) throw new NullPointerException("bcsl");
637
638 synchronized(bcsListeners) {
639 if (bcsListeners.contains(bcsl))
640 return;
641 else
642 bcsListeners.add(bcsl);
643 }
644 }
645
646 /**
647 * remove a BeanContextServicesListener
648 */
649
650 public void removeBeanContextServicesListener(BeanContextServicesListener bcsl) {
651 if (bcsl == null) throw new NullPointerException("bcsl");
652
653 synchronized(bcsListeners) {
654 if (!bcsListeners.contains(bcsl))
655 return;
656 else
657 bcsListeners.remove(bcsl);
658 }
659 }
660
661 /**
662 * add a service
663 */
664
665 public boolean addService(Class serviceClass, BeanContextServiceProvider bcsp) {
666 return addService(serviceClass, bcsp, true);
667 }
668
669 /**
670 * add a service
671 */
672
673 protected boolean addService(Class serviceClass, BeanContextServiceProvider bcsp, boolean fireEvent) {
674
675 if (serviceClass == null) throw new NullPointerException("serviceClass");
676 if (bcsp == null) throw new NullPointerException("bcsp");
677
678 synchronized(BeanContext.globalHierarchyLock) {
679 if (services.containsKey(serviceClass))
680 return false;
681 else {
682 services.put(serviceClass, createBCSSServiceProvider(serviceClass, bcsp));
683
684 if (bcsp instanceof Serializable) serializable++;
685
686 if (!fireEvent) return true;
687
688
689 BeanContextServiceAvailableEvent bcssae = new BeanContextServiceAvailableEvent(getBeanContextServicesPeer(), serviceClass);
690
691 fireServiceAdded(bcssae);
692
693 synchronized(children) {
694 Iterator i = children.keySet().iterator();
695
696 while (i.hasNext()) {
697 Object c = i.next();
698
699 if (c instanceof BeanContextServices) {
700 ((BeanContextServicesListener)c).serviceAvailable(bcssae);
701 }
702 }
703 }
704
705 return true;
706 }
707 }
708 }
709
710 /**
711 * remove a service
712 */
713
714 public void revokeService(Class serviceClass, BeanContextServiceProvider bcsp, boolean revokeCurrentServicesNow) {
715
716 if (serviceClass == null) throw new NullPointerException("serviceClass");
717 if (bcsp == null) throw new NullPointerException("bcsp");
718
719 synchronized(BeanContext.globalHierarchyLock) {
720 if (!services.containsKey(serviceClass)) return;
721
722 BCSSServiceProvider bcsssp = (BCSSServiceProvider)services.get(serviceClass);
723
724 if (!bcsssp.getServiceProvider().equals(bcsp))
725 throw new IllegalArgumentException("service provider mismatch");
726
727 services.remove(serviceClass);
728
729 if (bcsp instanceof Serializable) serializable--;
730
731 Iterator i = bcsChildren(); // get the BCSChild values.
732
733 while (i.hasNext()) {
734 ((BCSSChild)i.next()).revokeService(serviceClass, false, revokeCurrentServicesNow);
735 }
736
737 fireServiceRevoked(serviceClass, revokeCurrentServicesNow);
738 }
739 }
740
741 /**
742 * has a service, which may be delegated
743 */
744
745 public synchronized boolean hasService(Class serviceClass) {
746 if (serviceClass == null) throw new NullPointerException("serviceClass");
747
748 synchronized(BeanContext.globalHierarchyLock) {
749 if (services.containsKey(serviceClass)) return true;
750
751 BeanContextServices bcs = null;
752
753 try {
754 bcs = (BeanContextServices)getBeanContext();
755 } catch (ClassCastException cce) {
756 return false;
757 }
758
759 return bcs == null ? false : bcs.hasService(serviceClass);
760 }
761 }
762
763 /************************************************************************/
764
765 /*
766 * a nested subclass used to represent a proxy for serviceClasses delegated
767 * to an enclosing BeanContext.
768 */
769
770 protected class BCSSProxyServiceProvider implements BeanContextServiceProvider, BeanContextServiceRevokedListener {
771
772 BCSSProxyServiceProvider(BeanContextServices bcs) {
773 super();
774
775 nestingCtxt = bcs;
776 }
777
778 public Object getService(BeanContextServices bcs, Object requestor, Class serviceClass, Object serviceSelector) {
779 Object service = null;
780
781 try {
782 service = nestingCtxt.getService(bcs, requestor, serviceClass, serviceSelector, this);
783 } catch (TooManyListenersException tmle) {
784 return null;
785 }
786
787 return service;
788 }
789
790 public void releaseService(BeanContextServices bcs, Object requestor, Object service) {
791 nestingCtxt.releaseService(bcs, requestor, service);
792 }
793
794 public Iterator getCurrentServiceSelectors(BeanContextServices bcs, Class serviceClass) {
795 return nestingCtxt.getCurrentServiceSelectors(serviceClass);
796 }
797
798 public void serviceRevoked(BeanContextServiceRevokedEvent bcsre) {
799 Iterator i = bcsChildren(); // get the BCSChild values.
800
801 while (i.hasNext()) {
802 ((BCSSChild)i.next()).revokeService(bcsre.getServiceClass(), true, bcsre.isCurrentServiceInvalidNow());
803 }
804 }
805
806 /*
807 * fields
808 */
809
810 private BeanContextServices nestingCtxt;
811 }
812
813 /************************************************************************/
814
815 /**
816 * obtain a service which may be delegated
817 */
818
819 public Object getService(BeanContextChild child, Object requestor, Class serviceClass, Object serviceSelector, BeanContextServiceRevokedListener bcsrl) throws TooManyListenersException {
820 if (child == null) throw new NullPointerException("child");
821 if (serviceClass == null) throw new NullPointerException("serviceClass");
822 if (requestor == null) throw new NullPointerException("requestor");
823 if (bcsrl == null) throw new NullPointerException("bcsrl");
824
825 Object service = null;
826 BCSSChild bcsc;
827 BeanContextServices bcssp = getBeanContextServicesPeer();
828
829 synchronized(BeanContext.globalHierarchyLock) {
830 synchronized(children) { bcsc = (BCSSChild)children.get(child); }
831
832 if (bcsc == null) throw new IllegalArgumentException("not a child of this context"); // not a child ...
833
834 BCSSServiceProvider bcsssp = (BCSSServiceProvider)services.get(serviceClass);
835
836 if (bcsssp != null) {
837 BeanContextServiceProvider bcsp = bcsssp.getServiceProvider();
838 service = bcsp.getService(bcssp, requestor, serviceClass, serviceSelector);
839 if (service != null) { // do bookkeeping ...
840 try {
841 bcsc.usingService(requestor, service, serviceClass, bcsp, false, bcsrl);
842 } catch (TooManyListenersException tmle) {
843 bcsp.releaseService(bcssp, requestor, service);
844 throw tmle;
845 } catch (UnsupportedOperationException uope) {
846 bcsp.releaseService(bcssp, requestor, service);
847 throw uope; // unchecked rt exception
848 }
849
850 return service;
851 }
852 }
853
854
855 if (proxy != null) {
856
857 // try to delegate ...
858
859 service = proxy.getService(bcssp, requestor, serviceClass, serviceSelector);
860
861 if (service != null) { // do bookkeeping ...
862 try {
863 bcsc.usingService(requestor, service, serviceClass, proxy, true, bcsrl);
864 } catch (TooManyListenersException tmle) {
865 proxy.releaseService(bcssp, requestor, service);
866 throw tmle;
867 } catch (UnsupportedOperationException uope) {
868 proxy.releaseService(bcssp, requestor, service);
869 throw uope; // unchecked rt exception
870 }
871
872 return service;
873 }
874 }
875 }
876
877 return null;
878 }
879
880 /**
881 * release a service
882 */
883
884 public void releaseService(BeanContextChild child, Object requestor, Object service) {
885 if (child == null) throw new NullPointerException("child");
886 if (requestor == null) throw new NullPointerException("requestor");
887 if (service == null) throw new NullPointerException("service");
888
889 BCSSChild bcsc;
890
891 synchronized(BeanContext.globalHierarchyLock) {
892 synchronized(children) { bcsc = (BCSSChild)children.get(child); }
893
894 if (bcsc != null)
895 bcsc.releaseService(requestor, service);
896 else
897 throw new IllegalArgumentException("child actual is not a child of this BeanContext");
898 }
899 }
900
901 /**
902 * @return an iterator for all the currently registered service classes.
903 */
904
905 public Iterator getCurrentServiceClasses() {
906 return new BCSIterator(services.keySet().iterator());
907 }
908
909 /**
910 * @return an iterator for all the currently available service selectors
911 * (if any) available for the specified service.
912 */
913
914 public Iterator getCurrentServiceSelectors(Class serviceClass) {
915
916 BCSSServiceProvider bcsssp = (BCSSServiceProvider)services.get(serviceClass);
917
918 return bcsssp != null ? new BCSIterator(bcsssp.getServiceProvider().getCurrentServiceSelectors(getBeanContextServicesPeer(), serviceClass)) : null;
919 }
920
921 /**
922 * BeanContextServicesListener callback, propagates event to all
923 * currently registered listeners and BeanContextServices children,
924 * if this BeanContextService does not already implement this service
925 * itself.
926 *
927 * subclasses may override or envelope this method to implement their
928 * own propagation semantics.
929 */
930
931 public void serviceAvailable(BeanContextServiceAvailableEvent bcssae) {
932 synchronized(BeanContext.globalHierarchyLock) {
933 if (services.containsKey(bcssae.getServiceClass())) return;
934
935 fireServiceAdded(bcssae);
936
937 Iterator i;
938
939 synchronized(children) {
940 i = children.keySet().iterator();
941 }
942
943 while (i.hasNext()) {
944 Object c = i.next();
945
946 if (c instanceof BeanContextServices) {
947 ((BeanContextServicesListener)c).serviceAvailable(bcssae);
948 }
949 }
950 }
951 }
952
953 /**
954 * BeanContextServicesListener callback, propagates event to all
955 * currently registered listeners and BeanContextServices children,
956 * if this BeanContextService does not already implement this service
957 * itself.
958 *
959 * subclasses may override or envelope this method to implement their
960 * own propagation semantics.
961 */
962
963 public void serviceRevoked(BeanContextServiceRevokedEvent bcssre) {
964 synchronized(BeanContext.globalHierarchyLock) {
965 if (services.containsKey(bcssre.getServiceClass())) return;
966
967 fireServiceRevoked(bcssre);
968
969 Iterator i;
970
971 synchronized(children) {
972 i = children.keySet().iterator();
973 }
974
975 while (i.hasNext()) {
976 Object c = i.next();
977
978 if (c instanceof BeanContextServices) {
979 ((BeanContextServicesListener)c).serviceRevoked(bcssre);
980 }
981 }
982 }
983 }
984
985 /**
986 * Gets the <tt>BeanContextServicesListener</tt> (if any) of the specified
987 * child.
988 *
989 * @param child the specified child
990 * @return the BeanContextServicesListener (if any) of the specified child
991 */
992 protected static final BeanContextServicesListener getChildBeanContextServicesListener(Object child) {
993 try {
994 return (BeanContextServicesListener)child;
995 } catch (ClassCastException cce) {
996 return null;
997 }
998 }
999
1000 /**
1001 * called from superclass child removal operations after a child
1002 * has been successfully removed. called with child synchronized.
1003 *
1004 * This subclass uses this hook to immediately revoke any services
1005 * being used by this child if it is a BeanContextChild.
1006 *
1007 * subclasses may envelope this method in order to implement their
1008 * own child removal side-effects.
1009 */
1010
1011 protected void childJustRemovedHook(Object child, BCSChild bcsc) {
1012 BCSSChild bcssc = (BCSSChild)bcsc;
1013
1014 bcssc.cleanupReferences();
1015 }
1016
1017 /**
1018 * called from setBeanContext to notify a BeanContextChild
1019 * to release resources obtained from the nesting BeanContext.
1020 *
1021 * This method revokes any services obtained from its parent.
1022 *
1023 * subclasses may envelope this method to implement their own semantics.
1024 */
1025
1026 protected synchronized void releaseBeanContextResources() {
1027 Object[] bcssc;
1028
1029 super.releaseBeanContextResources();
1030
1031 synchronized(children) {
1032 if (children.isEmpty()) return;
1033
1034 bcssc = children.values().toArray();
1035 }
1036
1037
1038 for (int i = 0; i < bcssc.length; i++) {
1039 ((BCSSChild)bcssc[i]).revokeAllDelegatedServicesNow();
1040 }
1041
1042 proxy = null;
1043 }
1044
1045 /**
1046 * called from setBeanContext to notify a BeanContextChild
1047 * to allocate resources obtained from the nesting BeanContext.
1048 *
1049 * subclasses may envelope this method to implement their own semantics.
1050 */
1051
1052 protected synchronized void initializeBeanContextResources() {
1053 super.initializeBeanContextResources();
1054
1055 BeanContext nbc = getBeanContext();
1056
1057 if (nbc == null) return;
1058
1059 try {
1060 BeanContextServices bcs = (BeanContextServices)nbc;
1061
1062 proxy = new BCSSProxyServiceProvider(bcs);
1063 } catch (ClassCastException cce) {
1064 // do nothing ...
1065 }
1066 }
1067
1068 /**
1069 * Fires a <tt>BeanContextServiceEvent</tt> notifying of a new service.
1070 */
1071 protected final void fireServiceAdded(Class serviceClass) {
1072 BeanContextServiceAvailableEvent bcssae = new BeanContextServiceAvailableEvent(getBeanContextServicesPeer(), serviceClass);
1073
1074 fireServiceAdded(bcssae);
1075 }
1076
1077 /**
1078 * Fires a <tt>BeanContextServiceAvailableEvent</tt> indicating that a new
1079 * service has become available.
1080 *
1081 * @param bcssae the <tt>BeanContextServiceAvailableEvent</tt>
1082 */
1083 protected final void fireServiceAdded(BeanContextServiceAvailableEvent bcssae) {
1084 Object[] copy;
1085
1086 synchronized (bcsListeners) { copy = bcsListeners.toArray(); }
1087
1088 for (int i = 0; i < copy.length; i++) {
1089 ((BeanContextServicesListener)copy[i]).serviceAvailable(bcssae);
1090 }
1091 }
1092
1093 /**
1094 * Fires a <tt>BeanContextServiceEvent</tt> notifying of a service being revoked.
1095 *
1096 * @param bcsre the <tt>BeanContextServiceRevokedEvent</tt>
1097 */
1098 protected final void fireServiceRevoked(BeanContextServiceRevokedEvent bcsre) {
1099 Object[] copy;
1100
1101 synchronized (bcsListeners) { copy = bcsListeners.toArray(); }
1102
1103 for (int i = 0; i < copy.length; i++) {
1104 ((BeanContextServiceRevokedListener)copy[i]).serviceRevoked(bcsre);
1105 }
1106 }
1107
1108 /**
1109 * Fires a <tt>BeanContextServiceRevokedEvent</tt>
1110 * indicating that a particular service is
1111 * no longer available.
1112 */
1113 protected final void fireServiceRevoked(Class serviceClass, boolean revokeNow) {
1114 Object[] copy;
1115 BeanContextServiceRevokedEvent bcsre = new BeanContextServiceRevokedEvent(getBeanContextServicesPeer(), serviceClass, revokeNow);
1116
1117 synchronized (bcsListeners) { copy = bcsListeners.toArray(); }
1118
1119 for (int i = 0; i < copy.length; i++) {
1120 ((BeanContextServicesListener)copy[i]).serviceRevoked(bcsre);
1121 }
1122 }
1123
1124 /**
1125 * called from BeanContextSupport writeObject before it serializes the
1126 * children ...
1127 *
1128 * This class will serialize any Serializable BeanContextServiceProviders
1129 * herein.
1130 *
1131 * subclasses may envelope this method to insert their own serialization
1132 * processing that has to occur prior to serialization of the children
1133 */
1134
1135 protected synchronized void bcsPreSerializationHook(ObjectOutputStream oos) throws IOException {
1136
1137 oos.writeInt(serializable);
1138
1139 if (serializable <= 0) return;
1140
1141 int count = 0;
1142
1143 Iterator i = services.entrySet().iterator();
1144
1145 while (i.hasNext() && count < serializable) {
1146 Map.Entry entry = (Map.Entry)i.next();
1147 BCSSServiceProvider bcsp = null;
1148
1149 try {
1150 bcsp = (BCSSServiceProvider)entry.getValue();
1151 } catch (ClassCastException cce) {
1152 continue;
1153 }
1154
1155 if (bcsp.getServiceProvider() instanceof Serializable) {
1156 oos.writeObject(entry.getKey());
1157 oos.writeObject(bcsp);
1158 count++;
1159 }
1160 }
1161
1162 if (count != serializable)
1163 throw new IOException("wrote different number of service providers than expected");
1164 }
1165
1166 /**
1167 * called from BeanContextSupport readObject before it deserializes the
1168 * children ...
1169 *
1170 * This class will deserialize any Serializable BeanContextServiceProviders
1171 * serialized earlier thus making them available to the children when they
1172 * deserialized.
1173 *
1174 * subclasses may envelope this method to insert their own serialization
1175 * processing that has to occur prior to serialization of the children
1176 */
1177
1178 protected synchronized void bcsPreDeserializationHook(ObjectInputStream ois) throws IOException, ClassNotFoundException {
1179
1180 serializable = ois.readInt();
1181
1182 int count = serializable;
1183
1184 while (count > 0) {
1185 services.put(ois.readObject(), ois.readObject());
1186 count--;
1187 }
1188 }
1189
1190 /**
1191 * serialize the instance
1192 */
1193
1194 private synchronized void writeObject(ObjectOutputStream oos) throws IOException {
1195 oos.defaultWriteObject();
1196
1197 serialize(oos, (Collection)bcsListeners);
1198 }
1199
1200 /**
1201 * deserialize the instance
1202 */
1203
1204 private synchronized void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
1205
1206 ois.defaultReadObject();
1207
1208 deserialize(ois, (Collection)bcsListeners);
1209 }
1210
1211
1212 /*
1213 * fields
1214 */
1215
1216 /**
1217 * all accesses to the <code> protected transient HashMap services </code>
1218 * field should be synchronized on that object
1219 */
1220 protected transient HashMap services;
1221
1222 /**
1223 * The number of instances of a serializable <tt>BeanContextServceProvider</tt>.
1224 */
1225 protected transient int serializable = 0;
1226
1227
1228 /**
1229 * Delegate for the <tt>BeanContextServiceProvider</tt>.
1230 */
1231 protected transient BCSSProxyServiceProvider proxy;
1232
1233
1234 /**
1235 * List of <tt>BeanContextServicesListener</tt> objects.
1236 */
1237 protected transient ArrayList bcsListeners;
1238}
java/pkg/java/beans/beancontext/BeanContextSupport$1.class+0−0

Binary file not shown.

java/pkg/java/beans/beancontext/BeanContextSupport$2.class+0−0

Binary file not shown.

java/pkg/java/beans/beancontext/BeanContextSupport$BCSChild.class+0−0

Binary file not shown.

java/pkg/java/beans/beancontext/BeanContextSupport$BCSIterator.class+0−0

Binary file not shown.

java/pkg/java/beans/beancontext/BeanContextSupport.class+0−0

Binary file not shown.

java/pkg/java/beans/beancontext/BeanContextSupport.java+1393−0
@@ -0,0 +1,1393 @@
1/*
2 * Copyright (c) 1997, 2004, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.beans.beancontext;
27
28import java.awt.Component;
29import java.awt.Container;
30
31import java.beans.Beans;
32import java.beans.AppletInitializer;
33
34import java.beans.DesignMode;
35
36import java.beans.PropertyChangeEvent;
37import java.beans.PropertyChangeListener;
38import java.beans.PropertyChangeSupport;
39
40import java.beans.VetoableChangeListener;
41import java.beans.VetoableChangeSupport;
42import java.beans.PropertyVetoException;
43
44import java.beans.Visibility;
45
46import java.io.IOException;
47import java.io.InputStream;
48import java.io.ObjectInputStream;
49import java.io.ObjectOutputStream;
50import java.io.Serializable;
51
52import java.net.URL;
53
54import java.util.ArrayList;
55import java.util.Collection;
56import java.util.HashMap;
57import java.util.Iterator;
58import java.util.Locale;
59import java.util.Map;
60
61
62/**
63 * This helper class provides a utility implementation of the
64 * java.beans.beancontext.BeanContext interface.
65 * </p>
66 * <p>
67 * Since this class directly implements the BeanContext interface, the class
68 * can, and is intended to be used either by subclassing this implementation,
69 * or via ad-hoc delegation of an instance of this class from another.
70 * </p>
71 *
72 * @author Laurence P. G. Cable
73 * @since 1.2
74 */
75public class BeanContextSupport extends BeanContextChildSupport
76 implements BeanContext,
77 Serializable,
78 PropertyChangeListener,
79 VetoableChangeListener {
80
81 // Fix for bug 4282900 to pass JCK regression test
82 static final long serialVersionUID = -4879613978649577204L;
83
84 /**
85 *
86 * Construct a BeanContextSupport instance
87 *
88 *
89 * @param peer The peer <tt>BeanContext</tt> we are
90 * supplying an implementation for,
91 * or <tt>null</tt>
92 * if this object is its own peer
93 * @param lcle The current Locale for this BeanContext. If
94 * <tt>lcle</tt> is <tt>null</tt>, the default locale
95 * is assigned to the <tt>BeanContext</tt> instance.
96 * @param dTime The initial state,
97 * <tt>true</tt> if in design mode,
98 * <tt>false</tt> if runtime.
99 * @param visible The initial visibility.
100 * @see java.util.Locale#getDefault()
101 * @see java.util.Locale#setDefault(java.util.Locale)
102 */
103 public BeanContextSupport(BeanContext peer, Locale lcle, boolean dTime, boolean visible) {
104 super(peer);
105
106 locale = lcle != null ? lcle : Locale.getDefault();
107 designTime = dTime;
108 okToUseGui = visible;
109
110 initialize();
111 }
112
113 /**
114 * Create an instance using the specified Locale and design mode.
115 *
116 * @param peer The peer <tt>BeanContext</tt> we
117 * are supplying an implementation for,
118 * or <tt>null</tt> if this object is its own peer
119 * @param lcle The current Locale for this <tt>BeanContext</tt>. If
120 * <tt>lcle</tt> is <tt>null</tt>, the default locale
121 * is assigned to the <tt>BeanContext</tt> instance.
122 * @param dtime The initial state, <tt>true</tt>
123 * if in design mode,
124 * <tt>false</tt> if runtime.
125 * @see java.util.Locale#getDefault()
126 * @see java.util.Locale#setDefault(java.util.Locale)
127 */
128 public BeanContextSupport(BeanContext peer, Locale lcle, boolean dtime) {
129 this (peer, lcle, dtime, true);
130 }
131
132 /**
133 * Create an instance using the specified locale
134 *
135 * @param peer The peer BeanContext we are
136 * supplying an implementation for,
137 * or <tt>null</tt> if this object
138 * is its own peer
139 * @param lcle The current Locale for this
140 * <tt>BeanContext</tt>. If
141 * <tt>lcle</tt> is <tt>null</tt>,
142 * the default locale
143 * is assigned to the <tt>BeanContext</tt>
144 * instance.
145 * @see java.util.Locale#getDefault()
146 * @see java.util.Locale#setDefault(java.util.Locale)
147 */
148 public BeanContextSupport(BeanContext peer, Locale lcle) {
149 this (peer, lcle, false, true);
150 }
151
152 /**
153 * Create an instance using with a default locale
154 *
155 * @param peer The peer <tt>BeanContext</tt> we are
156 * supplying an implementation for,
157 * or <tt>null</tt> if this object
158 * is its own peer
159 */
160 public BeanContextSupport(BeanContext peer) {
161 this (peer, null, false, true);
162 }
163
164 /**
165 * Create an instance that is not a delegate of another object
166 */
167
168 public BeanContextSupport() {
169 this (null, null, false, true);
170 }
171
172 /**
173 * Gets the instance of <tt>BeanContext</tt> that
174 * this object is providing the implementation for.
175 * @return the BeanContext instance
176 */
177 public BeanContext getBeanContextPeer() { return (BeanContext)getBeanContextChildPeer(); }
178
179 /**
180 * <p>
181 * The instantiateChild method is a convenience hook
182 * in BeanContext to simplify
183 * the task of instantiating a Bean, nested,
184 * into a <tt>BeanContext</tt>.
185 * </p>
186 * <p>
187 * The semantics of the beanName parameter are defined by java.beans.Beans.instantate.
188 * </p>
189 *
190 * @param beanName the name of the Bean to instantiate within this BeanContext
191 * @throws IOException if there is an I/O error when the bean is being deserialized
192 * @throws ClassNotFoundException if the class
193 * identified by the beanName parameter is not found
194 * @return the new object
195 */
196 public Object instantiateChild(String beanName)
197 throws IOException, ClassNotFoundException {
198 BeanContext bc = getBeanContextPeer();
199
200 return Beans.instantiate(bc.getClass().getClassLoader(), beanName, bc);
201 }
202
203 /**
204 * Gets the number of children currently nested in
205 * this BeanContext.
206 *
207 * @return number of children
208 */
209 public int size() {
210 synchronized(children) {
211 return children.size();
212 }
213 }
214
215 /**
216 * Reports whether or not this
217 * <tt>BeanContext</tt> is empty.
218 * A <tt>BeanContext</tt> is considered
219 * empty when it contains zero
220 * nested children.
221 * @return if there are not children
222 */
223 public boolean isEmpty() {
224 synchronized(children) {
225 return children.isEmpty();
226 }
227 }
228
229 /**
230 * Determines whether or not the specified object
231 * is currently a child of this <tt>BeanContext</tt>.
232 * @param o the Object in question
233 * @return if this object is a child
234 */
235 public boolean contains(Object o) {
236 synchronized(children) {
237 return children.containsKey(o);
238 }
239 }
240
241 /**
242 * Determines whether or not the specified object
243 * is currently a child of this <tt>BeanContext</tt>.
244 * @param o the Object in question
245 * @return if this object is a child
246 */
247 public boolean containsKey(Object o) {
248 synchronized(children) {
249 return children.containsKey(o);
250 }
251 }
252
253 /**
254 * Gets all JavaBean or <tt>BeanContext</tt> instances
255 * currently nested in this <tt>BeanContext</tt>.
256 * @return an <tt>Iterator</tt> of the nested children
257 */
258 public Iterator iterator() {
259 synchronized(children) {
260 return new BCSIterator(children.keySet().iterator());
261 }
262 }
263
264 /**
265 * Gets all JavaBean or <tt>BeanContext</tt>
266 * instances currently nested in this BeanContext.
267 */
268 public Object[] toArray() {
269 synchronized(children) {
270 return children.keySet().toArray();
271 }
272 }
273
274 /**
275 * Gets an array containing all children of
276 * this <tt>BeanContext</tt> that match
277 * the types contained in arry.
278 * @param arry The array of object
279 * types that are of interest.
280 * @return an array of children
281 */
282 public Object[] toArray(Object[] arry) {
283 synchronized(children) {
284 return children.keySet().toArray(arry);
285 }
286 }
287
288
289 /************************************************************************/
290
291 /**
292 * protected final subclass that encapsulates an iterator but implements
293 * a noop remove() method.
294 */
295
296 protected static final class BCSIterator implements Iterator {
297 BCSIterator(Iterator i) { super(); src = i; }
298
299 public boolean hasNext() { return src.hasNext(); }
300 public Object next() { return src.next(); }
301 public void remove() { /* do nothing */ }
302
303 private Iterator src;
304 }
305
306 /************************************************************************/
307
308 /*
309 * protected nested class containing per child information, an instance
310 * of which is associated with each child in the "children" hashtable.
311 * subclasses can extend this class to include their own per-child state.
312 *
313 * Note that this 'value' is serialized with the corresponding child 'key'
314 * when the BeanContextSupport is serialized.
315 */
316
317 protected class BCSChild implements Serializable {
318
319 private static final long serialVersionUID = -5815286101609939109L;
320
321 BCSChild(Object bcc, Object peer) {
322 super();
323
324 child = bcc;
325 proxyPeer = peer;
326 }
327
328 Object getChild() { return child; }
329
330 void setRemovePending(boolean v) { removePending = v; }
331
332 boolean isRemovePending() { return removePending; }
333
334 boolean isProxyPeer() { return proxyPeer != null; }
335
336 Object getProxyPeer() { return proxyPeer; }
337 /*
338 * fields
339 */
340
341
342 private Object child;
343 private Object proxyPeer;
344
345 private transient boolean removePending;
346 }
347
348 /**
349 * <p>
350 * Subclasses can override this method to insert their own subclass
351 * of Child without having to override add() or the other Collection
352 * methods that add children to the set.
353 * </p>
354 *
355 * @param targetChild the child to create the Child on behalf of
356 * @param peer the peer if the tragetChild and the peer are related by an implementation of BeanContextProxy
357 */
358
359 protected BCSChild createBCSChild(Object targetChild, Object peer) {
360 return new BCSChild(targetChild, peer);
361 }
362
363 /************************************************************************/
364
365 /**
366 * Adds/nests a child within this <tt>BeanContext</tt>.
367 * <p>
368 * Invoked as a side effect of java.beans.Beans.instantiate().
369 * If the child object is not valid for adding then this method
370 * throws an IllegalStateException.
371 * </p>
372 *
373 *
374 * @param targetChild The child objects to nest
375 * within this <tt>BeanContext</tt>
376 * @return true if the child was added successfully.
377 * @see #validatePendingAdd
378 */
379 public boolean add(Object targetChild) {
380
381 if (targetChild == null) throw new IllegalArgumentException();
382
383 // The specification requires that we do nothing if the child
384 // is already nested herein.
385
386 if (children.containsKey(targetChild)) return false; // test before locking
387
388 synchronized(BeanContext.globalHierarchyLock) {
389 if (children.containsKey(targetChild)) return false; // check again
390
391 if (!validatePendingAdd(targetChild)) {
392 throw new IllegalStateException();
393 }
394
395
396 // The specification requires that we invoke setBeanContext() on the
397 // newly added child if it implements the java.beans.beancontext.BeanContextChild interface
398
399 BeanContextChild cbcc = getChildBeanContextChild(targetChild);
400 BeanContextChild bccp = null;
401
402 synchronized(targetChild) {
403
404 if (targetChild instanceof BeanContextProxy) {
405 bccp = ((BeanContextProxy)targetChild).getBeanContextProxy();
406
407 if (bccp == null) throw new NullPointerException("BeanContextPeer.getBeanContextProxy()");
408 }
409
410 BCSChild bcsc = createBCSChild(targetChild, bccp);
411 BCSChild pbcsc = null;
412
413 synchronized (children) {
414 children.put(targetChild, bcsc);
415
416 if (bccp != null) children.put(bccp, pbcsc = createBCSChild(bccp, targetChild));
417 }
418
419 if (cbcc != null) synchronized(cbcc) {
420 try {
421 cbcc.setBeanContext(getBeanContextPeer());
422 } catch (PropertyVetoException pve) {
423
424 synchronized (children) {
425 children.remove(targetChild);
426
427 if (bccp != null) children.remove(bccp);
428 }
429
430 throw new IllegalStateException();
431 }
432
433 cbcc.addPropertyChangeListener("beanContext", childPCL);
434 cbcc.addVetoableChangeListener("beanContext", childVCL);
435 }
436
437 Visibility v = getChildVisibility(targetChild);
438
439 if (v != null) {
440 if (okToUseGui)
441 v.okToUseGui();
442 else
443 v.dontUseGui();
444 }
445
446 if (getChildSerializable(targetChild) != null) serializable++;
447
448 childJustAddedHook(targetChild, bcsc);
449
450 if (bccp != null) {
451 v = getChildVisibility(bccp);
452
453 if (v != null) {
454 if (okToUseGui)
455 v.okToUseGui();
456 else
457 v.dontUseGui();
458 }
459
460 if (getChildSerializable(bccp) != null) serializable++;
461
462 childJustAddedHook(bccp, pbcsc);
463 }
464
465
466 }
467
468 // The specification requires that we fire a notification of the change
469
470 fireChildrenAdded(new BeanContextMembershipEvent(getBeanContextPeer(), bccp == null ? new Object[] { targetChild } : new Object[] { targetChild, bccp } ));
471
472 }
473
474 return true;
475 }
476
477 /**
478 * Removes a child from this BeanContext. If the child object is not
479 * for adding then this method throws an IllegalStateException.
480 * @param targetChild The child objects to remove
481 * @see #validatePendingRemove
482 */
483 public boolean remove(Object targetChild) {
484 return remove(targetChild, true);
485 }
486
487 /**
488 * internal remove used when removal caused by
489 * unexpected <tt>setBeanContext</tt> or
490 * by <tt>remove()</tt> invocation.
491 * @param targetChild the JavaBean, BeanContext, or Object to be removed
492 * @param callChildSetBC used to indicate that
493 * the child should be notified that it is no
494 * longer nested in this <tt>BeanContext</tt>.
495 */
496 protected boolean remove(Object targetChild, boolean callChildSetBC) {
497
498 if (targetChild == null) throw new IllegalArgumentException();
499
500 synchronized(BeanContext.globalHierarchyLock) {
501 if (!containsKey(targetChild)) return false;
502
503 if (!validatePendingRemove(targetChild)) {
504 throw new IllegalStateException();
505 }
506
507 BCSChild bcsc = (BCSChild)children.get(targetChild);
508 BCSChild pbcsc = null;
509 Object peer = null;
510
511 // we are required to notify the child that it is no longer nested here if
512 // it implements java.beans.beancontext.BeanContextChild
513
514 synchronized(targetChild) {
515 if (callChildSetBC) {
516 BeanContextChild cbcc = getChildBeanContextChild(targetChild);
517 if (cbcc != null) synchronized(cbcc) {
518 cbcc.removePropertyChangeListener("beanContext", childPCL);
519 cbcc.removeVetoableChangeListener("beanContext", childVCL);
520
521 try {
522 cbcc.setBeanContext(null);
523 } catch (PropertyVetoException pve1) {
524 cbcc.addPropertyChangeListener("beanContext", childPCL);
525 cbcc.addVetoableChangeListener("beanContext", childVCL);
526 throw new IllegalStateException();
527 }
528
529 }
530 }
531
532 synchronized (children) {
533 children.remove(targetChild);
534
535 if (bcsc.isProxyPeer()) {
536 pbcsc = (BCSChild)children.get(peer = bcsc.getProxyPeer());
537 children.remove(peer);
538 }
539 }
540
541 if (getChildSerializable(targetChild) != null) serializable--;
542
543 childJustRemovedHook(targetChild, bcsc);
544
545 if (peer != null) {
546 if (getChildSerializable(peer) != null) serializable--;
547
548 childJustRemovedHook(peer, pbcsc);
549 }
550 }
551
552 fireChildrenRemoved(new BeanContextMembershipEvent(getBeanContextPeer(), peer == null ? new Object[] { targetChild } : new Object[] { targetChild, peer } ));
553
554 }
555
556 return true;
557 }
558
559 /**
560 * Tests to see if all objects in the
561 * specified <tt>Collection</tt> are children of
562 * this <tt>BeanContext</tt>.
563 * @param c the specified <tt>Collection</tt>
564 *
565 * @return <tt>true</tt> if all objects
566 * in the collection are children of
567 * this <tt>BeanContext</tt>, false if not.
568 */
569 public boolean containsAll(Collection c) {
570 synchronized(children) {
571 Iterator i = c.iterator();
572 while (i.hasNext())
573 if(!contains(i.next()))
574 return false;
575
576 return true;
577 }
578 }
579
580 /**
581 * add Collection to set of Children (Unsupported)
582 * implementations must synchronized on the hierarchy lock and "children" protected field
583 * @throws UnsupportedOperationException
584 */
585 public boolean addAll(Collection c) {
586 throw new UnsupportedOperationException();
587 }
588
589 /**
590 * remove all specified children (Unsupported)
591 * implementations must synchronized on the hierarchy lock and "children" protected field
592 * @throws UnsupportedOperationException
593 */
594 public boolean removeAll(Collection c) {
595 throw new UnsupportedOperationException();
596 }
597
598
599 /**
600 * retain only specified children (Unsupported)
601 * implementations must synchronized on the hierarchy lock and "children" protected field
602 * @throws UnsupportedOperationException
603 */
604 public boolean retainAll(Collection c) {
605 throw new UnsupportedOperationException();
606 }
607
608 /**
609 * clear the children (Unsupported)
610 * implementations must synchronized on the hierarchy lock and "children" protected field
611 * @throws UnsupportedOperationException
612 */
613 public void clear() {
614 throw new UnsupportedOperationException();
615 }
616
617 /**
618 * Adds a BeanContextMembershipListener
619 *
620 * @param bcml the BeanContextMembershipListener to add
621 * @throws NullPointerException
622 */
623
624 public void addBeanContextMembershipListener(BeanContextMembershipListener bcml) {
625 if (bcml == null) throw new NullPointerException("listener");
626
627 synchronized(bcmListeners) {
628 if (bcmListeners.contains(bcml))
629 return;
630 else
631 bcmListeners.add(bcml);
632 }
633 }
634
635 /**
636 * Removes a BeanContextMembershipListener
637 *
638 * @param bcml the BeanContextMembershipListener to remove
639 * @throws NullPointerException
640 */
641
642 public void removeBeanContextMembershipListener(BeanContextMembershipListener bcml) {
643 if (bcml == null) throw new NullPointerException("listener");
644
645 synchronized(bcmListeners) {
646 if (!bcmListeners.contains(bcml))
647 return;
648 else
649 bcmListeners.remove(bcml);
650 }
651 }
652
653 /**
654 * @param name the name of the resource requested.
655 * @param bcc the child object making the request.
656 *
657 * @return the requested resource as an InputStream
658 * @throws NullPointerException
659 */
660
661 public InputStream getResourceAsStream(String name, BeanContextChild bcc) {
662 if (name == null) throw new NullPointerException("name");
663 if (bcc == null) throw new NullPointerException("bcc");
664
665 if (containsKey(bcc)) {
666 ClassLoader cl = bcc.getClass().getClassLoader();
667
668 return cl != null ? cl.getResourceAsStream(name)
669 : ClassLoader.getSystemResourceAsStream(name);
670 } else throw new IllegalArgumentException("Not a valid child");
671 }
672
673 /**
674 * @param name the name of the resource requested.
675 * @param bcc the child object making the request.
676 *
677 * @return the requested resource as an InputStream
678 */
679
680 public URL getResource(String name, BeanContextChild bcc) {
681 if (name == null) throw new NullPointerException("name");
682 if (bcc == null) throw new NullPointerException("bcc");
683
684 if (containsKey(bcc)) {
685 ClassLoader cl = bcc.getClass().getClassLoader();
686
687 return cl != null ? cl.getResource(name)
688 : ClassLoader.getSystemResource(name);
689 } else throw new IllegalArgumentException("Not a valid child");
690 }
691
692 /**
693 * Sets the new design time value for this <tt>BeanContext</tt>.
694 * @param dTime the new designTime value
695 */
696 public synchronized void setDesignTime(boolean dTime) {
697 if (designTime != dTime) {
698 designTime = dTime;
699
700 firePropertyChange("designMode", Boolean.valueOf(!dTime), Boolean.valueOf(dTime));
701 }
702 }
703
704
705 /**
706 * Reports whether or not this object is in
707 * currently in design time mode.
708 * @return <tt>true</tt> if in design time mode,
709 * <tt>false</tt> if not
710 */
711 public synchronized boolean isDesignTime() { return designTime; }
712
713 /**
714 * Sets the locale of this BeanContext.
715 * @param newLocale the new locale. This method call will have
716 * no effect if newLocale is <CODE>null</CODE>.
717 * @throws PropertyVetoException if the new value is rejected
718 */
719 public synchronized void setLocale(Locale newLocale) throws PropertyVetoException {
720
721 if ((locale != null && !locale.equals(newLocale)) && newLocale != null) {
722 Locale old = locale;
723
724 fireVetoableChange("locale", old, newLocale); // throws
725
726 locale = newLocale;
727
728 firePropertyChange("locale", old, newLocale);
729 }
730 }
731
732 /**
733 * Gets the locale for this <tt>BeanContext</tt>.
734 *
735 * @return the current Locale of the <tt>BeanContext</tt>
736 */
737 public synchronized Locale getLocale() { return locale; }
738
739 /**
740 * <p>
741 * This method is typically called from the environment in order to determine
742 * if the implementor "needs" a GUI.
743 * </p>
744 * <p>
745 * The algorithm used herein tests the BeanContextPeer, and its current children
746 * to determine if they are either Containers, Components, or if they implement
747 * Visibility and return needsGui() == true.
748 * </p>
749 * @return <tt>true</tt> if the implementor needs a GUI
750 */
751 public synchronized boolean needsGui() {
752 BeanContext bc = getBeanContextPeer();
753
754 if (bc != this) {
755 if (bc instanceof Visibility) return ((Visibility)bc).needsGui();
756
757 if (bc instanceof Container || bc instanceof Component)
758 return true;
759 }
760
761 synchronized(children) {
762 for (Iterator i = children.keySet().iterator(); i.hasNext();) {
763 Object c = i.next();
764
765 try {
766 return ((Visibility)c).needsGui();
767 } catch (ClassCastException cce) {
768 // do nothing ...
769 }
770
771 if (c instanceof Container || c instanceof Component)
772 return true;
773 }
774 }
775
776 return false;
777 }
778
779 /**
780 * notify this instance that it may no longer render a GUI.
781 */
782
783 public synchronized void dontUseGui() {
784 if (okToUseGui) {
785 okToUseGui = false;
786
787 // lets also tell the Children that can that they may not use their GUI's
788 synchronized(children) {
789 for (Iterator i = children.keySet().iterator(); i.hasNext();) {
790 Visibility v = getChildVisibility(i.next());
791
792 if (v != null) v.dontUseGui();
793 }
794 }
795 }
796 }
797
798 /**
799 * Notify this instance that it may now render a GUI
800 */
801
802 public synchronized void okToUseGui() {
803 if (!okToUseGui) {
804 okToUseGui = true;
805
806 // lets also tell the Children that can that they may use their GUI's
807 synchronized(children) {
808 for (Iterator i = children.keySet().iterator(); i.hasNext();) {
809 Visibility v = getChildVisibility(i.next());
810
811 if (v != null) v.okToUseGui();
812 }
813 }
814 }
815 }
816
817 /**
818 * Used to determine if the <tt>BeanContext</tt>
819 * child is avoiding using its GUI.
820 * @return is this instance avoiding using its GUI?
821 * @see Visibility
822 */
823 public boolean avoidingGui() {
824 return !okToUseGui && needsGui();
825 }
826
827 /**
828 * Is this <tt>BeanContext</tt> in the
829 * process of being serialized?
830 * @return if this <tt>BeanContext</tt> is
831 * currently being serialized
832 */
833 public boolean isSerializing() { return serializing; }
834
835 /**
836 * Returns an iterator of all children
837 * of this <tt>BeanContext</tt>.
838 * @return an iterator for all the current BCSChild values
839 */
840 protected Iterator bcsChildren() { synchronized(children) { return children.values().iterator(); } }
841
842 /**
843 * called by writeObject after defaultWriteObject() but prior to
844 * serialization of currently serializable children.
845 *
846 * This method may be overridden by subclasses to perform custom
847 * serialization of their state prior to this superclass serializing
848 * the children.
849 *
850 * This method should not however be used by subclasses to replace their
851 * own implementation (if any) of writeObject().
852 */
853
854 protected void bcsPreSerializationHook(ObjectOutputStream oos) throws IOException {
855 }
856
857 /**
858 * called by readObject after defaultReadObject() but prior to
859 * deserialization of any children.
860 *
861 * This method may be overridden by subclasses to perform custom
862 * deserialization of their state prior to this superclass deserializing
863 * the children.
864 *
865 * This method should not however be used by subclasses to replace their
866 * own implementation (if any) of readObject().
867 */
868
869 protected void bcsPreDeserializationHook(ObjectInputStream ois) throws IOException, ClassNotFoundException {
870 }
871
872 /**
873 * Called by readObject with the newly deserialized child and BCSChild.
874 * @param child the newly deserialized child
875 * @param bcsc the newly deserialized BCSChild
876 */
877 protected void childDeserializedHook(Object child, BCSChild bcsc) {
878 synchronized(children) {
879 children.put(child, bcsc);
880 }
881 }
882
883 /**
884 * Used by writeObject to serialize a Collection.
885 * @param oos the <tt>ObjectOutputStream</tt>
886 * to use during serialization
887 * @param coll the <tt>Collection</tt> to serialize
888 * @throws IOException if serialization failed
889 */
890 protected final void serialize(ObjectOutputStream oos, Collection coll) throws IOException {
891 int count = 0;
892 Object[] objects = coll.toArray();
893
894 for (int i = 0; i < objects.length; i++) {
895 if (objects[i] instanceof Serializable)
896 count++;
897 else
898 objects[i] = null;
899 }
900
901 oos.writeInt(count); // number of subsequent objects
902
903 for (int i = 0; count > 0; i++) {
904 Object o = objects[i];
905
906 if (o != null) {
907 oos.writeObject(o);
908 count--;
909 }
910 }
911 }
912
913 /**
914 * used by readObject to deserialize a collection.
915 * @param ois the ObjectInputStream to use
916 * @param coll the Collection
917 */
918 protected final void deserialize(ObjectInputStream ois, Collection coll) throws IOException, ClassNotFoundException {
919 int count = 0;
920
921 count = ois.readInt();
922
923 while (count-- > 0) {
924 coll.add(ois.readObject());
925 }
926 }
927
928 /**
929 * Used to serialize all children of
930 * this <tt>BeanContext</tt>.
931 * @param oos the <tt>ObjectOutputStream</tt>
932 * to use during serialization
933 * @throws IOException if serialization failed
934 */
935 public final void writeChildren(ObjectOutputStream oos) throws IOException {
936 if (serializable <= 0) return;
937
938 boolean prev = serializing;
939
940 serializing = true;
941
942 int count = 0;
943
944 synchronized(children) {
945 Iterator i = children.entrySet().iterator();
946
947 while (i.hasNext() && count < serializable) {
948 Map.Entry entry = (Map.Entry)i.next();
949
950 if (entry.getKey() instanceof Serializable) {
951 try {
952 oos.writeObject(entry.getKey()); // child
953 oos.writeObject(entry.getValue()); // BCSChild
954 } catch (IOException ioe) {
955 serializing = prev;
956 throw ioe;
957 }
958 count++;
959 }
960 }
961 }
962
963 serializing = prev;
964
965 if (count != serializable) {
966 throw new IOException("wrote different number of children than expected");
967 }
968
969 }
970
971 /**
972 * Serialize the BeanContextSupport, if this instance has a distinct
973 * peer (that is this object is acting as a delegate for another) then
974 * the children of this instance are not serialized here due to a
975 * 'chicken and egg' problem that occurs on deserialization of the
976 * children at the same time as this instance.
977 *
978 * Therefore in situations where there is a distinct peer to this instance
979 * it should always call writeObject() followed by writeChildren() and
980 * readObject() followed by readChildren().
981 *
982 * @param oos the ObjectOutputStream
983 */
984
985 private synchronized void writeObject(ObjectOutputStream oos) throws IOException, ClassNotFoundException {
986 serializing = true;
987
988 synchronized (BeanContext.globalHierarchyLock) {
989 try {
990 oos.defaultWriteObject(); // serialize the BeanContextSupport object
991
992 bcsPreSerializationHook(oos);
993
994 if (serializable > 0 && this.equals(getBeanContextPeer()))
995 writeChildren(oos);
996
997 serialize(oos, (Collection)bcmListeners);
998 } finally {
999 serializing = false;
1000 }
1001 }
1002 }
1003
1004 /**
1005 * When an instance of this class is used as a delegate for the
1006 * implementation of the BeanContext protocols (and its subprotocols)
1007 * there exists a 'chicken and egg' problem during deserialization
1008 */
1009
1010 public final void readChildren(ObjectInputStream ois) throws IOException, ClassNotFoundException {
1011 int count = serializable;
1012
1013 while (count-- > 0) {
1014 Object child = null;
1015 BeanContextSupport.BCSChild bscc = null;
1016
1017 try {
1018 child = ois.readObject();
1019 bscc = (BeanContextSupport.BCSChild)ois.readObject();
1020 } catch (IOException ioe) {
1021 continue;
1022 } catch (ClassNotFoundException cnfe) {
1023 continue;
1024 }
1025
1026
1027 synchronized(child) {
1028 BeanContextChild bcc = null;
1029
1030 try {
1031 bcc = (BeanContextChild)child;
1032 } catch (ClassCastException cce) {
1033 // do nothing;
1034 }
1035
1036 if (bcc != null) {
1037 try {
1038 bcc.setBeanContext(getBeanContextPeer());
1039
1040 bcc.addPropertyChangeListener("beanContext", childPCL);
1041 bcc.addVetoableChangeListener("beanContext", childVCL);
1042
1043 } catch (PropertyVetoException pve) {
1044 continue;
1045 }
1046 }
1047
1048 childDeserializedHook(child, bscc);
1049 }
1050 }
1051 }
1052
1053 /**
1054 * deserialize contents ... if this instance has a distinct peer the
1055 * children are *not* serialized here, the peer's readObject() must call
1056 * readChildren() after deserializing this instance.
1057 */
1058
1059 private synchronized void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
1060
1061 synchronized(BeanContext.globalHierarchyLock) {
1062 ois.defaultReadObject();
1063
1064 initialize();
1065
1066 bcsPreDeserializationHook(ois);
1067
1068 if (serializable > 0 && this.equals(getBeanContextPeer()))
1069 readChildren(ois);
1070
1071 deserialize(ois, bcmListeners = new ArrayList(1));
1072 }
1073 }
1074
1075 /**
1076 * subclasses may envelope to monitor veto child property changes.
1077 */
1078
1079 public void vetoableChange(PropertyChangeEvent pce) throws PropertyVetoException {
1080 String propertyName = pce.getPropertyName();
1081 Object source = pce.getSource();
1082
1083 synchronized(children) {
1084 if ("beanContext".equals(propertyName) &&
1085 containsKey(source) &&
1086 !getBeanContextPeer().equals(pce.getNewValue())
1087 ) {
1088 if (!validatePendingRemove(source)) {
1089 throw new PropertyVetoException("current BeanContext vetoes setBeanContext()", pce);
1090 } else ((BCSChild)children.get(source)).setRemovePending(true);
1091 }
1092 }
1093 }
1094
1095 /**
1096 * subclasses may envelope to monitor child property changes.
1097 */
1098
1099 public void propertyChange(PropertyChangeEvent pce) {
1100 String propertyName = pce.getPropertyName();
1101 Object source = pce.getSource();
1102
1103 synchronized(children) {
1104 if ("beanContext".equals(propertyName) &&
1105 containsKey(source) &&
1106 ((BCSChild)children.get(source)).isRemovePending()) {
1107 BeanContext bc = getBeanContextPeer();
1108
1109 if (bc.equals(pce.getOldValue()) && !bc.equals(pce.getNewValue())) {
1110 remove(source, false);
1111 } else {
1112 ((BCSChild)children.get(source)).setRemovePending(false);
1113 }
1114 }
1115 }
1116 }
1117
1118 /**
1119 * <p>
1120 * Subclasses of this class may override, or envelope, this method to
1121 * add validation behavior for the BeanContext to examine child objects
1122 * immediately prior to their being added to the BeanContext.
1123 * </p>
1124 *
1125 * @return true iff the child may be added to this BeanContext, otherwise false.
1126 */
1127
1128 protected boolean validatePendingAdd(Object targetChild) {
1129 return true;
1130 }
1131
1132 /**
1133 * <p>
1134 * Subclasses of this class may override, or envelope, this method to
1135 * add validation behavior for the BeanContext to examine child objects
1136 * immediately prior to their being removed from the BeanContext.
1137 * </p>
1138 *
1139 * @return true iff the child may be removed from this BeanContext, otherwise false.
1140 */
1141
1142 protected boolean validatePendingRemove(Object targetChild) {
1143 return true;
1144 }
1145
1146 /**
1147 * subclasses may override this method to simply extend add() semantics
1148 * after the child has been added and before the event notification has
1149 * occurred. The method is called with the child synchronized.
1150 */
1151
1152 protected void childJustAddedHook(Object child, BCSChild bcsc) {
1153 }
1154
1155 /**
1156 * subclasses may override this method to simply extend remove() semantics
1157 * after the child has been removed and before the event notification has
1158 * occurred. The method is called with the child synchronized.
1159 */
1160
1161 protected void childJustRemovedHook(Object child, BCSChild bcsc) {
1162 }
1163
1164 /**
1165 * Gets the Component (if any) associated with the specified child.
1166 * @param child the specified child
1167 * @return the Component (if any) associated with the specified child.
1168 */
1169 protected static final Visibility getChildVisibility(Object child) {
1170 try {
1171 return (Visibility)child;
1172 } catch (ClassCastException cce) {
1173 return null;
1174 }
1175 }
1176
1177 /**
1178 * Gets the Serializable (if any) associated with the specified Child
1179 * @param child the specified child
1180 * @return the Serializable (if any) associated with the specified Child
1181 */
1182 protected static final Serializable getChildSerializable(Object child) {
1183 try {
1184 return (Serializable)child;
1185 } catch (ClassCastException cce) {
1186 return null;
1187 }
1188 }
1189
1190 /**
1191 * Gets the PropertyChangeListener
1192 * (if any) of the specified child
1193 * @param child the specified child
1194 * @return the PropertyChangeListener (if any) of the specified child
1195 */
1196 protected static final PropertyChangeListener getChildPropertyChangeListener(Object child) {
1197 try {
1198 return (PropertyChangeListener)child;
1199 } catch (ClassCastException cce) {
1200 return null;
1201 }
1202 }
1203
1204 /**
1205 * Gets the VetoableChangeListener
1206 * (if any) of the specified child
1207 * @param child the specified child
1208 * @return the VetoableChangeListener (if any) of the specified child
1209 */
1210 protected static final VetoableChangeListener getChildVetoableChangeListener(Object child) {
1211 try {
1212 return (VetoableChangeListener)child;
1213 } catch (ClassCastException cce) {
1214 return null;
1215 }
1216 }
1217
1218 /**
1219 * Gets the BeanContextMembershipListener
1220 * (if any) of the specified child
1221 * @param child the specified child
1222 * @return the BeanContextMembershipListener (if any) of the specified child
1223 */
1224 protected static final BeanContextMembershipListener getChildBeanContextMembershipListener(Object child) {
1225 try {
1226 return (BeanContextMembershipListener)child;
1227 } catch (ClassCastException cce) {
1228 return null;
1229 }
1230 }
1231
1232 /**
1233 * Gets the BeanContextChild (if any) of the specified child
1234 * @param child the specified child
1235 * @return the BeanContextChild (if any) of the specified child
1236 * @throws IllegalArgumentException if child implements both BeanContextChild and BeanContextProxy
1237 */
1238 protected static final BeanContextChild getChildBeanContextChild(Object child) {
1239 try {
1240 BeanContextChild bcc = (BeanContextChild)child;
1241
1242 if (child instanceof BeanContextChild && child instanceof BeanContextProxy)
1243 throw new IllegalArgumentException("child cannot implement both BeanContextChild and BeanContextProxy");
1244 else
1245 return bcc;
1246 } catch (ClassCastException cce) {
1247 try {
1248 return ((BeanContextProxy)child).getBeanContextProxy();
1249 } catch (ClassCastException cce1) {
1250 return null;
1251 }
1252 }
1253 }
1254
1255 /**
1256 * Fire a BeanContextshipEvent on the BeanContextMembershipListener interface
1257 */
1258
1259 protected final void fireChildrenAdded(BeanContextMembershipEvent bcme) {
1260 Object[] copy;
1261
1262 synchronized(bcmListeners) { copy = bcmListeners.toArray(); }
1263
1264 for (int i = 0; i < copy.length; i++)
1265 ((BeanContextMembershipListener)copy[i]).childrenAdded(bcme);
1266 }
1267
1268 /**
1269 * Fire a BeanContextshipEvent on the BeanContextMembershipListener interface
1270 */
1271
1272 protected final void fireChildrenRemoved(BeanContextMembershipEvent bcme) {
1273 Object[] copy;
1274
1275 synchronized(bcmListeners) { copy = bcmListeners.toArray(); }
1276
1277 for (int i = 0; i < copy.length; i++)
1278 ((BeanContextMembershipListener)copy[i]).childrenRemoved(bcme);
1279 }
1280
1281 /**
1282 * protected method called from constructor and readObject to initialize
1283 * transient state of BeanContextSupport instance.
1284 *
1285 * This class uses this method to instantiate inner class listeners used
1286 * to monitor PropertyChange and VetoableChange events on children.
1287 *
1288 * subclasses may envelope this method to add their own initialization
1289 * behavior
1290 */
1291
1292 protected synchronized void initialize() {
1293 children = new HashMap(serializable + 1);
1294 bcmListeners = new ArrayList(1);
1295
1296 childPCL = new PropertyChangeListener() {
1297
1298 /*
1299 * this adaptor is used by the BeanContextSupport class to forward
1300 * property changes from a child to the BeanContext, avoiding
1301 * accidential serialization of the BeanContext by a badly
1302 * behaved Serializable child.
1303 */
1304
1305 public void propertyChange(PropertyChangeEvent pce) {
1306 BeanContextSupport.this.propertyChange(pce);
1307 }
1308 };
1309
1310 childVCL = new VetoableChangeListener() {
1311
1312 /*
1313 * this adaptor is used by the BeanContextSupport class to forward
1314 * vetoable changes from a child to the BeanContext, avoiding
1315 * accidential serialization of the BeanContext by a badly
1316 * behaved Serializable child.
1317 */
1318
1319 public void vetoableChange(PropertyChangeEvent pce) throws PropertyVetoException {
1320 BeanContextSupport.this.vetoableChange(pce);
1321 }
1322 };
1323 }
1324
1325 /**
1326 * Gets a copy of the this BeanContext's children.
1327 * @return a copy of the current nested children
1328 */
1329 protected final Object[] copyChildren() {
1330 synchronized(children) { return children.keySet().toArray(); }
1331 }
1332
1333 /**
1334 * Tests to see if two class objects,
1335 * or their names are equal.
1336 * @param first the first object
1337 * @param second the second object
1338 * @return true if equal, false if not
1339 */
1340 protected static final boolean classEquals(Class first, Class second) {
1341 return first.equals(second) || first.getName().equals(second.getName());
1342 }
1343
1344
1345 /*
1346 * fields
1347 */
1348
1349
1350 /**
1351 * all accesses to the <code> protected HashMap children </code> field
1352 * shall be synchronized on that object.
1353 */
1354 protected transient HashMap children;
1355
1356 private int serializable = 0; // children serializable
1357
1358 /**
1359 * all accesses to the <code> protected ArrayList bcmListeners </code> field
1360 * shall be synchronized on that object.
1361 */
1362 protected transient ArrayList bcmListeners;
1363
1364 //
1365
1366 /**
1367 * The current locale of this BeanContext.
1368 */
1369 protected Locale locale;
1370
1371 /**
1372 * A <tt>boolean</tt> indicating if this
1373 * instance may now render a GUI.
1374 */
1375 protected boolean okToUseGui;
1376
1377
1378 /**
1379 * A <tt>boolean</tt> indicating whether or not
1380 * this object is currently in design time mode.
1381 */
1382 protected boolean designTime;
1383
1384 /*
1385 * transient
1386 */
1387
1388 private transient PropertyChangeListener childPCL;
1389
1390 private transient VetoableChangeListener childVCL;
1391
1392 private transient boolean serializing;
1393}
java/pkg/java/beans/beancontext/mkfile+25−0
@@ -0,0 +1,25 @@
1<../../../../../mkconfig
2
3TARG=\
4 BeanContext.dis\
5 BeanContextChild.dis\
6 BeanContextChildComponentProxy.dis\
7 BeanContextChildSupport.dis\
8 BeanContextContainerProxy.dis\
9 BeanContextEvent.dis\
10 BeanContextMembershipEvent.dis\
11 BeanContextMembershipListener.dis\
12 BeanContextProxy.dis\
13 BeanContextServiceAvailableEvent.dis\
14 BeanContextServiceProvider.dis\
15 BeanContextServiceProviderBeanInfo.dis\
16 BeanContextServiceRevokedEvent.dis\
17 BeanContextServiceRevokedListener.dis\
18 BeanContextServices.dis\
19 BeanContextServicesListener.dis\
20 BeanContextServicesSupport.dis\
21 BeanContextSupport.dis\
22
23DISBIN=$ROOT/java/dis/java/java/java/beans/beancontext
24
25<$ROOT/mkfiles/mkjava
java/pkg/java/beans/beancontext/package.html+55−0
@@ -0,0 +1,55 @@
1<!--
2 Copyright (c) 1998, 1999, Oracle and/or its affiliates. All rights reserved.
3 DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
5 This code is free software; you can redistribute it and/or modify it
6 under the terms of the GNU General Public License version 2 only, as
7 published by the Free Software Foundation. Oracle designates this
8 particular file as subject to the "Classpath" exception as provided
9 by Oracle in the LICENSE file that accompanied this code.
10
11 This code is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 version 2 for more details (a copy is included in the LICENSE file that
15 accompanied this code).
16
17 You should have received a copy of the GNU General Public License version
18 2 along with this work; if not, write to the Free Software Foundation,
19 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
21 Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 or visit www.oracle.com if you need additional information or have any
23 questions.
24-->
25
26<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
27<html>
28<body bgcolor="white">
29
30Provides classes and interfaces relating to bean context.
31A bean context is a container for beans and defines the execution
32environment for the beans it contains. There can be several beans in
33a single bean context, and a bean context can be nested within another
34bean context. This package also contains events and listener
35interface for beans being added and removed from a bean context.
36
37<!--
38<h2>Package Specification</h2>
39
40##### FILL IN ANY SPECS NEEDED BY JAVA COMPATIBILITY KIT #####
41<ul>
42 <li><a href="">##### REFER TO ANY FRAMEMAKER SPECIFICATION HERE #####</a>
43</ul>
44
45<h2>Related Documentation</h2>
46
47For overviews, tutorials, examples, guides, and tool documentation, please see:
48<ul>
49 <li><a href="">##### REFER TO NON-SPEC DOCUMENTATION HERE #####</a>
50</ul>
51-->
52
53@since 1.2
54</body>
55</html>
java/pkg/java/beans/java_awt_AWTKeyStroke_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_awt_BorderLayout_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_awt_CardLayout_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_awt_Choice_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_awt_Component_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_awt_Container_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_awt_Font_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_awt_GridBagLayout_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_awt_Insets_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_awt_List_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_awt_MenuBar_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_awt_MenuShortcut_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_awt_Menu_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_awt_SystemColor_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_awt_font_TextAttribute_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_beans_beancontext_BeanContextSupport_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_lang_Class_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_lang_String_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_lang_reflect_Field_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_lang_reflect_Method_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_sql_Timestamp_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_util_AbstractCollection_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_util_AbstractList_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_util_AbstractMap_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_util_Collection_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_util_Collections$CheckedCollection_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_util_Collections$CheckedList_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_util_Collections$CheckedMap_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_util_Collections$CheckedRandomAccessList_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_util_Collections$CheckedSet_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_util_Collections$CheckedSortedMap_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_util_Collections$CheckedSortedSet_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_util_Collections$EmptyList_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_util_Collections$EmptyMap_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_util_Collections$EmptySet_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_util_Collections$SingletonList_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_util_Collections$SingletonMap_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_util_Collections$SingletonSet_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_util_Collections$SynchronizedCollection_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_util_Collections$SynchronizedList_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_util_Collections$SynchronizedMap_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_util_Collections$SynchronizedRandomAccessList_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_util_Collections$SynchronizedSet_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_util_Collections$SynchronizedSortedMap_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_util_Collections$SynchronizedSortedSet_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_util_Collections$UnmodifiableCollection_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_util_Collections$UnmodifiableList_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_util_Collections$UnmodifiableMap_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_util_Collections$UnmodifiableRandomAccessList_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_util_Collections$UnmodifiableSet_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_util_Collections$UnmodifiableSortedMap_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_util_Collections$UnmodifiableSortedSet_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_util_Collections.class+0−0

Binary file not shown.

java/pkg/java/beans/java_util_Date_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_util_EnumMap_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_util_EnumSet_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_util_Hashtable_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_util_List_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/java_util_Map_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/javax_swing_Box_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/javax_swing_DefaultComboBoxModel_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/javax_swing_DefaultListModel_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/javax_swing_JFrame_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/javax_swing_JMenu_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/javax_swing_JTabbedPane_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/javax_swing_ToolTipManager_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/javax_swing_border_MatteBorder_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/javax_swing_tree_DefaultMutableTreeNode_PersistenceDelegate.class+0−0

Binary file not shown.

java/pkg/java/beans/mkfile+54−0
@@ -0,0 +1,54 @@
1<../../../../mkconfig
2
3DIRS=\
4 beancontext\
5
6TARG=\
7 AppletInitializer.dis\
8 BeanDescriptor.dis\
9 BeanInfo.dis\
10 Beans.dis\
11 ChangeListenerMap.dis\
12 ConstructorProperties.dis\
13 Customizer.dis\
14 DefaultPersistenceDelegate.dis\
15 DesignMode.dis\
16 Encoder.dis\
17 EventHandler.dis\
18 EventSetDescriptor.dis\
19 ExceptionListener.dis\
20 Expression.dis\
21 FeatureDescriptor.dis\
22 IndexedPropertyChangeEvent.dis\
23 IndexedPropertyDescriptor.dis\
24 IntrospectionException.dis\
25 Introspector.dis\
26 MetaData.dis\
27 MethodDescriptor.dis\
28 NameGenerator.dis\
29 ParameterDescriptor.dis\
30 PersistenceDelegate.dis\
31 PropertyChangeEvent.dis\
32 PropertyChangeListener.dis\
33 PropertyChangeListenerProxy.dis\
34 PropertyChangeSupport.dis\
35 PropertyDescriptor.dis\
36 PropertyEditor.dis\
37 PropertyEditorManager.dis\
38 PropertyEditorSupport.dis\
39 PropertyVetoException.dis\
40 ReflectionUtils.dis\
41 SimpleBeanInfo.dis\
42 Statement.dis\
43 Transient.dis\
44 VetoableChangeListener.dis\
45 VetoableChangeListenerProxy.dis\
46 VetoableChangeSupport.dis\
47 Visibility.dis\
48 XMLDecoder.dis\
49 XMLEncoder.dis\
50
51DISBIN=$ROOT/java/dis/java/java/java/beans
52
53<$ROOT/mkfiles/mkjava
54<$ROOT/mkfiles/mksubdirs
java/pkg/java/beans/package.html+156−0
@@ -0,0 +1,156 @@
1<!--
2 Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
3 DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
5 This code is free software; you can redistribute it and/or modify it
6 under the terms of the GNU General Public License version 2 only, as
7 published by the Free Software Foundation. Oracle designates this
8 particular file as subject to the "Classpath" exception as provided
9 by Oracle in the LICENSE file that accompanied this code.
10
11 This code is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 version 2 for more details (a copy is included in the LICENSE file that
15 accompanied this code).
16
17 You should have received a copy of the GNU General Public License version
18 2 along with this work; if not, write to the Free Software Foundation,
19 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
21 Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 or visit www.oracle.com if you need additional information or have any
23 questions.
24-->
25
26<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
27<html>
28<body bgcolor="white">
29
30Contains classes related to developing
31<em>beans</em> -- components
32based on the JavaBeans&trade; architecture.
33A few of the
34classes are used by beans while they run in an application.
35For example, the event classes are
36used by beans that fire property and vetoable change
37events (see
38{@link java.beans.PropertyChangeEvent}). However, most of the classes in this
39package are meant to be used by a bean editor (that is, a development environment
40for customizing and putting together beans to create an application). In
41particular, these classes help the bean editor create a user
42interface that the user can use to customize the bean. For example, a bean may
43contain a property of a special type that a bean editor may not know how to handle.
44By using the <code>PropertyEditor</code> interface, a bean developer can
45provide an editor for this special type.
46
47<p>
48To minimize the resources used by a bean, the classes used by bean editors are loaded only
49when the bean is being edited. They are not needed while the bean is running in an application
50and therefore not loaded. This information is kept in what's called a bean-info (see {@link java.beans.BeanInfo}).
51
52<p>
53Unless explicitly stated, null values or empty Strings are not valid
54parameters for the methods in this package. You may expect to see
55exceptions if these parameters are used.
56
57
58<h2>Long-Term Persistence</h2>
59
60As of v1.4,
61the <code>java.beans</code> package provides support for
62<em>long-term persistence</em> -- reading and
63writing a bean as a textual representation of its property values.
64The property values are treated as beans,
65and are recursively read or written to capture
66their publicly available state.
67This approach is suitable for long-term storage
68because it relies only on public API,
69rather than the likely-to-change private implementation.
70
71<blockquote>
72<hr>
73<b>Note:</b>
74The persistence scheme cannot automatically instantiate
75custom inner classes, such as you might use for event handlers.
76By using the {@link java.beans.EventHandler} class
77instead of inner classes for custom event handlers,
78you can avoid this problem.
79<hr>
80</blockquote>
81
82<p>
83
84You read and write beans in XML format using the
85{@link java.beans.XMLDecoder}
86and
87{@link java.beans.XMLEncoder}
88classes, respectively.
89One notable feature of the persistence scheme is that
90reading in a bean requires no special knowledge of the bean.
91
92<p>
93Writing out a bean, on the other hand,
94sometimes requires special knowledge of the bean's type.
95If the bean's state can be
96expressed using only the no-argument constructor and
97public getter and setter methods for properties,
98no special knowledge is required.
99Otherwise, the bean requires a custom <em>persistence delegate</em> --
100an object that is in charge of writing out beans of a particular type.
101All classes provided in the JDK that descend
102from <code>java.awt.Component</code>,
103as well as all their properties,
104automatically have persistence delegates.
105
106<p>
107
108If you need (or choose) to provide a persistence delegate for a bean,
109you can do so either by using a
110{@link java.beans.DefaultPersistenceDelegate}
111instance
112or by creating your own subclass of <code>PersistenceDelegate</code>.
113If the only reason a bean needs a persistence delegate
114is because you want to invoke the bean's constructor with
115property values as arguments,
116you can create the bean's persistence delegate
117with the one-argument
118<code>DefaultPersistenceDelegate</code>
119constructor.
120Otherwise,
121you need to implement your own persistence delegate,
122for which you're likely to need the following classes:
123
124<dl>
125<dt> {@link java.beans.PersistenceDelegate}
126<dd> The abstract class from which all persistence delegates descend.
127 Your subclass should use its knowledge of the bean's type to provide
128 whatever <code>Statement</code>s and <code>Expression</code>s
129 are necessary to create the bean
130 and restore its state.
131<dt> {@link java.beans.Statement}
132<dd> Represents the invocation of a single method on an object.
133 Includes a set of arguments to the method.
134<dt> {@link java.beans.Expression}
135<dd> A subclass of <code>Statement</code>
136 used for methods that return a value.
137</dl>
138
139<p>
140Once you create a persistence delegate,
141you register it using the
142<code>setPersistenceDelegate</code> method of
143<code>XMLEncoder</code>.
144
145
146<h2>Related Documentation</h2>
147
148For overview, architecture, and tutorial documentation, please see:
149<ul>
150 <li><a href="http://java.sun.com/docs/books/tutorial/javabeans/">JavaBeans</a>, a trail in <em>The Java Tutorial</em>.
151 <li><a href="http://java.sun.com/products/jfc/tsc/articles/persistence2/">Long-Term Persistence</a>, an article in <em>The Swing Connection</em>.
152</ul>
153<p>
154
155</body>
156</html>
java/pkg/java/beans/sun_swing_PrintColorUIResource_PersistenceDelegate.class+0−0

Binary file not shown.