feat(jdk8): move files to new folder to avoid resources compiled.

This commit is contained in:
2025-09-07 15:25:52 +08:00
parent 3f0047bf6f
commit 8c35cfb1c0
17415 changed files with 217 additions and 213 deletions

View File

@@ -0,0 +1,207 @@
/*
* Copyright (c) 2008, 2013, 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.finder;
import java.lang.reflect.Executable;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
/**
* This abstract class provides functionality
* to find a public method or constructor
* with specified parameter types.
* It supports a variable number of parameters.
*
* @since 1.7
*
* @author Sergey A. Malenkov
*/
abstract class AbstractFinder<T extends Executable> {
private final Class<?>[] args;
/**
* Creates finder for array of classes of arguments.
* If a particular element of array equals {@code null},
* than the appropriate pair of classes
* does not take into consideration.
*
* @param args array of classes of arguments
*/
protected AbstractFinder(Class<?>[] args) {
this.args = args;
}
/**
* Checks validness of the method.
* At least the valid method should be public.
*
* @param method the object that represents method
* @return {@code true} if the method is valid,
* {@code false} otherwise
*/
protected boolean isValid(T method) {
return Modifier.isPublic(method.getModifiers());
}
/**
* Performs a search in the {@code methods} array.
* The one method is selected from the array of the valid methods.
* The list of parameters of the selected method shows
* the best correlation with the list of arguments
* specified at class initialization.
* If more than one method is both accessible and applicable
* to a method invocation, it is necessary to choose one
* to provide the descriptor for the run-time method dispatch.
* The most specific method should be chosen.
*
* @param methods the array of methods to search within
* @return the object that represents found method
* @throws NoSuchMethodException if no method was found or several
* methods meet the search criteria
* @see #isAssignable
*/
final T find(T[] methods) throws NoSuchMethodException {
Map<T, Class<?>[]> map = new HashMap<T, Class<?>[]>();
T oldMethod = null;
Class<?>[] oldParams = null;
boolean ambiguous = false;
for (T newMethod : methods) {
if (isValid(newMethod)) {
Class<?>[] newParams = newMethod.getParameterTypes();
if (newParams.length == this.args.length) {
PrimitiveWrapperMap.replacePrimitivesWithWrappers(newParams);
if (isAssignable(newParams, this.args)) {
if (oldMethod == null) {
oldMethod = newMethod;
oldParams = newParams;
} else {
boolean useNew = isAssignable(oldParams, newParams);
boolean useOld = isAssignable(newParams, oldParams);
if (useOld && useNew) {
// only if parameters are equal
useNew = !newMethod.isSynthetic();
useOld = !oldMethod.isSynthetic();
}
if (useOld == useNew) {
ambiguous = true;
} else if (useNew) {
oldMethod = newMethod;
oldParams = newParams;
ambiguous = false;
}
}
}
}
if (newMethod.isVarArgs()) {
int length = newParams.length - 1;
if (length <= this.args.length) {
Class<?>[] array = new Class<?>[this.args.length];
System.arraycopy(newParams, 0, array, 0, length);
if (length < this.args.length) {
Class<?> type = newParams[length].getComponentType();
if (type.isPrimitive()) {
type = PrimitiveWrapperMap.getType(type.getName());
}
for (int i = length; i < this.args.length; i++) {
array[i] = type;
}
}
map.put(newMethod, array);
}
}
}
}
for (T newMethod : methods) {
Class<?>[] newParams = map.get(newMethod);
if (newParams != null) {
if (isAssignable(newParams, this.args)) {
if (oldMethod == null) {
oldMethod = newMethod;
oldParams = newParams;
} else {
boolean useNew = isAssignable(oldParams, newParams);
boolean useOld = isAssignable(newParams, oldParams);
if (useOld && useNew) {
// only if parameters are equal
useNew = !newMethod.isSynthetic();
useOld = !oldMethod.isSynthetic();
}
if (useOld == useNew) {
if (oldParams == map.get(oldMethod)) {
ambiguous = true;
}
} else if (useNew) {
oldMethod = newMethod;
oldParams = newParams;
ambiguous = false;
}
}
}
}
}
if (ambiguous) {
throw new NoSuchMethodException("Ambiguous methods are found");
}
if (oldMethod == null) {
throw new NoSuchMethodException("Method is not found");
}
return oldMethod;
}
/**
* Determines if every class in {@code min} array is either the same as,
* or is a superclass of, the corresponding class in {@code max} array.
* The length of every array must equal the number of arguments.
* This comparison is performed in the {@link #find} method
* before the first call of the isAssignable method.
* If an argument equals {@code null}
* the appropriate pair of classes does not take into consideration.
*
* @param min the array of classes to be checked
* @param max the array of classes that is used to check
* @return {@code true} if all classes in {@code min} array
* are assignable from corresponding classes in {@code max} array,
* {@code false} otherwise
*
* @see Class#isAssignableFrom
*/
private boolean isAssignable(Class<?>[] min, Class<?>[] max) {
for (int i = 0; i < this.args.length; i++) {
if (null != this.args[i]) {
if (!min[i].isAssignableFrom(max[i])) {
return false;
}
}
}
return true;
}
}

