001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.jmeter.testbeans;
018:
019: import java.awt.Image;
020: import java.beans.BeanDescriptor;
021: import java.beans.BeanInfo;
022: import java.beans.EventSetDescriptor;
023: import java.beans.IntrospectionException;
024: import java.beans.Introspector;
025: import java.beans.MethodDescriptor;
026: import java.beans.PropertyDescriptor;
027: import java.beans.SimpleBeanInfo;
028: import java.util.MissingResourceException;
029: import java.util.ResourceBundle;
030:
031: import org.apache.jmeter.testbeans.gui.GenericTestBeanCustomizer;
032: import org.apache.jmeter.util.JMeterUtils;
033: import org.apache.jorphan.logging.LoggingManager;
034: import org.apache.log.Logger;
035:
036: /**
037: * Support class for test bean beanInfo objects. It will help using the
038: * introspector to get most of the information, to then modify it at will.
039: * <p>
040: * To use, subclass it, create a subclass with a parameter-less constructor
041: * that:
042: * <ol>
043: * <li>Calls super(beanClass)
044: * <li>Modifies the property descriptors, bean descriptor, etc. at will.
045: * </ol>
046: * <p>
047: * Even before any such modifications, a resource bundle named xxxResources
048: * (where xxx is the fully qualified bean class name) will be obtained if
049: * available and used to localize the following:
050: * <ul>
051: * <li>Bean's display name -- from property <b>displayName</b>.
052: * <li>Properties' display names -- from properties <b><i>propertyName</i>.displayName</b>.
053: * <li>Properties' short descriptions -- from properties <b><i>propertyName</i>.shortDescription</b>.
054: * </ul>
055: * <p>
056: * The resource bundle will be stored as the bean descriptor's "resourceBundle"
057: * attribute, so that it can be used for further localization. TestBeanGUI, for
058: * example, uses it to obtain the group's display names from properties <b><i>groupName</i>.displayName</b>.
059: *
060: * @author <a href="mailto:jsalvata@apache.org">Jordi Salvat i Alabart</a>
061: * @version $Revision: 577345 $ updated on $Date: 2007-09-19 17:29:45 +0100 (Wed, 19 Sep 2007) $
062: */
063: public abstract class BeanInfoSupport extends SimpleBeanInfo {
064:
065: private static final Logger log = LoggingManager
066: .getLoggerForClass();
067:
068: // Some known attribute names, just for convenience:
069: public static final String TAGS = GenericTestBeanCustomizer.TAGS;
070:
071: public static final String NOT_UNDEFINED = GenericTestBeanCustomizer.NOT_UNDEFINED;
072:
073: public static final String NOT_EXPRESSION = GenericTestBeanCustomizer.NOT_EXPRESSION;
074:
075: public static final String NOT_OTHER = GenericTestBeanCustomizer.NOT_OTHER;
076:
077: public static final String DEFAULT = GenericTestBeanCustomizer.DEFAULT;
078:
079: public static final String RESOURCE_BUNDLE = GenericTestBeanCustomizer.RESOURCE_BUNDLE;
080:
081: /** The class for which we're providing the bean info. */
082: // NOTREAD private Class beanClass;
083: /** The BeanInfo for our class as obtained by the introspector. */
084: private BeanInfo rootBeanInfo;
085:
086: /** The icons for this bean. */
087: private Image[] icons = new Image[5];
088:
089: /**
090: * Construct a BeanInfo for the given class.
091: */
092: protected BeanInfoSupport(Class beanClass) {
093: // NOTREAD this.beanClass= beanClass;
094:
095: try {
096: rootBeanInfo = Introspector.getBeanInfo(beanClass,
097: Introspector.IGNORE_IMMEDIATE_BEANINFO);
098: } catch (IntrospectionException e) {
099: log.error("Can't introspect.", e);
100: throw new Error(e.toString()); // Programming error: bail out.
101: }
102:
103: try {
104: ResourceBundle resourceBundle = ResourceBundle.getBundle(
105: beanClass.getName() + "Resources", // $NON-NLS-1$
106: JMeterUtils.getLocale());
107:
108: // Store the resource bundle as an attribute of the BeanDescriptor:
109: getBeanDescriptor().setValue(RESOURCE_BUNDLE,
110: resourceBundle);
111: // Localize the bean name
112: try {
113: getBeanDescriptor().setDisplayName(
114: resourceBundle.getString("displayName")); // $NON-NLS-1$
115: } catch (MissingResourceException e) {
116: log
117: .debug("Localized display name not available for bean "
118: + beanClass.getName());
119: }
120: // Localize the property names and descriptions:
121: PropertyDescriptor[] properties = getPropertyDescriptors();
122: for (int i = 0; i < properties.length; i++) {
123: String name = properties[i].getName();
124: try {
125: properties[i].setDisplayName(resourceBundle
126: .getString(name + ".displayName")); // $NON-NLS-1$
127: } catch (MissingResourceException e) {
128: log
129: .debug("Localized display name not available for property "
130: + name);
131: }
132:
133: try {
134: properties[i].setShortDescription(resourceBundle
135: .getString(name + ".shortDescription"));
136: } catch (MissingResourceException e) {
137: log
138: .debug("Localized short description not available for property "
139: + name);
140: }
141: }
142: } catch (MissingResourceException e) {
143: log.warn("Localized strings not available for bean "
144: + beanClass, e);
145: } catch (Exception e) {
146: log
147: .warn(
148: "Something bad happened when loading bean info",
149: e);
150: }
151: }
152:
153: /**
154: * Get the property descriptor for the property of the given name.
155: *
156: * @param name
157: * property name
158: * @return descriptor for a property of that name, or null if there's none
159: */
160: protected PropertyDescriptor property(String name) {
161: PropertyDescriptor[] properties = getPropertyDescriptors();
162: for (int i = 0; i < properties.length; i++) {
163: if (properties[i].getName().equals(name)) {
164: return properties[i];
165: }
166: }
167: log.warn("Cannot find property: " + name);
168: return null;
169: }
170:
171: /**
172: * Set the bean's 16x16 colour icon.
173: *
174: * @param resourceName
175: * A pathname relative to the directory holding the class file of
176: * the current class.
177: */
178: protected void setIcon(String resourceName) {
179: icons[ICON_COLOR_16x16] = loadImage(resourceName);
180: }
181:
182: /** Number of groups created so far by createPropertyGroup. */
183: private int numCreatedGroups = 0;
184:
185: /**
186: * Utility method to group and order properties.
187: * <p>
188: * It will assing the given group name to each of the named properties, and
189: * set their order attribute so that they are shown in the given order.
190: * <p>
191: * The created groups will get order 1, 2, 3,... in the order in which they
192: * are created.
193: *
194: * @param group
195: * name of the group
196: * @param names
197: * property names in the desired order
198: */
199: protected void createPropertyGroup(String group, String[] names) {
200: for (int i = 0; i < names.length; i++) {
201: log.debug("Getting property for: " + names[i]);
202: PropertyDescriptor p = property(names[i]);
203: p.setValue(GenericTestBeanCustomizer.GROUP, group);
204: p.setValue(GenericTestBeanCustomizer.ORDER, new Integer(i));
205: }
206: numCreatedGroups++;
207: getBeanDescriptor().setValue(
208: GenericTestBeanCustomizer.ORDER(group),
209: new Integer(numCreatedGroups));
210: }
211:
212: public BeanInfo[] getAdditionalBeanInfo() {
213: return rootBeanInfo.getAdditionalBeanInfo();
214: }
215:
216: public BeanDescriptor getBeanDescriptor() {
217: return rootBeanInfo.getBeanDescriptor();
218: }
219:
220: public int getDefaultEventIndex() {
221: return rootBeanInfo.getDefaultEventIndex();
222: }
223:
224: public int getDefaultPropertyIndex() {
225: return rootBeanInfo.getDefaultPropertyIndex();
226: }
227:
228: public EventSetDescriptor[] getEventSetDescriptors() {
229: return rootBeanInfo.getEventSetDescriptors();
230: }
231:
232: public Image getIcon(int iconKind) {
233: return icons[iconKind];
234: }
235:
236: public MethodDescriptor[] getMethodDescriptors() {
237: return rootBeanInfo.getMethodDescriptors();
238: }
239:
240: public PropertyDescriptor[] getPropertyDescriptors() {
241: return rootBeanInfo.getPropertyDescriptors();
242: }
243: }
|