1 /*
2 * Copyright (c) 2003 The Visigoth Software Society. All rights
3 * reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. The end-user documentation included with the redistribution, if
18 * any, must include the following acknowledgement:
19 * "This product includes software developed by the
20 * Visigoth Software Society (http://www.visigoths.org/)."
21 * Alternately, this acknowledgement may appear in the software itself,
22 * if and wherever such third-party acknowledgements normally appear.
23 *
24 * 4. Neither the name "FreeMarker", "Visigoth", nor any of the names of the
25 * project contributors may be used to endorse or promote products derived
26 * from this software without prior written permission. For written
27 * permission, please contact visigoths@visigoths.org.
28 *
29 * 5. Products derived from this software may not be called "FreeMarker" or "Visigoth"
30 * nor may "FreeMarker" or "Visigoth" appear in their names
31 * without prior written permission of the Visigoth Software Society.
32 *
33 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
34 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
35 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
36 * DISCLAIMED. IN NO EVENT SHALL THE VISIGOTH SOFTWARE SOCIETY OR
37 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
38 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
39 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
40 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
41 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
42 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
43 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44 * SUCH DAMAGE.
45 * ====================================================================
46 *
47 * This software consists of voluntary contributions made by many
48 * individuals on behalf of the Visigoth Software Society. For more
49 * information on the Visigoth Software Society, please see
50 * http://www.visigoths.org/
51 */
52
53 package freemarker.ext.beans;
54
55 import java.lang.reflect.InvocationTargetException;
56 import java.lang.reflect.Method;
57 import java.lang.reflect.Modifier;
58 import java.util.List;
59
60 import freemarker.template.SimpleNumber;
61 import freemarker.template.TemplateMethodModelEx;
62 import freemarker.template.TemplateModel;
63 import freemarker.template.TemplateModelException;
64 import freemarker.template.TemplateSequenceModel;
65 import freemarker.template.utility.Collections12;
66
67 /**
68 * A class that will wrap a reflected method call into a
69 * {@link freemarker.template.TemplateMethodModel} interface.
70 * It is used by {@link BeanModel} to wrap reflected method calls
71 * for non-overloaded methods.
72 * @author Attila Szegedi, szegedia at users dot sourceforge dot net
73 * @version $Id: SimpleMethodModel.java,v 1.27 2005/06/11 12:12:04 szegedia Exp $
74 */
75 public final class SimpleMethodModel extends SimpleMemberModel
76 implements
77 TemplateMethodModelEx,
78 TemplateSequenceModel
79 {
80 private final Object object;
81 private final BeansWrapper wrapper;
82
83 /**
84 * Creates a model for a specific method on a specific object.
85 * @param object the object to call the method on. Can be
86 * <tt>null</tt> for static methods.
87 * @param method the method that will be invoked.
88 */
89 SimpleMethodModel(Object object, Method method, Class[] argTypes,
90 BeansWrapper wrapper)
91 {
92 super(method, argTypes);
93 this.object = object;
94 this.wrapper = wrapper;
95 }
96
97 /**
98 * Invokes the method, passing it the arguments from the list.
99 */
100 public Object exec(List arguments)
101 throws
102 TemplateModelException
103 {
104 try
105 {
106 return wrapper.invokeMethod(object, (Method)getMember(),
107 unwrapArguments(arguments, wrapper));
108 }
109 catch(Exception e)
110 {
111 while(e instanceof InvocationTargetException)
112 {
113 Throwable t = ((InvocationTargetException)e).getTargetException();
114 if(t instanceof Exception)
115 {
116 e = (Exception)t;
117 }
118 else
119 {
120 break;
121 }
122 }
123 if((getMember().getModifiers() & Modifier.STATIC) != 0)
124 {
125 throw new TemplateModelException("Method " + getMember() +
126 " threw an exception", e);
127 }
128 else
129 {
130 throw new TemplateModelException("Method " + getMember() +
131 " threw an exception when invoked on " + object, e);
132 }
133 }
134 }
135
136 public TemplateModel get(int index) throws TemplateModelException
137 {
138 return (TemplateModel) exec(Collections12.singletonList(
139 new SimpleNumber(new Integer(index))));
140 }
141
142 public int size() throws TemplateModelException
143 {
144 throw new TemplateModelException("?size is unsupported for: " + getClass().getName());
145 }
146
147 public String toString() {
148 return getMember().toString();
149 }
150 }