View File

@@ -0,0 +1,102 @@
/*
* Copyright (c) 2009, 2012, 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.finder;
import java.beans.BeanDescriptor;
import java.beans.BeanInfo;
import java.beans.MethodDescriptor;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
/**
* This is utility class that provides functionality
* to find a {@link BeanInfo} for a JavaBean specified by its type.
*
* @since 1.7
*
* @author Sergey A. Malenkov
*/
public final class BeanInfoFinder
extends InstanceFinder<BeanInfo> {
private static final String DEFAULT = "sun.beans.infos";
private static final String DEFAULT_NEW = "com.sun.beans.infos";
public BeanInfoFinder() {
super(BeanInfo.class, true, "BeanInfo", DEFAULT);
}
private static boolean isValid(Class<?> type, Method method) {
return (method != null) && method.getDeclaringClass().isAssignableFrom(type);
}
@Override
protected BeanInfo instantiate(Class<?> type, String prefix, String name) {
if (DEFAULT.equals(prefix)) {
prefix = DEFAULT_NEW;
}
// this optimization will only use the BeanInfo search path
// if is has changed from the original
// or trying to get the ComponentBeanInfo
BeanInfo info = !DEFAULT_NEW.equals(prefix) || "ComponentBeanInfo".equals(name)
? super.instantiate(type, prefix, name)
: null;
if (info != null) {
// make sure that the returned BeanInfo matches the class
BeanDescriptor bd = info.getBeanDescriptor();
if (bd != null) {
if (type.equals(bd.getBeanClass())) {
return info;
}
}
else {
PropertyDescriptor[] pds = info.getPropertyDescriptors();
if (pds != null) {
for (PropertyDescriptor pd : pds) {
Method method = pd.getReadMethod();
if (method == null) {
method = pd.getWriteMethod();
}
if (isValid(type, method)) {
return info;
}
}
}
else {
MethodDescriptor[] mds = info.getMethodDescriptors();
if (mds != null) {
for (MethodDescriptor md : mds) {
if (isValid(type, md.getMethod())) {
return info;
}
}
}
}
}
}
return null;
}
}

View File

