    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
    015package org.apache.tapestry5.plastic;
    016
    017import org.apache.tapestry5.internal.plastic.PrimitiveType;
    018
    019import java.lang.reflect.Method;
    020import java.util.concurrent.atomic.AtomicLong;
    021
    022/**
    023 * Utilities for user code making use of Plastic.
    024 */
    025public 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}