Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/java/beans/FeatureDescriptor.java
38829 views
/*1* Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package java.beans;2627import com.sun.beans.TypeResolver;2829import java.lang.ref.Reference;30import java.lang.ref.WeakReference;31import java.lang.ref.SoftReference;3233import java.lang.reflect.Method;3435import java.util.Enumeration;36import java.util.Hashtable;37import java.util.Map.Entry;3839/**40* The FeatureDescriptor class is the common baseclass for PropertyDescriptor,41* EventSetDescriptor, and MethodDescriptor, etc.42* <p>43* It supports some common information that can be set and retrieved for44* any of the introspection descriptors.45* <p>46* In addition it provides an extension mechanism so that arbitrary47* attribute/value pairs can be associated with a design feature.48*/4950public class FeatureDescriptor {51private static final String TRANSIENT = "transient";5253private Reference<? extends Class<?>> classRef;5455/**56* Constructs a <code>FeatureDescriptor</code>.57*/58public FeatureDescriptor() {59}6061/**62* Gets the programmatic name of this feature.63*64* @return The programmatic name of the property/method/event65*/66public String getName() {67return name;68}6970/**71* Sets the programmatic name of this feature.72*73* @param name The programmatic name of the property/method/event74*/75public void setName(String name) {76this.name = name;77}7879/**80* Gets the localized display name of this feature.81*82* @return The localized display name for the property/method/event.83* This defaults to the same as its programmatic name from getName.84*/85public String getDisplayName() {86if (displayName == null) {87return getName();88}89return displayName;90}9192/**93* Sets the localized display name of this feature.94*95* @param displayName The localized display name for the96* property/method/event.97*/98public void setDisplayName(String displayName) {99this.displayName = displayName;100}101102/**103* The "expert" flag is used to distinguish between those features that are104* intended for expert users from those that are intended for normal users.105*106* @return True if this feature is intended for use by experts only.107*/108public boolean isExpert() {109return expert;110}111112/**113* The "expert" flag is used to distinguish between features that are114* intended for expert users from those that are intended for normal users.115*116* @param expert True if this feature is intended for use by experts only.117*/118public void setExpert(boolean expert) {119this.expert = expert;120}121122/**123* The "hidden" flag is used to identify features that are intended only124* for tool use, and which should not be exposed to humans.125*126* @return True if this feature should be hidden from human users.127*/128public boolean isHidden() {129return hidden;130}131132/**133* The "hidden" flag is used to identify features that are intended only134* for tool use, and which should not be exposed to humans.135*136* @param hidden True if this feature should be hidden from human users.137*/138public void setHidden(boolean hidden) {139this.hidden = hidden;140}141142/**143* The "preferred" flag is used to identify features that are particularly144* important for presenting to humans.145*146* @return True if this feature should be preferentially shown to human users.147*/148public boolean isPreferred() {149return preferred;150}151152/**153* The "preferred" flag is used to identify features that are particularly154* important for presenting to humans.155*156* @param preferred True if this feature should be preferentially shown157* to human users.158*/159public void setPreferred(boolean preferred) {160this.preferred = preferred;161}162163/**164* Gets the short description of this feature.165*166* @return A localized short description associated with this167* property/method/event. This defaults to be the display name.168*/169public String getShortDescription() {170if (shortDescription == null) {171return getDisplayName();172}173return shortDescription;174}175176/**177* You can associate a short descriptive string with a feature. Normally178* these descriptive strings should be less than about 40 characters.179* @param text A (localized) short description to be associated with180* this property/method/event.181*/182public void setShortDescription(String text) {183shortDescription = text;184}185186/**187* Associate a named attribute with this feature.188*189* @param attributeName The locale-independent name of the attribute190* @param value The value.191*/192public void setValue(String attributeName, Object value) {193getTable().put(attributeName, value);194}195196/**197* Retrieve a named attribute with this feature.198*199* @param attributeName The locale-independent name of the attribute200* @return The value of the attribute. May be null if201* the attribute is unknown.202*/203public Object getValue(String attributeName) {204return (this.table != null)205? this.table.get(attributeName)206: null;207}208209/**210* Gets an enumeration of the locale-independent names of this211* feature.212*213* @return An enumeration of the locale-independent names of any214* attributes that have been registered with setValue.215*/216public Enumeration<String> attributeNames() {217return getTable().keys();218}219220/**221* Package-private constructor,222* Merge information from two FeatureDescriptors.223* The merged hidden and expert flags are formed by or-ing the values.224* In the event of other conflicts, the second argument (y) is225* given priority over the first argument (x).226*227* @param x The first (lower priority) MethodDescriptor228* @param y The second (higher priority) MethodDescriptor229*/230FeatureDescriptor(FeatureDescriptor x, FeatureDescriptor y) {231expert = x.expert | y.expert;232hidden = x.hidden | y.hidden;233preferred = x.preferred | y.preferred;234name = y.name;235shortDescription = x.shortDescription;236if (y.shortDescription != null) {237shortDescription = y.shortDescription;238}239displayName = x.displayName;240if (y.displayName != null) {241displayName = y.displayName;242}243classRef = x.classRef;244if (y.classRef != null) {245classRef = y.classRef;246}247addTable(x.table);248addTable(y.table);249}250251/*252* Package-private dup constructor253* This must isolate the new object from any changes to the old object.254*/255FeatureDescriptor(FeatureDescriptor old) {256expert = old.expert;257hidden = old.hidden;258preferred = old.preferred;259name = old.name;260shortDescription = old.shortDescription;261displayName = old.displayName;262classRef = old.classRef;263264addTable(old.table);265}266267/**268* Copies all values from the specified attribute table.269* If some attribute is exist its value should be overridden.270*271* @param table the attribute table with new values272*/273private void addTable(Hashtable<String, Object> table) {274if ((table != null) && !table.isEmpty()) {275getTable().putAll(table);276}277}278279/**280* Returns the initialized attribute table.281*282* @return the initialized attribute table283*/284private Hashtable<String, Object> getTable() {285if (this.table == null) {286this.table = new Hashtable<>();287}288return this.table;289}290291/**292* Sets the "transient" attribute according to the annotation.293* If the "transient" attribute is already set294* it should not be changed.295*296* @param annotation the annotation of the element of the feature297*/298void setTransient(Transient annotation) {299if ((annotation != null) && (null == getValue(TRANSIENT))) {300setValue(TRANSIENT, annotation.value());301}302}303304/**305* Indicates whether the feature is transient.306*307* @return {@code true} if the feature is transient,308* {@code false} otherwise309*/310boolean isTransient() {311Object value = getValue(TRANSIENT);312return (value instanceof Boolean)313? (Boolean) value314: false;315}316317// Package private methods for recreating the weak/soft referent318319void setClass0(Class<?> cls) {320this.classRef = getWeakReference(cls);321}322323Class<?> getClass0() {324return (this.classRef != null)325? this.classRef.get()326: null;327}328329/**330* Creates a new soft reference that refers to the given object.331*332* @return a new soft reference or <code>null</code> if object is <code>null</code>333*334* @see SoftReference335*/336static <T> Reference<T> getSoftReference(T object) {337return (object != null)338? new SoftReference<>(object)339: null;340}341342/**343* Creates a new weak reference that refers to the given object.344*345* @return a new weak reference or <code>null</code> if object is <code>null</code>346*347* @see WeakReference348*/349static <T> Reference<T> getWeakReference(T object) {350return (object != null)351? new WeakReference<>(object)352: null;353}354355/**356* Resolves the return type of the method.357*358* @param base the class that contains the method in the hierarchy359* @param method the object that represents the method360* @return a class identifying the return type of the method361*362* @see Method#getGenericReturnType363* @see Method#getReturnType364*/365static Class<?> getReturnType(Class<?> base, Method method) {366if (base == null) {367base = method.getDeclaringClass();368}369return TypeResolver.erase(TypeResolver.resolveInClass(base, method.getGenericReturnType()));370}371372/**373* Resolves the parameter types of the method.374*375* @param base the class that contains the method in the hierarchy376* @param method the object that represents the method377* @return an array of classes identifying the parameter types of the method378*379* @see Method#getGenericParameterTypes380* @see Method#getParameterTypes381*/382static Class<?>[] getParameterTypes(Class<?> base, Method method) {383if (base == null) {384base = method.getDeclaringClass();385}386return TypeResolver.erase(TypeResolver.resolveInClass(base, method.getGenericParameterTypes()));387}388389private boolean expert;390private boolean hidden;391private boolean preferred;392private String shortDescription;393private String name;394private String displayName;395private Hashtable<String, Object> table;396397/**398* Returns a string representation of the object.399*400* @return a string representation of the object401*402* @since 1.7403*/404public String toString() {405StringBuilder sb = new StringBuilder(getClass().getName());406sb.append("[name=").append(this.name);407appendTo(sb, "displayName", this.displayName);408appendTo(sb, "shortDescription", this.shortDescription);409appendTo(sb, "preferred", this.preferred);410appendTo(sb, "hidden", this.hidden);411appendTo(sb, "expert", this.expert);412if ((this.table != null) && !this.table.isEmpty()) {413sb.append("; values={");414for (Entry<String, Object> entry : this.table.entrySet()) {415sb.append(entry.getKey()).append("=").append(entry.getValue()).append("; ");416}417sb.setLength(sb.length() - 2);418sb.append("}");419}420appendTo(sb);421return sb.append("]").toString();422}423424void appendTo(StringBuilder sb) {425}426427static void appendTo(StringBuilder sb, String name, Reference<?> reference) {428if (reference != null) {429appendTo(sb, name, reference.get());430}431}432433static void appendTo(StringBuilder sb, String name, Object value) {434if (value != null) {435sb.append("; ").append(name).append("=").append(value);436}437}438439static void appendTo(StringBuilder sb, String name, boolean value) {440if (value) {441sb.append("; ").append(name);442}443}444}445446447