001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019 020package org.apache.isis.core.commons.lang; 021 022import java.util.Arrays; 023import java.util.HashMap; 024import java.util.List; 025import java.util.Map; 026 027import com.google.common.collect.Maps; 028 029public final class ClassUtil { 030 031 static final String JAVA_CLASS_PREFIX = "java."; 032 033 private static Map<String, Class<?>> builtInClasses = new HashMap<String, Class<?>>(); 034 035 static { 036 put(void.class); 037 put(boolean.class); 038 put(char.class); 039 put(byte.class); 040 put(short.class); 041 put(int.class); 042 put(long.class); 043 put(float.class); 044 put(double.class); 045 } 046 047 private static void put(final Class<?> cls) { 048 builtInClasses.put(cls.getName(), cls); 049 } 050 051 static final Map<Class<?>, Object> defaultByPrimitiveClass = 052 MapUtil.asMap( 053 boolean.class, false, 054 byte.class, (byte)0, 055 short.class, (short)0, 056 int.class, 0, 057 long.class, 0L, 058 float.class, 0.0f, 059 double.class, 0.0, 060 char.class, (char)0 061 ); 062 static Map<Class<?>, Class<?>> wrapperClasses = 063 MapUtil.asMap( 064 // TODO: there is a better way of doing this in 1.6 using TypeMirror 065 boolean.class, Boolean.class, 066 byte.class, Byte.class, 067 char.class, Character.class, 068 short.class, Short.class, 069 int.class, Integer.class, 070 long.class, Long.class, 071 float.class, Float.class, 072 double.class, Double.class, 073 void.class, Void.class 074 ); 075 076 static Map<Class<?>, Object> defaultByPrimitiveType = new HashMap<Class<?>, Object>(); 077 078 static { 079 defaultByPrimitiveType.put(byte.class, (byte) 0); 080 defaultByPrimitiveType.put(short.class, (short) 0); 081 defaultByPrimitiveType.put(int.class, 0); 082 defaultByPrimitiveType.put(long.class, 0L); 083 defaultByPrimitiveType.put(char.class, 0); 084 defaultByPrimitiveType.put(float.class, 0.0F); 085 defaultByPrimitiveType.put(double.class, 0.0); 086 defaultByPrimitiveType.put(boolean.class, false); 087 } 088 089 public static Map<String, Class<?>> primitives = Maps.newHashMap(); 090 091 static { 092 @SuppressWarnings({ "rawtypes" }) 093 final List<Class> primitiveClasses = Arrays.<Class> asList( 094 boolean.class, 095 byte.class, 096 short.class, 097 int.class, 098 long.class, 099 float.class, 100 double.class, 101 char.class); 102 for (final Class<?> cls : primitiveClasses) { 103 primitives.put(cls.getName(), cls); 104 } 105 } 106 107 108 // ////////////////////////////////////// 109 110 111 112 private ClassUtil() { 113 } 114 115 public static Class<?> getBuiltIn(final String name) { 116 return builtInClasses.get(name); 117 } 118 119 /** 120 * Returns the supplied Class so long as it implements (or is a subclass of) 121 * the required class, and also has either a constructor accepting the 122 * specified param type, or has a no-arg constructor. 123 */ 124 public static Class<?> implementingClassOrNull(final String classCandidateName, final Class<?> requiredClass, final Class<?> constructorParamType) { 125 if (classCandidateName == null) { 126 return null; 127 } 128 Class<?> classCandidate = null; 129 try { 130 classCandidate = Class.forName(classCandidateName); 131 return ClassExtensions.implementingClassOrNull(classCandidate, requiredClass, constructorParamType); 132 } catch (final ClassNotFoundException e) { 133 return null; 134 } 135 } 136 137 public static boolean directlyImplements(final Class<?> cls, final Class<?> interfaceType) { 138 for (final Class<?> directlyImplementedInterface : cls.getInterfaces()) { 139 if (directlyImplementedInterface == interfaceType) { 140 return true; 141 } 142 } 143 return false; 144 } 145 146 public static boolean directlyImplements(final Class<?> extendee, final String interfaceTypeName) { 147 try { 148 final Class<?> interfaceType = Thread.currentThread().getContextClassLoader().loadClass(interfaceTypeName); 149 return directlyImplements(extendee, interfaceType); 150 } catch (ClassNotFoundException e) { 151 throw new RuntimeException(e); 152 } 153 } 154 155 public static Class<?> forName(final String fullName) { 156 final Class<?> primitiveCls = primitives.get(fullName); 157 if (primitiveCls != null) { 158 return primitiveCls; 159 } 160 try { 161 return Thread.currentThread().getContextClassLoader().loadClass(fullName); 162 } catch (final ClassNotFoundException e) { 163 throw new RuntimeException(e); 164 } 165 } 166 167 public static Class<?> forNameElseNull(final String fullName) { 168 if (fullName == null) { 169 return null; 170 } 171 try { 172 return Thread.currentThread().getContextClassLoader().loadClass(fullName); 173 } catch (final ClassNotFoundException e) { 174 return null; 175 } 176 } 177 178}