KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > freemarker > core > UnifiedCall


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.core;
54
55 import java.io.*;
56 import java.util.*;
57 import freemarker.template.*;
58
59 /**
60  * An element for the unified macro/transform syntax.
61  */

62 final class UnifiedCall extends TemplateElement {
63
64     private Expression nameExp;
65     private Map namedArgs;
66     private List positionalArgs, bodyParameterNames;
67     boolean legacySyntax, notransform;
68
69
70     UnifiedCall(Expression nameExp,
71          Map namedArgs,
72          TemplateElement nestedBlock,
73          List bodyParameterNames)
74     {
75         this.nameExp = nameExp;
76         this.namedArgs = namedArgs;
77         this.nestedBlock = nestedBlock;
78         this.bodyParameterNames = bodyParameterNames;
79         notransform = legacySyntax
80                       || (positionalArgs != null && positionalArgs.isEmpty())
81                       || (bodyParameterNames != null && !bodyParameterNames.isEmpty());
82     }
83
84     UnifiedCall(Expression nameExp,
85          List positionalArgs,
86          TemplateElement nestedBlock,
87          List bodyParameterNames)
88     {
89         this.nameExp = nameExp;
90         this.positionalArgs = positionalArgs;
91         if (nestedBlock == TextBlock.EMPTY_BLOCK) {
92             nestedBlock = null;
93         }
94         this.nestedBlock = nestedBlock;
95         this.bodyParameterNames = bodyParameterNames;
96     }
97
98
99     void accept(Environment env) throws TemplateException, IOException {
100         TemplateModel tm = nameExp.getAsTemplateModel(env);
101         if (tm == Macro.DO_NOTHING_MACRO) return; // shortcut here.
102
if (!notransform && (tm instanceof TemplateTransformModel)) {
103             Map args;
104             if (namedArgs != null && !namedArgs.isEmpty()) {
105                 args = new HashMap();
106                 for (Iterator it = namedArgs.entrySet().iterator(); it.hasNext();) {
107                     Map.Entry entry = (Map.Entry) it.next();
108                     String JavaDoc key = (String JavaDoc) entry.getKey();
109                     Expression valueExp = (Expression) entry.getValue();
110                     TemplateModel value = valueExp.getAsTemplateModel(env);
111                     args.put(key, value);
112                 }
113             } else {
114                 args = EmptyMap.instance;
115             }
116             env.visit(nestedBlock, (TemplateTransformModel) tm, args);
117             return;
118         }
119         if (tm instanceof Macro) {
120             Macro macro = (Macro) tm;
121             if (macro.isFunction && !legacySyntax) {
122                 throw new TemplateException("Routine "
123                                              + macro.getName()
124                                              + " is a function. "
125                                              + "A function can only be called within the evaluation of an expression.",
126                                              env);
127             }
128             env.visit(macro,
129                       namedArgs,
130                       positionalArgs,
131                       bodyParameterNames,
132                       nestedBlock);
133             return;
134         }
135         if (tm == null) {
136             throw new InvalidReferenceException(this.getStartLocation() + " " + nameExp + " not found.", env);
137         } else if (notransform) {
138             throw new TemplateException(getStartLocation() + ": " + nameExp + " is not a Macro.", env);
139         } else {
140             throw new TemplateException(getStartLocation() + ": " + nameExp + " is not a Macro or Transform.", env);
141         }
142     }
143
144     public String JavaDoc getCanonicalForm() {
145         StringBuffer JavaDoc buf = new StringBuffer JavaDoc("<@");
146         buf.append(nameExp.getCanonicalForm());
147         if (positionalArgs != null) {
148             for (int i=0; i<positionalArgs.size(); i++) {
149                 Expression arg = (Expression) positionalArgs.get(i);
150                 if (i!=0) {
151                     buf.append(',');
152                 }
153                 buf.append(' ');
154                 buf.append(arg.getCanonicalForm());
155             }
156         }
157         else {
158             ArrayList keys = new ArrayList(namedArgs.keySet());
159             Collections.sort(keys);
160             for (int i=0; i<keys.size();i++) {
161                 Expression arg = (Expression) namedArgs.get(keys.get(i));
162                 buf.append(' ');
163                 buf.append(keys.get(i));
164                 buf.append('=');
165                 buf.append(arg.getCanonicalForm());
166             }
167         }
168         if (nestedBlock == null) {
169             buf.append("/>");
170         }
171         else {
172             buf.append('>');
173             buf.append(nestedBlock.getCanonicalForm());
174             buf.append("</@");
175             if (nameExp instanceof Identifier || (nameExp instanceof Dot && ((Dot) nameExp).onlyHasIdentifiers())) {
176                 buf.append(nameExp);
177             }
178             buf.append('>');
179         }
180         return buf.toString();
181     }
182
183     public String JavaDoc getDescription() {
184         return "user-directive " + nameExp;
185     }
186 /*
187     //REVISIT
188     boolean heedsOpeningWhitespace() {
189         return nestedBlock == null;
190     }
191
192     //REVISIT
193     boolean heedsTrailingWhitespace() {
194         return nestedBlock == null;
195     }*/

196 }
197
Popular Tags