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 true if the system property "java.version" starts with "1.7". 016 * 017 * @return true if the current java version is 1.7 018 */ 019 public static final boolean isJava7() { 020 return System.getProperty("java.version").startsWith("1.7"); 021 } 022 023 /** 024 * Returns a new instance of the Java 7 version of the given class if it 025 * exists and can be instantiated. Otherwise, the given 026 * {@code defaultInstance} is returned. 027 * <p> 028 * The Java 7 version of the class must be a subtype of {@code baseClass} 029 * and its fully qualified name must be identical to that of 030 * {@code baseClass} with a suffix "7". For instance, if the Java 6 base 031 * class is called "org.unix4j.MyClass", the Java 7 version must be called 032 * "org.unix4j.MyClass7". Furthermore, the class must have a default 033 * constructor with no arguments. 034 * <p> 035 * If the Java 7 version of the class is not found (usually because unix4j 036 * was compiled with a Java 6 compiler) or if the Java 7 class cannot be 037 * instantiated (usually because unix4j is run in a Java 6 JVM), the given 038 * {@code defaultInstance} is returned. 039 * 040 * @param <T> 041 * the generic return type 042 * @param baseClass 043 * the base class and superclass of the Java 7 class 044 * @return a new instance of the Java 7 subtype if possible and 045 * {@code defaultInstance} otherwise 046 */ 047 public static <T> T newInstance(Class<T> baseClass, T defaultInstance) { 048 final Class<? extends T> clazz = loadClass(baseClass); 049 try { 050 return clazz.newInstance(); 051 } catch (Exception e) { 052 return defaultInstance; 053 } 054 } 055 056 /** 057 * Returns the Java 7 version of the given class if it exists and can be 058 * loaded, and the given {@code baseClass} otherwise. 059 * <p> 060 * The Java 7 version of the class must be a subtype of {@code baseClass} 061 * and its fully qualified name must be identical to that of 062 * {@code baseClass} with a suffix "7". For instance, if the Java 6 base 063 * class is called "org.unix4j.MyClass", the Java 7 version must be called 064 * "org.unix4j.MyClass7". 065 * <p> 066 * If the Java 7 version of the class is not found (usually because unix4j 067 * was compiled with a Java 6 compiler), the given {@code defaultInstance} 068 * is returned. If the class is found but it is not a subtype of the given 069 * {@code baseClass}, an exception is thrown. 070 * 071 * @param <T> 072 * the generic type of the base class 073 * @param baseClass 074 * the base class and superclass of the Java 7 class 075 * @return the Java 7 subclass if possible and {@code baseClass} otherwise 076 * @throws NullPointerException 077 * if {@code baseClass} is null 078 * @throws IllegalArgumentException 079 * if the Java 7 class is found but it is not a subclass of 080 * {@code baseClass} 081 */ 082 public static <T> Class<? extends T> loadClass(Class<T> baseClass) { 083 if (baseClass == null) { 084 throw new NullPointerException("baseClass cannot be null"); 085 } 086 final Class<?> java7Class; 087 try { 088 java7Class = Class.forName(baseClass.getName() + JAVA7_CLASS_NAME_SUFFIX); 089 } catch (ClassNotFoundException e) { 090 return baseClass; 091 } 092 if (baseClass.isAssignableFrom(java7Class)) { 093 return java7Class.asSubclass(baseClass); 094 } 095 throw new IllegalArgumentException("class " + java7Class.getName() + " is not a subclass of " + baseClass.getName()); 096 } 097}