View Javadoc
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