KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > velocity > runtime > directive > Include


1
2 package org.apache.velocity.runtime.directive;
3
4 /*
5  * Copyright 2000-2001,2004 The Apache Software Foundation.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */

19
20 import java.io.Writer JavaDoc;
21 import java.io.IOException JavaDoc;
22
23 import org.apache.velocity.context.InternalContextAdapter;
24 import org.apache.velocity.runtime.RuntimeServices;
25 import org.apache.velocity.runtime.RuntimeConstants;
26 import org.apache.velocity.runtime.parser.ParserTreeConstants;
27 import org.apache.velocity.runtime.parser.node.Node;
28 import org.apache.velocity.runtime.resource.Resource;
29
30 import org.apache.velocity.exception.MethodInvocationException;
31 import org.apache.velocity.exception.ResourceNotFoundException;
32
33 /**
34  * Pluggable directive that handles the #include() statement in VTL.
35  * This #include() can take multiple arguments of either
36  * StringLiteral or Reference.
37  *
38  * Notes:
39  * -----
40  * 1) The included source material can only come from somewhere in
41  * the TemplateRoot tree for security reasons. There is no way
42  * around this. If you want to include content from elsewhere on
43  * your disk, use a link from somwhere under Template Root to that
44  * content.
45  *
46  * 2) By default, there is no output to the render stream in the event of
47  * a problem. You can override this behavior with two property values :
48  * include.output.errormsg.start
49  * include.output.errormsg.end
50  * If both are defined in velocity.properties, they will be used to
51  * in the render output to bracket the arg string that caused the
52  * problem.
53  * Ex. : if you are working in html then
54  * include.output.errormsg.start=<!-- #include error :
55  * include.output.errormsg.end= -->
56  * might be an excellent way to start...
57  *
58  * 3) As noted above, #include() can take multiple arguments.
59  * Ex : #include( "foo.vm" "bar.vm" $foo )
60  * will simply include all three if valid to output w/o any
61  * special separator.
62  *
63  * @author <a HREF="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
64  * @author <a HREF="mailto:jvanzyl@apache.org">Jason van Zyl</a>
65  * @author <a HREF="mailto:kav@kav.dk">Kasper Nielsen</a>
66  * @version $Id: Include.java,v 1.26.4.1 2004/03/03 23:22:56 geirm Exp $
67  */

68 public class Include extends InputBase
69 {
70     private String JavaDoc outputMsgStart = "";
71     private String JavaDoc outputMsgEnd = "";
72
73     /**
74      * Return name of this directive.
75      */

76     public String JavaDoc getName()
77     {
78         return "include";
79     }
80     
81     /**
82      * Return type of this directive.
83      */

84     public int getType()
85     {
86         return LINE;
87     }
88
89     /**
90      * simple init - init the tree and get the elementKey from
91      * the AST
92      */

93     public void init(RuntimeServices rs, InternalContextAdapter context,
94                      Node node)
95         throws Exception JavaDoc
96     {
97         super.init( rs, context, node );
98
99         /*
100          * get the msg, and add the space so we don't have to
101          * do it each time
102          */

103         outputMsgStart = rsvc.getString(RuntimeConstants.ERRORMSG_START);
104         outputMsgStart = outputMsgStart + " ";
105         
106         outputMsgEnd = rsvc.getString(RuntimeConstants.ERRORMSG_END );
107         outputMsgEnd = " " + outputMsgEnd;
108     }
109
110     /**
111      * iterates through the argument list and renders every
112      * argument that is appropriate. Any non appropriate
113      * arguments are logged, but render() continues.
114      */

115     public boolean render(InternalContextAdapter context,
116                            Writer JavaDoc writer, Node node)
117         throws IOException JavaDoc, MethodInvocationException,
118                ResourceNotFoundException
119     {
120         /*
121          * get our arguments and check them
122          */

123
124         int argCount = node.jjtGetNumChildren();
125
126         for( int i = 0; i < argCount; i++)
127         {
128             /*
129              * we only handle StringLiterals and References right now
130              */

131
132             Node n = node.jjtGetChild(i);
133
134             if ( n.getType() == ParserTreeConstants.JJTSTRINGLITERAL ||
135                  n.getType() == ParserTreeConstants.JJTREFERENCE )
136             {
137                 if (!renderOutput( n, context, writer ))
138                     outputErrorToStream( writer, "error with arg " + i
139                         + " please see log.");
140             }
141             else
142             {
143                 rsvc.error("#include() error : invalid argument type : "
144                     + n.toString());
145                 outputErrorToStream( writer, "error with arg " + i
146                     + " please see log.");
147             }
148         }
149         
150         return true;
151     }
152
153     /**
154      * does the actual rendering of the included file
155      *
156      * @param node AST argument of type StringLiteral or Reference
157      * @param context valid context so we can render References
158      * @param writer output Writer
159      * @return boolean success or failure. failures are logged
160      */

161     private boolean renderOutput( Node node, InternalContextAdapter context,
162                                   Writer JavaDoc writer )
163         throws IOException JavaDoc, MethodInvocationException,
164                ResourceNotFoundException
165     {
166         String JavaDoc arg = "";
167         
168         if ( node == null )
169         {
170             rsvc.error("#include() error : null argument");
171             return false;
172         }
173             
174         /*
175          * does it have a value? If you have a null reference, then no.
176          */

177         Object JavaDoc value = node.value( context );
178         if ( value == null)
179         {
180             rsvc.error("#include() error : null argument");
181             return false;
182         }
183
184         /*
185          * get the path
186          */

187         arg = value.toString();
188
189         Resource resource = null;
190
191         try
192         {
193             resource = rsvc.getContent(arg, getInputEncoding(context));
194         }
195         catch ( ResourceNotFoundException rnfe )
196         {
197             /*
198              * the arg wasn't found. Note it and throw
199              */

200              
201             rsvc.error("#include(): cannot find resource '" + arg +
202                        "', called from template " +
203                        context.getCurrentTemplateName() + " at (" +
204                        getLine() + ", " + getColumn() + ")" );
205             throw rnfe;
206         }
207
208         catch (Exception JavaDoc e)
209         {
210             rsvc.error("#include(): arg = '" + arg +
211                        "', called from template " +
212                        context.getCurrentTemplateName() + " at (" +
213                        getLine() + ", " + getColumn() + ") : " + e);
214         }
215         
216         if ( resource == null )
217             return false;
218        
219         writer.write((String JavaDoc)resource.getData());
220         return true;
221     }
222
223     /**
224      * Puts a message to the render output stream if ERRORMSG_START / END
225      * are valid property strings. Mainly used for end-user template
226      * debugging.
227      */

228     private void outputErrorToStream( Writer JavaDoc writer, String JavaDoc msg )
229         throws IOException JavaDoc
230     {
231         if ( outputMsgStart != null && outputMsgEnd != null)
232         {
233             writer.write(outputMsgStart);
234             writer.write(msg);
235             writer.write(outputMsgEnd);
236         }
237         return;
238     }
239 }
240
Popular Tags