@@ -0,0 +1,180 @@
/*
* Copyright (c) 2006, 2012, 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.finder;
import static sun.reflect.misc.ReflectUtil.checkPackageAccess;
/**
* This is utility class that provides {@code static} methods
* to find a class with the specified name using the specified class loader.
*
* @since 1.7
*
* @author Sergey A. Malenkov
*/
public final class ClassFinder {
/**
* Returns the {@code Class} object associated
* with the class or interface with the given string name,
* using the default class loader.
* <p>
* The {@code name} can denote an array class
* (see {@link Class#getName} for details).
*
* @param name fully qualified name of the desired class
* @return class object representing the desired class
*
* @throws ClassNotFoundException if the class cannot be located
* by the specified class loader
*
* @see Class#forName(String)
* @see Class#forName(String,boolean,ClassLoader)
* @see ClassLoader#getSystemClassLoader()
* @see Thread#getContextClassLoader()
*/
public static Class<?> findClass(String name) throws ClassNotFoundException {
checkPackageAccess(name);
try {
ClassLoader loader = Thread.currentThread().getContextClassLoader();
if (loader == null) {
// can be null in IE (see 6204697)
loader = ClassLoader.getSystemClassLoader();
}
if (loader != null) {
return Class.forName(name, false, loader);
}
} catch (ClassNotFoundException exception) {
// use current class loader instead
} catch (SecurityException exception) {
// use current class loader instead
}
return Class.forName(name);
}
/**
* Returns the {@code Class} object associated with
* the class or interface with the given string name,
* using the given class loader.
* <p>
* The {@code name} can denote an array class
* (see {@link Class#getName} for details).
* <p>
* If the parameter {@code loader} is null,
* the class is loaded through the default class loader.
*
* @param name fully qualified name of the desired class
* @param loader class loader from which the class must be loaded
* @return class object representing the desired class
*
* @throws ClassNotFoundException if the class cannot be located
* by the specified class loader
*
* @see #findClass(String,ClassLoader)
* @see Class#forName(String,boolean,ClassLoader)
*/
public static Class<?> findClass(String name, ClassLoader loader) throws ClassNotFoundException {
checkPackageAccess(name);
if (loader != null) {
try {
return Class.forName(name, false, loader);
} catch (ClassNotFoundException exception) {
// use default class loader instead
} catch (SecurityException exception) {
// use default class loader instead
}
}
return findClass(name);
}
/**
* Returns the {@code Class} object associated
* with the class or interface with the given string name,
* using the default class loader.
* <p>
* The {@code name} can denote an array class
* (see {@link Class#getName} for details).
* <p>
* This method can be used to obtain
* any of the {@code Class} objects
* representing {@code void} or primitive Java types:
* {@code char}, {@code byte}, {@code short},
* {@code int}, {@code long}, {@code float},
* {@code double} and {@code boolean}.
*
* @param name fully qualified name of the desired class
* @return class object representing the desired class
*
* @throws ClassNotFoundException if the class cannot be located
* by the specified class loader
*
* @see #resolveClass(String,ClassLoader)
*/
public static Class<?> resolveClass(String name) throws ClassNotFoundException {
return resolveClass(name, null);
}
/**
* Returns the {@code Class} object associated with
* the class or interface with the given string name,
* using the given class loader.
* <p>
* The {@code name} can denote an array class
* (see {@link Class#getName} for details).
* <p>
* If the parameter {@code loader} is null,
* the class is loaded through the default class loader.
* <p>
* This method can be used to obtain
* any of the {@code Class} objects
* representing {@code void} or primitive Java types:
* {@code char}, {@code byte}, {@code short},
* {@code int}, {@code long}, {@code float},
* {@code double} and {@code boolean}.
*
* @param name fully qualified name of the desired class
* @param loader class loader from which the class must be loaded
* @return class object representing the desired class
*
* @throws ClassNotFoundException if the class cannot be located
* by the specified class loader
*
* @see #findClass(String,ClassLoader)
* @see PrimitiveTypeMap#getType(String)
*/
public static Class<?> resolveClass(String name, ClassLoader loader) throws ClassNotFoundException {
Class<?> type = PrimitiveTypeMap.getType(name);
return (type == null)
? findClass(name, loader)
: type;
}
/**
* Disable instantiation.
*/
private ClassFinder() {
}
}

View File

