KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > freemarker > template > utility > CaptureOutput


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.template.utility;
54
55 import freemarker.template.*;
56 import freemarker.core.Environment;
57 import java.io.*;
58 import java.util.Map JavaDoc;
59
60 /**
61  * A transform that captures the output of a block of FTL code and stores that in a variable.
62  *
63  * <p>As this transform is initially present in the shared variable set, you can always
64  * access it from the templates:</p>
65  *
66  * <pre>
67  * &lt;@capture_output var="captured">
68  * ...
69  * &lt;/@capture_output>
70  * </pre>
71  *
72  * <p>And later in the template you can use the captured output:</p>
73  *
74  * ${captured}
75  *
76  * <p>This transform requires one of three parameters: <code>var</code>, <code>local</code>, or <code>global</code>.
77  * Each of them specifies the name of the variable that stores the captured output, but the first creates a
78  * variable in a name-space (as &lt;#assign>), the second creates a macro-local variable (as &lt;#local>),
79  * and the last creates a global variable (as &lt;#global>).
80  * </p>
81  * <p>In the case of an assignment within a namespace, there is an optional parameter
82  * <code>namespace</code> that indicates in which namespace to do the assignment.
83  * if this is omitted, the current namespace is used, and this will be, by far, the most
84  * common usage pattern.</p>
85  *
86  * @deprecated Use block-assignments instead, as <code>&lt;assign x>...&lt;/assign></code>.
87  *
88  * @version $Id: CaptureOutput.java,v 1.31 2004/01/06 17:06:43 szegedia Exp $
89  */

90 public class CaptureOutput implements TemplateTransformModel {
91
92     public Writer getWriter(final Writer out, final Map JavaDoc args) throws TemplateModelException {
93         String JavaDoc errmsg = "Must specify the name of the variable in "
94                 + "which to capture the output with the 'var' or 'local' or 'global' parameter.";
95         if (args == null) throw new TemplateModelException(errmsg);
96
97         boolean local = false, global=false;
98         final TemplateModel nsModel = (TemplateModel) args.get("namespace");
99         Object JavaDoc varNameModel = args.get("var");
100         if (varNameModel == null) {
101             varNameModel = args.get("local");
102             if (varNameModel == null) {
103                 varNameModel = args.get("global");
104                 global = true;
105             } else {
106                 local = true;
107             }
108             if (varNameModel == null) {
109                 throw new TemplateModelException(errmsg);
110             }
111         }
112         if (args.size()==2) {
113             if (nsModel == null) {
114                 throw new TemplateModelException("Second parameter can only be namespace");
115             }
116             if (local) {
117                 throw new TemplateModelException("Cannot specify namespace for a local assignment");
118             }
119             if (global) {
120                 throw new TemplateModelException("Cannot specify namespace for a global assignment");
121             }
122             if (!(nsModel instanceof Environment.Namespace)) {
123                 throw new TemplateModelException("namespace parameter does not specify a namespace. It is a " + nsModel.getClass().getName());
124             }
125         }
126         else if (args.size() != 1) throw new TemplateModelException(
127                 "Bad parameters. Use only one of 'var' or 'local' or 'global' parameters.");
128
129         if(!(varNameModel instanceof TemplateScalarModel)) {
130             throw new TemplateModelException("'var' or 'local' or 'global' parameter doesn't evaluate to a string");
131         }
132         final String JavaDoc varName = ((TemplateScalarModel) varNameModel).getAsString();
133         if(varName == null) {
134             throw new TemplateModelException("'var' or 'local' or 'global' parameter evaluates to null string");
135         }
136
137         final StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
138         final Environment env = Environment.getCurrentEnvironment();
139         final boolean localVar = local;
140         final boolean globalVar = global;
141
142         return new Writer() {
143
144             public void write(char cbuf[], int off, int len) {
145                 buf.append(cbuf, off, len);
146             }
147
148             public void flush() throws IOException {
149                 out.flush();
150             }
151
152             public void close() throws IOException {
153                 SimpleScalar result = new SimpleScalar(buf.toString());
154                 try {
155                     if (localVar) {
156                         env.setLocalVariable(varName, result);
157                     } else if (globalVar) {
158                         env.setGlobalVariable(varName, result);
159                     }
160                     else {
161                         if (nsModel == null) {
162                             env.setVariable(varName, result);
163                         } else {
164                             ((Environment.Namespace) nsModel).put(varName, result);
165                         }
166                     }
167                 } catch (java.lang.IllegalStateException JavaDoc ise) { // if somebody uses 'local' outside a macro
168
throw new IOException("Could not set variable " + varName + ": " + ise.getMessage());
169                 }
170             }
171         };
172     }
173 }
174
Popular Tags