001// Copyright 2006, 2007 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.internal.util;
016
017import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
018import org.apache.tapestry5.services.ClassTransformation;
019import org.apache.tapestry5.services.TransformMethodSignature;
020import org.apache.tapestry5.services.TransformUtils;
021
022import java.util.Map;
023
024/**
025 * A utility class for building part of a method body to invoke a method. Analyzes the method and matches parameter
026 * types to ParameterBuilders.
027 */
028public final class MethodInvocationBuilder
029{
030    private final Map<String, ParameterBuilder> builders = CollectionFactory.newMap();
031
032    /**
033     * Maps a parameter type to a {@link ParameterBuilder}.
034     */
035    public void addParameter(String parameterType, ParameterBuilder builder)
036    {
037        // TODO: Name conflicts
038
039        builders.put(parameterType, builder);
040    }
041
042    /**
043     * Maps a parameter type to a literal string to be used for the parameter expression.
044     *
045     * @see StringParameterBuilder
046     */
047    public void addParameter(String parameterType, String expression)
048    {
049        addParameter(parameterType, new StringParameterBuilder(expression));
050    }
051
052    /**
053     * Builds the method invocation. Analyzes the type of each parameter to the method, and uses a {@link
054     * ParameterBuilder} to provide the expression. Supplies a default value (usually null) for any parameters that do
055     * not have parameter builders.
056     *
057     * @param signature      of the method to invoke
058     * @param transformation
059     * @return method invocation expression
060     * @see TransformUtils#getDefaultValue(String)
061     */
062    public String buildMethodInvocation(TransformMethodSignature signature,
063                                        ClassTransformation transformation)
064    {
065        StringBuilder builder = new StringBuilder(signature.getMethodName());
066
067        builder.append("(");
068
069        String[] parameterTypes = signature.getParameterTypes();
070
071        for (int i = 0; i < parameterTypes.length; i++)
072        {
073            if (i > 0) builder.append(", ");
074
075            String type = parameterTypes[i];
076
077            ParameterBuilder parameterBuilder = builders.get(type);
078
079            if (parameterBuilder == null)
080            {
081                // TODO: Log an error
082
083                builder.append(TransformUtils.getDefaultValue(type));
084            }
085            else
086            {
087                builder.append(parameterBuilder.buildParameter(transformation));
088            }
089        }
090
091        builder.append(")");
092
093        return builder.toString();
094    }
095
096}