@@ -0,0 +1,100 @@
/*
* Copyright (c) 2008, 2013, 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.finder;
import com.sun.beans.util.Cache;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import static com.sun.beans.util.Cache.Kind.SOFT;
import static sun.reflect.misc.ReflectUtil.isPackageAccessible;
/**
* This utility class provides {@code static} methods
* to find a public constructor with specified parameter types
* in specified class.
*
* @since 1.7
*
* @author Sergey A. Malenkov
*/
public final class ConstructorFinder extends AbstractFinder<Constructor<?>> {
private static final Cache<Signature, Constructor<?>> CACHE = new Cache<Signature, Constructor<?>>(SOFT, SOFT) {
@Override
public Constructor create(Signature signature) {
try {
ConstructorFinder finder = new ConstructorFinder(signature.getArgs());
return finder.find(signature.getType().getConstructors());
}
catch (Exception exception) {
throw new SignatureException(exception);
}
}
};
/**
* Finds public constructor
* that is declared in public class.
*
* @param type the class that can have constructor
* @param args parameter types that is used to find constructor
* @return object that represents found constructor
* @throws NoSuchMethodException if constructor could not be found
* or some constructors are found
*/
public static Constructor<?> findConstructor(Class<?> type, Class<?>...args) throws NoSuchMethodException {
if (type.isPrimitive()) {
throw new NoSuchMethodException("Primitive wrapper does not contain constructors");
}
if (type.isInterface()) {
throw new NoSuchMethodException("Interface does not contain constructors");
}
if (Modifier.isAbstract(type.getModifiers())) {
throw new NoSuchMethodException("Abstract class cannot be instantiated");
}
if (!Modifier.isPublic(type.getModifiers()) || !isPackageAccessible(type)) {
throw new NoSuchMethodException("Class is not accessible");
}
PrimitiveWrapperMap.replacePrimitivesWithWrappers(args);
Signature signature = new Signature(type, args);
try {
return CACHE.get(signature);
}
catch (SignatureException exception) {
throw exception.toNoSuchMethodException("Constructor is not found");
}
}
/**
* Creates constructor finder with specified array of parameter types.
*
* @param args the array of parameter types
*/
private ConstructorFinder(Class<?>[] args) {
super(args);
}
}

View File

@@ -0,0 +1,109 @@
/*
* Copyright (c) 2008, 2012, 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.finder;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import static sun.reflect.misc.ReflectUtil.isPackageAccessible;
/**
* This utility class provides {@code static} methods
* to find a public field with specified name
* in specified class.
*
* @since 1.7
*
* @author Sergey A. Malenkov
*/
public final class FieldFinder {
/**
* Finds public field (static or non-static)
* that is declared in public class.
*
* @param type the class that can have field
* @param name the name of field to find
* @return object that represents found field
* @throws NoSuchFieldException if field is not found
* @see Class#getField
*/
public static Field findField(Class<?> type, String name) throws NoSuchFieldException {
if (name == null) {
throw new IllegalArgumentException("Field name is not set");
}
Field field = type.getField(name);
if (!Modifier.isPublic(field.getModifiers())) {
throw new NoSuchFieldException("Field '" + name + "' is not public");
}
type = field.getDeclaringClass();
if (!Modifier.isPublic(type.getModifiers()) || !isPackageAccessible(type)) {
throw new NoSuchFieldException("Field '" + name + "' is not accessible");
}
return field;
}
/**
* Finds public non-static field
* that is declared in public class.
*
* @param type the class that can have field
* @param name the name of field to find
* @return object that represents found field
* @throws NoSuchFieldException if field is not found
* @see Class#getField
*/
public static Field findInstanceField(Class<?> type, String name) throws NoSuchFieldException {
Field field = findField(type, name);
if (Modifier.isStatic(field.getModifiers())) {
throw new NoSuchFieldException("Field '" + name + "' is static");
}
return field;
}
/**
* Finds public static field
* that is declared in public class.
*
* @param type the class that can have field
* @param name the name of field to find
* @return object that represents found field
* @throws NoSuchFieldException if field is not found
* @see Class#getField
*/
public static Field findStaticField(Class<?> type, String name) throws NoSuchFieldException {
Field field = findField(type, name);
if (!Modifier.isStatic(field.getModifiers())) {
throw new NoSuchFieldException("Field '" + name + "' is not static");
}
return field;
}
/**
* Disable instantiation.
*/
private FieldFinder() {
}
}

View File

