Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, 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.util.reflection;
import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.GenericDeclaration;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import javax.enterprise.inject.spi.AnnotatedConstructor;
import javax.enterprise.inject.spi.AnnotatedField;
import javax.enterprise.inject.spi.AnnotatedMethod;
import javax.enterprise.inject.spi.AnnotatedParameter;
import javax.enterprise.inject.spi.AnnotatedType;
import javax.enterprise.inject.spi.InjectionPoint;
import org.jboss.classfilewriter.util.DescriptorUtils;
import org.jboss.weld.ejb.spi.BusinessInterfaceDescriptor;
import org.jboss.weld.resources.ClassLoaderResourceLoader;
import org.jboss.weld.resources.DefaultResourceLoader;
import org.jboss.weld.resources.WeldClassLoaderResourceLoader;
import org.jboss.weld.resources.spi.ResourceLoader;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
/**
* Utility class to produce friendly names e.g. for debugging
*
* @author Pete Muir
* @author Nicklas Karlsson
* @author Jozef Hartinger
*/
public class Formats {
private static final String SNAPSHOT = "SNAPSHOT";
private static final String NULL = "null";
private static final String SQUARE_BRACKETS = "[]";
private static final String BCEL_CLASS_PARSER_FQCN = "com.sun.org.apache.bcel.internal.classfile.ClassParser";
private static final String BCEL_JAVA_CLASS_FQCN = "com.sun.org.apache.bcel.internal.classfile.JavaClass";
private static final String BCEL_METHOD_FQCN = "com.sun.org.apache.bcel.internal.classfile.Method";
private static final String BCEL_LINE_NUMBER_TABLE_FQCN = "com.sun.org.apache.bcel.internal.classfile.LineNumberTable";
private static final String BCEL_M_PARSE = "parse";
private static final String BCEL_M_GET_METHODS = "getMethods";
private static final String BCEL_M_GET_LINE_NUMBER_TABLE = "getLineNumberTable";
private static final String BCEL_M_GET_SOURCE_LINE = "getSourceLine";
private static final String BCEL_M_GET_NAME = "getName";
private static final String BCEL_M_GET_MODIFIERS = "getModifiers";
private static final String BCEL_M_GET_SIGNATURE = "getSignature";
private static final String INIT_METHOD_NAME = "";
private static final String BUILD_PROPERTIES_FILE = "weld-build.properties";
private static final String BUILD_PROPERTIES_VERSION = "version";
private static final String BUILD_PROPERTIES_TIMESTAMP = "timestamp";
private static final String UPPER_BOUND = " extends ";
private static final String WILDCARD = "?";
private static final String WILDCARD_UPPER_BOUND = WILDCARD + UPPER_BOUND;
private static final String WILDCARD_LOWER_BOUND = WILDCARD + " super ";
private static final String GT = ">";
private static final String LT = "<";
private Formats() {
}
/**
* See also WELD-1454.
*
* @param ij
* @return the formatted string
*/
public static String formatAsStackTraceElement(InjectionPoint ij) {
Member member;
if (ij.getAnnotated() instanceof AnnotatedField) {
AnnotatedField> annotatedField = (AnnotatedField>) ij.getAnnotated();
member = annotatedField.getJavaMember();
} else if (ij.getAnnotated() instanceof AnnotatedParameter>) {
AnnotatedParameter> annotatedParameter = (AnnotatedParameter>) ij.getAnnotated();
member = annotatedParameter.getDeclaringCallable().getJavaMember();
} else {
// Not throwing an exception, because this method is invoked when an exception is already being thrown.
// Throwing an exception here would hide the original exception.
return "-";
}
return formatAsStackTraceElement(member);
}
public static String formatAsStackTraceElement(Member member) {
return member.getDeclaringClass().getName()
+ "." + (member instanceof Constructor> ? INIT_METHOD_NAME : member.getName())
+ "(" + getFileName(member.getDeclaringClass()) + ":" + getLineNumber(member) + ")";
}
/**
* Try to get the line number associated with the given member.
*
* The reflection API does not expose such an info and so we need to analyse the bytecode. Unfortunately, it seems there is no way to get this kind of
* information for fields. Moreover, the LineNumberTable attribute is just optional, i.e. the compiler is not required to store this
* information at all. See also Java Virtual Machine Specification
*
* Implementation note: it wouldn't be appropriate to add a bytecode scanning dependency just for this functionality, therefore Apache BCEL included in
* Oracle JDK 1.5+ and OpenJDK 1.6+ is used. Other JVMs should not crash as we only use it if it's on the classpath and by means of reflection calls.
*
* @param member
* @param resourceLoader
* @return the line number or 0 if it's not possible to find it
*/
public static int getLineNumber(Member member) {
if (!(member instanceof Method || member instanceof Constructor)) {
// We are not able to get this info for fields
return 0;
}
ResourceLoader bcelResourceLoader = WeldClassLoaderResourceLoader.INSTANCE;
if (!Reflections.isClassLoadable(BCEL_JAVA_CLASS_FQCN, bcelResourceLoader)) {
// Try TCCL as a fallback
bcelResourceLoader = DefaultResourceLoader.INSTANCE;
if (!Reflections.isClassLoadable(BCEL_JAVA_CLASS_FQCN, bcelResourceLoader)) {
// Apache BCEL classes not found on the classpath
return 0;
}
}
String classFile = member.getDeclaringClass().getName().replace('.', '/');
ClassLoaderResourceLoader classFileResourceLoader = new ClassLoaderResourceLoader(member.getDeclaringClass().getClassLoader());
InputStream in = null;
try {
URL classFileUrl = classFileResourceLoader.getResource(classFile + ".class");
if (classFileUrl == null) {
// The class file is not available
return 0;
}
in = classFileUrl.openStream();
Class> classParserClass = Reflections.loadClass(BCEL_CLASS_PARSER_FQCN, bcelResourceLoader);
Class> javaClassClass = Reflections.loadClass(BCEL_JAVA_CLASS_FQCN, bcelResourceLoader);
Class> methodClass = Reflections.loadClass(BCEL_METHOD_FQCN, bcelResourceLoader);
Class> lntClass = Reflections.loadClass(BCEL_LINE_NUMBER_TABLE_FQCN, bcelResourceLoader);
Object parser = classParserClass.getConstructor(InputStream.class, String.class).newInstance(in, classFile);
Object javaClass = classParserClass.getMethod(BCEL_M_PARSE).invoke(parser);
// First get all declared methods and constructors
// Note that in bytecode constructor is translated into a method
Object[] methods = (Object[]) javaClassClass.getMethod(BCEL_M_GET_METHODS).invoke(javaClass);
Object match = null;
String signature;
String name;
if (member instanceof Method) {
signature = DescriptorUtils.methodDescriptor((Method) member);
name = member.getName();
} else if (member instanceof Constructor) {
signature = DescriptorUtils.makeDescriptor((Constructor>) member);
name = INIT_METHOD_NAME;
} else {
return 0;
}
for (Object method : methods) {
// Matching method must have the same name, modifiers and signature
if (methodClass.getMethod(BCEL_M_GET_NAME).invoke(method).equals(name)
&& methodClass.getMethod(BCEL_M_GET_MODIFIERS).invoke(method).equals(member.getModifiers())
&& methodClass.getMethod(BCEL_M_GET_SIGNATURE).invoke(method).equals(signature)) {
match = method;
}
}
if (match != null) {
// If a method is found, try to obtain the optional LineNumberTable attribute
Object lineNumberTable = methodClass.getMethod(BCEL_M_GET_LINE_NUMBER_TABLE).invoke(match);
if (lineNumberTable != null) {
Integer line = (Integer) lntClass.getMethod(BCEL_M_GET_SOURCE_LINE, int.class).invoke(lineNumberTable, 0);
return line == -1 ? 0 : line;
}
}
// No suitable method found
return 0;
} catch (Throwable t) {
return 0;
} finally {
if (in != null) {
try {
in.close();
} catch (Exception e) {
return 0;
}
}
}
}
private static String getFileName(Class> clazz) {
// TODO find the actual file name the class is declared in
return clazz.getSimpleName() + ".java";
}
/**
* A transformation from one object to a String.
*
* @param the type of the function input
*/
private interface Function {
/**
* Applies the function to an object of type {@code F}, resulting in an
* object of type String.
*
* @param from the source object
* @param position the position in the list the object is at
* @return the resulting object
*/
String apply(F from, int position);
}
private static final Function> SPACE_DELIMITER_FUNCTION = new Function