001// Copyright 2005 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.tapestry.annotations;
016
017import java.beans.Introspector;
018import java.lang.annotation.Annotation;
019import java.lang.reflect.Method;
020
021import org.apache.hivemind.ApplicationRuntimeException;
022import org.apache.hivemind.Location;
023import org.apache.hivemind.Resource;
024import org.apache.tapestry.util.DescribedLocation;
025
026/**
027 * @author Howard M. Lewis Ship
028 * @since 4.0
029 */
030
031public class AnnotationUtils
032{
033    /**
034     * Determines the property name for a method, by stripping off the is/get/set prefix and
035     * decapitalizing the first name.
036     * 
037     * @param method
038     *            accessor method (get/set/is)
039     * @return the property name for the method
040     * @throws ApplicationRuntimeException
041     *             if the method is not an accessor or mutator method
042     */
043    public static String getPropertyName(Method method)
044    {
045        String name = method.getName();
046
047        if (name.startsWith("is"))
048        {
049            checkGetter(method);
050            return Introspector.decapitalize(name.substring(2));
051        }
052
053        if (name.startsWith("get"))
054        {
055            checkGetter(method);
056            return Introspector.decapitalize(name.substring(3));
057        }
058
059        if (name.startsWith("set"))
060        {
061            checkSetter(method);
062            return Introspector.decapitalize(name.substring(3));
063        }
064
065        throw new ApplicationRuntimeException(AnnotationMessages.notAccessor(method));
066    }
067
068    private static void checkGetter(Method method)
069    {
070        if (method.getParameterTypes().length > 0)
071            throw new ApplicationRuntimeException(AnnotationMessages.noParametersExpected(method));
072
073        if (method.getReturnType().equals(void.class))
074            throw new ApplicationRuntimeException(AnnotationMessages.voidAccessor(method));
075
076    }
077
078    private static void checkSetter(Method method)
079    {
080        if (!method.getReturnType().equals(void.class))
081            throw new ApplicationRuntimeException(AnnotationMessages.nonVoidMutator(method));
082
083        if (method.getParameterTypes().length != 1)
084            throw new ApplicationRuntimeException(AnnotationMessages.wrongParameterCount(method));
085    }
086
087    public static Location buildLocationForAnnotation(Method method, Annotation annotation,
088            Resource classResource)
089    {
090        return new DescribedLocation(classResource, AnnotationMessages.methodAnnotation(
091                annotation,
092                method));
093    }
094}