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+
26+package java.beans;
27+
28+import java.applet.Applet;
29+
30+import 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+
47+public 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+
26+package java.beans;
27+
28+import 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+
38+public 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+
26+package 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+
52+public 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+
26+package java.beans;
27+
28+import com.sun.beans.finder.ClassFinder;
29+
30+import java.applet.Applet;
31+import java.applet.AppletContext;
32+import java.applet.AppletStub;
33+import java.applet.AudioClip;
34+
35+import java.awt.GraphicsEnvironment;
36+import java.awt.Image;
37+
38+import java.beans.beancontext.BeanContext;
39+
40+import java.io.IOException;
41+import java.io.InputStream;
42+import java.io.ObjectInputStream;
43+import java.io.ObjectStreamClass;
44+import java.io.StreamCorruptedException;
45+
46+import java.net.URL;
47+
48+import java.security.AccessController;
49+import java.security.PrivilegedAction;
50+
51+import java.util.Enumeration;
52+import java.util.Hashtable;
53+import java.util.Iterator;
54+import java.util.Vector;
55+
56+import sun.awt.AppContext;
57+
58+/**
59+ * This class provides some general purpose beans control methods.
60+ */
61+
62+public 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+
478+class 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+
512+class 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+ */
596+class 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+ */
25+package java.beans;
26+
27+import java.util.ArrayList;
28+import java.util.Collections;
29+import java.util.EventListener;
30+import java.util.EventListenerProxy;
31+import java.util.HashMap;
32+import java.util.List;
33+import java.util.Map;
34+import java.util.Map.Entry;
35+import 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+ */
47+abstract 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+
26+package java.beans;
27+
28+import java.lang.annotation.*;
29+import static java.lang.annotation.ElementType.*;
30+import 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)
69+public @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+
26+package 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+
38+public 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+ */
25+package java.beans;
26+
27+import java.util.*;
28+import java.lang.reflect.*;
29+import java.util.Objects;
30+import 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+
60+public 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+
26+package 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+
49+public 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+ */
25+package java.beans;
26+
27+import com.sun.beans.finder.PersistenceDelegateFinder;
28+
29+import java.util.HashMap;
30+import java.util.IdentityHashMap;
31+import 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+
48+public 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+ */
25+package java.beans;
26+
27+import java.lang.reflect.InvocationHandler;
28+import java.lang.reflect.InvocationTargetException;
29+import java.lang.reflect.Proxy;
30+import java.lang.reflect.Method;
31+import java.security.AccessControlContext;
32+import java.security.AccessController;
33+import java.security.PrivilegedAction;
34+
35+import 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+ */
278+public 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+
26+package java.beans;
27+
28+import java.lang.ref.Reference;
29+import java.lang.reflect.Method;
30+import 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+ */
40+public 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+ */
25+package java.beans;
26+
27+/**
28+ * An ExceptionListener is notified of internal exceptions.
29+ *
30+ * @since 1.4
31+ *
32+ * @author Philip Milne
33+ */
34+public 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+
26+package 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+ */
47+public 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+
26+package java.beans;
27+
28+import com.sun.beans.TypeResolver;
29+
30+import java.lang.ref.Reference;
31+import java.lang.ref.WeakReference;
32+import java.lang.ref.SoftReference;
33+
34+import java.lang.reflect.Method;
35+
36+import java.util.Enumeration;
37+import java.util.Hashtable;
38+import 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+
51+public 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+ */
25+package 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+ */
43+public 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+
26+package java.beans;
27+
28+import java.lang.ref.Reference;
29+import 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+
41+public 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+
26+package 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+
37+public
38+class 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+
26+package java.beans;
27+
28+import com.sun.beans.WeakCache;
29+import com.sun.beans.finder.BeanInfoFinder;
30+import com.sun.beans.finder.ClassFinder;
31+
32+import java.awt.Component;
33+
34+import java.lang.ref.Reference;
35+import java.lang.ref.SoftReference;
36+import java.lang.reflect.Method;
37+import java.lang.reflect.Modifier;
38+
39+import java.util.Map;
40+import java.util.ArrayList;
41+import java.util.HashMap;
42+import java.util.Iterator;
43+import java.util.EventListener;
44+import java.util.EventObject;
45+import java.util.List;
46+import java.util.TreeMap;
47+import java.util.WeakHashMap;
48+
49+import sun.awt.AppContext;
50+import 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+
93+public 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+
1465+class 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+ */
25+package java.beans;
26+
27+import com.sun.beans.finder.PrimitiveWrapperMap;
28+
29+import java.awt.AWTKeyStroke;
30+import java.awt.BorderLayout;
31+import java.awt.Dimension;
32+import java.awt.Color;
33+import java.awt.Font;
34+import java.awt.GridBagConstraints;
35+import java.awt.Insets;
36+import java.awt.Point;
37+import java.awt.Rectangle;
38+import java.awt.event.KeyEvent;
39+import java.awt.font.TextAttribute;
40+
41+import java.lang.reflect.Array;
42+import java.lang.reflect.Constructor;
43+import java.lang.reflect.Field;
44+import java.lang.reflect.Method;
45+import java.lang.reflect.InvocationTargetException;
46+
47+import java.security.AccessController;
48+import java.security.PrivilegedAction;
49+
50+import java.util.*;
51+
52+import javax.swing.Box;
53+import javax.swing.JLayeredPane;
54+import javax.swing.border.MatteBorder;
55+import javax.swing.plaf.ColorUIResource;
56+
57+import sun.swing.PrintColorUIResource;
58+
59+import 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+
73+class 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+ */
90+class 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+
101+class 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+
112+class 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+
153+class 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
188+class 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
197+class 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
231+class 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
246+class 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+ */
270+class 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+ */
293+final 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+/*
339+The Hashtable and AbstractMap classes have no common ancestor yet may
340+be handled with a single persistence delegate: one which uses the methods
341+of the Map insterface exclusively. Attatching the persistence delegates
342+to the interfaces themselves is fraught however since, in the case of
343+the Map, both the AbstractMap and HashMap classes are declared to
344+implement the Map interface, leaving the obvious implementation prone
345+to repeating their initialization. These issues and questions around
346+the ordering of delegates attached to interfaces have lead us to
347+ignore any delegates attached to interfaces and force all persistence
348+delegates 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+ */
357+abstract 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+ */
572+class 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+ */
591+class 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
606+class 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
621+class 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
656+class 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+
694+class java_util_AbstractCollection_PersistenceDelegate extends java_util_Collection_PersistenceDelegate {}
695+class java_util_AbstractList_PersistenceDelegate extends java_util_List_PersistenceDelegate {}
696+class java_util_AbstractMap_PersistenceDelegate extends java_util_Map_PersistenceDelegate {}
697+class java_util_Hashtable_PersistenceDelegate extends java_util_Map_PersistenceDelegate {}
698+
699+
700+// Beans
701+class 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+ */
712+final 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+ */
736+final 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+ */
805+final 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+
846+class 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
873+class java_awt_SystemColor_PersistenceDelegate extends StaticFieldsPersistenceDelegate {}
874+
875+// TextAttribute
876+class java_awt_font_TextAttribute_PersistenceDelegate extends StaticFieldsPersistenceDelegate {}
877+
878+// MenuShortcut
879+class 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
892+class 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
939+class 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
974+class 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
986+class 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
998+class 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
1010+class 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
1025+class 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
1056+class 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
1075+class 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).
1098+class 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
1118+class 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
1132+class 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
1144+class 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
1160+class 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
1168+class 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
1183+class 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.
1204+class 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+ */
1222+final 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.
1242+class 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+ */
1264+final 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+
1276+class 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+
26+package java.beans;
27+
28+import java.lang.ref.Reference;
29+import java.lang.ref.WeakReference;
30+import java.lang.reflect.Method;
31+import java.util.List;
32+import 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+
39+public 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+ */
25+package java.beans;
26+
27+import java.util.HashMap;
28+import java.util.IdentityHashMap;
29+import java.util.Map;
30+
31+import 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+ */
44+class 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+
26+package 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+
37+public 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+ */
25+package 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+
88+public 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+
26+package 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+
46+public 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+
26+package 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+
34+public 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+
26+package java.beans;
27+
28+import 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+ */
46+public 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+ */
25+package java.beans;
26+
27+import java.io.Serializable;
28+import java.io.ObjectStreamField;
29+import java.io.ObjectOutputStream;
30+import java.io.ObjectInputStream;
31+import java.io.IOException;
32+import java.util.Hashtable;
33+import 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+ */
81+public 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+
26+package java.beans;
27+
28+import java.lang.ref.Reference;
29+import java.lang.reflect.Method;
30+import 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+ */
36+public 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+
26+package 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+
56+public 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+
26+package java.beans;
27+
28+import com.sun.beans.finder.PropertyEditorFinder;
29+import 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+
56+public 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+
26+package java.beans;
27+
28+import 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+
36+public 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+
26+package java.beans;
27+
28+
29+/**
30+ * A PropertyVetoException is thrown when a proposed change to a
31+ * property represents an unacceptable value.
32+ */
33+
34+public
35+class 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+ */
25+package java.beans;
26+
27+import java.lang.reflect.Field;
28+
29+/**
30+ * A utility class for reflectively finding methods, constuctors and fields
31+ * using reflection.
32+ */
33+class 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+
26+package 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+
39+public 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+ */
25+package java.beans;
26+
27+import java.lang.reflect.AccessibleObject;
28+import java.lang.reflect.Array;
29+import java.lang.reflect.Constructor;
30+import java.lang.reflect.InvocationTargetException;
31+import java.lang.reflect.Method;
32+import java.security.AccessControlContext;
33+import java.security.AccessController;
34+import java.security.PrivilegedActionException;
35+import java.security.PrivilegedExceptionAction;
36+
37+import com.sun.beans.finder.ClassFinder;
38+import com.sun.beans.finder.ConstructorFinder;
39+import com.sun.beans.finder.MethodFinder;
40+import 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+ */
58+public 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+
26+package java.beans;
27+
28+import java.lang.annotation.Retention;
29+import java.lang.annotation.Target;
30+
31+import static java.lang.annotation.ElementType.METHOD;
32+import 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)
66+public @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+
26+package 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+ */
33+public 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+
26+package java.beans;
27+
28+import 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+ */
46+public 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+ */
25+package java.beans;
26+
27+import java.io.Serializable;
28+import java.io.ObjectStreamField;
29+import java.io.ObjectOutputStream;
30+import java.io.ObjectInputStream;
31+import java.io.IOException;
32+import java.util.Hashtable;
33+import 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+ */
81+public 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+
26+package 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+
39+public 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+ */
25+package java.beans;
26+
27+import com.sun.beans.decoder.DocumentHandler;
28+
29+import java.io.Closeable;
30+import java.io.InputStream;
31+import java.io.IOException;
32+
33+import org.xml.sax.InputSource;
34+import 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+ */
63+public 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+ */
25+package java.beans;
26+
27+import java.io.*;
28+import java.util.*;
29+import java.lang.reflect.*;
30+import java.nio.charset.Charset;
31+import java.nio.charset.CharsetEncoder;
32+import java.nio.charset.IllegalCharsetNameException;
33+import 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+ */
207+public 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+
26+package java.beans.beancontext;
27+
28+import java.beans.DesignMode;
29+import java.beans.Visibility;
30+
31+import java.io.InputStream;
32+import java.io.IOException;
33+
34+import java.net.URL;
35+
36+import java.util.Collection;
37+import 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+
56+public 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+
26+package java.beans.beancontext;
27+
28+import java.beans.PropertyChangeListener;
29+import java.beans.VetoableChangeListener;
30+import java.beans.PropertyVetoException;
31+
32+import 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+
68+public 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+
26+package java.beans.beancontext;
27+
28+import 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+
44+public 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+
26+package java.beans.beancontext;
27+
28+import java.beans.PropertyChangeEvent;
29+import java.beans.PropertyChangeListener;
30+import java.beans.PropertyChangeSupport;
31+
32+import java.beans.VetoableChangeListener;
33+import java.beans.VetoableChangeSupport;
34+
35+import java.beans.PropertyVetoException;
36+
37+import java.io.IOException;
38+import java.io.ObjectInputStream;
39+import java.io.ObjectOutputStream;
40+import 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+
59+public 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+
26+package java.beans.beancontext;
27+
28+import 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+
43+public 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+
26+package java.beans.beancontext;
27+
28+import java.util.EventObject;
29+
30+import 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+
50+public 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+
26+package java.beans.beancontext;
27+
28+import java.util.EventObject;
29+
30+import java.beans.beancontext.BeanContext;
31+import java.beans.beancontext.BeanContextEvent;
32+
33+import java.util.Arrays;
34+import java.util.Collection;
35+import 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+ */
57+public 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+
26+package java.beans.beancontext;
27+
28+import java.beans.beancontext.BeanContextMembershipEvent;
29+
30+import 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+
43+public 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+
26+package 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+
76+public 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+
26+package java.beans.beancontext;
27+
28+import java.beans.beancontext.BeanContextChild;
29+import java.beans.beancontext.BeanContextEvent;
30+
31+import java.beans.beancontext.BeanContextServices;
32+
33+import 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+
42+public 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+
26+package java.beans.beancontext;
27+
28+import 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+
52+public 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+
26+package java.beans.beancontext;
27+
28+import 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+
38+public 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+
26+package java.beans.beancontext;
27+
28+import java.beans.beancontext.BeanContextEvent;
29+
30+import 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+ */
39+public 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+ */
25+package java.beans.beancontext;
26+
27+import java.beans.beancontext.BeanContextServiceRevokedEvent;
28+
29+import 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+ */
37+public 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+
26+package java.beans.beancontext;
27+
28+import java.util.Iterator;
29+
30+import java.util.TooManyListenersException;
31+
32+import java.beans.beancontext.BeanContext;
33+
34+import java.beans.beancontext.BeanContextServiceProvider;
35+
36+import 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+ */
45+public 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+
26+package java.beans.beancontext;
27+
28+import java.beans.beancontext.BeanContextServiceAvailableEvent;
29+import java.beans.beancontext.BeanContextServiceRevokedEvent;
30+import 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+ */
38+public 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+
26+package java.beans.beancontext;
27+
28+import java.util.ArrayList;
29+import java.util.Collection;
30+import java.util.HashMap;
31+import java.util.HashSet;
32+import java.util.Iterator;
33+import java.util.Map;
34+import java.util.Map.Entry;
35+
36+import java.io.IOException;
37+import java.io.ObjectInputStream;
38+import java.io.ObjectOutputStream;
39+import java.io.Serializable;
40+
41+import java.util.TooManyListenersException;
42+
43+import 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+
61+public 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+
26+package java.beans.beancontext;
27+
28+import java.awt.Component;
29+import java.awt.Container;
30+
31+import java.beans.Beans;
32+import java.beans.AppletInitializer;
33+
34+import java.beans.DesignMode;
35+
36+import java.beans.PropertyChangeEvent;
37+import java.beans.PropertyChangeListener;
38+import java.beans.PropertyChangeSupport;
39+
40+import java.beans.VetoableChangeListener;
41+import java.beans.VetoableChangeSupport;
42+import java.beans.PropertyVetoException;
43+
44+import java.beans.Visibility;
45+
46+import java.io.IOException;
47+import java.io.InputStream;
48+import java.io.ObjectInputStream;
49+import java.io.ObjectOutputStream;
50+import java.io.Serializable;
51+
52+import java.net.URL;
53+
54+import java.util.ArrayList;
55+import java.util.Collection;
56+import java.util.HashMap;
57+import java.util.Iterator;
58+import java.util.Locale;
59+import 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+ */
75+public 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+
3+TARG=\
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+
23+DISBIN=$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+
30+Provides classes and interfaces relating to bean context.
31+A bean context is a container for beans and defines the execution
32+environment for the beans it contains. There can be several beans in
33+a single bean context, and a bean context can be nested within another
34+bean context. This package also contains events and listener
35+interface 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+
47+For 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+
3+DIRS=\
4+ beancontext\
5+
6+TARG=\
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+
51+DISBIN=$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+
30+Contains classes related to developing
31+<em>beans</em> -- components
32+based on the JavaBeans&trade; architecture.
33+A few of the
34+classes are used by beans while they run in an application.
35+For example, the event classes are
36+used by beans that fire property and vetoable change
37+events (see
38+{@link java.beans.PropertyChangeEvent}). However, most of the classes in this
39+package are meant to be used by a bean editor (that is, a development environment
40+for customizing and putting together beans to create an application). In
41+particular, these classes help the bean editor create a user
42+interface that the user can use to customize the bean. For example, a bean may
43+contain a property of a special type that a bean editor may not know how to handle.
44+By using the <code>PropertyEditor</code> interface, a bean developer can
45+provide an editor for this special type.
46+
47+<p>
48+To minimize the resources used by a bean, the classes used by bean editors are loaded only
49+when the bean is being edited. They are not needed while the bean is running in an application
50+and therefore not loaded. This information is kept in what's called a bean-info (see {@link java.beans.BeanInfo}).
51+
52+<p>
53+Unless explicitly stated, null values or empty Strings are not valid
54+parameters for the methods in this package. You may expect to see
55+exceptions if these parameters are used.
56+
57+
58+<h2>Long-Term Persistence</h2>
59+
60+As of v1.4,
61+the <code>java.beans</code> package provides support for
62+<em>long-term persistence</em> -- reading and
63+writing a bean as a textual representation of its property values.
64+The property values are treated as beans,
65+and are recursively read or written to capture
66+their publicly available state.
67+This approach is suitable for long-term storage
68+because it relies only on public API,
69+rather than the likely-to-change private implementation.
70+
71+<blockquote>
72+<hr>
73+<b>Note:</b>
74+The persistence scheme cannot automatically instantiate
75+custom inner classes, such as you might use for event handlers.
76+By using the {@link java.beans.EventHandler} class
77+instead of inner classes for custom event handlers,
78+you can avoid this problem.
79+<hr>
80+</blockquote>
81+
82+<p>
83+
84+You read and write beans in XML format using the
85+{@link java.beans.XMLDecoder}
86+and
87+{@link java.beans.XMLEncoder}
88+classes, respectively.
89+One notable feature of the persistence scheme is that
90+reading in a bean requires no special knowledge of the bean.
91+
92+<p>
93+Writing out a bean, on the other hand,
94+sometimes requires special knowledge of the bean's type.
95+If the bean's state can be
96+expressed using only the no-argument constructor and
97+public getter and setter methods for properties,
98+no special knowledge is required.
99+Otherwise, the bean requires a custom <em>persistence delegate</em> --
100+an object that is in charge of writing out beans of a particular type.
101+All classes provided in the JDK that descend
102+from <code>java.awt.Component</code>,
103+as well as all their properties,
104+automatically have persistence delegates.
105+
106+<p>
107+
108+If you need (or choose) to provide a persistence delegate for a bean,
109+you can do so either by using a
110+{@link java.beans.DefaultPersistenceDelegate}
111+instance
112+or by creating your own subclass of <code>PersistenceDelegate</code>.
113+If the only reason a bean needs a persistence delegate
114+is because you want to invoke the bean's constructor with
115+property values as arguments,
116+you can create the bean's persistence delegate
117+with the one-argument
118+<code>DefaultPersistenceDelegate</code>
119+constructor.
120+Otherwise,
121+you need to implement your own persistence delegate,
122+for 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>
140+Once you create a persistence delegate,
141+you register it using the
142+<code>setPersistenceDelegate</code> method of
143+<code>XMLEncoder</code>.
144+
145+
146+<h2>Related Documentation</h2>
147+
148+For 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.