Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/java/beans/MethodDescriptor.java
38829 views
/*1* Copyright (c) 1996, 2013, 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 java.lang.ref.Reference;28import java.lang.ref.WeakReference;29import java.lang.reflect.Method;30import java.util.List;31import java.util.ArrayList;3233/**34* A MethodDescriptor describes a particular method that a Java Bean35* supports for external access from other components.36*/3738public class MethodDescriptor extends FeatureDescriptor {3940private final MethodRef methodRef = new MethodRef();4142private String[] paramNames;4344private List<WeakReference<Class<?>>> params;4546private ParameterDescriptor parameterDescriptors[];4748/**49* Constructs a <code>MethodDescriptor</code> from a50* <code>Method</code>.51*52* @param method The low-level method information.53*/54public MethodDescriptor(Method method) {55this(method, null);56}575859/**60* Constructs a <code>MethodDescriptor</code> from a61* <code>Method</code> providing descriptive information for each62* of the method's parameters.63*64* @param method The low-level method information.65* @param parameterDescriptors Descriptive information for each of the66* method's parameters.67*/68public MethodDescriptor(Method method,69ParameterDescriptor parameterDescriptors[]) {70setName(method.getName());71setMethod(method);72this.parameterDescriptors = (parameterDescriptors != null)73? parameterDescriptors.clone()74: null;75}7677/**78* Gets the method that this MethodDescriptor encapsulates.79*80* @return The low-level description of the method81*/82public synchronized Method getMethod() {83Method method = this.methodRef.get();84if (method == null) {85Class<?> cls = getClass0();86String name = getName();87if ((cls != null) && (name != null)) {88Class<?>[] params = getParams();89if (params == null) {90for (int i = 0; i < 3; i++) {91// Find methods for up to 2 params. We are guessing here.92// This block should never execute unless the classloader93// that loaded the argument classes disappears.94method = Introspector.findMethod(cls, name, i, null);95if (method != null) {96break;97}98}99} else {100method = Introspector.findMethod(cls, name, params.length, params);101}102setMethod(method);103}104}105return method;106}107108private synchronized void setMethod(Method method) {109if (method == null) {110return;111}112if (getClass0() == null) {113setClass0(method.getDeclaringClass());114}115setParams(getParameterTypes(getClass0(), method));116this.methodRef.set(method);117}118119private synchronized void setParams(Class<?>[] param) {120if (param == null) {121return;122}123paramNames = new String[param.length];124params = new ArrayList<>(param.length);125for (int i = 0; i < param.length; i++) {126paramNames[i] = param[i].getName();127params.add(new WeakReference<Class<?>>(param[i]));128}129}130131// pp getParamNames used as an optimization to avoid method.getParameterTypes.132String[] getParamNames() {133return paramNames;134}135136private synchronized Class<?>[] getParams() {137Class<?>[] clss = new Class<?>[params.size()];138139for (int i = 0; i < params.size(); i++) {140Reference<? extends Class<?>> ref = (Reference<? extends Class<?>>)params.get(i);141Class<?> cls = ref.get();142if (cls == null) {143return null;144} else {145clss[i] = cls;146}147}148return clss;149}150151/**152* Gets the ParameterDescriptor for each of this MethodDescriptor's153* method's parameters.154*155* @return The locale-independent names of the parameters. May return156* a null array if the parameter names aren't known.157*/158public ParameterDescriptor[] getParameterDescriptors() {159return (this.parameterDescriptors != null)160? this.parameterDescriptors.clone()161: null;162}163164private static Method resolve(Method oldMethod, Method newMethod) {165if (oldMethod == null) {166return newMethod;167}168if (newMethod == null) {169return oldMethod;170}171return !oldMethod.isSynthetic() && newMethod.isSynthetic() ? oldMethod : newMethod;172}173174/*175* Package-private constructor176* Merge two method descriptors. Where they conflict, give the177* second argument (y) priority over the first argument (x).178* @param x The first (lower priority) MethodDescriptor179* @param y The second (higher priority) MethodDescriptor180*/181182MethodDescriptor(MethodDescriptor x, MethodDescriptor y) {183super(x, y);184185this.methodRef.set(resolve(x.methodRef.get(), y.methodRef.get()));186params = x.params;187if (y.params != null) {188params = y.params;189}190paramNames = x.paramNames;191if (y.paramNames != null) {192paramNames = y.paramNames;193}194195parameterDescriptors = x.parameterDescriptors;196if (y.parameterDescriptors != null) {197parameterDescriptors = y.parameterDescriptors;198}199}200201/*202* Package-private dup constructor203* This must isolate the new object from any changes to the old object.204*/205MethodDescriptor(MethodDescriptor old) {206super(old);207208this.methodRef.set(old.getMethod());209params = old.params;210paramNames = old.paramNames;211212if (old.parameterDescriptors != null) {213int len = old.parameterDescriptors.length;214parameterDescriptors = new ParameterDescriptor[len];215for (int i = 0; i < len ; i++) {216parameterDescriptors[i] = new ParameterDescriptor(old.parameterDescriptors[i]);217}218}219}220221void appendTo(StringBuilder sb) {222appendTo(sb, "method", this.methodRef.get());223if (this.parameterDescriptors != null) {224sb.append("; parameterDescriptors={");225for (ParameterDescriptor pd : this.parameterDescriptors) {226sb.append(pd).append(", ");227}228sb.setLength(sb.length() - 2);229sb.append("}");230}231}232}233234235