1 /* 2 * Copyright (c) 2014, 2016, 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 com.sun.beans.TypeResolver; 29 import com.sun.beans.finder.MethodFinder; 30 31 import java.lang.reflect.Method; 32 import java.lang.reflect.Modifier; 33 import java.lang.reflect.Type; 34 import java.util.ArrayList; 35 import java.util.Arrays; 36 import java.util.Collections; 37 import java.util.Comparator; 38 import java.util.List; 39 40 final class MethodInfo { 41 final Method method; 42 final Class<?> type; 43 44 MethodInfo(Method method, Class<?> type) { 45 this.method = method; 46 this.type = type; 47 } 48 49 MethodInfo(Method method, Type type) { 50 this.method = method; 51 this.type = resolve(method, type); 52 } 53 54 boolean isThrow(Class<?> exception) { 55 for (Class<?> type : this.method.getExceptionTypes()) { 56 if (type == exception) { 57 return true; 58 } 59 } 60 return false; 61 } 62 63 static Class<?> resolve(Method method, Type type) { 64 return TypeResolver.erase(TypeResolver.resolveInClass(method.getDeclaringClass(), type)); 65 } 66 67 static List<Method> get(Class<?> type) { 68 List<Method> list = null; 69 if (type != null) { 70 boolean inaccessible = !Modifier.isPublic(type.getModifiers()); 71 for (Method method : type.getMethods()) { 72 if (method.getDeclaringClass().equals(type)) { 73 if (inaccessible) { 74 try { 75 method = MethodFinder.findAccessibleMethod(method); 76 if (!method.getDeclaringClass().isInterface()) { 77 method = null; // ignore methods from superclasses 78 } 79 } catch (NoSuchMethodException exception) { 80 // commented out because of 6976577 81 // method = null; // ignore inaccessible methods 82 } 83 } 84 if (method != null) { 85 if (list == null) { 86 list = new ArrayList<>(); 87 } 88 list.add(method); 89 } 90 } 91 } 92 } 93 if (list != null) { 94 list.sort(MethodOrder.instance); 95 return Collections.unmodifiableList(list); 96 } 97 return Collections.emptyList(); 98 } 99 100 /** 101 * A comparator that defines a total order so that methods have the same 102 * name and identical signatures appear next to each others. The methods are 103 * sorted in such a way that methods which override each other will sit next 104 * to each other, with the overridden method last - e.g. is Integer getFoo() 105 * placed before Object getFoo(). 106 **/ 107 private static final class MethodOrder implements Comparator<Method> { 108 109 /* 110 * Code particularly was copied from com.sun.jmx.mbeanserver.MethodOrder 111 */ 112 @Override 113 public int compare(final Method a, final Method b) { 114 int cmp = a.getName().compareTo(b.getName()); 115 if (cmp != 0) { 116 return cmp; 117 } 118 final Class<?>[] aparams = a.getParameterTypes(); 119 final Class<?>[] bparams = b.getParameterTypes(); 120 if (aparams.length != bparams.length) { 121 return aparams.length - bparams.length; 122 } 123 for (int i = 0; i < aparams.length; ++i) { 124 final Class<?> aparam = aparams[i]; 125 final Class<?> bparam = bparams[i]; 126 if (aparam == bparam) { 127 continue; 128 } 129 cmp = aparam.getName().compareTo(bparam.getName()); 130 if (cmp != 0) { 131 return cmp; 132 } 133 } 134 final Class<?> aret = a.getReturnType(); 135 final Class<?> bret = b.getReturnType(); 136 if (aret == bret) { 137 return 0; 138 } 139 140 // Super type comes last: Integer, Number, Object 141 if (aret.isAssignableFrom(bret)) { 142 return 1; 143 } 144 return -1; 145 } 146 147 static final MethodOrder instance = new MethodOrder(); 148 } 149 }