FeatureDescriptor.java revision 243
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj/*
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj * Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved.
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj *
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj * This code is free software; you can redistribute it and/or modify it
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj * under the terms of the GNU General Public License version 2 only, as
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj * published by the Free Software Foundation. Sun designates this
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj * particular file as subject to the "Classpath" exception as provided
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj * by Sun in the LICENSE file that accompanied this code.
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj *
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj * This code is distributed in the hope that it will be useful, but WITHOUT
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj * version 2 for more details (a copy is included in the LICENSE file that
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj * accompanied this code).
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj *
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj * You should have received a copy of the GNU General Public License version
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj * 2 along with this work; if not, write to the Free Software Foundation,
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj *
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj * CA 95054 USA or visit www.sun.com if you need additional information or
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj * have any questions.
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj */
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonjpackage java.beans;
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonjimport com.sun.beans.TypeResolver;
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonjimport java.lang.ref.Reference;
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonjimport java.lang.ref.WeakReference;
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonjimport java.lang.ref.SoftReference;
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonjimport java.lang.reflect.Method;
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonjimport java.util.Enumeration;
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonjimport java.util.Hashtable;
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj/**
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj * The FeatureDescriptor class is the common baseclass for PropertyDescriptor,
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj * EventSetDescriptor, and MethodDescriptor, etc.
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj * <p>
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj * It supports some common information that can be set and retrieved for
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj * any of the introspection descriptors.
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj * <p>
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj * In addition it provides an extension mechanism so that arbitrary
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj * attribute/value pairs can be associated with a design feature.
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj */
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonjpublic class FeatureDescriptor {
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj private static final String TRANSIENT = "transient";
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj private Reference<Class> classRef;
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj /**
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj * Constructs a <code>FeatureDescriptor</code>.
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj */
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj public FeatureDescriptor() {
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj }
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj /**
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj * Gets the programmatic name of this feature.
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj *
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj * @return The programmatic name of the property/method/event
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj */
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj public String getName() {
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj return name;
d04ccbb3f3163ae5962a8b7465d9796bff6ca434carlsonj }
/**
* Sets the programmatic name of this feature.
*
* @param name The programmatic name of the property/method/event
*/
public void setName(String name) {
this.name = name;
}
/**
* Gets the localized display name of this feature.
*
* @return The localized display name for the property/method/event.
* This defaults to the same as its programmatic name from getName.
*/
public String getDisplayName() {
if (displayName == null) {
return getName();
}
return displayName;
}
/**
* Sets the localized display name of this feature.
*
* @param displayName The localized display name for the
* property/method/event.
*/
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
/**
* The "expert" flag is used to distinguish between those features that are
* intended for expert users from those that are intended for normal users.
*
* @return True if this feature is intended for use by experts only.
*/
public boolean isExpert() {
return expert;
}
/**
* The "expert" flag is used to distinguish between features that are
* intended for expert users from those that are intended for normal users.
*
* @param expert True if this feature is intended for use by experts only.
*/
public void setExpert(boolean expert) {
this.expert = expert;
}
/**
* The "hidden" flag is used to identify features that are intended only
* for tool use, and which should not be exposed to humans.
*
* @return True if this feature should be hidden from human users.
*/
public boolean isHidden() {
return hidden;
}
/**
* The "hidden" flag is used to identify features that are intended only
* for tool use, and which should not be exposed to humans.
*
* @param hidden True if this feature should be hidden from human users.
*/
public void setHidden(boolean hidden) {
this.hidden = hidden;
}
/**
* The "preferred" flag is used to identify features that are particularly
* important for presenting to humans.
*
* @return True if this feature should be preferentially shown to human users.
*/
public boolean isPreferred() {
return preferred;
}
/**
* The "preferred" flag is used to identify features that are particularly
* important for presenting to humans.
*
* @param preferred True if this feature should be preferentially shown
* to human users.
*/
public void setPreferred(boolean preferred) {
this.preferred = preferred;
}
/**
* Gets the short description of this feature.
*
* @return A localized short description associated with this
* property/method/event. This defaults to be the display name.
*/
public String getShortDescription() {
if (shortDescription == null) {
return getDisplayName();
}
return shortDescription;
}
/**
* You can associate a short descriptive string with a feature. Normally
* these descriptive strings should be less than about 40 characters.
* @param text A (localized) short description to be associated with
* this property/method/event.
*/
public void setShortDescription(String text) {
shortDescription = text;
}
/**
* Associate a named attribute with this feature.
*
* @param attributeName The locale-independent name of the attribute
* @param value The value.
*/
public void setValue(String attributeName, Object value) {
getTable().put(attributeName, value);
}
/**
* Retrieve a named attribute with this feature.
*
* @param attributeName The locale-independent name of the attribute
* @return The value of the attribute. May be null if
* the attribute is unknown.
*/
public Object getValue(String attributeName) {
return (this.table != null)
? this.table.get(attributeName)
: null;
}
/**
* Gets an enumeration of the locale-independent names of this
* feature.
*
* @return An enumeration of the locale-independent names of any
* attributes that have been registered with setValue.
*/
public Enumeration<String> attributeNames() {
return getTable().keys();
}
/**
* Package-private constructor,
* Merge information from two FeatureDescriptors.
* The merged hidden and expert flags are formed by or-ing the values.
* In the event of other conflicts, the second argument (y) is
* given priority over the first argument (x).
*
* @param x The first (lower priority) MethodDescriptor
* @param y The second (higher priority) MethodDescriptor
*/
FeatureDescriptor(FeatureDescriptor x, FeatureDescriptor y) {
expert = x.expert | y.expert;
hidden = x.hidden | y.hidden;
preferred = x.preferred | y.preferred;
name = y.name;
shortDescription = x.shortDescription;
if (y.shortDescription != null) {
shortDescription = y.shortDescription;
}
displayName = x.displayName;
if (y.displayName != null) {
displayName = y.displayName;
}
classRef = x.classRef;
if (y.classRef != null) {
classRef = y.classRef;
}
addTable(x.table);
addTable(y.table);
}
/*
* Package-private dup constructor
* This must isolate the new object from any changes to the old object.
*/
FeatureDescriptor(FeatureDescriptor old) {
expert = old.expert;
hidden = old.hidden;
preferred = old.preferred;
name = old.name;
shortDescription = old.shortDescription;
displayName = old.displayName;
classRef = old.classRef;
addTable(old.table);
}
/**
* Copies all values from the specified attribute table.
* If some attribute is exist its value should be overridden.
*
* @param table the attribute table with new values
*/
private void addTable(Hashtable<String, Object> table) {
if ((table != null) && !table.isEmpty()) {
getTable().putAll(table);
}
}
/**
* Returns the initialized attribute table.
*
* @return the initialized attribute table
*/
private Hashtable<String, Object> getTable() {
if (this.table == null) {
this.table = new Hashtable<String, Object>();
}
return this.table;
}
/**
* Sets the "transient" attribute according to the annotation.
* If the "transient" attribute is already set
* it should not be changed.
*
* @param annotation the annotation of the element of the feature
*/
void setTransient(Transient annotation) {
if ((annotation != null) && (null == getValue(TRANSIENT))) {
setValue(TRANSIENT, annotation.value());
}
}
/**
* Indicates whether the feature is transient.
*
* @return {@code true} if the feature is transient,
* {@code false} otherwise
*/
boolean isTransient() {
Object value = getValue(TRANSIENT);
return (value instanceof Boolean)
? (Boolean) value
: false;
}
// Package private methods for recreating the weak/soft referent
void setClass0(Class cls) {
this.classRef = getWeakReference(cls);
}
Class getClass0() {
return (this.classRef != null)
? this.classRef.get()
: null;
}
/**
* Creates a new soft reference that refers to the given object.
*
* @return a new soft reference or <code>null</code> if object is <code>null</code>
*
* @see SoftReference
*/
static <T> Reference<T> getSoftReference(T object) {
return (object != null)
? new SoftReference<T>(object)
: null;
}
/**
* Creates a new weak reference that refers to the given object.
*
* @return a new weak reference or <code>null</code> if object is <code>null</code>
*
* @see WeakReference
*/
static <T> Reference<T> getWeakReference(T object) {
return (object != null)
? new WeakReference<T>(object)
: null;
}
/**
* Resolves the return type of the method.
*
* @param base the class that contains the method in the hierarchy
* @param method the object that represents the method
* @return a class identifying the return type of the method
*
* @see Method#getGenericReturnType
* @see Method#getReturnType
*/
static Class getReturnType(Class base, Method method) {
if (base == null) {
base = method.getDeclaringClass();
}
return TypeResolver.erase(TypeResolver.resolveInClass(base, method.getGenericReturnType()));
}
/**
* Resolves the parameter types of the method.
*
* @param base the class that contains the method in the hierarchy
* @param method the object that represents the method
* @return an array of classes identifying the parameter types of the method
*
* @see Method#getGenericParameterTypes
* @see Method#getParameterTypes
*/
static Class[] getParameterTypes(Class base, Method method) {
if (base == null) {
base = method.getDeclaringClass();
}
return TypeResolver.erase(TypeResolver.resolveInClass(base, method.getGenericParameterTypes()));
}
private boolean expert;
private boolean hidden;
private boolean preferred;
private String shortDescription;
private String name;
private String displayName;
private Hashtable<String, Object> table;
}