/*
* JBoss, Home of Professional Open Source
* Copyright 2010, Red Hat, Inc., and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.jboss.weld.test.util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamClass;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import javax.el.ELContext;
import javax.enterprise.context.ContextNotActiveException;
import javax.enterprise.context.spi.Context;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.util.TypeLiteral;
import org.jboss.weld.bean.proxy.ProxyObject;
import org.jboss.weld.logging.BeanManagerLogger;
import org.jboss.weld.manager.BeanManagerImpl;
import org.jboss.weld.manager.api.WeldManager;
import org.jboss.weld.test.util.el.EL;
import org.jboss.weld.util.collections.EnumerationList;
import org.jboss.weld.util.reflection.Reflections;
public class Utils {
public static final int MASK = 0xff;
private Utils() {
}
/**
* Checks if all annotations are in a given set of annotations
*
* @param annotations The annotation set
* @param annotationTypes The annotations to match
* @return True if match, false otherwise
*/
@SafeVarargs
public static boolean annotationSetMatches(Set<? extends Annotation> annotations, Class<? extends Annotation>... annotationTypes) {
List<Class<? extends Annotation>> annotationTypeList = new ArrayList<Class<? extends Annotation>>();
annotationTypeList.addAll(Arrays.asList(annotationTypes));
for (Annotation annotation : annotations) {
if (annotationTypeList.contains(annotation.annotationType())) {
annotationTypeList.remove(annotation.annotationType());
} else {
return false;
}
}
return annotationTypeList.size() == 0;
}
public static boolean typeSetMatches(Set<Type> types, Type... requiredTypes) {
List<Type> typeList = Arrays.asList(requiredTypes);
return requiredTypes.length == types.size() && types.containsAll(typeList);
}
public static Iterable<URL> getResources(Class<?> clazz, String name) {
if (name.startsWith("/")) {
name = name.substring(1);
} else {
name = clazz.getPackage().getName().replace(".", "/") + "/" + name;
}
try {
return new EnumerationList<>(clazz.getClassLoader().getResources(name));
} catch (IOException e) {
throw new RuntimeException("Error loading resource from classloader" + name, e);
}
}
public static byte[] serialize(Object instance) throws IOException {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(bytes);
out.writeObject(instance);
return bytes.toByteArray();
}
public static <T> T deserialize(byte[] bytes) throws IOException, ClassNotFoundException {
try (TCCLObjectInputStream in = new TCCLObjectInputStream(new ByteArrayInputStream(bytes))) {
return Reflections.<T>cast(in.readObject());
}
}
public static <T> T deserialize(byte[] bytes, ClassLoader cl) throws IOException, ClassNotFoundException {
try (TCCLObjectInputStream in = new TCCLObjectInputStream(new ByteArrayInputStream(bytes), cl)) {
return Reflections.<T>cast(in.readObject());
}
}
public static boolean isExceptionInHierarchy(Throwable exception, Class<? extends Throwable> expectedException) {
while (exception != null) {
if (exception.getClass().equals(expectedException)) {
return true;
}
exception = exception.getCause();
}
return false;
}
public static <T> Bean<T> getBean(BeanManager beanManager, Type beanType, Annotation... bindings) {
Set<Bean<?>> beans = beanManager.getBeans(beanType, bindings);
Bean<?> bean = beanManager.resolve(beans);
if (bean == null) {
throw BeanManagerLogger.LOG.unresolvableType(beanType, Arrays.toString(bindings));
}
@SuppressWarnings("unchecked")
Bean<T> typedBean = (Bean<T>) bean;
return typedBean;
}
@SuppressWarnings("unchecked")
public static <T> Set<Bean<T>> getBeans(BeanManager beanManager, Class<T> type, Annotation... bindings) {
return (Set) beanManager.getBeans(type, bindings);
}
@SuppressWarnings("unchecked")
public static <T> Set<Bean<T>> getBeans(BeanManager beanManager, TypeLiteral<T> type, Annotation... bindings) {
return (Set) beanManager.getBeans(type.getType(), bindings);
}
@SuppressWarnings("unchecked")
public static <T> T getReference(BeanManager beanManager, Class<T> beanType, Annotation... bindings) {
Bean<?> bean = getBean(beanManager, beanType, bindings);
return (T) beanManager.getReference(bean, beanType, beanManager.createCreationalContext(bean));
}
public static <T> T getReference(BeanManager beanManager, Bean<T> bean) {
return getReference(beanManager, bean, Object.class);
}
@SuppressWarnings("unchecked")
public static <T> T getReference(BeanManager beanManager, Bean<T> bean, Type beanType) {
return (T) beanManager.getReference(bean, beanType, beanManager.createCreationalContext(bean));
}
@SuppressWarnings("unchecked")
public static <T> T evaluateValueExpression(BeanManagerImpl beanManager, String expression, Class<T> expectedType) {
ELContext elContext = EL.createELContext(beanManager);
return (T) EL.EXPRESSION_FACTORY.createValueExpression(elContext, expression, expectedType).getValue(elContext);
}
public static boolean isProxy(Object proxy) {
return proxy instanceof ProxyObject;
}
public static <T extends Context> T getActiveContext(WeldManager beanManager, Class<T> type) {
for (T context : beanManager.instance().select(type)) {
if (context.isActive()) {
return context;
}
}
throw new ContextNotActiveException();
}
private static class TCCLObjectInputStream extends ObjectInputStream {
private final ClassLoader tccl;
private final ClassLoader optionalClassLoader;
public TCCLObjectInputStream(InputStream in) throws IOException {
this(in, null);
}
public TCCLObjectInputStream(InputStream in, ClassLoader cl) throws IOException {
super(in);
this.tccl = Thread.currentThread().getContextClassLoader();
this.optionalClassLoader = cl;
}
@Override
protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
try {
String name = desc.getName();
return Class.forName(name, false, tccl);
} catch (ClassNotFoundException e) {
try {
return super.resolveClass(desc);
} catch (ClassNotFoundException e1) {
try {
return BeanManagerImpl.class.getClassLoader().loadClass(desc.getName());
} catch (ClassNotFoundException cnfe) {
if (optionalClassLoader != null) {
// should all else fail, try the optional CL, if supplied
return optionalClassLoader.loadClass(desc.getName());
} else {
// rethrow the exception, we cannot handle this
throw cnfe;
}
}
}
}
}
}
public static String getDeploymentNameAsHash(Class<?> testClass, ARCHIVE_TYPE archiveType) {
String hexString = getHashOfTestClass(testClass.getName());
switch (archiveType) {
case JAR:
return hexString.toString() + ".jar";
case WAR:
return hexString.toString() + ".war";
case EAR:
return hexString.toString() + ".ear";
default:
break;
}
return null;
}
public static String getDeploymentNameAsHash(Class<?> testClass) {
return getDeploymentNameAsHash(testClass, ARCHIVE_TYPE.JAR);
}
public static String getHashOfTestClass(String testClassName) {
MessageDigest messageDigest = null;
try {
messageDigest = MessageDigest.getInstance("SHA-1");
} catch (NoSuchAlgorithmException e) {
return null;
}
messageDigest.update(testClassName.getBytes());
byte[] digest = messageDigest.digest();
StringBuilder hexString = new StringBuilder();
for (int i = 0; i < digest.length; i++) {
hexString.append(Integer.toHexString(MASK & digest[i]));
}
return hexString.toString();
}
public enum ARCHIVE_TYPE {
JAR,
WAR,
EAR
}
}