2 * See the file LICENSE for redistribution information.
4 * Copyright (c) 2002, 2012 Oracle and/or its affiliates. All rights reserved.
8 package com.sleepycat.util;
10 import java.beans.BeanDescriptor;
11 import java.beans.EventSetDescriptor;
12 import java.beans.IntrospectionException;
13 import java.beans.PropertyDescriptor;
14 import java.beans.SimpleBeanInfo;
15 import java.lang.reflect.Method;
16 import java.util.ArrayList;
19 * If someone add a property in some FooConfig.java,
20 * (1) If the setter/getter methods are setFoo/getFoo, the name of the
21 * property should be "foo", which means the first letter of the property
22 * name should be lower case.
23 * (2) The setter method for this property setProperty should return "this",
24 * and setPropertyVoid method which returns void value must be added.
25 * The return type of the getter method should be the same as the
26 * parameter of the setter method.
27 * (3) The setter method and getter method must be added into
29 * (4) If for some of the setter methods in the FooConfig.java, setterVoid
30 * methods are not necessary, then add the name of such setter methods
31 * into the ArrayList ignoreMethods within the corresponding
32 * FooConfigBeanInfo.getPropertyDescriptors method. For example,
33 * setMaxSeedTestHook method in DiskOrderedCursorConfig.java is only used
34 * for unit tests, so "setMaxSeedTestHook" is added into ignoreMethods
35 * list within DiskOrderedCursorConfigBeanInfo.getPropertyDescriptors.
38 * If someone adds a new FooConfig.java,
39 * (1) The definition of setter/getter mehods and the names of the properties
40 * should follow the rules described above.
41 * (2) There must be FooConfigBeanInfo.java. You can write it according to
42 * the current beaninfo classes.
43 * (3) "PackagePath.FooConfig" must be added into the unit test:
44 * com.sleepycat.db.ConfigBeanInfoTest.
46 * If someond remove an existing FooConfig.java, then "PackagePath.FooConfig"
47 * must be deleted in the unit test com.sleepycat.db.ConfigBeanInfoTest.
49 public class ConfigBeanInfoBase extends SimpleBeanInfo {
50 private static java.awt.Image iconColor16 = null;
51 private static java.awt.Image iconColor32 = null;
52 private static java.awt.Image iconMono16 = null;
53 private static java.awt.Image iconMono32 = null;
54 private static String iconNameC16 = null;
55 private static String iconNameC32 = null;
56 private static String iconNameM16 = null;
57 private static String iconNameM32 = null;
59 private static final int defaultPropertyIndex = -1;
60 private static final int defaultEventIndex = -1;
62 protected static ArrayList<String> propertiesName = new ArrayList<String>();
63 protected static ArrayList<String>
64 getterAndSetterMethods = new ArrayList<String>();
66 protected static ArrayList<String> ignoreMethods = new ArrayList<String>();
69 * Get the propertis' infomation, including all the properties's names
70 * and their getter/setter methods.
72 protected static void getPropertiesInfo(Class cls) {
73 propertiesName.clear();
74 getterAndSetterMethods.clear();
77 /* Get all of the public methods. */
78 ArrayList<String> allMethodNames = new ArrayList<String>();
79 Method[] methods = cls.getMethods();
80 for (int i = 0; i < methods.length; i++) {
81 allMethodNames.add(methods[i].getName());
83 for (int i = 0; i < allMethodNames.size(); i++) {
84 String name = allMethodNames.get(i);
85 String subName = name.substring(0, 3);
87 /* If it is a setter method. */
88 if (subName.equals("set")) {
89 if (isIgnoreMethods(name)) {
92 String propertyName = name.substring(3);
93 Method getterMethod = null;
95 getterMethod = cls.getMethod("get" + propertyName);
96 } catch (NoSuchMethodException e) {
99 if (getterMethod != null) {
100 getterAndSetterMethods.add("get" + propertyName);
101 getterAndSetterMethods.add(name + "Void");
104 * Add the real property name into propertiesName.
105 * if the names of setter/getter methods are
106 * setFoo/getFoo, the name of the property should be
110 (propertyName.substring(0, 1).toLowerCase() +
111 propertyName.substring(1));
115 } catch (SecurityException e) {
120 private static boolean isIgnoreMethods(String methodName) {
121 for (int i = 0; i < ignoreMethods.size(); i++) {
122 if (ignoreMethods.get(i).equals(methodName)) {
129 protected static PropertyDescriptor[] getPdescriptor(Class cls) {
130 getPropertiesInfo(cls);
131 final int propertyNum = propertiesName.size();
132 assert propertyNum * 2 == getterAndSetterMethods.size();
133 PropertyDescriptor[] properties = new PropertyDescriptor[propertyNum];
135 for (int i = 0, j = 0; i < propertyNum; i += 1, j += 2) {
136 properties[i] = new PropertyDescriptor
137 (propertiesName.get(i), cls, getterAndSetterMethods.get(j),
138 getterAndSetterMethods.get(j + 1));
140 } catch(IntrospectionException e) {
146 protected static BeanDescriptor getBdescriptor(Class cls) {
147 BeanDescriptor beanDescriptor = new BeanDescriptor(cls, null);
148 return beanDescriptor;
152 * Gets the bean's <code>BeanDescriptor</code>s.
154 * @return BeanDescriptor describing the editable
155 * properties of this bean. May return null if the
156 * information should be obtained by automatic analysis.
158 public BeanDescriptor getBeanDescriptor(Class cls) {
163 * Gets the bean's <code>PropertyDescriptor</code>s.
165 * @return An array of PropertyDescriptors describing the editable
166 * properties supported by this bean. May return null if the
167 * information should be obtained by automatic analysis.
169 * If a property is indexed, then its entry in the result array will
170 * belong to the IndexedPropertyDescriptor subclass of PropertyDescriptor.
171 * A client of getPropertyDescriptors can use "instanceof" to check
172 * if a given PropertyDescriptor is an IndexedPropertyDescriptor.
174 public PropertyDescriptor[] getPropertyDescriptors(Class cls) {
179 * Gets the bean's <code>EventSetDescriptor</code>s.
181 * @return An array of EventSetDescriptors describing the kinds of
182 * events fired by this bean. May return null if the information
183 * should be obtained by automatic analysis.
185 public EventSetDescriptor[] getEventSetDescriptors() {
186 EventSetDescriptor[] eventSets = new EventSetDescriptor[0];
191 * A bean may have a "default" property that is the property that will
192 * mostly commonly be initially chosen for update by human's who are
193 * customizing the bean.
194 * @return Index of default property in the PropertyDescriptor array
195 * returned by getPropertyDescriptors.
196 * <p> Returns -1 if there is no default property.
198 public int getDefaultPropertyIndex() {
199 return defaultPropertyIndex;
203 * A bean may have a "default" event that is the event that will
204 * mostly commonly be used by human's when using the bean.
205 * @return Index of default event in the EventSetDescriptor array
206 * returned by getEventSetDescriptors.
207 * <p> Returns -1 if there is no default event.
209 public int getDefaultEventIndex() {
210 return defaultEventIndex;
214 * This method returns an image object that can be used to
215 * represent the bean in toolboxes, toolbars, etc. Icon images
216 * will typically be GIFs, but may in future include other formats.
218 * Beans aren't required to provide icons and may return null from
221 * There are four possible flavors of icons (16x16 color,
222 * 32x32 color, 16x16 mono, 32x32 mono). If a bean choses to only
223 * support a single icon we recommend supporting 16x16 color.
225 * We recommend that icons have a "transparent" background
226 * so they can be rendered onto an existing background.
228 * @param iconKind The kind of icon requested. This should be
229 * one of the constant values ICON_COLOR_16x16, ICON_COLOR_32x32,
230 * ICON_MONO_16x16, or ICON_MONO_32x32.
231 * @return An image object representing the requested icon. May
232 * return null if no suitable icon is available.
234 public java.awt.Image getIcon(int iconKind) {
236 case ICON_COLOR_16x16:
237 if (iconNameC16 == null) {
240 if (iconColor16 == null) {
241 iconColor16 = loadImage(iconNameC16);
246 case ICON_COLOR_32x32:
247 if (iconNameC32 == null) {
250 if (iconColor32 == null) {
251 iconColor32 = loadImage(iconNameC32);
256 case ICON_MONO_16x16:
257 if (iconNameM16 == null) {
260 if (iconMono16 == null) {
261 iconMono16 = loadImage(iconNameM16);
266 case ICON_MONO_32x32:
267 if (iconNameM32 == null) {
270 if (iconMono32 == null) {
271 iconMono32 = loadImage(iconNameM32);