1 /* 2 * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.beans.introspect; 27 28 import java.lang.reflect.Method; 29 import java.lang.reflect.Modifier; 30 import java.lang.reflect.Type; 31 import java.util.ArrayList; 32 import java.util.Collections; 33 import java.util.Comparator; 34 import java.util.List; 35 36 import com.sun.beans.TypeResolver; 37 import com.sun.beans.finder.MethodFinder; 38 39 final class MethodInfo { 40 final Method method; 41 final Class<?> type; 42 43 MethodInfo(Method method, Class<?> type) { 44 this.method = method; 45 this.type = type; 46 } 47 48 MethodInfo(Method method, Type type) { 49 this.method = method; 50 this.type = resolve(method, type); 51 } 52 53 boolean isThrow(Class<?> exception) { 54 for (Class<?> type : this.method.getExceptionTypes()) { 55 if (type == exception) { 56 return true; 57 } 58 } 59 return false; 60 } 61 62 static Class<?> resolve(Method method, Type type) { 63 return TypeResolver.erase(TypeResolver.resolveInClass(method.getDeclaringClass(), type)); 64 } 65 66 static List<Method> get(Class<?> type) { 67 List<Method> list = null; 68 if (type != null) { 69 boolean inaccessible = !Modifier.isPublic(type.getModifiers()); 70 for (Method method : type.getMethods()) { 71 if (method.getDeclaringClass().equals(type)) { 72 if (inaccessible) { 73 try { 74 method = MethodFinder.findAccessibleMethod(method); 75 if (!method.getDeclaringClass().isInterface()) { 76 method = null; // ignore methods from superclasses 77 } 78 } catch (NoSuchMethodException exception) { 79 // commented out because of 6976577 80 // method = null; // ignore inaccessible methods 81 } 82 } 83 if (method != null) { 84 if (list == null) { 85 list = new ArrayList<>(); 86 } 87 list.add(method); 88 } 89 } 90 } 91 } 92 if (list != null) { 93 list.sort(MethodOrder.instance); 94 return Collections.unmodifiableList(list); 95 } 96 return Collections.emptyList(); 97 } 98 99 /** 100 * A comparator that defines a total order so that methods have the same 101 * name and identical signatures appear next to each others. The methods are 102 * sorted in such a way that methods which override each other will sit next 103 * to each other, with the overridden method last - e.g. is Integer getFoo() 104 * placed before Object getFoo(). 105 **/ 106 private static final class MethodOrder implements Comparator<Method> { 107 108 /* 109 * Code particularly was copied from com.sun.jmx.mbeanserver.MethodOrder 110 */ 111 @Override 112 public int compare(final Method a, final Method b) { 113 int cmp = a.getName().compareTo(b.getName()); 114 if (cmp != 0) { 115 return cmp; 116 } 117 final Class<?>[] aparams = a.getParameterTypes(); 118 final Class<?>[] bparams = b.getParameterTypes(); 119 if (aparams.length != bparams.length) { 120 return aparams.length - bparams.length; 121 } 122 for (int i = 0; i < aparams.length; ++i) { 123 final Class<?> aparam = aparams[i]; 124 final Class<?> bparam = bparams[i]; 125 if (aparam == bparam) { 126 continue; 127 } 128 cmp = aparam.getName().compareTo(bparam.getName()); 129 if (cmp != 0) { 130 return cmp; 131 } 132 } 133 final Class<?> aret = a.getReturnType(); 134 final Class<?> bret = b.getReturnType(); 135 if (aret == bret) { 136 return 0; 137 } 138 139 // Super type comes last: Integer, Number, Object 140 if (aret.isAssignableFrom(bret)) { 141 return 1; 142 } 143 if (bret.isAssignableFrom(aret)) { 144 return -1; 145 } 146 return aret.getName().compareTo(bret.getName()); 147 } 148 149 static final MethodOrder instance = new MethodOrder(); 150 } 151 }