1 package org.apache.turbine.modules.actions;
2
3 /* ====================================================================
4 * The Apache Software License, Version 1.1
5 *
6 * Copyright (c) 2001 The Apache Software Foundation. All rights
7 * reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
19 * distribution.
20 *
21 * 3. The end-user documentation included with the redistribution,
22 * if any, must include the following acknowledgment:
23 * "This product includes software developed by the
24 * Apache Software Foundation (http://www.apache.org/)."
25 * Alternately, this acknowledgment may appear in the software itself,
26 * if and wherever such third-party acknowledgments normally appear.
27 *
28 * 4. The names "Apache" and "Apache Software Foundation" and
29 * "Apache Turbine" must not be used to endorse or promote products
30 * derived from this software without prior written permission. For
31 * written permission, please contact apache@apache.org.
32 *
33 * 5. Products derived from this software may not be called "Apache",
34 * "Apache Turbine", nor may "Apache" appear in their name, without
35 * prior written permission of the Apache Software Foundation.
36 *
37 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
41 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48 * SUCH DAMAGE.
49 * ====================================================================
50 *
51 * This software consists of voluntary contributions made by many
52 * individuals on behalf of the Apache Software Foundation. For more
53 * information on the Apache Software Foundation, please see
54 * <http://www.apache.org/>.
55 */
56
57 // Java Core Classes
58 import java.util.Enumeration;
59 import java.util.Hashtable;
60 import java.util.LinkedList;
61 import java.util.List;
62 import java.util.Vector;
63 import java.net.URL;
64 import java.io.BufferedReader;
65 import java.io.BufferedWriter;
66 import java.io.File;
67 import java.io.FileReader;
68 import java.io.FileWriter;
69 import java.io.InputStreamReader;
70
71 // Turbine Utility Classes
72 import org.apache.turbine.modules.Action;
73 import org.apache.turbine.services.resources.TurbineResources;
74 import org.apache.turbine.services.freemarker.DynamicURIModel;
75 import org.apache.turbine.util.Log;
76 import org.apache.turbine.util.RunData;
77
78 import freemarker.template.SimpleScalar;
79
80 /***
81 * This action parses all files located in the screens, navigations,
82 * and layouts directories under the services.freemarker.path given in
83 * TurbineResources.properties. It cycles through links and parses
84 * the responses for urls. It writes the response to a file replacing
85 * the urls with the static variation.
86 *
87 * @author <a href="mailto:john.mcnally@clearink.com">John D. McNally</a>
88 * @version $Id: FreeMarkerSiteCooker.java,v 1.1.1.1 2001/08/16 05:08:32 jvanzyl Exp $
89 * @deprecated you should use velocity
90 */
91 public class FreeMarkerSiteCooker extends Action
92 {
93 /***
94 * Execute the action.
95 *
96 * @param data Turbine information.
97 * @exception Exception, a generic exception.
98 */
99 public void doPerform( RunData data )
100 throws Exception
101 {
102 long start = System.currentTimeMillis();
103 try
104 {
105 Hashtable links = new Hashtable();
106 Vector files = new Vector();
107 Object value = new Object();
108 String basePath;
109 basePath = TurbineResources.getString("services.freemarker.path");
110
111 // Add all files under basePath to the files Vector.
112 String[] templatePaths = {"layouts", "navigations", "screens"};
113 for (int i=0; i<templatePaths.length; i++)
114 {
115 File tempPath = new File(basePath, templatePaths[i]);
116 dirRecurse(tempPath, files);
117 }
118
119 // Parse the files looking for ${link("xxx")}. Place the
120 // List into links keyed by the template name.
121 for (int i=0; i<files.size(); i++)
122 {
123 File file = (File)files.elementAt(i);
124 BufferedReader in = null;
125 char[] contents = null;
126 try
127 {
128 in = new BufferedReader(new FileReader(file));
129 parseTemplateFile(in, links);
130 }
131 finally
132 {
133 if (in != null) in.close();
134 }
135 }
136
137 // Now we have a Hashtable full of all the links on the
138 // site. Let's go through them create the url, hit the
139 // server, parse the response, and save the translated
140 // response to a file.
141 int fileCount = 0;
142 Enumeration e = links.keys();
143 while (e.hasMoreElements())
144 {
145 String templateName = (String) e.nextElement();
146 List alist = (List)links.get(templateName);
147 DynamicURIModel uriModel = new DynamicURIModel(data);
148 String uri =
149 ((SimpleScalar)uriModel.exec(alist)).getAsString();
150 // System.out.println(uri);
151
152 // Work around. Do not have an ssl connection (not
153 // really necessary for internal development, but
154 // might want to add it later), so use http to get
155 // response for parsing.
156 String useUrl = null;
157 String partialPath = null;
158 if (uri.startsWith("https"))
159 {
160 useUrl = "http" + uri.substring(5);
161 partialPath = "../cooked_ssl";
162 }
163 else
164 {
165 useUrl = uri;
166 partialPath = "../cooked";
167 }
168 File cookedFile = new File(basePath +
169 File.separator +
170 partialPath, templateName);
171 File parent = new File(cookedFile.getParent());
172 if (!parent.exists() &&
173 !parent.equals(cookedFile))
174 {
175 parent.mkdirs();
176 }
177 if (!cookedFile.exists())
178 {
179 fileCount++;
180 System.out.println(fileCount + ": " + cookedFile);
181 // cookedFile.createNewFile();
182
183 BufferedReader in = null;
184 BufferedWriter[] out = new BufferedWriter[1];
185 try
186 {
187 out[0] = new BufferedWriter(new FileWriter(cookedFile));
188
189 URL url = new URL(useUrl);
190 in = new BufferedReader(
191 new InputStreamReader(url.openStream()));
192
193 parseFlatFile(uri, in, out);
194 System.out.println(fileCount + ": Successful");
195 }
196 finally
197 {
198 if (in != null) in.close();
199 if (out[0] != null) out[0].close();
200 }
201 }
202 }
203 }
204 catch (Exception e)
205 {
206 Log.error(e);
207 }
208 System.out.println("Time:" +
209 ((System.currentTimeMillis() - start)/1000) );
210
211 }
212
213 /***
214 * Recurse through directories, adding all non-directorty entries
215 * to the vector files.
216 *
217 * @param basePath The starting path to recurse into.
218 * @param files The vector of gathered files.
219 */
220 private void dirRecurse(File basePath,
221 Vector files)
222 {
223 String[] dirList = basePath.list();
224 for (int i=0; i<dirList.length; i++)
225 {
226 File tempPath = new File(basePath, dirList[i]);
227 if (tempPath.isDirectory())
228 {
229 dirRecurse(tempPath, files);
230 }
231 else
232 {
233 files.addElement(tempPath);
234 }
235 }
236 }
237
238 /***
239 * Parse a template file.
240 *
241 * @param in
242 * @param links
243 * @exception Exception, a generic exception.
244 */
245 private void parseTemplateFile(BufferedReader in,
246 Hashtable links)
247 throws Exception
248 {
249 char[] cbuf = new char[7];
250 String templateName = null;
251 StringBuffer argBuffer = new StringBuffer();
252 LinkedList args = new LinkedList();
253 boolean firstquote = false;
254 boolean armed = false;
255 int chint = in.read();
256 while ( chint != -1)
257 {
258 char ch = (char)chint;
259 if (armed)
260 {
261 // System.out.print(ch);
262 if (ch == '\"')
263 {
264 // Toggle between first and second quotes.
265 firstquote = !firstquote;
266 if (!firstquote)
267 {
268 // Finished an argument string.
269 String arg = argBuffer.toString();
270 args.add(arg);
271 argBuffer = new StringBuffer();
272
273 if ( !arg.startsWith("http") &&
274 templateName == null)
275 {
276 templateName = arg;
277 }
278 }
279 }
280 else if (firstquote)
281 {
282 argBuffer.append(ch);
283 }
284 else if (ch == '}')
285 {
286 // System.out.print("\ntemplateName: " +
287 // templateName + "\nArguments: ");
288 // Iterator iter = args.iterator();
289 // while (iter.hasNext())
290 // {
291 // System.out.print((String)iter.next());
292 // }
293 // System.out.print("\n\n");
294
295 links.put(templateName, args);
296 templateName = null;
297 args = new LinkedList();
298 armed = false;
299 }
300 }
301 else
302 {
303 for (int i=0; i<6; i++)
304 {
305 cbuf[i] = cbuf[i+1];
306 }
307 cbuf[6] = ch;
308
309 // Check to see if cbuf contains "${link(".
310 if ( cbuf[0] == '$' &&
311 cbuf[1] == '{' &&
312 cbuf[2] == 'l' &&
313 cbuf[3] == 'i' &&
314 cbuf[4] == 'n' &&
315 cbuf[5] == 'k' &&
316 cbuf[6] == '(' )
317 {
318 armed = true;
319 }
320 }
321 chint = in.read();
322 }
323 }
324
325 /***
326 * Parse a flat file.
327 *
328 * @param url is the url of the current file which is being parsed.
329 * @param in is the input stream of the file being parsed.
330 * @param out is the output stream for the results.
331 * @exception Exception, a generic exception.
332 */
333 private void parseFlatFile(String uri,
334 BufferedReader in,
335 BufferedWriter[] out)
336 throws Exception
337 {
338 char[] cbuf = new char[4];
339 String templateName = null;
340 StringBuffer uriBuffer = new StringBuffer();
341 boolean armed = false;
342 int chint = in.read();
343 while ( chint != -1)
344 {
345 char ch = (char)chint;
346 // Write the current character to all the output streams.
347 for (int i=0; i<out.length; i++)
348 {
349 out[i].write(ch);
350 }
351
352 // Found an href.
353 if (armed)
354 {
355 // Found first quote which should surround the href
356 // attribute's value.
357 if (ch == '\"')
358 {
359 parseUri(uri, in, out[0]);
360 armed = false;
361 }
362 }
363 // Still looking for an href attribute.
364 else
365 {
366 // Bumped all the characters in the buffer over one
367 // char and add the current char.
368 for (int i=0; i<3; i++)
369 {
370 cbuf[i] = cbuf[i+1];
371 }
372 cbuf[3] = ch;
373
374 // Check to see if cbuf contains href.
375 if ( (cbuf[0] == 'h' || cbuf[0] == 'H') &&
376 (cbuf[1] == 'r' || cbuf[1] == 'R') &&
377 (cbuf[2] == 'e' || cbuf[2] == 'E') &&
378 (cbuf[3] == 'f' || cbuf[3] == 'F') )
379 {
380 armed = true;
381 }
382 }
383 // Get the next character and if it exists, loop back to
384 // the top.
385 chint = in.read();
386 }
387 }
388
389
390 /***
391 * Parse an URI.
392 *
393 * @param url is the url of the current file which is being parsed.
394 * @param in is the input stream of the file being parsed.
395 * @param out is the output stream for the results.
396 * @exception Exception, a generic exception.
397 */
398 private void parseUri(String url,
399 BufferedReader in,
400 BufferedWriter out)
401 throws Exception
402 {
403 // url is the url of the current file which is being parsed.
404 // The 10 is for the first char after the '/'.
405 int beginFile = url.indexOf("/template/") + 10;
406 int endFile = url.indexOf('/', beginFile);
407 if (endFile == -1)
408 {
409 endFile = url.indexOf('?', beginFile);
410 }
411 if (endFile == -1)
412 {
413 endFile = url.length();
414 }
415 String thisFilePath = url.substring(beginFile, endFile);
416 // System.out.println("Url: " + url);
417 char[] cbuf = new char[9];
418 String templateName = null;
419 StringBuffer uriBuffer = new StringBuffer();
420 boolean armed = false;
421 boolean sameHost = true;
422 // The first char read is after the first quote surrounding
423 // the href attribute's value.
424 while (true)
425 {
426 char ch = (char)in.read();
427 if (armed)
428 {
429 String urlPart = uriBuffer.toString();
430 if (!url.regionMatches(0, urlPart, 0, urlPart.length()))
431 {
432 System.out.println("Hosts do not match:");
433 System.out.println("This file's url starts with: " +
434 url.substring(0,urlPart.length()));
435 System.out.println("The link starts with: " +
436 urlPart);
437 out.write(urlPart, 0, urlPart.length());
438 sameHost = false;
439 }
440
441 int i=0;
442 int pathCounter = 0;
443 boolean firstMiss = true;
444 boolean missedAtLeastOnce = false;
445 uriBuffer = new StringBuffer();
446 while ( ch != '\"' && ch != '?')
447 {
448 // System.out.println(ch + "\t" + thisFilePath.charAt(i));
449
450 // If previous characters have not been the same
451 // or the link is not to the same host with
452 // characters still being equal.
453 if ( missedAtLeastOnce ||
454 !(sameHost && ch == thisFilePath.charAt(i++)) )
455 {
456 if (sameHost && firstMiss)
457 {
458 // The paths are diverging so insert the
459 // correct number of "../".
460 missedAtLeastOnce = true;
461 firstMiss = false;
462 String endPath = thisFilePath.substring(i);
463 char[] endPathArray = endPath.toCharArray();
464 for (int j=0; j<endPathArray.length-2; j++)
465 {
466 if (endPathArray[j] == '%' &&
467 endPathArray[j+1] == '2' &&
468 ( endPathArray[j+2] == 'c' ||
469 endPathArray[j+2] == 'C')
470 )
471 {
472 uriBuffer.append("../");
473 }
474 }
475 }
476
477 // Replace escaped commas with slashes and add
478 // the character to the buffer.
479 if (ch == '%')
480 {
481 char ch1 = (char)in.read();
482 char ch2 = (char)in.read();
483 if (ch1=='2' &&
484 (ch2=='c' ||
485 ch2=='C'))
486 {
487 uriBuffer.append('/');
488 }
489 else
490 {
491 uriBuffer.append(ch);
492 uriBuffer.append(ch1);
493 uriBuffer.append(ch2);
494 }
495 }
496 else
497 {
498 uriBuffer.append(ch);
499 }
500 }
501 ch = (char)in.read();
502 }
503
504 // In the event we stopped due to a ?, add the query
505 // data.
506 if (ch == '?')
507 {
508 while (ch != '\"')
509 {
510 // Until we get rid of the session id we will
511 // throw this away.
512 // uriBuffer.append(ch);
513 ch = (char)in.read();
514 }
515 }
516 uriBuffer.append('\"');
517 out.write(uriBuffer.toString(), 0, uriBuffer.length());
518 break;
519 }
520 // Have not found a template string yet.
521 else
522 {
523 // Add the current char to the template checking
524 // buffer and add it to the temp buffer for holding
525 // the url.
526 for (int i=0; i<8; i++)
527 {
528 cbuf[i] = cbuf[i+1];
529 }
530 cbuf[8] = ch;
531 uriBuffer.append(ch);
532
533 // If we come upon a quote the url must have been to
534 // an external site. So write the url and return.
535 if (ch == '\"')
536 {
537 out.write(uriBuffer.toString(), 0, uriBuffer.length());
538 break;
539 }
540
541 // Check to see if cbuf contains "template/".
542 if (cbuf[0] == 't' &&
543 cbuf[1] == 'e' &&
544 cbuf[2] == 'm' &&
545 cbuf[3] == 'p' &&
546 cbuf[4] == 'l' &&
547 cbuf[5] == 'a' &&
548 cbuf[6] == 't' &&
549 cbuf[7] == 'e' &&
550 cbuf[8] == '/' )
551 {
552 armed = true;
553 // Do not add "/template/" to the temp url buffer.
554 uriBuffer.setLength(uriBuffer.length()-10);
555 }
556 }
557 }
558 }
559 }
This page was automatically generated by Maven