    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
    015    package org.apache.tapestry5.internal.util;
    016
    017    import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
    018    import org.apache.tapestry5.services.ClassTransformation;
    019    import org.apache.tapestry5.services.TransformMethodSignature;
    020    import org.apache.tapestry5.services.TransformUtils;
    021
    022    import 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     */
    028    public 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    }