@@ -0,0 +1,109 @@
/*
* Copyright (c) 2009, 2010, 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.finder;
/**
* This is utility class that provides basic functionality
* to find an auxiliary class for a JavaBean specified by its type.
*
* @since 1.7
*
* @author Sergey A. Malenkov
*/
class InstanceFinder<T> {
private static final String[] EMPTY = { };
private final Class<? extends T> type;
private final boolean allow;
private final String suffix;
private volatile String[] packages;
InstanceFinder(Class<? extends T> type, boolean allow, String suffix, String... packages) {
this.type = type;
this.allow = allow;
this.suffix = suffix;
this.packages = packages.clone();
}
public String[] getPackages() {
return this.packages.clone();
}
public void setPackages(String... packages) {
this.packages = (packages != null) && (packages.length > 0)
? packages.clone()
: EMPTY;
}
public T find(Class<?> type) {
if (type == null) {
return null;
}
String name = type.getName() + this.suffix;
T object = instantiate(type, name);
if (object != null) {
return object;
}
if (this.allow) {
object = instantiate(type, null);
if (object != null) {
return object;
}
}
int index = name.lastIndexOf('.') + 1;
if (index > 0) {
name = name.substring(index);
}
for (String prefix : this.packages) {
object = instantiate(type, prefix, name);
if (object != null) {
return object;
}
}
return null;
}
protected T instantiate(Class<?> type, String name) {
if (type != null) {
try {
if (name != null) {
type = ClassFinder.findClass(name, type.getClassLoader());
}
if (this.type.isAssignableFrom(type)) {
return (T) type.newInstance();
}
}
catch (Exception exception) {
// ignore any exceptions
}
}
return null;
}
protected T instantiate(Class<?> type, String prefix, String name) {
return instantiate(type, prefix + '.' + name);
}
}

View File

@@ -0,0 +1,220 @@
/*
* Copyright (c) 2008, 2013, 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.finder;
import com.sun.beans.TypeResolver;
import com.sun.beans.util.Cache;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Arrays;
import static com.sun.beans.util.Cache.Kind.SOFT;
import static sun.reflect.misc.ReflectUtil.isPackageAccessible;
/**
* This utility class provides {@code static} methods
* to find a public method with specified name and parameter types
* in specified class.
*
* @since 1.7
*
* @author Sergey A. Malenkov
*/
public final class MethodFinder extends AbstractFinder<Method> {
private static final Cache<Signature, Method> CACHE = new Cache<Signature, Method>(SOFT, SOFT) {
@Override
public Method create(Signature signature) {
try {
MethodFinder finder = new MethodFinder(signature.getName(), signature.getArgs());
return findAccessibleMethod(finder.find(signature.getType().getMethods()));
}
catch (Exception exception) {
throw new SignatureException(exception);
}
}
};
/**
* Finds public method (static or non-static)
* that is accessible from public class.
*
* @param type the class that can have method
* @param name the name of method to find
* @param args parameter types that is used to find method
* @return object that represents found method
* @throws NoSuchMethodException if method could not be found
* or some methods are found
*/
public static Method findMethod(Class<?> type, String name, Class<?>...args) throws NoSuchMethodException {
if (name == null) {
throw new IllegalArgumentException("Method name is not set");
}
PrimitiveWrapperMap.replacePrimitivesWithWrappers(args);
Signature signature = new Signature(type, name, args);
try {
Method method = CACHE.get(signature);
return (method == null) || isPackageAccessible(method.getDeclaringClass()) ? method : CACHE.create(signature);
}
catch (SignatureException exception) {
throw exception.toNoSuchMethodException("Method '" + name + "' is not found");
}
}
/**
* Finds public non-static method
* that is accessible from public class.
*
* @param type the class that can have method
* @param name the name of method to find
* @param args parameter types that is used to find method
* @return object that represents found method
* @throws NoSuchMethodException if method could not be found
* or some methods are found
*/
public static Method findInstanceMethod(Class<?> type, String name, Class<?>... args) throws NoSuchMethodException {
Method method = findMethod(type, name, args);
if (Modifier.isStatic(method.getModifiers())) {
throw new NoSuchMethodException("Method '" + name + "' is static");
}
return method;
}
/**
* Finds public static method
* that is accessible from public class.
*
* @param type the class that can have method
* @param name the name of method to find
* @param args parameter types that is used to find method
* @return object that represents found method
* @throws NoSuchMethodException if method could not be found
* or some methods are found
*/
public static Method findStaticMethod(Class<?> type, String name, Class<?>...args) throws NoSuchMethodException {
Method method = findMethod(type, name, args);
if (!Modifier.isStatic(method.getModifiers())) {
throw new NoSuchMethodException("Method '" + name + "' is not static");
}
return method;
}
/**
* Finds method that is accessible from public class or interface through class hierarchy.
*
* @param method object that represents found method
* @return object that represents accessible method
* @throws NoSuchMethodException if method is not accessible or is not found
* in specified superclass or interface
*/
public static Method findAccessibleMethod(Method method) throws NoSuchMethodException {
Class<?> type = method.getDeclaringClass();
if (Modifier.isPublic(type.getModifiers()) && isPackageAccessible(type)) {
return method;
}
if (Modifier.isStatic(method.getModifiers())) {
throw new NoSuchMethodException("Method '" + method.getName() + "' is not accessible");
}
for (Type generic : type.getGenericInterfaces()) {
try {
return findAccessibleMethod(method, generic);
}
catch (NoSuchMethodException exception) {
// try to find in superclass or another interface
}
}
return findAccessibleMethod(method, type.getGenericSuperclass());
}
/**
* Finds method that accessible from specified class.
*
* @param method object that represents found method
* @param generic generic type that is used to find accessible method
* @return object that represents accessible method
* @throws NoSuchMethodException if method is not accessible or is not found
* in specified superclass or interface
*/
private static Method findAccessibleMethod(Method method, Type generic) throws NoSuchMethodException {
String name = method.getName();
Class<?>[] params = method.getParameterTypes();
if (generic instanceof Class) {
Class<?> type = (Class<?>) generic;
return findAccessibleMethod(type.getMethod(name, params));
}
if (generic instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType) generic;
Class<?> type = (Class<?>) pt.getRawType();
for (Method m : type.getMethods()) {
if (m.getName().equals(name)) {
Class<?>[] pts = m.getParameterTypes();
if (pts.length == params.length) {
if (Arrays.equals(params, pts)) {
return findAccessibleMethod(m);
}
Type[] gpts = m.getGenericParameterTypes();
if (params.length == gpts.length) {
if (Arrays.equals(params, TypeResolver.erase(TypeResolver.resolve(pt, gpts)))) {
return findAccessibleMethod(m);
}
}
}
}
}
}
throw new NoSuchMethodException("Method '" + name + "' is not accessible");
}
private final String name;
/**
* Creates method finder with specified array of parameter types.
*
* @param name the name of method to find
* @param args the array of parameter types
*/
private MethodFinder(String name, Class<?>[] args) {
super(args);
this.name = name;
}
/**
* Checks validness of the method.
* The valid method should be public and
* should have the specified name.
*
* @param method the object that represents method
* @return {@code true} if the method is valid,
* {@code false} otherwise
*/
@Override
protected boolean isValid(Method method) {
return super.isValid(method) && method.getName().equals(this.name);
}
}

