Package railo.commons.lang

Source Code of railo.commons.lang.ClassUtil

package railo.commons.lang;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLDecoder;
import java.util.Map;
import java.util.Set;

import railo.commons.collection.MapFactory;
import railo.commons.io.FileUtil;
import railo.commons.io.IOUtil;
import railo.commons.io.SystemUtil;
import railo.runtime.PageContextImpl;
import railo.runtime.config.Config;
import railo.runtime.engine.ThreadLocalPageContext;
import railo.runtime.exp.PageException;
import railo.runtime.op.Caster;
import railo.runtime.type.Array;
import railo.runtime.type.util.ListUtil;


public final class ClassUtil {

  /**
   * @param className
   * @return
   * @throws ClassException
   * @throws PageException
   */
  public static Class toClass(String className) throws ClassException {
    return ClassUtil.loadClass(className);
  }
 
  private static Class checkPrimaryTypes(String className, Class defaultValue) {
    String lcClassName=className.toLowerCase();
    boolean isRef=false;
   
    if(lcClassName.startsWith("java.lang.")){
      lcClassName=lcClassName.substring(10);
      isRef=true;
    }

    if(lcClassName.equals("boolean") || className.equals("[Z"))  {
      if(isRef) return Boolean.class;
      return boolean.class;
    }
    if(lcClassName.equals("byte") || className.equals("[B"))  {
      if(isRef) return Byte.class;
      return byte.class;
    }
    if(lcClassName.equals("int") || className.equals("[I"))  {
      return int.class;
    }
    if(lcClassName.equals("long") || className.equals("[J"))  {
      if(isRef) return Long.class;
      return long.class;
    }
    if(lcClassName.equals("float") || className.equals("[F"))  {
      if(isRef) return Float.class;
      return float.class;
    }
    if(lcClassName.equals("double") || className.equals("[D"))  {
      if(isRef) return Double.class;
      return double.class;
    }
    if(lcClassName.equals("char") || className.equals("[C"))  {
      return char.class;
    }
    if(lcClassName.equals("short") || className.equals("[S"))  {
      if(isRef) return Short.class;
      return short.class;
    }
   
    if(lcClassName.equals("integer"))  return Integer.class;
    if(lcClassName.equals("character"))  return Character.class;
    if(lcClassName.equals("object"))  return Object.class;
    if(lcClassName.equals("string"))  return String.class;
    if(lcClassName.equals("null"))    return Object.class;
    if(lcClassName.equals("numeric"))  return Double.class;
   
    return defaultValue;
  }
 
 
 
  /**
   * loads a class from a String classname
   * @param className
   * @param defaultValue
   * @return matching Class
   */
  public static Class loadClass(String className, Class defaultValue) {
    return loadClass(null,className,defaultValue);
  }

  /**
   * loads a class from a String classname
   * @param className
   * @return matching Class
   * @throws ClassException
   */
  public static Class loadClass(String className) throws ClassException {
    Config config = ThreadLocalPageContext.getConfig();
    Class clazz = loadClass(config==null?null:config.getClassLoader(),className,null);
    if(clazz!=null) return clazz;
    throw new ClassException("cannot load class through its string name, because no definition for the class with the specified name ["+className+"] could be found");
  }
 
