-
Notifications
You must be signed in to change notification settings - Fork 5.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
4058433: RFE: tool for creating BeanInfo template
Reviewed-by: alexsch, serb
- Loading branch information
Sergey Malenkov
committed
Jul 3, 2014
1 parent
52f8e9c
commit d5b9d36
Showing
17 changed files
with
1,761 additions
and
332 deletions.
There are no files selected for viewing
99 changes: 99 additions & 0 deletions
99
jdk/src/share/classes/com/sun/beans/introspect/ClassInfo.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
/* | ||
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. | ||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
* | ||
* This code is free software; you can redistribute it and/or modify it | ||
* under the terms of the GNU General Public License version 2 only, as | ||
* published by the Free Software Foundation. Oracle designates this | ||
* particular file as subject to the "Classpath" exception as provided | ||
* by Oracle in the LICENSE file that accompanied this code. | ||
* | ||
* This code is distributed in the hope that it will be useful, but WITHOUT | ||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
* version 2 for more details (a copy is included in the LICENSE file that | ||
* accompanied this code). | ||
* | ||
* You should have received a copy of the GNU General Public License version | ||
* 2 along with this work; if not, write to the Free Software Foundation, | ||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
* | ||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
* or visit www.oracle.com if you need additional information or have any | ||
* questions. | ||
*/ | ||
package com.sun.beans.introspect; | ||
|
||
import com.sun.beans.util.Cache; | ||
|
||
import java.lang.reflect.Method; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
import static sun.reflect.misc.ReflectUtil.checkPackageAccess; | ||
|
||
public final class ClassInfo { | ||
private static final ClassInfo DEFAULT = new ClassInfo(null); | ||
private static final Cache<Class<?>,ClassInfo> CACHE | ||
= new Cache<Class<?>,ClassInfo>(Cache.Kind.SOFT, Cache.Kind.SOFT) { | ||
@Override | ||
public ClassInfo create(Class<?> type) { | ||
return new ClassInfo(type); | ||
} | ||
}; | ||
|
||
public static ClassInfo get(Class<?> type) { | ||
if (type == null) { | ||
return DEFAULT; | ||
} | ||
try { | ||
checkPackageAccess(type); | ||
return CACHE.get(type); | ||
} catch (SecurityException exception) { | ||
return DEFAULT; | ||
} | ||
} | ||
|
||
private final Object mutex = new Object(); | ||
private final Class<?> type; | ||
private List<Method> methods; | ||
private Map<String,PropertyInfo> properties; | ||
private Map<String,EventSetInfo> eventSets; | ||
|
||
private ClassInfo(Class<?> type) { | ||
this.type = type; | ||
} | ||
|
||
public List<Method> getMethods() { | ||
if (this.methods == null) { | ||
synchronized (this.mutex) { | ||
if (this.methods == null) { | ||
this.methods = MethodInfo.get(this.type); | ||
} | ||
} | ||
} | ||
return this.methods; | ||
} | ||
|
||
public Map<String,PropertyInfo> getProperties() { | ||
if (this.properties == null) { | ||
synchronized (this.mutex) { | ||
if (this.properties == null) { | ||
this.properties = PropertyInfo.get(this.type); | ||
} | ||
} | ||
} | ||
return this.properties; | ||
} | ||
|
||
public Map<String,EventSetInfo> getEventSets() { | ||
if (this.eventSets == null) { | ||
synchronized (this.mutex) { | ||
if (this.eventSets == null) { | ||
this.eventSets = EventSetInfo.get(this.type); | ||
} | ||
} | ||
} | ||
return this.eventSets; | ||
} | ||
} |
145 changes: 145 additions & 0 deletions
145
jdk/src/share/classes/com/sun/beans/introspect/EventSetInfo.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
/* | ||
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. | ||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
* | ||
* This code is free software; you can redistribute it and/or modify it | ||
* under the terms of the GNU General Public License version 2 only, as | ||
* published by the Free Software Foundation. Oracle designates this | ||
* particular file as subject to the "Classpath" exception as provided | ||
* by Oracle in the LICENSE file that accompanied this code. | ||
* | ||
* This code is distributed in the hope that it will be useful, but WITHOUT | ||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
* version 2 for more details (a copy is included in the LICENSE file that | ||
* accompanied this code). | ||
* | ||
* You should have received a copy of the GNU General Public License version | ||
* 2 along with this work; if not, write to the Free Software Foundation, | ||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
* | ||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
* or visit www.oracle.com if you need additional information or have any | ||
* questions. | ||
*/ | ||
package com.sun.beans.introspect; | ||
|
||
import java.lang.reflect.Method; | ||
import java.lang.reflect.Modifier; | ||
import java.util.Collections; | ||
import java.util.EventListener; | ||
import java.util.Iterator; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.TooManyListenersException; | ||
import java.util.TreeMap; | ||
|
||
public final class EventSetInfo { | ||
private MethodInfo add; | ||
private MethodInfo remove; | ||
private MethodInfo get; | ||
|
||
private EventSetInfo() { | ||
} | ||
|
||
private boolean initialize() { | ||
if ((this.add == null) || (this.remove == null) || (this.remove.type != this.add.type)) { | ||
return false; | ||
} | ||
if ((this.get != null) && (this.get.type != this.add.type)) { | ||
this.get = null; | ||
} | ||
return true; | ||
} | ||
|
||
public Class<?> getListenerType() { | ||
return this.add.type; | ||
} | ||
|
||
public Method getAddMethod() { | ||
return this.add.method; | ||
} | ||
|
||
public Method getRemoveMethod() { | ||
return this.remove.method; | ||
} | ||
|
||
public Method getGetMethod() { | ||
return (this.get == null) ? null : this.get.method; | ||
} | ||
|
||
public boolean isUnicast() { | ||
// if the adder method throws the TooManyListenersException | ||
// then it is an Unicast event source | ||
return this.add.isThrow(TooManyListenersException.class); | ||
} | ||
|
||
private static MethodInfo getInfo(MethodInfo info, Method method, int prefix, int postfix) { | ||
Class<?> type = (postfix > 0) | ||
? MethodInfo.resolve(method, method.getGenericReturnType()).getComponentType() | ||
: MethodInfo.resolve(method, method.getGenericParameterTypes()[0]); | ||
|
||
if ((type != null) && EventListener.class.isAssignableFrom(type)) { | ||
String name = method.getName(); | ||
if (prefix + postfix < name.length()) { | ||
if (type.getName().endsWith(name.substring(prefix, name.length() - postfix))) { | ||
if ((info == null) || info.type.isAssignableFrom(type)) { | ||
return new MethodInfo(method, type); | ||
} | ||
} | ||
} | ||
} | ||
return info; | ||
} | ||
|
||
private static EventSetInfo getInfo(Map<String,EventSetInfo> map, String key) { | ||
EventSetInfo info = map.get(key); | ||
if (info == null) { | ||
info = new EventSetInfo(); | ||
map.put(key, info); | ||
} | ||
return info; | ||
} | ||
|
||
public static Map<String,EventSetInfo> get(Class<?> type) { | ||
List<Method> methods = ClassInfo.get(type).getMethods(); | ||
if (methods.isEmpty()) { | ||
return Collections.emptyMap(); | ||
} | ||
Map<String,EventSetInfo> map = new TreeMap<>(); | ||
for (Method method : ClassInfo.get(type).getMethods()) { | ||
if (!Modifier.isStatic(method.getModifiers())) { | ||
Class<?> returnType = method.getReturnType(); | ||
String name = method.getName(); | ||
switch (method.getParameterCount()) { | ||
case 1: | ||
if ((returnType == void.class) && name.endsWith("Listener")) { | ||
if (name.startsWith("add")) { | ||
EventSetInfo info = getInfo(map, name.substring(3, name.length() - 8)); | ||
info.add = getInfo(info.add, method, 3, 0); | ||
} else if (name.startsWith("remove")) { | ||
EventSetInfo info = getInfo(map, name.substring(6, name.length() - 8)); | ||
info.remove = getInfo(info.remove, method, 6, 0); | ||
} | ||
} | ||
break; | ||
case 0: | ||
if (returnType.isArray() && name.startsWith("get") && name.endsWith("Listeners")) { | ||
EventSetInfo info = getInfo(map, name.substring(3, name.length() - 9)); | ||
info.get = getInfo(info.get, method, 3, 1); | ||
} | ||
break; | ||
} | ||
} | ||
} | ||
Iterator<EventSetInfo> iterator = map.values().iterator(); | ||
while (iterator.hasNext()) { | ||
if (!iterator.next().initialize()) { | ||
iterator.remove(); | ||
} | ||
} | ||
return !map.isEmpty() | ||
? Collections.unmodifiableMap(map) | ||
: Collections.emptyMap(); | ||
} | ||
} |
94 changes: 94 additions & 0 deletions
94
jdk/src/share/classes/com/sun/beans/introspect/MethodInfo.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
/* | ||
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. | ||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
* | ||
* This code is free software; you can redistribute it and/or modify it | ||
* under the terms of the GNU General Public License version 2 only, as | ||
* published by the Free Software Foundation. Oracle designates this | ||
* particular file as subject to the "Classpath" exception as provided | ||
* by Oracle in the LICENSE file that accompanied this code. | ||
* | ||
* This code is distributed in the hope that it will be useful, but WITHOUT | ||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
* version 2 for more details (a copy is included in the LICENSE file that | ||
* accompanied this code). | ||
* | ||
* You should have received a copy of the GNU General Public License version | ||
* 2 along with this work; if not, write to the Free Software Foundation, | ||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
* | ||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
* or visit www.oracle.com if you need additional information or have any | ||
* questions. | ||
*/ | ||
package com.sun.beans.introspect; | ||
|
||
import com.sun.beans.TypeResolver; | ||
import com.sun.beans.finder.MethodFinder; | ||
|
||
import java.lang.reflect.Method; | ||
import java.lang.reflect.Modifier; | ||
import java.lang.reflect.Type; | ||
import java.util.ArrayList; | ||
import java.util.Collections; | ||
import java.util.List; | ||
|
||
final class MethodInfo { | ||
final Method method; | ||
final Class<?> type; | ||
|
||
MethodInfo(Method method, Class<?> type) { | ||
this.method = method; | ||
this.type = type; | ||
} | ||
|
||
MethodInfo(Method method, Type type) { | ||
this.method = method; | ||
this.type = resolve(method, type); | ||
} | ||
|
||
boolean isThrow(Class<?> exception) { | ||
for (Class<?> type : this.method.getExceptionTypes()) { | ||
if (type == exception) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
|
||
static Class<?> resolve(Method method, Type type) { | ||
return TypeResolver.erase(TypeResolver.resolveInClass(method.getDeclaringClass(), type)); | ||
} | ||
|
||
static List<Method> get(Class<?> type) { | ||
List<Method> list = null; | ||
if (type != null) { | ||
boolean inaccessible = !Modifier.isPublic(type.getModifiers()); | ||
for (Method method : type.getMethods()) { | ||
if (method.getDeclaringClass().equals(type)) { | ||
if (inaccessible) { | ||
try { | ||
method = MethodFinder.findAccessibleMethod(method); | ||
if (!method.getDeclaringClass().isInterface()) { | ||
method = null; // ignore methods from superclasses | ||
} | ||
} catch (NoSuchMethodException exception) { | ||
// commented out because of 6976577 | ||
// method = null; // ignore inaccessible methods | ||
} | ||
} | ||
if (method != null) { | ||
if (list == null) { | ||
list = new ArrayList<>(); | ||
} | ||
list.add(method); | ||
} | ||
} | ||
} | ||
} | ||
return (list != null) | ||
? Collections.unmodifiableList(list) | ||
: Collections.emptyList(); | ||
} | ||
} |
Oops, something went wrong.