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