001    // Copyright 2004, 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    package org.apache.tapestry.enhance;
015    
016    import java.lang.reflect.Modifier;
017    
018    import javassist.CtClass;
019    import javassist.CtMethod;
020    
021    import org.apache.hivemind.ApplicationRuntimeException;
022    import org.apache.hivemind.service.MethodFab;
023    import org.apache.hivemind.service.MethodSignature;
024    
025    /**
026     * Implementation of hivemind {@link MethodFab} utiltity.
027     */
028    public class MethodFabImpl implements MethodFab
029    {
030        private CtClassSource _source;
031    
032        private MethodSignature _signature;
033    
034        private CtMethod _method;
035    
036        private StringBuffer _descriptionBody = new StringBuffer();
037    
038        public MethodFabImpl(CtClassSource source, MethodSignature signature, CtMethod method,
039                String body)
040        {
041            _source = source;
042            _signature = signature;
043            _method = method;
044    
045            _descriptionBody.append(body);
046        }
047    
048        /**
049         * Returns a a text representation of the method, parameters and method body.
050         */
051        public String toString()
052        {
053            if (_method == null)
054                return "";
055            
056            StringBuffer buffer = new StringBuffer();
057    
058            try
059            {
060                buffer.append(Modifier.toString(_method.getModifiers()));
061    
062                buffer.append(" ");
063                buffer.append(_method.getReturnType().getName());
064    
065                buffer.append(" ");
066                buffer.append(_method.getName());
067                buffer.append("(");
068    
069                CtClass[] params = _method.getParameterTypes();
070    
071                for (int i = 0; i < params.length; i++)
072                {
073                    if (i > 0)
074                        buffer.append(", ");
075    
076                    buffer.append(params[i].getName());
077    
078                    buffer.append(" $");
079                    buffer.append(i + 1);
080                }
081                buffer.append(")");
082    
083                CtClass[] exceptions = _method.getExceptionTypes();
084    
085                for (int i = 0; i < exceptions.length; i++)
086                {
087                    if (i == 0)
088                        buffer.append("\n  throws ");
089                    else
090                        buffer.append(", ");
091    
092                    buffer.append(exceptions[i].getName());
093                }
094    
095                buffer.append("\n");
096                buffer.append(_descriptionBody);
097            }
098            catch (Exception ex)
099            {
100                buffer.append(" *** ");
101                buffer.append(ex);
102            }
103    
104            return buffer.toString();
105        }
106    
107        public void addCatch(Class exceptionClass, String catchBody)
108        {
109            if (_method == null)
110                return;
111            
112            CtClass ctException = _source.getCtClass(exceptionClass);
113    
114            try
115            {
116                _method.addCatch(catchBody, ctException);
117            }
118            catch (Exception ex)
119            {
120                throw new ApplicationRuntimeException(EnhanceMessages.unableToAddCatch(
121                        exceptionClass,
122                        _method,
123                        ex), ex);
124            }
125    
126            _descriptionBody.append("\ncatch(");
127            _descriptionBody.append(exceptionClass.getName());
128            _descriptionBody.append(" $e)\n");
129            _descriptionBody.append(catchBody);
130        }
131    
132        public void extend(String body, boolean asFinally)
133        {
134            if (_method == null)
135                return;
136            
137            try
138            {
139                _method.insertAfter(body, asFinally);
140            }
141            catch (Exception ex)
142            {
143                throw new ApplicationRuntimeException(EnhanceMessages.unableToExtendMethod(
144                        _signature,
145                        _method.getDeclaringClass().getName(),
146                        ex), ex);
147            }
148    
149            _descriptionBody.append("\n");
150    
151            if (asFinally)
152                _descriptionBody.append("finally\n");
153    
154            _descriptionBody.append(body);
155        }
156    
157    
158    }