1 import com.teamkonzept.lib.*; 2 import com.teamkonzept.web.*; 3 import com.teamkonzept.field.*; 4 import com.teamkonzept.db.*; 5 import com.teamkonzept.webman.*; 6 import com.teamkonzept.webman.db.*; 7 import de.webman.generator.*; 8 import com.teamkonzept.webman.mainint.db.MediaManager; 9 import com.teamkonzept.field.db.queries.*; 10 import java.lang.reflect.*; 11 12 import org.apache.log4j.Category; 14 import org.apache.log4j.WriterAppender; 15 import org.apache.log4j.xml.DOMConfigurator; 16 import org.apache.log4j.SimpleLayout; 17 18 import de.webman.util.log4j.WebmanPatternLayout; 19 import de.webman.util.log4j.WebmanCategory; 20 import java.io.*; 21 import java.util.*; 22 import java.sql.*; 23 import java.text.*; 24 import java.net.*; 25 26 35 public class WebManGen 36 { 37 38 39 static TKWMConverterSetup converterSetup = new TKWMConverterSetup(); 40 41 44 private static final short SECONDS_DIVIDER = 1000; 45 46 49 private static final short MINUTES_DIVIDER = 60; 50 51 54 private static final short DISPLAY_MODULATOR = 10; 55 56 58 59 private static String rootPath; 60 61 private static String templatePath; 62 63 private static int port = -1; 64 65 private static int user = WebmanCategory.ALL; 66 67 private static Socket socket = null; 68 69 private static GeneratorContext context; 70 71 private static String gendir = null; 72 73 private static boolean ignoreWorkflow = false; 74 75 private static boolean foundSubtree = false; 76 77 private static Integer instanceId = null; 79 80 private static final String APPENDER_NAME = "PROCESS"; 81 82 85 private static WebmanCategory logging = null; 86 87 private static Category root = Category.getRoot(); 88 89 90 private static ByteArrayOutputStream bout; 91 92 95 private static KeepAliveThread keepAlive = null; 96 97 private static void analyzeArgs(String [] args) 98 { 99 for (int i = 0; i < args.length; i++) 100 { 101 logging.info("*** arg["+i+"] = '"+args[i]+"'"); 102 } 103 rootPath = args[0]; 104 templatePath = rootPath + File.separator + TemplateUtils.getGenerationDirectory(); 105 for (int i=1; i<args.length; ++i) 106 { 107 if(args[i].equals("ignoreWorkflow")) { 108 ignoreWorkflow = true; 109 continue; 110 } 111 112 String cmd = null; 113 String par = null; 114 115 String arg = args[i]; 116 int pos = arg.indexOf ("="); 117 if ((pos > 0) && (pos < arg.length()-1)) 118 { 119 cmd = arg.substring (0,pos).trim(); 120 par = arg.substring (pos+1,arg.length()).trim(); 121 } 122 123 if ((cmd != null) && (par != null)) 124 { 125 if (cmd.equals ("refs")) { 126 context.siteNodes.setIncludeSubtreePath( 127 par.lastIndexOf("/") == par.length()-1 ? par : par+"/"); 128 logging.info("include refs for subtreePath = "+context.siteNodes.getIncludeSubtreePath()); 129 foundSubtree = true; 130 } else if (cmd.equals ("id")) { 131 context.siteNodes.setSubtreeId (Integer.parseInt (par)); 132 logging.info("subtreeId = "+context.siteNodes.getSubtreeId()); 133 foundSubtree = true; 134 } else if (cmd.equals ("path")) { 135 context.siteNodes.setSubtreePath( 136 par.lastIndexOf("/") == par.length()-1 ? par : par+"/"); 137 logging.info("subtreePath = "+context.siteNodes.getSubtreePath()); 138 foundSubtree = true; 139 } else if (cmd.equals ("port")) { 140 port = Integer.parseInt(par); 141 logging.debug("port = "+ port); 142 } 143 else if (cmd.equals("user")) 144 { 145 user = Integer.parseInt(par); 146 logging.info("user= " + user); 147 } 148 else if (cmd.equals("instance")) 149 { 150 instanceId = new Integer (0); logging.debug("instance= " + instanceId); 152 } 153 else if (cmd.equals ("gendir")) { 154 gendir = par; 155 logging.info("Output Directory = "+ gendir, WebmanCategory.ALL); 156 } 157 } 158 } 159 160 } 161 162 167 private static PrintStream redirectOut() throws IOException 168 { 169 bout = new ByteArrayOutputStream(); 170 PrintStream ps = new PrintStream(bout); 171 WriterAppender app = (WriterAppender)root.getAppender(APPENDER_NAME); 173 app.setWriter(new OutputStreamWriter(ps)); 175 return ps; 176 } 177 178 183 private static void redirectAppender(int port, PrintStream oldOut, PrintStream oldErr) throws IOException 184 { 185 WriterAppender app = (WriterAppender)root.getAppender(APPENDER_NAME); 186 187 if (port != -1) 188 { 189 socket = new Socket(InetAddress.getLocalHost(), port); 191 PrintStream stream = new PrintStream(socket.getOutputStream(), true); 192 app.setWriter(new OutputStreamWriter(stream)); 193 System.setErr(stream); 194 System.setOut(stream); 195 196 keepAlive = new KeepAliveThread(logging); 197 Thread t = new Thread (keepAlive); 198 199 201 t.setDaemon(true); 202 t.start(); 203 } 204 else 205 { 206 System.setErr(oldErr); 207 System.setOut(oldOut); 208 app.setWriter(new OutputStreamWriter(oldOut)); 209 } 210 } 211 212 public static void main( String [] args ) throws Exception  213 { 214 if (args.length > 0) 216 { 217 de.webman.util.log4j.WebmanRollingFileAppender.setDocRoot(args[0]); 218 } 219 DOMConfigurator.configure(WebManGen.class.getResource("/generatorLog4j.xml")); 220 Category root = Category.getRoot(); 221 223 root.getDefaultHierarchy().setCategoryFactory(WebmanCategory.factory); 224 logging = (WebmanCategory)WebmanCategory.getInstance(WebManGen.class); 225 try 226 { 227 if (args.length == 0) 228 { 229 printUsage(); 230 System.exit(1); 231 } 232 233 PrintStream oldOut = System.out; 236 PrintStream oldErr = System.err; 237 PrintStream ps = redirectOut(); 239 logging.debug( "Alter System.out: " + System.out); 240 logging.debug( "Alter System.err: " + System.err); 241 System.setErr(ps); 242 System.setOut(ps); 243 244 logging.debug( "Neuer System.out: " + System.out); 246 logging.debug( "Neuer System.err: " + System.err); 247 context = GeneratorContext.setup (); 248 249 analyzeArgs(args); 250 if (user == 1) { 252 WebmanCategory.setFilter(user); 253 } 254 long startTime = System.currentTimeMillis(); 255 TKWebmanDBManager.initConnection("/webmandb.ini", false); 256 TKUploadField.initStaticsForUpload(rootPath); 259 registerAllFields(); 260 redirectAppender(port, oldOut, oldErr); 261 if (gendir == null) 262 gendir = rootPath; 263 ps.flush(); 265 PrintStream fake = System.out; 267 fake.println(bout.toString()); 268 ps.close(); 269 logging.info("WebMan Generator started at " + new java.util.Date (), WebmanCategory.ALL ); 270 271 274 if (ignoreWorkflow) { 275 GeneratorContext.setup().setWorkflowIgnored(true); 276 } 277 283 logging.info("started build of site-tree at "+new java.util.Date () ); 284 SiteNode tree = context.siteNodes.buildSiteTree(); 285 286 validateSiteTree(tree); 287 288 logging.info("started generation of site at "+new java.util.Date (), WebmanCategory.ALL ); 289 290 294 if (context.siteNodes.subTreeUnmatched ()) { 295 296 logging.error ("Error: Subtree did not match"); 297 System.exit(1); 298 } 299 300 context.contentForms.prepareFormHash(); 301 context.siteContents.resetCounters(); 302 303 logging.info("building generation tree at "+new java.util.Date () ); 304 TKVector site = tree.createGenNodes(null); 305 306 logging.info("generation tree built at "+new java.util.Date () ); 307 Enumeration genNodes = site.elements(); 308 while( genNodes.hasMoreElements() ) { 309 ((GenNode) genNodes.nextElement()).prepareGeneration(); 310 } 311 logging.info("preparation finished "+new java.util.Date () ); 312 313 317 genNodes = context.siteNodes.getSubtreeNode() != null ? 318 context.siteNodes.getSubtreeNode().getGenNodes().elements() : 319 site.elements(); 320 321 322 323 326 327 328 MediaManager.setDocumentRoot(gendir); 329 MediaManager.setContextPath(getContextPath()); 330 File baseDir = new File( gendir ); 331 logging.info("Basedir is : " + baseDir); 332 PrintStream genFilesLog = openGenFilesLog(); 333 334 while( genNodes.hasMoreElements() ) 335 { 336 GenNode node = (GenNode) genNodes.nextElement(); 337 logging.info("Generating : " + node.getNodeName(), WebmanCategory.ALL); 338 339 node.generate( baseDir, 340 rootPath, 341 "file:"+templatePath+File.separator, 342 genFilesLog, 343 node.getParent() == null 344 ); 345 updateDirectoryFileListing(node, baseDir.getAbsolutePath()); 346 } 347 if (genFilesLog != null) 348 genFilesLog.close(); 349 350 logging.info("finished generation of site at "+new java.util.Date (), WebmanCategory.ALL ); 351 doAfterBurner(); 352 353 TKWebmanDBManager.deregister( false ); 354 355 long endTime = System.currentTimeMillis(); 356 logging.info("site generation took " + millisToString(endTime - startTime), WebmanCategory.ALL); 357 } 358 catch (OutOfMemoryError e) 359 { 360 logging.error("Not enough memory for Webman Generator, please adjust the system configuration", e, WebmanCategory.ALL); 361 System.exit(-1); 362 } 363 catch (Throwable t) 364 { 365 logging.error("Fehler in WebmanGen: " + t.getMessage() , t, WebmanCategory.ALL); 366 System.exit(-1); 368 } 369 finally 370 { 371 if (socket != null) 372 socket.close(); 373 } 374 375 } 376 377 public static void registerAllFields() throws Throwable  378 { 379 380 TKQuery q = TKWebmanDBManager.newQuery(TKDBFormFieldClassGet.class); 382 q.execute(); 383 ResultSet rs = q.fetchResultSet(); 384 385 TKVector classVector = new TKVector(); 387 while(rs.next()){ 388 String rowArray[] = { rs.getString("FIELD_TYPE"), rs.getString("FIELD_CLASS") }; 389 classVector.addElement(rowArray); 390 } 391 392 for (int i=0; i < classVector.size(); i++) { 394 Object element = classVector.elementAt(i); 395 String classInfoArray[] = (String []) element; 396 397 TKFieldRegistry.registry.registerClass(classInfoArray[0], classInfoArray[1]); 398 } 399 400 } 401 402 private static String getContextPath() 403 { 404 try 405 { 406 PropertyManager man = PropertyManager.getPropertyManager("GENERATION"); 407 String gen = man.getValue("CONTEXT", null); 408 return gen; 409 } 410 catch (Throwable t) 411 { 412 return null; 413 } 414 } 415 416 419 private static PropertyManager getAfterburnerstatics() 420 { 421 PropertyManager back; 422 try 423 { 424 back = PropertyManager.getPropertyManager("GENERATION"); 425 back.getValue("AFTERBURNER", null); 426 } 427 catch (Throwable t) 428 { 429 return null; 430 } 431 return back; 432 } 433 434 435 private static void doAfterBurner() 436 { 437 PropertyManager man = getAfterburnerstatics(); 438 if (man == null) 439 return; 440 try 441 { 442 String afterBurner = man.getValue("AFTERBURNER", null); 443 logging.info("Calling Class : " + afterBurner); 444 if (afterBurner != null) 445 { 446 Vector args = new Vector(); 448 int count = 0; 449 boolean abbruch = false; 450 while (!abbruch) 451 { 452 String arg = man.getValue("AFTERBURNER_ARG"+count, null); 453 count++; 454 logging.info("found arg : " + arg); 455 if (arg == null) 456 abbruch = true; 457 else 458 args.addElement(arg); 459 } 460 String [] strArgs = new String [args.size()]; 461 for (int i = 0; i < args.size(); i++) 462 { 463 strArgs[i] = (String )args.elementAt(i); 464 } 465 Class burner = Class.forName(afterBurner); 466 Class [] formalArgs = new Class [1]; 467 formalArgs[0] = strArgs.getClass(); 468 Method methode = burner.getMethod("main", formalArgs); 469 Object [] objArgs = new Object [1]; 470 objArgs[0] = strArgs; 471 Properties props = System.getProperties(); 472 props.put("docroot", rootPath); 473 System.setProperties(props); 474 methode.invoke(null, objArgs); 475 } 476 } 477 catch (java.lang.reflect.InvocationTargetException e) 478 { 479 logging.warn("Got Exception from Afterburner : " + e.getTargetException()); 480 } 481 catch (ClassNotFoundException ce) 482 { 483 logging.info("No Afterburner set !"); 484 } 485 catch (Throwable t) 486 { 487 logging.info("Error during afterburning..." + t); 488 } 489 490 } 491 496 private static PrintStream openGenFilesLog() 497 { 498 File logDir = new File(rootPath, "log"); 499 if (!logDir.exists()) { 500 if (!logDir.mkdir()) { 501 logging.error("Unable to create log-directory " 502 + rootPath + File.separator + "log"); 503 return null; 504 } 505 } 506 else if (logDir.isFile()) { 507 logging.error("Cannot create log-directory " 508 + rootPath + File.separator + "log. " 509 + "A file with the same name already exists."); 510 return null; 511 } 512 513 File logFile = new File(logDir, "genfiles.log"); 514 PrintStream ps = null; 515 try { 516 ps = new PrintStream(new FileOutputStream(logFile)); 517 } 518 catch (IOException e) { 519 logging.error("Unable to open log-file 'genfiles.log' in directory " 520 + logFile.getAbsolutePath() + ". "); 521 return null; 522 } 523 524 return ps; 525 } 526 527 533 private static boolean validateSiteTree(SiteNode tree) 534 { 535 logging.debug("Starting Validation "); 536 SiteTreeValidator validator = new SiteTreeValidator(rootPath, templatePath); 537 validator.apply(tree); 538 logging.debug("Validation finished"); 539 return false; 540 } 541 542 548 private static String millisToString (long duration) 549 { 550 long seconds = duration / SECONDS_DIVIDER; 552 long minutes = seconds / MINUTES_DIVIDER; 553 long hours = minutes / MINUTES_DIVIDER; 554 555 seconds = seconds - minutes * MINUTES_DIVIDER; 556 minutes = minutes - hours * MINUTES_DIVIDER; 557 558 StringBuffer buffer = new StringBuffer (hours > 0 ? String.valueOf(hours) : "00"); 559 buffer.append(':'); 560 561 if (minutes < DISPLAY_MODULATOR) 562 { 563 buffer.append('0'); 564 } 565 566 buffer.append(String.valueOf(minutes)); 567 buffer.append(':'); 568 569 if (seconds < DISPLAY_MODULATOR) 570 { 571 buffer.append('0'); 572 } 573 574 buffer.append(String.valueOf(seconds)); 575 buffer.append(" (hh:mm:ss)"); 576 577 return buffer.toString(); 578 } 579 580 581 private static void printUsage() 582 { 583 PrintStream fake = System.out; 584 fake.println("Usage: WebManGen rootPath " + 585 "[ path='siteNodePath' | id='siteNodeId' | refs='siteNodePath'] " + 586 " [ignoreWorkflow]"); 587 fake.println(""); 588 fake.println("Generates the site of defined by 'rootPath', or a subtree, "); 589 fake.println("if 'ref', path' or 'id' is specified"); 590 fake.println(""); 591 fake.println(" rootPath: Absolute path to the document root of the site."); 592 fake.println(" this is the path where the 'html_templates'"); 593 fake.println(" directory is located.)"); 594 fake.println(""); 595 fake.println("Subtree generation (optional):"); 596 fake.println(""); 597 fake.println("There are two types of subtree generation:"); 598 fake.println("1. The 'fast' one initiated by 'path' or 'id' generates the tree"); 599 fake.println("below the specified site node _without_ resolving references to content"); 600 fake.println("outside of this subtree."); 601 fake.println("2. The 'comlete' one initiated by 'refs' generates the tree"); 602 fake.println("below the specified site node _with_ all references resolved."); 603 fake.println(""); 604 fake.println(" path: Generates only the subtree starting with site node 'path'."); 605 fake.println(" 'path' must be the absolute site node path separated by '/'."); 606 fake.println(" and starting with a '/'. References are not expanded."); 607 fake.println(" example '/Presse/April'"); 608 fake.println(""); 609 fake.println(" id: Generates only the subtree starting with site node 'id'."); 610 fake.println(" 'id' is the database id of the site node. Similar to 'path'."); 611 fake.println(""); 612 fake.println(" user: defines the error messages, depending on the user"); 613 fake.println(""); 614 fake.println(" refs: Generates the subtree including 'refs'."); 615 fake.println(" 'refs' must be the absolute site node path separated by '/'."); 616 fake.println(" and starting with a '/'. References are expanded."); 617 fake.println(" example '/Presse/April'"); 618 fake.println(" port: All output is directed to the specified port"); 619 fake.println(); 620 fake.println(" ignoreWorkflow: Generation ignores the workflow."); 621 fake.println(" This means that, similar to preview mode, always the"); 622 fake.println(" latest version of a content is generated, not only a"); 623 fake.println(" released version."); 624 } 625 626 static private void updateDirectoryFileListing(GenNode node, String baseDir) 631 { 632 if (node.getParent() != null) { 633 DirectoryFileListing list = null; 634 try { 635 list = new DirectoryFileListing(baseDir); 636 } catch (IOException e) { 637 logging.warn("Unable to open log file of generated files in directory " + baseDir); 639 } 640 list.generatedDirectory(node.getNodeName()); 641 try { 642 list.save(true); 643 } catch (IOException e) { 644 logging.warn("Unable to save log file of generated files in directory " + baseDir); 646 } 647 } 648 } 649 650 726 727 } 728 729 732 class KeepAliveThread 733 implements Runnable  734 { 735 private static final int SLEEPTIME = 60 * 1000 * 5; 737 private Category logging = null; 738 private boolean finished = false; 739 740 744 KeepAliveThread(Category _logging) { 745 logging = _logging; 746 } 747 748 void stop() { 749 finished = true; 750 } 751 752 755 public void run() { 756 try { 757 Thread.currentThread().sleep(SLEEPTIME); } 759 catch (InterruptedException ie) { 760 } 762 763 while (!finished) { 764 765 logging.info(ProcessStarter.KEEP_ALIVE_TAG); 766 767 try { 768 Thread.currentThread().sleep(SLEEPTIME); 770 } 771 catch (InterruptedException ie) { 772 } 774 } 775 } 776 } 777
| Popular Tags
|