Coverage Report - org.crosswire.common.util.ClassUtil
 
Classes in this File Line Coverage Branch Coverage Complexity
ClassUtil
0%
0/55
0%
0/38
4.429
 
 1  
 /**
 2  
  * Distribution License:
 3  
  * JSword is free software; you can redistribute it and/or modify it under
 4  
  * the terms of the GNU Lesser General Public License, version 2.1 or later
 5  
  * as published by the Free Software Foundation. This program is distributed
 6  
  * in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
 7  
  * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 8  
  * See the GNU Lesser General Public License for more details.
 9  
  *
 10  
  * The License is available on the internet at:
 11  
  *      http://www.gnu.org/copyleft/lgpl.html
 12  
  * or by writing to:
 13  
  *      Free Software Foundation, Inc.
 14  
  *      59 Temple Place - Suite 330
 15  
  *      Boston, MA 02111-1307, USA
 16  
  *
 17  
  * © CrossWire Bible Society, 2005 - 2016
 18  
  *
 19  
  */
 20  
 package org.crosswire.common.util;
 21  
 
 22  
 import java.io.File;
 23  
 import java.io.IOException;
 24  
 import java.util.zip.ZipEntry;
 25  
 import java.util.zip.ZipFile;
 26  
 
 27  
 import org.slf4j.Logger;
 28  
 import org.slf4j.LoggerFactory;
 29  
 
 30  
 /**
 31  
  * Various Java Class Utilities.
 32  
  * 
 33  
  * @see gnu.lgpl.License The GNU Lesser General Public License for details.
 34  
  * @author Joe Walker
 35  
  */
 36  
 public final class ClassUtil {
 37  
     /**
 38  
      * Prevent instantiation
 39  
      */
 40  0
     private ClassUtil() {
 41  0
     }
 42  
 
 43  
     /**
 44  
      * Gets the Class for the className in a way that works well for extensions.
 45  
      * See: http://www.javageeks.com/Papers/ClassForName/ClassForName.pdf
 46  
      * 
 47  
      * @param className
 48  
      *            the class to get
 49  
      * @return the found Class
 50  
      * @throws ClassNotFoundException if the class is not found
 51  
      */
 52  
     public static Class<?> forName(String className) throws ClassNotFoundException {
 53  0
         return Thread.currentThread().getContextClassLoader().loadClass(className);
 54  
     }
 55  
 
 56  
     /**
 57  
      * This function finds the first matching filename for a Java class file
 58  
      * from the classpath, if none is found it returns null.
 59  
      * 
 60  
      * @param className
 61  
      *            the class to get
 62  
      * @param classPath the lookup class path
 63  
      * @return the filename for the class
 64  
      */
 65  
     public static String findClasspathEntry(String className, String classPath) {
 66  0
         String full = null;
 67  
 
 68  0
         String[] paths = StringUtil.split(classPath, File.pathSeparator);
 69  0
         for (int i = 0; i < paths.length; i++) {
 70  
             // Search the jar
 71  0
             if (paths[i].endsWith(EXTENSION_ZIP) || paths[i].endsWith(EXTENSION_JAR)) {
 72  0
                 ZipFile zip = null;
 73  
                 try {
 74  0
                     String fileName = className.replace(',', '/') + EXTENSION_CLASS;
 75  0
                     zip = new ZipFile(paths[i]);
 76  0
                     ZipEntry entry = zip.getEntry(fileName);
 77  
 
 78  0
                     if (entry != null && !entry.isDirectory()) {
 79  0
                         if (full != null && !full.equals(fileName)) {
 80  0
                             LOGGER.warn("Warning duplicate {} found: {} and {}", className, full, paths[i]);
 81  
                         } else {
 82  0
                             full = paths[i];
 83  
                         }
 84  
                     }
 85  0
                 } catch (IOException ex) {
 86  
                     // If that zip file failed, then ignore it and move on.
 87  0
                     LOGGER.warn("Missing zip file for {} and {}", className, paths[i]);
 88  
                 } finally {
 89  0
                     if (null != zip) {
 90  
                         try {
 91  0
                             zip.close();
 92  0
                         } catch (IOException ex) {
 93  0
                             LOGGER.error("close", ex);
 94  0
                         }
 95  
                     }
 96  
                 }
 97  0
             } else {
 98  0
                 StringBuilder path = new StringBuilder(256);
 99  
 
 100  
                 // Search for the file
 101  0
                 String extra = className.replace('.', File.separatorChar);
 102  
 
 103  0
                 path.append(paths[i]);
 104  0
                 if (paths[i].charAt(paths[i].length() - 1) != File.separatorChar) {
 105  0
                     path.append(File.separatorChar);
 106  
                 }
 107  
 
 108  0
                 path.append(extra);
 109  0
                 path.append(EXTENSION_CLASS);
 110  0
                 String fileName = path.toString();
 111  
 
 112  0
                 if (new File(fileName).isFile()) {
 113  0
                     if (full != null && !full.equals(fileName)) {
 114  0
                         LOGGER.warn("Warning duplicate {} found: {} and {}", className, full, paths[i]);
 115  
                     } else {
 116  0
                         full = paths[i];
 117  
                     }
 118  
                 }
 119  
             }
 120  
         }
 121  
 
 122  0
         return full;
 123  
     }
 124  
 
 125  
     /**
 126  
      * This function find the first matching filename for a Java class file from
 127  
      * the classpath, if none is found it returns null.
 128  
      * 
 129  
      * @param className
 130  
      *            the class to get
 131  
      * @return the filename for the class
 132  
      */
 133  
     public static String findClasspathEntry(String className) {
 134  0
         String classpath = System.getProperty("java.class.path", "");
 135  0
         return findClasspathEntry(className, classpath);
 136  
     }
 137  
 
 138  
     /**
 139  
      * Gets the class name minus the package name for an <code>Object</code>.
 140  
      * 
 141  
      * @param object
 142  
      *            the class to get the short name for, may be null
 143  
      * @param valueIfNull
 144  
      *            the value to return if null
 145  
      * @return the class name of the object without the package name, or the
 146  
      *         null value
 147  
      */
 148  
     public static String getShortClassName(Object object, String valueIfNull) {
 149  0
         if (object == null) {
 150  0
             return valueIfNull;
 151  
         }
 152  0
         return getShortClassName(object.getClass().getName());
 153  
     }
 154  
 
 155  
     /**
 156  
      * Gets the class name minus the package name from a <code>Class</code>.
 157  
      * 
 158  
      * @param cls
 159  
      *            the class to get the short name for, must not be
 160  
      *            <code>null</code>
 161  
      * @return the class name without the package name
 162  
      * @throws IllegalArgumentException
 163  
      *             if the class is <code>null</code>
 164  
      */
 165  
     public static String getShortClassName(Class<?> cls) {
 166  0
         if (cls == null) {
 167  0
             throw new IllegalArgumentException("The class must not be null");
 168  
         }
 169  0
         return getShortClassName(cls.getName());
 170  
     }
 171  
 
 172  
     /**
 173  
      * Gets the class name minus the package name from a String.
 174  
      * 
 175  
      * <p>
 176  
      * The string passed in is assumed to be a class name - it is not checked.
 177  
      * </p>
 178  
      * 
 179  
      * @param className
 180  
      *            the className to get the short name for, must not be empty or
 181  
      *            <code>null</code>
 182  
      * @return the class name of the class without the package name
 183  
      * @throws IllegalArgumentException
 184  
      *             if the className is empty
 185  
      */
 186  
     public static String getShortClassName(String className) {
 187  0
         if (className == null || className.length() == 0) {
 188  0
             throw new IllegalArgumentException("The class name must not be empty");
 189  
         }
 190  0
         char[] chars = className.toCharArray();
 191  0
         int lastDot = 0;
 192  0
         for (int i = 0; i < chars.length; i++) {
 193  0
             if (chars[i] == PACKAGE_SEPARATOR_CHAR) {
 194  0
                 lastDot = i + 1;
 195  0
             } else if (chars[i] == INNER_CLASS_SEPARATOR_CHAR) {
 196  0
                 chars[i] = PACKAGE_SEPARATOR_CHAR;
 197  
             }
 198  
         }
 199  0
         return new String(chars, lastDot, chars.length - lastDot);
 200  
     }
 201  
 
 202  
     /**
 203  
      * The package separator character: <code>&#x2e;</code>.
 204  
      */
 205  
     private static final char PACKAGE_SEPARATOR_CHAR = '.';
 206  
 
 207  
     /**
 208  
      * The inner class separator character: <code>$</code>.
 209  
      */
 210  
     private static final char INNER_CLASS_SEPARATOR_CHAR = '$';
 211  
 
 212  
     private static final String EXTENSION_CLASS = ".class";
 213  
     private static final String EXTENSION_JAR = ".jar";
 214  
     private static final String EXTENSION_ZIP = ".zip";
 215  
 
 216  
     /**
 217  
      * The log stream
 218  
      */
 219  0
     private static final Logger LOGGER = LoggerFactory.getLogger(ClassUtil.class);
 220  
 }