View File

@@ -0,0 +1,68 @@
/*
* Copyright (c) 2009, 2010, 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.finder;
import java.beans.PersistenceDelegate;
import java.util.HashMap;
import java.util.Map;
/**
* This is utility class that provides functionality
* to find a {@link PersistenceDelegate} for a JavaBean specified by its type.
*
* @since 1.7
*
* @author Sergey A. Malenkov
*/
public final class PersistenceDelegateFinder
extends InstanceFinder<PersistenceDelegate> {
private final Map<Class<?>, PersistenceDelegate> registry;
public PersistenceDelegateFinder() {
super(PersistenceDelegate.class, true, "PersistenceDelegate");
this.registry = new HashMap<Class<?>, PersistenceDelegate>();
}
public void register(Class<?> type, PersistenceDelegate delegate) {
synchronized (this.registry) {
if (delegate != null) {
this.registry.put(type, delegate);
}
else {
this.registry.remove(type);
}
}
}
@Override
public PersistenceDelegate find(Class<?> type) {
PersistenceDelegate delegate;
synchronized (this.registry) {
delegate = this.registry.get(type);
}
return (delegate != null) ? delegate : super.find(type);
}
}

View File

@@ -0,0 +1,70 @@
/*
* Copyright (c) 2006, 2008, 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.finder;
import java.util.HashMap;
import java.util.Map;
/**
* This utility class associates
* name of primitive type with appropriate class.
*
* @since 1.7
*
* @author Sergey A. Malenkov
*/
final class PrimitiveTypeMap {
/**
* Returns primitive type class by its name.
*
* @param name the name of primitive type
* @return found primitive type class,
* or {@code null} if not found
*/
static Class<?> getType(String name) {
return map.get(name);
}
private static final Map<String, Class<?>> map = new HashMap<String, Class<?>>(9);
static {
map.put(boolean.class.getName(), boolean.class);
map.put(char.class.getName(), char.class);
map.put(byte.class.getName(), byte.class);
map.put(short.class.getName(), short.class);
map.put(int.class.getName(), int.class);
map.put(long.class.getName(), long.class);
map.put(float.class.getName(), float.class);
map.put(double.class.getName(), double.class);
map.put(void.class.getName(), void.class);
}
/**
* Disable instantiation.
*/
private PrimitiveTypeMap() {
}
}

