001 package com.softnetConsult.utils.reflect; 002 003 import java.io.DataInputStream; 004 import java.io.IOException; 005 import java.io.InputStream; 006 007 import com.softnetConsult.utils.exceptions.Bug; 008 009 010 /** 011 * Defines static utilities for dealing with classes and reflection. 012 * 013 * <p style="font-size:smaller;">This product includes software developed by the 014 * <strong>SoftNet-Consult Java Utility Library</strong> project and its contributors.<br /> 015 * (<a href="http://java-tools.sourceforge.net" target="_blank">http://java-tools.sourceforge.net</a>)<br /> 016 * Copyright (c) 2007-2008 SoftNet-Consult.<br /> 017 * Copyright (c) 2007-2008 G. Paperin.<br /> 018 * All rights reserved. 019 * </p> 020 * <p style="font-size:smaller;">File: ClassTools.java<br /> 021 * Library API version: {@value com.softnetConsult.utils.APIProperties#apiVersion}<br /> 022 * Java compliance version: {@value com.softnetConsult.utils.APIProperties#javaComplianceVersion} 023 * </p> 024 * <p style="font-size:smaller;">Redistribution and use in source and binary forms, with or 025 * without modification, are permitted provided that the following terms and conditions are met: 026 * </p> 027 * <p style="font-size:smaller;">1. Redistributions of source code must retain the above 028 * acknowledgement of the SoftNet-Consult Java Utility Library project, the above copyright 029 * notice, this list of conditions and the following disclaimer.<br /> 030 * 2. Redistributions in binary form must reproduce the above acknowledgement of the 031 * SoftNet-Consult Java Utility Library project, the above copyright notice, this list of 032 * conditions and the following disclaimer in the documentation and/or other materials 033 * provided with the distribution.<br /> 034 * 3. All advertising materials mentioning features or use of this software or any derived 035 * software must display the following acknowledgement:<br /> 036 * <em>This product includes software developed by the SoftNet-Consult Java Utility Library 037 * project and its contributors.</em> 038 * </p> 039 * <p style="font-size:smaller;">THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY 040 * OF ANY KIND, EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 041 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 042 * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 043 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 044 * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 045 * </p> 046 * @author Greg Paperin (<a href="http://www.paperin.org" target="_blank">http://www.paperin.org</a>) 047 * @version {@value com.softnetConsult.utils.APIProperties#apiVersion} 048 * 049 */ 050 public final class ClassTools { 051 052 053 /** 054 * Prevents instances of this class from being created 055 * as this class contains only static utility methods. 056 */ 057 private ClassTools() {} 058 059 060 /** 061 * The magic number that must be contained in the first two bytes of all Java class binaries. 062 */ 063 public static final int JAVA_CLASSFILE_MAGIC_NUMBER = 0xCAFEBABE; 064 065 066 /** 067 * Find the correct wrapper class for a primitive type. 068 * If the specified class type does not describe a primitive type, it is simply returned. 069 * If the specified class type describes a primitive type, the corresponding warpper 070 * class type is returned. For instance:<br /> 071 * {@code int} => {@code Integer.class} <br /> 072 * {@code double} => {@code Double.class} <br /> 073 * {@code Object} => {@code Object} <br /> 074 * {@code null} => {@code null} <br /> 075 * 076 * @param type An object representing a Java class or interface. 077 * @return The wrapper class type corresponding to the specified class type. 078 */ 079 public static Class<?> getWrapperClass(Class<?> type) { 080 081 if (null == type) 082 return null; 083 084 if (!type.isPrimitive()) 085 return type; 086 087 if (type.equals(Boolean.TYPE)) 088 return Boolean.class; 089 090 if (type.equals(Character.TYPE)) 091 return Character.class; 092 093 if (type.equals(Byte.TYPE)) 094 return Byte.class; 095 096 if (type.equals(Short.TYPE)) 097 return Short.class; 098 099 if (type.equals(Integer.TYPE)) 100 return Integer.class; 101 102 if (type.equals(Long.TYPE)) 103 return Long.class; 104 105 if (type.equals(Float.TYPE)) 106 return Float.class; 107 108 if (type.equals(Double.TYPE)) 109 return Double.class; 110 111 if (type.equals(Void.TYPE)) 112 return Void.class; 113 114 throw new Bug("Should never get to this line!"); 115 } 116 117 118 /** 119 * Determines the minimum JVM version required to run a class binary of the specified version. 120 * The current version of this method supports class binaries up to version 50.0 (which 121 * corresponds to JVM 1.6). 122 * 123 * @param classBinaryMajorVersion Major version of a class binary. 124 * @param classBinaryMinorVersion Minor version of a class binary. 125 * @return A string specifying the <em>minimum</em> version of a Java virtual machine 126 * required to run a class binary with the specified version number. If the specified 127 * class binary version is unknown, the string {@code "<unknown>"} is returned. 128 */ 129 public static final String getMinimumRequiredJavaVersion(int classBinaryMajorVersion, 130 int classBinaryMinorVersion) { 131 132 final int major = classBinaryMajorVersion; 133 final int minor = classBinaryMinorVersion; 134 135 if (major == 45 && minor >= 0 && minor <= 3) 136 return "1.0.2"; 137 138 if (major == 45 && minor >= 0 && minor <= 65535) 139 return "1.1"; 140 141 if ((major == 45 && minor >= 0) || (major == 46 && minor == 0)) 142 return "1.2"; 143 144 if (major == 47 && minor == 0) 145 return "1.3"; 146 147 if (major == 48 && minor == 0) 148 return "1.4"; 149 150 if (major == 49 && minor == 0) 151 return "1.5"; 152 153 if (major == 50 && minor == 0) 154 return "1.6"; 155 156 return "<unknown>"; 157 } 158 159 160 /** 161 * Parses the version information from a a Java class binary. 162 * 163 * @param classdata A stream containing the Java class binary data. 164 * @return The version information of the specified class binary. 165 * @throws IOException If an error occurs when reading from the specified class binary stream. 166 */ 167 public static ClassVersionInfo getClassVersionInfo(InputStream classdata) throws IOException { 168 DataInputStream in = new DataInputStream(classdata); 169 int magic = in.readInt(); 170 if (JAVA_CLASSFILE_MAGIC_NUMBER != magic) 171 return null; 172 173 int minor = in.readShort(); 174 int major = in.readShort(); 175 String reqJavaVer = getMinimumRequiredJavaVersion(major, minor); 176 return new ClassVersionInfo(major, minor, reqJavaVer); 177 } 178 179 } // public final class ClassTools