001package org.unix4j.util; 002 003/** 004 * Utility class with static methods to help loading a Java 7 version of a class 005 * if it is available, and the Java 6 version otherwise. 006 */ 007public class Java7Util { 008 009 /** 010 * The suffix used for Java 7 classes, the string "7". 011 */ 012 public static final String JAVA7_CLASS_NAME_SUFFIX = "7"; 013 014 /** 015 * Returns a new instance of the Java 7 version of the given class if it 016 * exists and can be instantiated. Otherwise, the given 017 * {@code defaultInstance} is returned. 018 * <p> 019 * The Java 7 version of the class must be a subtype of {@code baseClass} 020 * and its fully qualified name must be identical to that of 021 * {@code baseClass} with a suffix "7". For instance, if the Java 6 base 022 * class is called "org.unix4j.MyClass", the Java 7 version must be called 023 * "org.unix4j.MyClass7". Furthermore, the class must have a default 024 * constructor with no arguments. 025 * <p> 026 * If the Java 7 version of the class is not found (usually because unix4j 027 * was compiled with a Java 6 compiler) or if the Java 7 class cannot be 028 * instantiated (usually because unix4j is run in a Java 6 JVM), the given 029 * {@code defaultInstance} is returned. 030 * 031 * @param <T> 032 * the generic return type 033 * @param baseClass 034 * the base class and superclass of the Java 7 class 035 * @return a new instance of the Java 7 subtype if possible and 036 * {@code defaultInstance} otherwise 037 */ 038 public static <T> T newInstance(Class<T> baseClass, T defaultInstance) { 039 final Class<? extends T> clazz = loadClass(baseClass); 040 try { 041 return clazz.newInstance(); 042 } catch (Exception e) { 043 return defaultInstance; 044 } 045 } 046 047 /** 048 * Returns the Java 7 version of the given class if it exists and can be 049 * loaded, and the given {@code baseClass} otherwise. 050 * <p> 051 * The Java 7 version of the class must be a subtype of {@code baseClass} 052 * and its fully qualified name must be identical to that of 053 * {@code baseClass} with a suffix "7". For instance, if the Java 6 base 054 * class is called "org.unix4j.MyClass", the Java 7 version must be called 055 * "org.unix4j.MyClass7". 056 * <p> 057 * If the Java 7 version of the class is not found (usually because unix4j 058 * was compiled with a Java 6 compiler), the given {@code defaultInstance} 059 * is returned. If the class is found but it is not a subtype of the given 060 * {@code baseClass}, an exception is thrown. 061 * 062 * @param <T> 063 * the generic type of the base class 064 * @param baseClass 065 * the base class and superclass of the Java 7 class 066 * @return the Java 7 subclass if possible and {@code baseClass} otherwise 067 * @throws NullPointerException 068 * if {@code baseClass} is null 069 * @throws IllegalArgumentException 070 * if the Java 7 class is found but it is not a subclass of 071 * {@code baseClass} 072 */ 073 public static <T> Class<? extends T> loadClass(Class<T> baseClass) { 074 if (baseClass == null) { 075 throw new NullPointerException("baseClass cannot be null"); 076 } 077 final Class<?> java7Class; 078 try { 079 java7Class = Class.forName(baseClass.getName() + JAVA7_CLASS_NAME_SUFFIX); 080 } catch (ClassNotFoundException e) { 081 return baseClass; 082 } 083 if (baseClass.isAssignableFrom(java7Class)) { 084 return java7Class.asSubclass(baseClass); 085 } 086 throw new IllegalArgumentException("class " + java7Class.getName() + " is not a subclass of " + baseClass.getName()); 087 } 088}