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    }