  /**
   * loads a class from a specified Classloader with given classname
   * @param className
   * @param cl
   * @return matching Class
   */
  public static Class loadClass(ClassLoader cl,String className, Class defaultValue) {
    className=className.trim();
   
    Class clazz = checkPrimaryTypes(className, null);
    if(clazz!=null) return clazz;
   
    if(cl==null){
      PageContextImpl pci = (PageContextImpl) ThreadLocalPageContext.get();
      if(pci!=null){
        try {
          cl=pci.getClassLoader();
        }
        catch (IOException e) {}
      }
      if(cl==null) {
        Config config = ThreadLocalPageContext.getConfig();
        if(config!=null)cl=config.getClassLoader();
      }
    }
   
   
   
    try {
      if(cl==null)return Class.forName(className.trim());
      return cl.loadClass(className.trim());
     
    }
    catch (ClassNotFoundException e) {
      try {
        return Class.forName(className, false, cl);
      }
      catch (ClassNotFoundException e1) {
        // array in the format boolean[] or java.lang.String[]
        if(!StringUtil.isEmpty(className) && className.endsWith("[]")) {
          StringBuilder pureCN=new StringBuilder(className);
          int dimensions=0;
          do{
            pureCN.delete(pureCN.length()-2, pureCN.length());
            dimensions++;
          }
          while(pureCN.lastIndexOf("[]")==pureCN.length()-2);
         
          clazz = loadClass(cl,pureCN.toString(),null);
          if(clazz!=null) {
            for(int i=0;i<dimensions;i++)clazz=toArrayClass(clazz);
            return clazz;
          }
        }
        // array in the format [C or [Ljava.lang.String;
        else if(!StringUtil.isEmpty(className) && className.charAt(0)=='[') {
          StringBuilder pureCN=new StringBuilder(className);
          int dimensions=0;
          do{
            pureCN.delete(0, 1);
            dimensions++;
          }
          while(pureCN.charAt(0)=='[');
         
          clazz = loadClass(cl,pureCN.toString(),null);
          if(clazz!=null) {
            for(int i=0;i<dimensions;i++)clazz=toArrayClass(clazz);
            return clazz;
          }
        }
        // class in format Ljava.lang.String;
        else if(!StringUtil.isEmpty(className) && className.charAt(0)=='L' && className.endsWith(";")) {
          className=className.substring(1,className.length()-1).replace('/', '.');
          return loadClass(cl, className,defaultValue);
        }
       
        return defaultValue;
      }
    }
  }

  /**
   * loads a class from a specified Classloader with given classname
   * @param className
   * @param cl
   * @return matching Class
   * @throws ClassException
   */
  public static Class loadClass(ClassLoader cl,String className) throws ClassException {
    Class clazz = loadClass(cl,className,null);
    if(clazz!=null) return clazz;
    throw new ClassException("cannot load class through its string name, because no definition for the class with the specified name ["+className+"] could be found");
  }

  /**
   * loads a class from a String classname
   * @param clazz class to load
   * @return matching Class
   * @throws ClassException
   */
  public static Object loadInstance(Class clazz) throws ClassException{
    try {
      return clazz.newInstance();
    }
    catch (InstantiationException e) {
      throw new ClassException("the specified class object ["+clazz.getName()+"()] cannot be instantiated");
    }
    catch (IllegalAccessException e) {
      throw new ClassException("can't load class because the currently executing method does not have access to the definition of the specified class");
    }
  }

  public static Object loadInstance(String className) throws ClassException{
    return loadInstance(loadClass(className));
  }
  public static Object loadInstance(ClassLoader cl, String className) throws ClassException{
    return loadInstance(loadClass(cl,className));
  }
 
  /**
   * loads a class from a String classname
   * @param clazz class to load
   * @return matching Class
   */
  public static Object loadInstance(Class clazz, Object defaultValue){
    try {
      return clazz.newInstance();
    }
    catch (Throwable t) {
      return defaultValue;
    }
  }
 
  public static Object loadInstance(String className, Object deaultValue){
    Class clazz = loadClass(className,null);
    if(clazz==null) return deaultValue;
    return loadInstance(clazz,deaultValue);
  }
 
  public static Object loadInstance(ClassLoader cl, String className, Object deaultValue) {
    Class clazz = loadClass(cl,className,null);
    if(clazz==null) return deaultValue;
    return loadInstance(clazz,deaultValue);
  }
 
  /**
   * loads a class from a String classname
   * @param clazz class to load
   * @param args
   * @return matching Class
   * @throws ClassException
   * @throws ClassException
   * @throws InvocationTargetException
   */
  public static Object loadInstance(Class clazz, Object[] args) throws ClassException, InvocationTargetException {
    if(args==null || args.length==0) return loadInstance(clazz);
   
    Class[] cArgs=new Class[args.length];
    for(int i=0;i<args.length;i++) {
      cArgs[i]=args[i].getClass();
    }
   
    try {
      Constructor c = clazz.getConstructor(cArgs);
      return c.newInstance(args);
     
    }
    catch (SecurityException e) {
      throw new ClassException("there is a security violation (throwed by security manager)");
    }
    catch (NoSuchMethodException e) {
     
      StringBuilder sb=new StringBuilder(clazz.getName());
      char del='(';
      for(int i=0;i<cArgs.length;i++) {
        sb.append(del);
        sb.append(cArgs[i].getName());
        del=',';
      }
      sb.append(')');
     
      throw new ClassException("there is no constructor with this ["+sb+"] signature for the class ["+clazz.getName()+"]");
    }
    catch (IllegalArgumentException e) {
      throw new ClassException("has been passed an illegal or inappropriate argument");
    }
    catch (InstantiationException e) {
      throw new ClassException("the specified class object ["+clazz.getName()+"] cannot be instantiated because it is an interface or is an abstract class");
    }
    catch (IllegalAccessException e) {
      throw new ClassException("can't load class because the currently executing method does not have access to the definition of the specified class");
    }
  }