View File

@@ -0,0 +1,86 @@
/*
* Copyright (c) 2008, 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.finder;
import java.util.HashMap;
import java.util.Map;
/**
* This utility class associates
* name of primitive type with appropriate wrapper.
*
* @since 1.7
*
* @author Sergey A. Malenkov
*/
public final class PrimitiveWrapperMap {
/**
* Replaces all primitive types in specified array with wrappers.
*
* @param types array of classes where all primitive types
* will be replaced by appropriate wrappers
*/
static void replacePrimitivesWithWrappers(Class<?>[] types) {
for (int i = 0; i < types.length; i++) {
if (types[i] != null) {
if (types[i].isPrimitive()) {
types[i] = getType(types[i].getName());
}
}
}
}
/**
* Returns wrapper for primitive type by its name.
*
* @param name the name of primitive type
* @return found wrapper for primitive type,
* or {@code null} if not found
*/
public static Class<?> getType(String name) {
return map.get(name);
}
private static final Map<String, Class<?>> map = new HashMap<String, Class<?>>(9);
static {
map.put(Boolean.TYPE.getName(), Boolean.class);
map.put(Character.TYPE.getName(), Character.class);
map.put(Byte.TYPE.getName(), Byte.class);
map.put(Short.TYPE.getName(), Short.class);
map.put(Integer.TYPE.getName(), Integer.class);
map.put(Long.TYPE.getName(), Long.class);
map.put(Float.TYPE.getName(), Float.class);
map.put(Double.TYPE.getName(), Double.class);
map.put(Void.TYPE.getName(), Void.class);
}
/**
* Disable instantiation.
*/
private PrimitiveWrapperMap() {
}
}

View File

@@ -0,0 +1,95 @@
/*
* Copyright (c) 2009, 2012, 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.finder;
import com.sun.beans.WeakCache;
import java.beans.PropertyEditor;
import com.sun.beans.editors.BooleanEditor;
import com.sun.beans.editors.ByteEditor;
import com.sun.beans.editors.DoubleEditor;
import com.sun.beans.editors.EnumEditor;
import com.sun.beans.editors.FloatEditor;
import com.sun.beans.editors.IntegerEditor;
import com.sun.beans.editors.LongEditor;
import com.sun.beans.editors.ShortEditor;
/**
* This is utility class that provides functionality
* to find a {@link PropertyEditor} for a JavaBean specified by its type.
*
* @since 1.7
*
* @author Sergey A. Malenkov
*/
public final class PropertyEditorFinder
extends InstanceFinder<PropertyEditor> {
private static final String DEFAULT = "sun.beans.editors";
private static final String DEFAULT_NEW = "com.sun.beans.editors";
private final WeakCache<Class<?>, Class<?>> registry;
public PropertyEditorFinder() {
super(PropertyEditor.class, false, "Editor", DEFAULT);
this.registry = new WeakCache<Class<?>, Class<?>>();
this.registry.put(Byte.TYPE, ByteEditor.class);
this.registry.put(Short.TYPE, ShortEditor.class);
this.registry.put(Integer.TYPE, IntegerEditor.class);
this.registry.put(Long.TYPE, LongEditor.class);
this.registry.put(Boolean.TYPE, BooleanEditor.class);
this.registry.put(Float.TYPE, FloatEditor.class);
this.registry.put(Double.TYPE, DoubleEditor.class);
}
public void register(Class<?> type, Class<?> editor) {
synchronized (this.registry) {
this.registry.put(type, editor);
}
}
@Override
public PropertyEditor find(Class<?> type) {
Class<?> predefined;
synchronized (this.registry) {
predefined = this.registry.get(type);
}
PropertyEditor editor = instantiate(predefined, null);
if (editor == null) {
editor = super.find(type);
if ((editor == null) && (null != type.getEnumConstants())) {
editor = new EnumEditor(type);
}
}
return editor;
}
@Override
protected PropertyEditor instantiate(Class<?> type, String prefix, String name) {
return super.instantiate(type, DEFAULT.equals(prefix) ? DEFAULT_NEW : prefix, name);
}
}

