Added: openejb/trunk/openejb/deps/webbeans-impl/src/main/java/org/apache/webbeans/proxy/javassist/JavassistFactory.java URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/deps/webbeans-impl/src/main/java/org/apache/webbeans/proxy/javassist/JavassistFactory.java?rev=1417182&view=auto ============================================================================== --- openejb/trunk/openejb/deps/webbeans-impl/src/main/java/org/apache/webbeans/proxy/javassist/JavassistFactory.java (added) +++ openejb/trunk/openejb/deps/webbeans-impl/src/main/java/org/apache/webbeans/proxy/javassist/JavassistFactory.java Tue Dec 4 21:07:25 2012 @@ -0,0 +1,148 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.webbeans.proxy.javassist; + +import java.lang.reflect.Method; +import java.security.AccessController; +import java.security.PrivilegedAction; + +import javassist.util.proxy.MethodFilter; +import javassist.util.proxy.ProxyFactory; +import javassist.util.proxy.ProxyObject; +import org.apache.webbeans.proxy.Factory; +import org.apache.webbeans.proxy.MethodHandler; + +/** +* @version $Rev$ $Date$ +*/ +public class JavassistFactory + implements Factory +{ + public Class<?> getProxyClass(Class<?> superClass, Class<?>[] interfaces) + { + ProxyFactory fact = new ProxyFactory(); + fact.setInterfaces(interfaces); + if(superClass != null) + { + fact.setSuperclass(superClass); + } + fact.setFilter(FinalizeMethodFilter.INSTANCE); + + return getProxyClass(fact); + } + + private static Class<?> getProxyClass(ProxyFactory factory) + { + ProxyFactory.ClassLoaderProvider classLoaderProvider = ProxyFactory.classLoaderProvider; + try + { + return doPrivilegedCreateClass(factory); + } + catch(RuntimeException e) + { + if(classLoaderProvider instanceof OpenWebBeansClassLoaderProvider) + { + ((OpenWebBeansClassLoaderProvider)classLoaderProvider).useCurrentClassLoader(); + } + + //try again with updated class loader + return doPrivilegedCreateClass(factory); + } + finally + { + if(classLoaderProvider instanceof OpenWebBeansClassLoaderProvider) + { + ((OpenWebBeansClassLoaderProvider)classLoaderProvider).reset(); + } + } + } + + public Object createProxy(Class<?> proxyClass) + throws InstantiationException, IllegalAccessException + { + return proxyClass.newInstance(); + } + + + private static Class<?> doPrivilegedCreateClass(ProxyFactory factory) + { + if (System.getSecurityManager() == null) + { + return factory.createClass(); + } + else + { + return (Class<?>) AccessController.doPrivileged(new PrivilegedActionForProxyFactory(factory)); + } + } + + /** + * @param o the object to check + * @return <code>true</code> if the given object is a proxy + */ + public boolean isProxyInstance(Object o) + { + return o instanceof ProxyObject; + } + + public Object createProxy(MethodHandler handler, Class<?>[] interfaces) + throws InstantiationException, IllegalAccessException + { + ProxyFactory pf = new ProxyFactory(); + pf.setInterfaces(interfaces); + pf.setHandler(handler); + + return getProxyClass(pf).newInstance(); + } + + public void setHandler(Object proxy, MethodHandler handler) + { + ((ProxyObject)proxy).setHandler(handler); + } + + + protected static class PrivilegedActionForProxyFactory implements PrivilegedAction<Object> + { + private ProxyFactory factory; + + protected PrivilegedActionForProxyFactory(ProxyFactory factory) + { + this.factory = factory; + } + + public Object run() + { + return factory.createClass(); + } + } + + public static class FinalizeMethodFilter implements MethodFilter + { + private static final String FINALIZE = "finalize".intern(); + + public static final FinalizeMethodFilter INSTANCE = new FinalizeMethodFilter(); + + public boolean isHandled(final Method method) + { + return !(method.getName() == FINALIZE + && method.getParameterTypes().length == 0 + && method.getReturnType() == Void.TYPE); + } + } +}
Added: openejb/trunk/openejb/deps/webbeans-impl/src/main/java/org/apache/webbeans/proxy/javassist/OpenWebBeansClassLoaderProvider.java URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/deps/webbeans-impl/src/main/java/org/apache/webbeans/proxy/javassist/OpenWebBeansClassLoaderProvider.java?rev=1417182&view=auto ============================================================================== --- openejb/trunk/openejb/deps/webbeans-impl/src/main/java/org/apache/webbeans/proxy/javassist/OpenWebBeansClassLoaderProvider.java (added) +++ openejb/trunk/openejb/deps/webbeans-impl/src/main/java/org/apache/webbeans/proxy/javassist/OpenWebBeansClassLoaderProvider.java Tue Dec 4 21:07:25 2012 @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.webbeans.proxy.javassist; + +import javassist.util.proxy.ProxyFactory; + +/** + * Allows to switch to the {@link ClassLoader} of the current thread + */ +public class OpenWebBeansClassLoaderProvider implements ProxyFactory.ClassLoaderProvider +{ + private ProxyFactory.ClassLoaderProvider wrapped; + + private static ThreadLocal<Boolean> useCurrentClassLoader = new ThreadLocal<Boolean>(); + + OpenWebBeansClassLoaderProvider() + { + wrapped = ProxyFactory.classLoaderProvider; + } + + public static void initProxyFactoryClassLoaderProvider() + { + ProxyFactory.classLoaderProvider = new OpenWebBeansClassLoaderProvider(); + } + + public void useCurrentClassLoader() + { + useCurrentClassLoader.set(true); + } + + public void reset() + { + useCurrentClassLoader.set(null); + useCurrentClassLoader.remove(); + } + + public ClassLoader get(ProxyFactory proxyFactory) + { + if(!Boolean.TRUE.equals(useCurrentClassLoader.get())) + { + return wrapped.get(proxyFactory); + } + return Thread.currentThread().getContextClassLoader(); + } +} Added: openejb/trunk/openejb/deps/webbeans-impl/src/main/java/org/apache/webbeans/service/DefaultLoaderService.java URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/deps/webbeans-impl/src/main/java/org/apache/webbeans/service/DefaultLoaderService.java?rev=1417182&view=auto ============================================================================== --- openejb/trunk/openejb/deps/webbeans-impl/src/main/java/org/apache/webbeans/service/DefaultLoaderService.java (added) +++ openejb/trunk/openejb/deps/webbeans-impl/src/main/java/org/apache/webbeans/service/DefaultLoaderService.java Tue Dec 4 21:07:25 2012 @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.webbeans.service; + +import org.apache.webbeans.logger.WebBeansLoggerFacade; +import org.apache.webbeans.spi.LoaderService; +import org.apache.webbeans.util.WebBeansUtil; + +import java.util.ArrayList; +import java.util.List; +import java.util.ServiceLoader; +import java.util.logging.Logger; + +/** + * Default implementation which delegates to the s{@link ServiceLoader} of Java 1.6 and + * uses a fallback for Java 1.5 + */ +public class DefaultLoaderService implements LoaderService +{ + private static final Logger logger = WebBeansLoggerFacade.getLogger(DefaultLoaderService.class); + + private static final boolean JAVA_6_AVAILABLE = isJava6(); + + public <T> List<T> load(Class<T> serviceType) + { + return load(serviceType, WebBeansUtil.getCurrentClassLoader()); + } + + public <T> List<T> load(Class<T> serviceType, ClassLoader classLoader) + { + if(JAVA_6_AVAILABLE) + { + List<T> result = new ArrayList<T>(); + ServiceLoader<T> services = ServiceLoader.load(serviceType, classLoader); + + for (T service : services) + { + result.add(service); + } + + return result; + } + + return new ManualImplementationLoaderService<T>(serviceType, classLoader).loadServiceImplementations(); + } + + private static boolean isJava6() + { + try + { + ServiceLoader.class.getName(); + return true; + } + catch (NoClassDefFoundError error) + { + logger.info("Using Java 5 compatibility mode, because didn't find ServiceLoader: " + error); + return false; + } + } +} Added: openejb/trunk/openejb/deps/webbeans-impl/src/main/java/org/apache/webbeans/service/ManualImplementationLoaderService.java URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/deps/webbeans-impl/src/main/java/org/apache/webbeans/service/ManualImplementationLoaderService.java?rev=1417182&view=auto ============================================================================== --- openejb/trunk/openejb/deps/webbeans-impl/src/main/java/org/apache/webbeans/service/ManualImplementationLoaderService.java (added) +++ openejb/trunk/openejb/deps/webbeans-impl/src/main/java/org/apache/webbeans/service/ManualImplementationLoaderService.java Tue Dec 4 21:07:25 2012 @@ -0,0 +1,228 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.webbeans.service; + +import org.apache.webbeans.util.ClassUtil; + +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.lang.reflect.Constructor; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Enumeration; +import java.util.List; + +/** + * Manual service loader as fallback for Java 1.5 + */ +class ManualImplementationLoaderService<T> +{ + private static final String SERVICE_CONFIG = "META-INF/services/"; + private static final String FILE_ENCODING = "UTF-8"; + + protected List<Class<?>> foundServiceClasses = new ArrayList<Class<?>>(); + private Class<T> serviceType; + private ClassLoader currentClassLoader; + + ManualImplementationLoaderService(Class<T> serviceType, ClassLoader currentClassLoader) + { + this.serviceType = serviceType; + this.currentClassLoader = currentClassLoader; + } + + List<T> loadServiceImplementations() + { + List<Class<?>> result = resolveServiceImplementations(); + + if (result == null) + { + return Collections.emptyList(); + } + + List<T> foundServices = new ArrayList<T>(); + + for (Class<?> serviceClass : result) + { + foundServices.add(createInstance(serviceClass)); + } + + return foundServices; + } + + private List<Class<?>> resolveServiceImplementations() + { + for (URL configFile : getConfigFileList()) + { + loadConfiguredServices(configFile); + } + + return foundServiceClasses; + } + + private List<URL> getConfigFileList() + { + List<URL> serviceFiles = new ArrayList<URL>(); + + try + { + Enumeration<URL> serviceFileEnumerator = currentClassLoader.getResources(getConfigFileLocation()); + + while (serviceFileEnumerator.hasMoreElements()) + { + serviceFiles.add(serviceFileEnumerator.nextElement()); + } + } + catch (Exception e) + { + throw new IllegalStateException( + "Failed to load " + serviceType.getName() + " configured in " + getConfigFileLocation(), e); + } + return serviceFiles; + } + + private String getConfigFileLocation() + { + return SERVICE_CONFIG + serviceType.getName(); + } + + private void loadConfiguredServices(URL serviceFile) + { + InputStream inputStream = null; + + try + { + String serviceClassName; + inputStream = serviceFile.openStream(); + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, FILE_ENCODING)); + + while ((serviceClassName = bufferedReader.readLine()) != null) + { + serviceClassName = extractConfiguredServiceClassName(serviceClassName); + if (!"".equals(serviceClassName)) + { + loadService(serviceClassName); + } + } + } + catch (Exception e) + { + throw new IllegalStateException("Failed to process service-config: " + serviceFile, e); + } + finally + { + if (inputStream != null) + { + try + { + inputStream.close(); + } + catch (Exception e) + { + throw new IllegalStateException("Failed to close " + serviceFile, e); + } + } + } + } + + private String extractConfiguredServiceClassName(String currentConfigLine) + { + int startOfComment = currentConfigLine.indexOf('#'); + + if (startOfComment > -1) + { + currentConfigLine = currentConfigLine.substring(0, startOfComment); + } + return currentConfigLine.trim(); + } + + private void loadService(String serviceClassName) + { + Class<T> serviceClass = (Class<T>) loadClass(serviceClassName); + + if (serviceClass != null && !foundServiceClasses.contains(serviceClass)) + { + foundServiceClasses.add(serviceClass); + } + else if (serviceClass == null) + { + throw new IllegalStateException(serviceClassName + " couldn't be loaded. " + + "Please ensure that this class is in the classpath or remove the entry from " + + getConfigFileLocation() + "."); + } + } + + private Class<? extends T> loadClass(String serviceClassName) + { + Class<?> targetClass = ClassUtil.getClassFromName(serviceClassName); + + if (targetClass == null) + { + targetClass = loadClassForName(serviceClassName, currentClassLoader); + + if (targetClass == null) + { + return null; + } + } + + return targetClass.asSubclass(serviceType); + } + + private static Class<?> loadClassForName(String serviceClassName, ClassLoader classLoader) + { + if (classLoader == null) + { + return null; + } + + try + { + return classLoader.loadClass(serviceClassName); + } + catch (Exception e) + { + return loadClassForName(serviceClassName, classLoader.getParent()); + } + } + + private T createInstance(Class<?> serviceClass) + { + try + { + Constructor<?> constructor = serviceClass.getDeclaredConstructor(); + constructor.setAccessible(true); + return (T) constructor.newInstance(); + } + catch (Exception e) + { + return null; + } + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() + { + return "Config file: " + getConfigFileLocation(); + } +} Added: openejb/trunk/openejb/deps/webbeans-impl/src/main/java/org/apache/webbeans/util/AnnotationUtil.java URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/deps/webbeans-impl/src/main/java/org/apache/webbeans/util/AnnotationUtil.java?rev=1417182&view=auto ============================================================================== --- openejb/trunk/openejb/deps/webbeans-impl/src/main/java/org/apache/webbeans/util/AnnotationUtil.java (added) +++ openejb/trunk/openejb/deps/webbeans-impl/src/main/java/org/apache/webbeans/util/AnnotationUtil.java Tue Dec 4 21:07:25 2012 @@ -0,0 +1,777 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.webbeans.util; + +import org.apache.webbeans.exception.WebBeansException; + +import javax.enterprise.inject.Any; +import javax.enterprise.inject.spi.AnnotatedMethod; +import javax.enterprise.inject.spi.AnnotatedParameter; +import javax.enterprise.inject.spi.Bean; +import javax.enterprise.util.Nonbinding; +import java.lang.annotation.Annotation; +import java.lang.reflect.AnnotatedElement; +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Set; + +/** + * Utility class related with {@link Annotation} operations. + * + * @author <a href="mailto:[email protected]">Gurkan Erdogdu</a> + * @since 1.0 + */ +public final class AnnotationUtil +{ + public static final Annotation[] EMPTY_ANNOTATION_ARRAY = new Annotation[0]; + + public static final Object[] EMPTY_OBJECT_ARRAY = new Object[0]; + + // No instantiate + private AnnotationUtil() + { + throw new UnsupportedOperationException(); + } + + /** + * Check given annotation exist on the method. + * + * @param method method + * @param clazz annotation class + * @return true or false + */ + public static boolean hasMethodAnnotation(Method method, Class<? extends Annotation> clazz) + { + final AnnotatedElement element = method; + Annotation[] anns = getDeclaredAnnotations(element); + for (Annotation annotation : anns) + { + if (annotation.annotationType().equals(clazz)) + { + return true; + } + } + + return false; + + } + + /** + * Utility method to get around some errors caused by + * interactions between the Equinox class loaders and + * the OpenJPA transformation process. There is a window + * where the OpenJPA transformation process can cause + * an annotation being processed to get defined in a + * classloader during the actual defineClass call for + * that very class (e.g., recursively). This results in + * a LinkageError exception. If we see one of these, + * retry the request. Since the annotation will be + * defined on the second pass, this should succeed. If + * we get a second exception, then it's likely some + * other problem. + * + * @param element The AnnotatedElement we need information for. + * + * @return An array of the Annotations defined on the element. + */ + private static Annotation[] getDeclaredAnnotations(AnnotatedElement element) + { + try + { + return element.getDeclaredAnnotations(); + } + catch (LinkageError e) + { + return element.getDeclaredAnnotations(); + } + } + + + /** + * Check given annotation exist in the any parameter of the given method. + * Return true if exist false otherwise. + * + * @param method method + * @param clazz checking annotation + * @return true or false + */ + public static boolean hasMethodParameterAnnotation(Method method, Class<? extends Annotation> clazz) + { + Asserts.assertNotNull(method, "Method argument can not be null"); + Asserts.nullCheckForClass(clazz); + + Annotation[][] parameterAnns = method.getParameterAnnotations(); + + for (Annotation[] parameters : parameterAnns) + { + for (Annotation param : parameters) + { + Class<? extends Annotation> btype = param.annotationType(); + if (btype.equals(clazz)) + { + return true; + } + } + + } + return false; + } + + public static <X> boolean hasAnnotatedMethodParameterAnnotation(AnnotatedMethod<X> annotatedMethod, Class<? extends Annotation> clazz) + { + Asserts.assertNotNull(annotatedMethod, "annotatedMethod argument can not be null"); + Asserts.nullCheckForClass(clazz); + + List<AnnotatedParameter<X>> parameters = annotatedMethod.getParameters(); + for(AnnotatedParameter<X> parameter : parameters) + { + if(parameter.isAnnotationPresent(clazz)) + { + return true; + } + } + + return false; + } + + /** + * Check given annotation exist in the multiple parameter of the given + * method. Return true if exist false otherwise. + * + * @param method method + * @param clazz checking annotation + * @return true or false + */ + public static boolean hasMethodMultipleParameterAnnotation(Method method, Class<? extends Annotation> clazz) + { + Asserts.assertNotNull(method, "Method argument can not be null"); + Asserts.nullCheckForClass(clazz); + + Annotation[][] parameterAnns = method.getParameterAnnotations(); + + boolean found = false; + + for (Annotation[] parameters : parameterAnns) + { + for (Annotation param : parameters) + { + + if (param.annotationType().equals(clazz)) + { + if (!found) + { + found = true; + } + else + { + return true; + } + } + } + + } + return false; + } + + public static <X> boolean hasAnnotatedMethodMultipleParameterAnnotation(AnnotatedMethod<X> annotatedMethod, Class<? extends Annotation> clazz) + { + Asserts.assertNotNull(annotatedMethod, "annotatedMethod argument can not be null"); + Asserts.nullCheckForClass(clazz); + + boolean found = false; + + List<AnnotatedParameter<X>> parameters = annotatedMethod.getParameters(); + for(AnnotatedParameter<X> parameter : parameters) + { + if(parameter.isAnnotationPresent(clazz)) + { + if(!found) + { + found = true; + } + else + { + return true; + } + } + } + + + return false; + } + + + /** + * Gets the method first found parameter type that is annotated with the + * given annotation. + * + * @param method method + * @param clazz checking annotation + * @return type + */ + public static Type getMethodFirstParameterWithAnnotation(Method method, Class<? extends Annotation> clazz) + { + Asserts.assertNotNull(method, "Method argument can not be null"); + Asserts.nullCheckForClass(clazz); + + Annotation[][] parameterAnns = method.getParameterAnnotations(); + Type[] params = method.getGenericParameterTypes(); + + int index = 0; + for (Annotation[] parameters : parameterAnns) + { + for (Annotation param : parameters) + { + Class<? extends Annotation> btype = param.annotationType(); + if (btype.equals(clazz)) + { + return params[index]; + } + } + + index++; + + } + return null; + } + + public static <X> Type getAnnotatedMethodFirstParameterWithAnnotation(AnnotatedMethod<X> annotatedMethod, Class<? extends Annotation> clazz) + { + Asserts.assertNotNull(annotatedMethod, "annotatedMethod argument can not be null"); + Asserts.nullCheckForClass(clazz); + + List<AnnotatedParameter<X>> parameters = annotatedMethod.getParameters(); + for(AnnotatedParameter<X> parameter : parameters) + { + if(parameter.isAnnotationPresent(clazz)) + { + return parameter.getBaseType(); + } + } + + return null; + } + + /** + * Get the Type of the method parameter which has the given annotation + * @param method which need to be scanned + * @param clazz the annotation to scan the method parameters for + * @return the Type of the method parameter which has the given annotation, or <code>null</code> if not found. + */ + public static Type getTypeOfParameterWithGivenAnnotation(Method method, Class<? extends Annotation> clazz) + { + Asserts.assertNotNull(method, "Method argument can not be null"); + Asserts.nullCheckForClass(clazz); + + Annotation[][] parameterAnns = method.getParameterAnnotations(); + Type result = null; + + int index = 0; + for (Annotation[] parameters : parameterAnns) + { + boolean found = false; + for (Annotation param : parameters) + { + Class<? extends Annotation> btype = param.annotationType(); + if (btype.equals(clazz)) + { + found = true; + //Adding Break instead of continue + break; + } + } + + if (found) + { + result = method.getGenericParameterTypes()[index]; + break; + } + + index++; + + } + return result; + } + + /** + * Gets the method first found parameter annotation with given type. + * + * @param method method + * @param clazz checking annotation + * @return annotation + */ + public static <T extends Annotation> T getMethodFirstParameterAnnotation(Method method, Class<T> clazz) + { + Asserts.assertNotNull(method, "Method argument can not be null"); + Asserts.nullCheckForClass(clazz); + + Annotation[][] parameterAnns = method.getParameterAnnotations(); + + for (Annotation[] parameters : parameterAnns) + { + for (Annotation param : parameters) + { + Class<? extends Annotation> btype = param.annotationType(); + if (btype.equals(clazz)) + { + return clazz.cast(param); + } + + } + + } + + return null; + } + + public static <X,T extends Annotation> T getAnnotatedMethodFirstParameterAnnotation(AnnotatedMethod<X> annotatedMethod, Class<T> clazz) + { + Asserts.assertNotNull(annotatedMethod, "annotatedMethod argument can not be null"); + Asserts.nullCheckForClass(clazz); + + + List<AnnotatedParameter<X>> parameters = annotatedMethod.getParameters(); + for(AnnotatedParameter<X> parameter : parameters) + { + if(parameter.isAnnotationPresent(clazz)) + { + return clazz.cast(parameter.getAnnotation(clazz)); + } + } + + return null; + } + + /** + * Checks if the given qualifiers are equal. + * + * Qualifiers are equal if they have the same annotationType and all their + * methods, except those annotated with @Nonbinding, return the same value. + * + * @param qualifier1 + * @param qualifier2 + * @return + */ + public static boolean isQualifierEqual(Annotation qualifier1, Annotation qualifier2) + { + Asserts.assertNotNull(qualifier1, "qualifier1 argument can not be null"); + Asserts.assertNotNull(qualifier2, "qualifier2 argument can not be null"); + + Class<? extends Annotation> qualifier1AnnotationType + = qualifier1.annotationType(); + + // check if the annotationTypes are equal + if (qualifier1AnnotationType == null + || !qualifier1AnnotationType.equals(qualifier2.annotationType())) + { + return false; + } + + // check the values of all qualifier-methods + // except those annotated with @Nonbinding + List<Method> bindingQualifierMethods + = getBindingQualifierMethods(qualifier1AnnotationType); + + for (int i = 0, size = bindingQualifierMethods.size(); i < size; i++) + { + Method method = bindingQualifierMethods.get(i); + Object value1 = callMethod(qualifier1, method); + Object value2 = callMethod(qualifier2, method); + + if (!checkEquality(value1, value2)) + { + return false; + } + } + + return true; + } + + /** + * Quecks if the two values are equal. + * + * @param value1 + * @param value2 + * @return + */ + private static boolean checkEquality(Object value1, Object value2) + { + if ((value1 == null && value2 != null) || + (value1 != null && value2 == null)) + { + return false; + } + + if (value1 == null && value2 == null) + { + return true; + } + + // now both values are != null + + Class<?> valueClass = value1.getClass(); + + if (!valueClass.equals(value2.getClass())) + { + return false; + } + + if (valueClass.isPrimitive()) + { + // primitive types can be checked with == + return value1 == value2; + } + else if (valueClass.isArray()) + { + Class<?> arrayType = valueClass.getComponentType(); + + if (arrayType.isPrimitive()) + { + if (Long.TYPE == arrayType) + { + return Arrays.equals(((long[]) value1), (long[]) value2); + } + else if (Integer.TYPE == arrayType) + { + return Arrays.equals(((int[]) value1), (int[]) value2); + } + else if (Short.TYPE == arrayType) + { + return Arrays.equals(((short[]) value1), (short[]) value2); + } + else if (Double.TYPE == arrayType) + { + return Arrays.equals(((double[]) value1), (double[]) value2); + } + else if (Float.TYPE == arrayType) + { + return Arrays.equals(((float[]) value1), (float[]) value2); + } + else if (Boolean.TYPE == arrayType) + { + return Arrays.equals(((boolean[]) value1), (boolean[]) value2); + } + else if (Byte.TYPE == arrayType) + { + return Arrays.equals(((byte[]) value1), (byte[]) value2); + } + else if (Character.TYPE == arrayType) + { + return Arrays.equals(((char[]) value1), (char[]) value2); + } + return false; + } + else + { + return Arrays.equals(((Object[]) value1), (Object[]) value2); + } + } + else + { + return value1.equals(value2); + } + } + + /** + * Calls the given method on the given instance. + * Used to determine the values of annotation instances. + * + * @param instance + * @param method + * @return + */ + private static Object callMethod(Object instance, Method method) + { + try + { + if (!method.isAccessible()) + { + method.setAccessible(true); + } + + return method.invoke(instance, EMPTY_OBJECT_ARRAY); + } + catch (Exception e) + { + throw new WebBeansException("Exception in method call : " + method.getName(), e); + } + } + + /** + * Return a List of all methods of the qualifier, + * which are not annotated with @Nonbinding. + * + * @param qualifierAnnotationType + */ + private static List<Method> getBindingQualifierMethods( + Class<? extends Annotation> qualifierAnnotationType) + { + Method[] qualifierMethods = qualifierAnnotationType.getDeclaredMethods(); + + if (qualifierMethods.length > 0) + { + List<Method> bindingMethods = new ArrayList<Method>(); + + for (Method qualifierMethod : qualifierMethods) + { + Annotation[] qualifierMethodAnnotations = getDeclaredAnnotations(qualifierMethod); + + if (qualifierMethodAnnotations.length > 0) + { + // look for @Nonbinding + boolean nonbinding = false; + + for (Annotation qualifierMethodAnnotation : qualifierMethodAnnotations) + { + if (Nonbinding.class.equals( + qualifierMethodAnnotation.annotationType())) + { + nonbinding = true; + break; + } + } + + if (!nonbinding) + { + // no @Nonbinding found - add to list + bindingMethods.add(qualifierMethod); + } + } + else + { + // no method-annotations - add to list + bindingMethods.add(qualifierMethod); + } + } + + return bindingMethods; + } + + // annotation has no methods + return Collections.emptyList(); + } + + + /** + * Gets array of methods that has parameter with given annotation type. + * + * @param clazz class for check + * @param annotation for check + * @return array of methods + */ + public static Method[] getMethodsWithParameterAnnotation(Class<?> clazz, Class<? extends Annotation> annotation) + { + Asserts.nullCheckForClass(clazz); + Asserts.assertNotNull(annotation, "Annotation argument can not be null"); + List<Method> list = new ArrayList<Method>(); + + do + { + Method[] methods = SecurityUtil.doPrivilegedGetDeclaredMethods(clazz); + + for (Method m : methods) + { + if (hasMethodParameterAnnotation(m, annotation)) + { + list.add(m); + } + } + clazz = clazz.getSuperclass(); + } while (clazz != null && clazz != Object.class); + + Method[] rMethod = list.toArray(new Method[list.size()]); + + return rMethod; + } + + + /** + * Check whether or not class contains the given annotation. + * + * @param clazz class instance + * @param annotation annotation class + * @return return true or false + */ + public static boolean hasClassAnnotation(Class<?> clazz, Class<? extends Annotation> annotation) + { + Asserts.nullCheckForClass(clazz); + Asserts.assertNotNull(annotation, "Annotation argument can not be null"); + + try + { + Annotation a = clazz.getAnnotation(annotation); + + if (a != null) + { + return true; + } + } + catch (ArrayStoreException e) + { + //log this? It is probably already logged in AnnotatedElementFactory + } + + return false; + } + + public static boolean hasMetaAnnotation(Annotation[] anns, Class<? extends Annotation> metaAnnotation) + { + Asserts.assertNotNull(anns, "Anns argument can not be null"); + Asserts.assertNotNull(metaAnnotation, "MetaAnnotation argument can not be null"); + + for (Annotation annot : anns) + { + if (annot.annotationType().isAnnotationPresent(metaAnnotation)) + { + return true; + } + } + + return false; + + } + + public static boolean hasAnnotation(Annotation[] anns, Class<? extends Annotation> annotation) + { + return getAnnotation(anns, annotation) != null; + } + + /** + * get the annotation of the given type from the array. + * @param anns + * @param annotation + * @return the Annotation with the given type or <code>null</code> if no such found. + */ + @SuppressWarnings("unchecked") + public static <T extends Annotation> T getAnnotation(Annotation[] anns, Class<T> annotation) + { + Asserts.assertNotNull(anns, "anns argument can not be null"); + Asserts.assertNotNull(annotation, "annotation argument can not be null"); + for (Annotation annot : anns) + { + if (annot.annotationType().equals(annotation)) + { + return (T)annot; + } + } + + return null; + } + + /** + * Returns a subset of annotations that are annotated with the specified meta-annotation + * + * @param anns + * @param metaAnnotation + * @return + */ + public static Annotation[] getMetaAnnotations(Annotation[] anns, Class<? extends Annotation> metaAnnotation) + { + List<Annotation> annots = new ArrayList<Annotation>(); + Annotation[] result; + Asserts.assertNotNull(anns, "Anns argument can not be null"); + Asserts.assertNotNull(metaAnnotation, "MetaAnnotation argument can not be null"); + + for (Annotation annot : anns) + { + if (annot.annotationType().isAnnotationPresent(metaAnnotation)) + { + annots.add(annot); + } + } + + result = new Annotation[annots.size()]; + result = annots.toArray(result); + + return result; + } + + + /** + * Returns true if any binding exist + * + * @param bean bean + * @return true if any binding exist + */ + public static boolean hasAnyQualifier(Bean<?> bean) + { + Asserts.assertNotNull(bean, "bean parameter can not be null"); + Set<Annotation> qualifiers = bean.getQualifiers(); + + return getAnnotation(qualifiers, Any.class) != null; + } + + /** + * Search in the given Set of Annotations for the one with the given AnnotationClass. + * @param annotations to scan + * @param annotationClass to search for + * @return the annotation with the given annotationClass or <code>null</code> if not found. + */ + public static <T extends Annotation> T getAnnotation(Set<Annotation> annotations, Class<T> annotationClass) + { + if (annotations == null) + { + return null; + } + + for(Annotation ann : annotations) + { + if(ann.annotationType().equals(annotationClass)) + { + return (T) ann; + } + } + + return null; + } + + + public static Annotation hasOwbInjectableResource(Annotation[] annotations) + { + for (Annotation anno : annotations) + { + for(String name : WebBeansConstants.OWB_INJECTABLE_RESOURCE_ANNOTATIONS) + { + if(anno.annotationType().getName().equals(name)) + { + return anno; + } + } + } + + return null; + } + + public static Annotation[] getAnnotationsFromSet(Set<Annotation> set) + { + if(set != null) + { + Annotation[] anns = new Annotation[set.size()]; + anns = set.toArray(anns); + + return anns; + } + + return EMPTY_ANNOTATION_ARRAY; + } +} Added: openejb/trunk/openejb/deps/webbeans-impl/src/main/java/org/apache/webbeans/util/ArrayUtil.java URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/deps/webbeans-impl/src/main/java/org/apache/webbeans/util/ArrayUtil.java?rev=1417182&view=auto ============================================================================== --- openejb/trunk/openejb/deps/webbeans-impl/src/main/java/org/apache/webbeans/util/ArrayUtil.java (added) +++ openejb/trunk/openejb/deps/webbeans-impl/src/main/java/org/apache/webbeans/util/ArrayUtil.java Tue Dec 4 21:07:25 2012 @@ -0,0 +1,105 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.webbeans.util; + +import java.util.HashSet; +import java.util.Set; + +public final class ArrayUtil +{ + + private ArrayUtil() + { + + } + + /** + * Compare two arrays regardless of the position of the elements + * in the arrays. The complex handling with temporary flags is necessary due + * to the possibility of having multiple occurrences of the same element in + * the arrays. In this case both arrays have to contain the exactly same + * amount of those elements. This is only suited for smaller arrays (e.g. + * count < 100) since the algorithm uses a product of both arrays. If one + * likes to use this for larger arrays, we'd have to use hashes. + * + * @param arr1 + * @param arr2 + * @return + */ + public static boolean equalsIgnorePosition(Object[] arr1, Object[] arr2) + { + if (arr1 == null && arr2 == null) + { + return true; + } + + if (arr1 == null || arr2 == null) + { + return false; + } + + if (arr1.length != arr2.length) + { + return false; + } + + boolean[] found1 = new boolean[arr1.length]; + boolean[] found2 = new boolean[arr2.length]; + + for (int i1 = 0; i1 < arr1.length; i1++) + { + Object o1 = arr1[i1]; + + for (int i2 = 0; i2 < arr2.length; i2++) + { + Object o2 = arr2[i2]; + + // if they are equal and not found already + if (o1.equals(o2) && !found2[i2]) + { + // mark the entries in both arrays as found + found1[i1] = true; + found2[i2] = true; + break; + } + } + } + + for (int i = 0; i < found1.length; i++) + { + if (!found1[i] || !found2[i]) + { + return false; + } + } + return true; + } + + public static <T> Set<T> asSet(T... items) + { + Set<T> set = new HashSet<T>(); + + for(T item : items) + { + set.add(item); + } + + return set; + } +} Added: openejb/trunk/openejb/deps/webbeans-impl/src/main/java/org/apache/webbeans/util/Asserts.java URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/deps/webbeans-impl/src/main/java/org/apache/webbeans/util/Asserts.java?rev=1417182&view=auto ============================================================================== --- openejb/trunk/openejb/deps/webbeans-impl/src/main/java/org/apache/webbeans/util/Asserts.java (added) +++ openejb/trunk/openejb/deps/webbeans-impl/src/main/java/org/apache/webbeans/util/Asserts.java Tue Dec 4 21:07:25 2012 @@ -0,0 +1,107 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.webbeans.util; + +import java.lang.reflect.Method; + +/** + * Simple utility classes with some assertions methods. + * + * @author <a href="mailto:[email protected]">Gurkan Erdogdu</a> + * @since 1.0 + */ +public final class Asserts +{ + + /* + * Private constructor + */ + private Asserts() + { + throw new UnsupportedOperationException(); + } + + /** + * Check the object is null or not + * + * @param obj null check object + * @param message exception message + */ + public static void assertNotNull(Object obj, String message) + { + if (obj == null) + { + throw new NullPointerException(message); + } + } + + /** + * Check the object is null or not + * + * @param obj null check object + */ + public static void assertNotNull(Object obj) + { + if (obj == null) + { + throw new NullPointerException(); + } + } + + /** + * Null check for type modifiers. + * + * @param modifier modifier parameter check + */ + public static void nullCheckForModifier(Integer modifier) + { + Asserts.assertNotNull(modifier, "modifier argument can not be null"); + } + + /** + * Null check for class parameter. + * + * @param clazz parameter + */ + public static void nullCheckForClass(Class<?> clazz) + { + Asserts.assertNotNull(clazz, "clazz argument can not be null"); + } + + /** + * Null check for class parameter. + * + * @param clazz parameter + */ + public static void nullCheckForClass(Class<?> clazz, String message) + { + Asserts.assertNotNull(clazz, message); + } + + /** + * Null check for method parameter. + * + * @param method parameter + */ + public static void nullCheckForMethod(Method method) + { + Asserts.assertNotNull(method, "method argument can not be null"); + } + +}
