Path: blob/master/src/java.desktop/share/classes/com/sun/beans/introspect/EventSetInfo.java
41171 views
/*1* Copyright (c) 2014, 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*/24package com.sun.beans.introspect;2526import java.lang.reflect.Method;27import java.lang.reflect.Modifier;28import java.util.Collections;29import java.util.EventListener;30import java.util.Iterator;31import java.util.List;32import java.util.Map;33import java.util.TooManyListenersException;34import java.util.TreeMap;3536public final class EventSetInfo {37private MethodInfo add;38private MethodInfo remove;39private MethodInfo get;4041private EventSetInfo() {42}4344private boolean initialize() {45if ((this.add == null) || (this.remove == null) || (this.remove.type != this.add.type)) {46return false;47}48if ((this.get != null) && (this.get.type != this.add.type)) {49this.get = null;50}51return true;52}5354public Class<?> getListenerType() {55return this.add.type;56}5758public Method getAddMethod() {59return this.add.method;60}6162public Method getRemoveMethod() {63return this.remove.method;64}6566public Method getGetMethod() {67return (this.get == null) ? null : this.get.method;68}6970public boolean isUnicast() {71// if the adder method throws the TooManyListenersException72// then it is an Unicast event source73return this.add.isThrow(TooManyListenersException.class);74}7576private static MethodInfo getInfo(MethodInfo info, Method method, int prefix, int postfix) {77Class<?> type = (postfix > 0)78? MethodInfo.resolve(method, method.getGenericReturnType()).getComponentType()79: MethodInfo.resolve(method, method.getGenericParameterTypes()[0]);8081if ((type != null) && EventListener.class.isAssignableFrom(type)) {82String name = method.getName();83if (prefix + postfix < name.length()) {84if (type.getName().endsWith(name.substring(prefix, name.length() - postfix))) {85if ((info == null) || info.type.isAssignableFrom(type)) {86return new MethodInfo(method, type);87}88}89}90}91return info;92}9394private static EventSetInfo getInfo(Map<String,EventSetInfo> map, String key) {95EventSetInfo info = map.get(key);96if (info == null) {97info = new EventSetInfo();98map.put(key, info);99}100return info;101}102103public static Map<String,EventSetInfo> get(Class<?> type) {104List<Method> methods = ClassInfo.get(type).getMethods();105if (methods.isEmpty()) {106return Collections.emptyMap();107}108Map<String,EventSetInfo> map = new TreeMap<>();109for (Method method : ClassInfo.get(type).getMethods()) {110if (!Modifier.isStatic(method.getModifiers())) {111Class<?> returnType = method.getReturnType();112String name = method.getName();113switch (method.getParameterCount()) {114case 1:115if ((returnType == void.class) && name.endsWith("Listener")) {116if (name.startsWith("add")) {117EventSetInfo info = getInfo(map, name.substring(3, name.length() - 8));118info.add = getInfo(info.add, method, 3, 0);119} else if (name.startsWith("remove")) {120EventSetInfo info = getInfo(map, name.substring(6, name.length() - 8));121info.remove = getInfo(info.remove, method, 6, 0);122}123}124break;125case 0:126if (returnType.isArray() && name.startsWith("get") && name.endsWith("Listeners")) {127EventSetInfo info = getInfo(map, name.substring(3, name.length() - 9));128info.get = getInfo(info.get, method, 3, 1);129}130break;131}132}133}134Iterator<EventSetInfo> iterator = map.values().iterator();135while (iterator.hasNext()) {136if (!iterator.next().initialize()) {137iterator.remove();138}139}140return !map.isEmpty()141? Collections.unmodifiableMap(map)142: Collections.emptyMap();143}144}145146147