1 16 package org.apache.cocoon.bean; 17 18 import java.io.File ; 19 import java.io.FileInputStream ; 20 import java.io.FileNotFoundException ; 21 import java.io.IOException ; 22 import java.io.OutputStream ; 23 import java.util.ArrayList ; 24 import java.util.Arrays ; 25 import java.util.Collection ; 26 import java.util.HashMap ; 27 import java.util.Iterator ; 28 import java.util.List ; 29 import java.util.Map ; 30 import java.util.TreeMap ; 31 32 import org.apache.avalon.excalibur.component.ExcaliburComponentManager; 33 import org.apache.avalon.excalibur.logger.LogKitLoggerManager; 34 35 import org.apache.avalon.framework.configuration.Configuration; 36 import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder; 37 import org.apache.avalon.framework.container.ContainerUtil; 38 import org.apache.avalon.framework.context.DefaultContext; 39 import org.apache.avalon.framework.logger.LogKitLogger; 40 import org.apache.avalon.framework.logger.Logger; 41 42 import org.apache.cocoon.Cocoon; 43 import org.apache.cocoon.CocoonAccess; 44 import org.apache.cocoon.Constants; 45 import org.apache.cocoon.ProcessingException; 46 import org.apache.cocoon.components.CocoonComponentManager; 47 import org.apache.cocoon.components.pipeline.ProcessingPipeline; 48 import org.apache.cocoon.environment.Environment; 49 import org.apache.cocoon.environment.commandline.CommandLineContext; 50 import org.apache.cocoon.environment.commandline.FileSavingEnvironment; 51 import org.apache.cocoon.environment.commandline.LinkSamplingEnvironment; 52 import org.apache.cocoon.util.ClassUtils; 53 import org.apache.cocoon.util.IOUtils; 54 import org.apache.cocoon.util.NetUtils; 55 import org.apache.cocoon.xml.ContentHandlerWrapper; 56 import org.apache.cocoon.xml.XMLConsumer; 57 import org.apache.commons.lang.SystemUtils; 58 59 import org.apache.log.Hierarchy; 60 import org.apache.log.Priority; 61 import org.xml.sax.ContentHandler ; 62 63 73 public class CocoonWrapper { 74 75 protected static final String DEFAULT_USER_AGENT = Constants.COMPLETE_NAME; 76 protected static final String DEFAULT_ACCEPT = "text/html, */*"; 77 78 private String contextDir = Constants.DEFAULT_CONTEXT_DIR; 80 private String configFile = null; 81 82 private String workDir = Constants.DEFAULT_WORK_DIR; 83 private String logKit = null; 84 protected String logger = null; 85 protected String logLevel = "ERROR"; 86 private String userAgent = DEFAULT_USER_AGENT; 87 private String accept = DEFAULT_ACCEPT; 88 private List classList = new ArrayList (); 89 90 private File context; 92 private File work; 93 private File conf; 94 95 private CommandLineContext cliContext; 97 private LogKitLoggerManager logManager; 98 private Cocoon cocoon; 99 protected Logger log; 100 private HashMap empty = new HashMap (); 101 102 private boolean initialized = false; 103 private boolean useExistingCocoon = false; 104 105 public void initialize() throws Exception { 109 111 final Hierarchy hierarchy = new Hierarchy(); 114 115 final Priority priority = Priority.getPriorityForName(logLevel); 116 hierarchy.setDefaultPriority(priority); 117 118 this.log = new LogKitLogger(hierarchy.getLoggerFor("")); 120 121 try { 122 124 this.context = getDir(this.contextDir, "context"); 127 this.work = getDir(workDir, "working"); 128 DefaultContext appContext = new DefaultContext(); 129 appContext.put(Constants.CONTEXT_WORK_DIR, work); 130 131 this.logManager = new LogKitLoggerManager(hierarchy); 132 this.logManager.enableLogging(log); 133 134 if (this.logKit != null) { 135 final FileInputStream fis = new FileInputStream (logKit); 136 final DefaultConfigurationBuilder builder = 137 new DefaultConfigurationBuilder(); 138 final Configuration logKitConf = builder.build(fis); 139 final DefaultContext subcontext = new DefaultContext(appContext); 140 subcontext.put("context-root", this.contextDir); 141 subcontext.put("context-work", this.workDir); 142 this.logManager.contextualize(subcontext); 143 this.logManager.configure(logKitConf); 144 if (logger != null) { 145 log = this.logManager.getLoggerForCategory(logger); 146 } else { 147 log = this.logManager.getLoggerForCategory("cocoon"); 148 } 149 } 150 151 this.conf = getConfigurationFile(this.context, this.configFile); 152 153 cliContext = new CommandLineContext(contextDir); 154 cliContext.enableLogging(log); 155 156 appContext.put(Constants.CONTEXT_ENVIRONMENT_CONTEXT, cliContext); 157 appContext.put(Constants.CONTEXT_CLASS_LOADER, 158 CocoonWrapper.class.getClassLoader()); 159 appContext.put(Constants.CONTEXT_CLASSPATH, getClassPath(contextDir)); 160 appContext.put(Constants.CONTEXT_UPLOAD_DIR, contextDir + "upload-dir"); 161 File cacheDir = getDir(workDir + File.separator + "cache-dir", "cache"); 162 appContext.put(Constants.CONTEXT_CACHE_DIR, cacheDir); 163 appContext.put(Constants.CONTEXT_CONFIG_URL, conf.toURL()); 164 appContext.put(Constants.CONTEXT_DEFAULT_ENCODING, "ISO-8859-1"); 165 166 loadClasses(classList); 167 168 if (this.useExistingCocoon) { 169 cocoon = getCocoon(); 170 } 171 if (cocoon == null) { 172 cocoon = new Cocoon(); 173 ContainerUtil.enableLogging(cocoon, log); 174 ContainerUtil.contextualize(cocoon, appContext); 175 cocoon.setLoggerManager(logManager); 176 ContainerUtil.initialize(cocoon); 177 } 178 } catch (Exception e) { 179 log.fatalError("Exception caught", e); 180 throw e; 181 } 182 initialized = true; 183 } 184 185 private Cocoon getCocoon() { 186 return new CocoonAccess() { 187 final Cocoon instance() { 188 return super.getCocoon(); 189 } 190 }.instance(); 191 } 192 193 protected ExcaliburComponentManager getComponentManager() { 194 return cocoon.getComponentManager(); 195 } 196 197 204 private File getConfigurationFile(File dir, String configFile) 205 throws IOException { 206 File conf; 207 if (configFile == null) { 208 conf = tryConfigurationFile(dir + File.separator + Constants.DEFAULT_CONF_FILE); 209 if (conf == null) { 210 conf = tryConfigurationFile(dir 211 + File.separator 212 + "WEB-INF" 213 + File.separator 214 + Constants.DEFAULT_CONF_FILE); 215 } 216 if (conf == null) { 217 conf = tryConfigurationFile( 218 SystemUtils.USER_DIR 219 + File.separator 220 + Constants.DEFAULT_CONF_FILE); 221 } 222 if (conf == null) { 223 conf = tryConfigurationFile( 224 "/usr/local/etc/" + Constants.DEFAULT_CONF_FILE); 225 } 226 } else { 227 conf = new File (configFile); 228 if (!conf.exists()) { 229 conf = new File (dir, configFile); 230 } 231 } 232 if (conf == null) { 233 log.error("Could not find the configuration file."); 234 throw new FileNotFoundException ("The configuration file could not be found."); 235 } 236 return conf; 237 } 238 239 242 private File tryConfigurationFile(String filename) { 243 if (log.isDebugEnabled()) { 244 log.debug("Trying configuration file at: " + filename); 245 } 246 File conf = new File (filename); 247 if (conf.canRead()) { 248 return conf; 249 } else { 250 return null; 251 } 252 } 253 254 262 private File getDir(String dir, String type) throws IOException { 263 if (log.isDebugEnabled()) { 264 log.debug("Getting handle to " + type + " directory '" + dir + "'"); 265 } 266 File d = new File (dir); 267 268 if (!d.exists()) { 269 if (!d.mkdirs()) { 270 throw new IOException ( 271 "Error creating " + type + " directory '" + d + "'"); 272 } 273 } 274 275 if (!d.isDirectory()) { 276 throw new IOException ("'" + d + "' is not a directory."); 277 } 278 279 if (!d.canRead()) { 280 throw new IOException ( 281 "Directory '" + d + "' is not readable"); 282 } 283 284 if ("working".equals( type ) && !d.canWrite()) { 285 throw new IOException ( 286 "Directory '" + d + "' is not writable"); 287 } 288 289 return d; 290 } 291 292 protected void finalize() throws Throwable { 293 dispose(); 294 super.finalize(); 295 } 296 297 protected void loadClasses(List classList) { 298 if (classList != null) { 299 for (Iterator i = classList.iterator(); i.hasNext();) { 300 String className = (String ) i.next(); 301 try { 302 if (log.isDebugEnabled()) { 303 log.debug("Trying to load class: " + className); 304 } 305 ClassUtils.loadClass(className).newInstance(); 306 } catch (Exception e) { 307 if (log.isWarnEnabled()) { 308 log.warn("Could not force-load class: " + className, e); 309 } 310 } 312 } 313 } 314 } 315 316 320 324 public void setLogKit(String logKit) { 325 this.logKit = logKit; 326 } 327 328 332 public void setLogLevel(String logLevel) { 333 this.logLevel = logLevel; 334 } 335 336 340 public void setLogger(String logger) { 341 this.logger = logger; 342 } 343 344 public String getLoggerName() { 345 return logger; 346 } 347 348 352 public void setContextDir(String contextDir) { 353 this.contextDir = contextDir; 354 } 355 356 360 public void setWorkDir(String workDir) { 361 this.workDir = workDir; 362 } 363 364 public void setConfigFile(String configFile) { 365 this.configFile = configFile; 366 } 367 368 public void setAgentOptions(String userAgent) { 369 this.userAgent = userAgent; 370 } 371 372 public void setAcceptOptions(String accept) { 373 this.accept = accept; 374 } 375 376 public void addLoadedClass(String className) { 377 this.classList.add(className); 378 } 379 380 public void addLoadedClasses(List classList) { 381 this.classList.addAll(classList); 382 } 383 384 public void setUseExistingCocoon(boolean useExistingCocoon) { 385 this.useExistingCocoon = useExistingCocoon; 386 } 387 388 394 public void processURI(String uri, OutputStream outputStream) 395 throws Exception { 396 397 if (!initialized) { 398 initialize(); 399 } 400 log.info("Processing URI: " + uri); 401 402 final TreeMap parameters = new TreeMap (); 404 final String deparameterizedURI = 405 NetUtils.deparameterize(uri, parameters); 406 parameters.put("user-agent", userAgent); 407 parameters.put("accept", accept); 408 409 int status = 410 getPage(deparameterizedURI, 0L, parameters, null, null, outputStream); 411 412 if (status >= 400) { 413 throw new ProcessingException("Resource not found: " + status); 414 } 415 } 416 417 424 public void processURI(String uri, ContentHandler handler) 425 throws Exception { 426 427 if (!initialized) { 428 initialize(); 429 } 430 log.info("Processing URI: " + uri); 431 432 final TreeMap parameters = new TreeMap (); 434 final String deparameterizedURI = 435 NetUtils.deparameterize(uri, parameters); 436 parameters.put("user-agent", userAgent); 437 parameters.put("accept", accept); 438 439 int status = 440 getPage(deparameterizedURI, 0L, parameters, null, null, handler); 441 442 if (status >= 400) { 443 throw new ProcessingException("Resource not found: " + status); 444 } 445 } 446 447 public void dispose() { 448 if (this.initialized) { 449 this.initialized = false; 450 ContainerUtil.dispose(this.cocoon); 451 this.cocoon = null; 452 this.logManager.dispose(); 453 if (log.isDebugEnabled()) { 454 log.debug("Disposed"); 455 } 456 } 457 } 458 459 467 protected Collection getLinks(String deparameterizedURI, Map parameters) 468 throws Exception { 469 470 parameters.put("user-agent", userAgent); 471 parameters.put("accept", accept); 472 473 LinkSamplingEnvironment env = 474 new LinkSamplingEnvironment(deparameterizedURI, context, null, 475 parameters, cliContext, log); 476 processLenient(env); 477 return env.getLinks(); 478 } 479 480 490 protected int getPage(String deparameterizedURI, 491 long lastModified, 492 Map parameters, 493 Map links, 494 List gatheredLinks, 495 OutputStream stream) 496 throws Exception { 497 498 parameters.put("user-agent", userAgent); 499 parameters.put("accept", accept); 500 501 FileSavingEnvironment env = 502 new FileSavingEnvironment(deparameterizedURI, lastModified, context, 503 null, parameters, links, 504 gatheredLinks, cliContext, stream, log); 505 506 cocoon.process(env); 508 509 int status = env.getStatus(); 511 if (!env.isModified()) { 512 status = -1; 513 } 514 return status; 515 } 516 517 527 protected int getPage(String deparameterizedURI, 528 long lastModified, 529 Map parameters, 530 Map links, 531 List gatheredLinks, 532 ContentHandler handler) 533 throws Exception { 534 535 parameters.put("user-agent", userAgent); 536 parameters.put("accept", accept); 537 538 FileSavingEnvironment env = 539 new FileSavingEnvironment(deparameterizedURI, lastModified, context, 540 null, parameters, links, 541 gatheredLinks, cliContext, null, log); 542 543 XMLConsumer consumer = new ContentHandlerWrapper(handler); 544 ProcessingPipeline pipeline = cocoon.buildPipeline(env); 545 CocoonComponentManager.enterEnvironment(env, cocoon.getComponentManager(), cocoon); 546 try { 547 pipeline.prepareInternal(env); 548 pipeline.process(env, consumer); 549 } finally { 550 CocoonComponentManager.leaveEnvironment(); 551 } 552 553 int status = env.getStatus(); 555 if (!env.isModified()) { 556 status = -1; 557 } 558 return status; 559 } 560 561 562 static class NullOutputStream extends OutputStream { 563 public void write(int b) throws IOException { 564 } 565 public void write(byte b[]) throws IOException { 566 } 567 public void write(byte b[], int off, int len) throws IOException { 568 } 569 } 570 571 579 protected String getType(String deparameterizedURI, Map parameters) 580 throws Exception { 581 582 parameters.put("user-agent", userAgent); 583 parameters.put("accept", accept); 584 585 FileSavingEnvironment env = 586 new FileSavingEnvironment(deparameterizedURI, context, null, 587 parameters, empty, null, cliContext, 588 new NullOutputStream(), log); 589 processLenient(env); 590 return env.getContentType(); 591 } 592 593 600 private boolean processLenient(Environment env) throws Exception { 601 try { 602 this.cocoon.process(env); 603 } catch (ProcessingException pe) { 604 return false; 605 } 606 return true; 607 } 608 609 622 protected String getClassPath(final String context) { 623 StringBuffer buildClassPath = new StringBuffer (); 624 625 String classDir = context + "/WEB-INF/classes"; 626 buildClassPath.append(classDir); 627 628 File root = new File (context + "/WEB-INF/lib"); 629 if (root.isDirectory()) { 630 File [] libraries = root.listFiles(); 631 Arrays.sort(libraries); 632 for (int i = 0; i < libraries.length; i++) { 633 if (libraries[i].getAbsolutePath().endsWith(".jar")) { 634 buildClassPath.append(File.pathSeparatorChar).append( 635 IOUtils.getFullFilename(libraries[i])); 636 } 637 } 638 } 639 640 buildClassPath.append(File.pathSeparatorChar).append(SystemUtils.JAVA_CLASS_PATH); 641 642 646 if (log.isDebugEnabled()) { 647 log.debug("Context classpath: " + buildClassPath); 648 } 649 return buildClassPath.toString(); 650 } 651 } 652 | Popular Tags |