001 /* 002 * Copyright © 2008, 2012 Pedro Agulló Soliveres. 003 * 004 * This file is part of DirectJNgine. 005 * 006 * DirectJNgine is free software: you can redistribute it and/or modify 007 * it under the terms of the GNU Lesser General Public License as published by 008 * the Free Software Foundation, either version 3 of the License. 009 * 010 * Commercial use is permitted to the extent that the code/component(s) 011 * do NOT become part of another Open Source or Commercially developed 012 * licensed development library or toolkit without explicit permission. 013 * 014 * DirectJNgine is distributed in the hope that it will be useful, 015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 017 * GNU Lesser General Public License for more details. 018 * 019 * You should have received a copy of the GNU Lesser General Public License 020 * along with DirectJNgine. If not, see <http://www.gnu.org/licenses/>. 021 * 022 * This software uses the ExtJs library (http://extjs.com), which is 023 * distributed under the GPL v3 license (see http://extjs.com/license). 024 */ 025 026 package com.softwarementors.extjs.djn; 027 028 import java.lang.reflect.Field; 029 030 import edu.umd.cs.findbugs.annotations.Nullable; 031 032 033 public final class ClassUtils { 034 private ClassUtils() { 035 // Disable class instantiation 036 } 037 038 // Returns null if field does not exist 039 @Nullable public static Class<?> getFieldType( Class<?> cls, String field ) { 040 assert cls != null; 041 assert field != null; 042 043 Class<?> vClass = cls; 044 Class<?> fieldType = null; 045 while(true) { 046 Field[] fields = vClass.getDeclaredFields(); 047 for( Field f : fields ) { 048 if( f.getName().equals(field)) { 049 fieldType = f.getType(); 050 return fieldType; 051 } 052 } 053 054 vClass = vClass.getSuperclass(); 055 if( vClass.equals(Object.class) ) { 056 return null; 057 } 058 } 059 } 060 061 public static boolean isNumericType( Class<?> cls ) { 062 assert cls != null; 063 064 if( cls== float.class || cls == double.class || cls == byte.class || cls == short.class || cls == int.class || cls == long.class) { 065 return true; 066 } 067 068 Class<?> currentClass = cls; 069 while( currentClass != null ) { 070 if( currentClass.equals(Number.class) ) 071 return true; 072 currentClass = currentClass.getSuperclass(); 073 } 074 return false; 075 } 076 077 // JDK 1.4 does not implement Class.getSimpleName() 078 public static String getSimpleName( Class<?> cls ) { 079 assert cls != null; 080 081 String result = cls.getName(); 082 083 // Special case: inner classes! 084 int simpleNameStart = result.lastIndexOf("$"); 085 if( simpleNameStart >= 0 ) { 086 simpleNameStart++; // Skip the "$" 087 // Need to skip the digits immediately after the "$" 088 for( ; simpleNameStart < result.length(); simpleNameStart++ ) { 089 if( !Character.isDigit(result.charAt(simpleNameStart)) ) { 090 return result.substring(simpleNameStart); 091 } 092 } 093 } 094 else { 095 simpleNameStart = result.lastIndexOf( "."); 096 if( simpleNameStart >= 0) { 097 return result.substring(simpleNameStart+1); 098 } 099 } 100 return result; 101 } 102 103 // Note: would be nice to make recursive, so that we can handle array of array of array of ..., 104 // but in reality pretty-printing just one-dimensional arrays is ok 105 public static String getNicePrintableName( Class<?> cls ) { 106 assert cls != null; 107 108 Class<?> type = cls; 109 if( cls.isArray() ) { 110 type = cls.getComponentType(); 111 } 112 113 String typeName = type.getName(); 114 if( typeName.startsWith( "java.lang") ) { 115 typeName = getSimpleName(type); 116 } 117 118 if( cls.isArray() ) { 119 typeName += "[]"; 120 } 121 return typeName; 122 } 123 124 }