001// Licensed under the Apache License, Version 2.0 (the "License"); 002// you may not use this file except in compliance with the License. 003// You may obtain a copy of the License at 004// 005// http://www.apache.org/licenses/LICENSE-2.0 006// 007// Unless required by applicable law or agreed to in writing, software 008// distributed under the License is distributed on an "AS IS" BASIS, 009// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 010// See the License for the specific language governing permissions and 011// limitations under the License. 012 013package org.apache.tapestry5.plastic; 014 015import org.apache.tapestry5.internal.plastic.PrimitiveType; 016 017import java.lang.reflect.Method; 018import java.util.concurrent.atomic.AtomicLong; 019 020/** 021 * Utilities for user code making use of Plastic. 022 */ 023public class PlasticUtils 024{ 025 /** 026 * The {@code toString()} method inherited from Object. 027 */ 028 public static final Method TO_STRING = getMethod(Object.class, "toString"); 029 030 /** 031 * The MethodDescription version of {@code toString()}. 032 */ 033 public static final MethodDescription TO_STRING_DESCRIPTION = new MethodDescription(TO_STRING); 034 035 private static final AtomicLong UID_GENERATOR = new AtomicLong(System.nanoTime()); 036 037 /** 038 * Returns a string that can be used as part of a Java identifier and is unique 039 * for this JVM. Currently returns a hexadecimal string and initialized by 040 * System.nanoTime() (but both those details may change in the future). 041 * 042 * Note that the returned value may start with a numeric digit, so it should be used as a <em>suffix</em>, not 043 * <em>prefix</em> of a Java identifier. 044 * 045 * @return unique id that can be used as part of a Java identifier 046 */ 047 public static String nextUID() 048 { 049 return Long.toHexString(PlasticUtils.UID_GENERATOR.getAndIncrement()); 050 } 051 052 /** 053 * Converts a type (including array and primitive types) to their type name (the way they are represented in Java 054 * source files). 055 */ 056 public static String toTypeName(Class type) 057 { 058 if (type.isArray()) 059 return toTypeName(type.getComponentType()) + "[]"; 060 061 return type.getName(); 062 } 063 064 /** Converts a number of types (usually, arguments to a method or constructor) into their type names. */ 065 public static String[] toTypeNames(Class[] types) 066 { 067 String[] result = new String[types.length]; 068 069 for (int i = 0; i < result.length; i++) 070 result[i] = toTypeName(types[i]); 071 072 return result; 073 } 074 075 /** 076 * Gets the wrapper type for a given type (if primitive) 077 * 078 * @param type 079 * type to look up 080 * @return the input type for non-primitive type, or corresponding wrapper type (Boolean.class for boolean.class, 081 * etc.) 082 */ 083 public static Class toWrapperType(Class type) 084 { 085 assert type != null; 086 087 return type.isPrimitive() ? PrimitiveType.getByPrimitiveType(type).wrapperType : type; 088 } 089 090 /** 091 * Convenience for getting a method from a class. 092 * 093 * @param declaringClass 094 * containing class 095 * @param name 096 * name of method 097 * @param parameterTypes 098 * types of parameters 099 * @return the Method 100 * @throws RuntimeException 101 * if any error (such as method not found) 102 */ 103 @SuppressWarnings("unchecked") 104 public static Method getMethod(Class declaringClass, String name, Class... parameterTypes) 105 { 106 try 107 { 108 return declaringClass.getMethod(name, parameterTypes); 109 } 110 catch (Exception ex) 111 { 112 throw new RuntimeException(ex); 113 } 114 } 115 116 /** 117 * Uses {@link #getMethod(Class, String, Class...)} and wraps the result as a {@link MethodDescription}. 118 * 119 * @param declaringClass 120 * containing class 121 * @param name 122 * name of method 123 * @param parameterTypes 124 * types of parameters 125 * @return description for method 126 * @throws RuntimeException 127 * if any error (such as method not found) 128 */ 129 public static MethodDescription getMethodDescription(Class declaringClass, String name, Class... parameterTypes) 130 { 131 return new MethodDescription(getMethod(declaringClass, name, parameterTypes)); 132 } 133 134 /** 135 * Determines if the provided type name is a primitive type. 136 * 137 * @param typeName Java type name, such as "boolean" or "java.lang.String" 138 * @return true if primitive 139 */ 140 public static boolean isPrimitive(String typeName) 141 { 142 return PrimitiveType.getByName(typeName) != null; 143 } 144}