  public static Object loadInstance(String className, Object[] args) throws ClassException, InvocationTargetException{
    return loadInstance(loadClass(className),args);
  }
 
  public static Object loadInstance(ClassLoader cl, String className, Object[] args) throws ClassException, InvocationTargetException{
    return loadInstance(loadClass(cl,className),args);
  }
 
  /**
   * loads a class from a String classname
   * @param clazz class to load
   * @param args
   * @return matching Class
   */
  public static Object loadInstance(Class clazz, Object[] args, Object defaultValue) {
    if(args==null || args.length==0) return loadInstance(clazz,defaultValue);
    try {
      Class[] cArgs=new Class[args.length];
      for(int i=0;i<args.length;i++) {
        if(args[i]==null)cArgs[i]=Object.class;
        else cArgs[i]=args[i].getClass();
      }
      Constructor c = clazz.getConstructor(cArgs);
      return c.newInstance(args);
     
    }
    catch (Throwable t) {//print.printST(t);
      return defaultValue;
    }
   
  }
 
  public static Object loadInstance(String className, Object[] args, Object deaultValue){
    Class clazz = loadClass(className,null);
    if(clazz==null) return deaultValue;
    return loadInstance(clazz,args,deaultValue);
  }
 
  public static Object loadInstance(ClassLoader cl, String className, Object[] args, Object deaultValue) {
    Class clazz = loadClass(cl,className,null);
    if(clazz==null) return deaultValue;
    return loadInstance(clazz,args,deaultValue);
  }
 
  /**
   * @return returns a string array of all pathes in classpath
   */
  public static String[] getClassPath(Config config) {

        Map<String,String> pathes=MapFactory.<String,String>getConcurrentMap();
    String pathSeperator=System.getProperty("path.separator");
    if(pathSeperator==null)pathSeperator=";";
     
  // pathes from system properties
    String strPathes=System.getProperty("java.class.path");
    if(strPathes!=null) {
      Array arr=ListUtil.listToArrayRemoveEmpty(strPathes,pathSeperator);
      int len=arr.size();
      for(int i=1;i<=len;i++) {
        File file=FileUtil.toFile(Caster.toString(arr.get(i,""),"").trim());
        if(file.exists())
          try {
            pathes.put(file.getCanonicalPath(),"");
          } catch (IOException e) {}
      }
    }
   
   
  // pathes from url class Loader (dynamic loaded classes)
    getClassPathesFromLoader(new ClassUtil().getClass().getClassLoader(), pathes);
    getClassPathesFromLoader(config.getClassLoader(), pathes);
   
    Set set = pathes.keySet();
    return (String[]) set.toArray(new String[set.size()]);
  }
 
  /**
   * get class pathes from all url ClassLoaders
   * @param cl URL Class Loader
   * @param pathes Hashmap with allpathes
   */
  private static void getClassPathesFromLoader(ClassLoader cl, Map pathes) {
    if(cl instanceof URLClassLoader)
      _getClassPathesFromLoader((URLClassLoader) cl, pathes);
  }
   
 
  private static void _getClassPathesFromLoader(URLClassLoader ucl, Map pathes) {
    getClassPathesFromLoader(ucl.getParent(), pathes);
   
    // get all pathes
    URL[] urls=ucl.getURLs();
   
    for(int i=0;i<urls.length;i++) {
      File file=FileUtil.toFile(urls[i].getPath());
      if(file.exists())
        try {
          pathes.put(file.getCanonicalPath(),"");
        } catch (IOException e) {}
    }
  }
 
  // CafeBabe (Java Magic Number)
  private static final int ICA=202;//CA
    private static final int IFE=254;//FE
    private static final int IBA=186;//BA
    private static final int IBE=190;//BE
   
    // CF33 (Railo Magic Number)
    private static final int ICF=207;//CF
    private static final int I33=51;//33
   

  private static final byte BCA=(byte)ICA;//CA
    private static final byte BFE=(byte)IFE;//FE
    private static final byte BBA=(byte)IBA;//BA
    private static final byte BBE=(byte)IBE;//BE
   