View File

@@ -0,0 +1,181 @@
/*
* Copyright (c) 2008, 2013, 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.finder;
/**
* This class is designed to be a key of a cache
* of constructors or methods.
*
* @since 1.7
*
* @author Sergey A. Malenkov
*/
final class Signature {
private final Class<?> type;
private final String name;
private final Class<?>[] args;
private volatile int code;
/**
* Constructs signature for constructor.
*
* @param type the class that contains constructor
* @param args the types of constructor's parameters
*/
Signature(Class<?> type, Class<?>[] args) {
this(type, null, args);
}
/**
* Constructs signature for method.
*
* @param type the class that contains method
* @param name the name of the method
* @param args the types of method's parameters
*/
Signature(Class<?> type, String name, Class<?>[] args) {
this.type = type;
this.name = name;
this.args = args;
}
Class<?> getType() {
return this.type;
}
String getName() {
return this.name;
}
Class<?>[] getArgs() {
return this.args;
}
/**
* Indicates whether some other object is "equal to" this one.
*
* @param object the reference object with which to compare
* @return {@code true} if this object is the same as the
* {@code object} argument, {@code false} otherwise
* @see #hashCode()
*/
@Override
public boolean equals(Object object) {
if (this == object) {
return true;
}
if (object instanceof Signature) {
Signature signature = (Signature) object;
return isEqual(signature.type, this.type)
&& isEqual(signature.name, this.name)
&& isEqual(signature.args, this.args);
}
return false;
}
/**
* Indicates whether some object is "equal to" another one.
* This method supports {@code null} values.
*
* @param obj1 the first reference object that will compared
* @param obj2 the second reference object that will compared
* @return {@code true} if first object is the same as the second object,
* {@code false} otherwise
*/
private static boolean isEqual(Object obj1, Object obj2) {
return (obj1 == null)
? obj2 == null
: obj1.equals(obj2);
}
/**
* Indicates whether some array is "equal to" another one.
* This method supports {@code null} values.
*
* @param args1 the first reference array that will compared
* @param args2 the second reference array that will compared
* @return {@code true} if first array is the same as the second array,
* {@code false} otherwise
*/
private static boolean isEqual(Class<?>[] args1, Class<?>[] args2) {
if ((args1 == null) || (args2 == null)) {
return args1 == args2;
}
if (args1.length != args2.length) {
return false;
}
for (int i = 0; i < args1.length; i++) {
if (!isEqual(args1[i], args2[i])) {
return false;
}
}
return true;
}
/**
* Returns a hash code value for the object.
* This method is supported for the benefit of hashtables
* such as {@link java.util.HashMap} or {@link java.util.HashSet}.
* Hash code computed using algorithm
* suggested in Effective Java, Item 8.
*
* @return a hash code value for this object
* @see #equals(Object)
*/
@Override
public int hashCode() {
if (this.code == 0) {
int code = 17;
code = addHashCode(code, this.type);
code = addHashCode(code, this.name);
if (this.args != null) {
for (Class<?> arg : this.args) {
code = addHashCode(code, arg);
}
}
this.code = code;
}
return this.code;
}
/**
* Adds hash code value if specified object.
* This is a part of the algorithm
* suggested in Effective Java, Item 8.
*
* @param code current hash code value
* @param object object that updates hash code value
* @return updated hash code value
* @see #hashCode()
*/
private static int addHashCode(int code, Object object) {
code *= 37;
return (object != null)
? code + object.hashCode()
: code;
}
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright (c) 2013, 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.finder;
final class SignatureException extends RuntimeException {
SignatureException(Throwable cause) {
super(cause);
}
NoSuchMethodException toNoSuchMethodException(String message) {
Throwable throwable = getCause();
if (throwable instanceof NoSuchMethodException) {
return (NoSuchMethodException) throwable;
}
NoSuchMethodException exception = new NoSuchMethodException(message);
exception.initCause(throwable);
return exception;
}
}