    private static final byte BCF=(byte)ICF;//CF
    private static final byte B33=(byte)I33;//33
   
   
    /**
     * check if given stream is a bytecode stream, if yes remove bytecode mark
     * @param is
     * @return is bytecode stream
     * @throws IOException
     */
    public static boolean isBytecode(InputStream is) throws IOException {
            if(!is.markSupported())
                    throw new IOException("can only read input streams that support mark/reset");
            is.mark(-1);
            //print(bytes);
            int first=is.read();
            int second=is.read();
             boolean rtn=(first==ICF && second==I33) || (first==ICA && second==IFE && is.read()==IBA && is.read()==IBE);
           
        is.reset();
        return rtn;
    }
   

    public static boolean isBytecode(byte[] barr){
        if(barr.length<4) return false;
        return (barr[0]==BCF && barr[1]==B33) || (barr[0]==BCA && barr[1]==BFE && barr[2]==BBA && barr[3]==BBE);
    }
    public static boolean isRawBytecode(byte[] barr){
        if(barr.length<4) return false;
        return (barr[0]==BCA && barr[1]==BFE && barr[2]==BBA && barr[3]==BBE);
    }
   
    public static boolean hasCF33Prefix(byte[] barr) {
        if(barr.length<4) return false;
        return (barr[0]==BCF && barr[1]==B33);
    }
   
  public static byte[] removeCF33Prefix(byte[] barr) {
    if(!hasCF33Prefix(barr)) return barr;
     
    byte[] dest = new byte[barr.length-10];
    System.arraycopy(barr, 10, dest, 0, 10);
    return dest;
  }

  public static String getName(Class clazz) {
    if(clazz.isArray()){
      return getName(clazz.getComponentType())+"[]";
    }
   
    return clazz.getName();
  }

  public static Method getMethodIgnoreCase(Class clazz, String methodName, Class[] args) throws ClassException {
    Method[] methods = clazz.getMethods();
    Method method;
    Class[] params;
    outer:for(int i=0;i<methods.length;i++){
      method=methods[i];
      if(method.getName().equalsIgnoreCase(methodName)){
        params = method.getParameterTypes();
        if(params.length==args.length){
          for(int y=0;y<params.length;y++){
            if(!params[y].equals(args[y])){
              continue outer;
            }
          }
          return method;
        }
      }
    }
   
    throw new ClassException("class "+clazz.getName()+" has no method with name "+methodName);
  }

 
  /**
   * return all field names as String array
   * @param clazz class to get field names from
   * @return field names
   */
  public static String[] getFieldNames(Class clazz) {
    Field[] fields = clazz.getFields();
    String[] names=new String[fields.length];
    for(int i=0;i<names.length;i++){
      names[i]=fields[i].getName();
    }
    return names;
  }

  public static byte[] toBytes(Class clazz) throws IOException {
    return IOUtil.toBytes(clazz.getClassLoader().getResourceAsStream(clazz.getName().replace('.','/')+".class"),true);
  }

  /**
   * return a array class based on the given class (opposite from Class.getComponentType())
   * @param clazz
   * @return
   */
  public static Class toArrayClass(Class clazz) {
    return java.lang.reflect.Array.newInstance(clazz, 0).getClass();
  }



  public static Class<?> toComponentType(Class<?> clazz) {
    Class<?> tmp;
    while(true){
      tmp=clazz.getComponentType();
      if(tmp==null) break;
      clazz=tmp;
    }
    return clazz;
  }


  /**
   * returns the path to the directory or jar file that the class was loaded from
   *
   * @param clazz - the Class object to check, for a live object pass obj.getClass();
   * @param defaultValue - a value to return in case the source could not be determined
   * @return
   */
  public static String getSourcePathForClass(Class clazz, String defaultValue) {

    try {

      String result = clazz.getProtectionDomain().getCodeSource().getLocation().getPath();
      result = URLDecoder.decode(result, Charset.UTF8);
      result = SystemUtil.fixWindowsPath(result);
      return result;
    }
    catch (Throwable t) {}

    return defaultValue;
  }


  /**
   * tries to load the class and returns the path that it was loaded from
   *
   * @param className - the name of the class to check
   * @param defaultValue - a value to return in case the source could not be determined
   * @return
   */
  public static String getSourcePathForClass(String className, String defaultValue) {

    try {

      return  getSourcePathForClass(ClassUtil.loadClass(className), defaultValue);
    }
    catch (Throwable t) {}

    return defaultValue;
  }


}
TOP

Related Classes of railo.commons.lang.ClassUtil

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.