Source Code Cross Referenced for CocoonServlet.java in  » Content-Management-System » apache-lenya-2.0 » org » apache » cocoon » servlet » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Content Management System » apache lenya 2.0 » org.apache.cocoon.servlet 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Licensed to the Apache Software Foundation (ASF) under one or more
0003:         * contributor license agreements.  See the NOTICE file distributed with
0004:         * this work for additional information regarding copyright ownership.
0005:         * The ASF licenses this file to You under the Apache License, Version 2.0
0006:         * (the "License"); you may not use this file except in compliance with
0007:         * the License.  You may obtain a copy of the License at
0008:         *
0009:         *      http://www.apache.org/licenses/LICENSE-2.0
0010:         *
0011:         * Unless required by applicable law or agreed to in writing, software
0012:         * distributed under the License is distributed on an "AS IS" BASIS,
0013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014:         * See the License for the specific language governing permissions and
0015:         * limitations under the License.
0016:         */
0017:        package org.apache.cocoon.servlet;
0018:
0019:        import org.apache.avalon.excalibur.logger.Log4JLoggerManager;
0020:        import org.apache.avalon.excalibur.logger.LogKitLoggerManager;
0021:        import org.apache.avalon.excalibur.logger.LoggerManager;
0022:        import org.apache.avalon.framework.activity.Disposable;
0023:        import org.apache.avalon.framework.activity.Initializable;
0024:        import org.apache.avalon.framework.component.ComponentManager;
0025:        import org.apache.avalon.framework.configuration.Configurable;
0026:        import org.apache.avalon.framework.configuration.Configuration;
0027:        import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
0028:        import org.apache.avalon.framework.container.ContainerUtil;
0029:        import org.apache.avalon.framework.context.Contextualizable;
0030:        import org.apache.avalon.framework.context.DefaultContext;
0031:        import org.apache.avalon.framework.logger.LogEnabled;
0032:        import org.apache.avalon.framework.logger.LogKitLogger;
0033:        import org.apache.avalon.framework.logger.Logger;
0034:
0035:        import org.apache.cocoon.Cocoon;
0036:        import org.apache.cocoon.ConnectionResetException;
0037:        import org.apache.cocoon.Constants;
0038:        import org.apache.cocoon.ResourceNotFoundException;
0039:        import org.apache.cocoon.components.notification.DefaultNotifyingBuilder;
0040:        import org.apache.cocoon.components.notification.Notifier;
0041:        import org.apache.cocoon.components.notification.Notifying;
0042:        import org.apache.cocoon.environment.Environment;
0043:        import org.apache.cocoon.environment.http.HttpContext;
0044:        import org.apache.cocoon.environment.http.HttpEnvironment;
0045:        import org.apache.cocoon.servlet.multipart.MultipartHttpServletRequest;
0046:        import org.apache.cocoon.servlet.multipart.RequestFactory;
0047:        import org.apache.cocoon.util.ClassUtils;
0048:        import org.apache.cocoon.util.Deprecation;
0049:        import org.apache.cocoon.util.IOUtils;
0050:        import org.apache.cocoon.util.StringUtils;
0051:        import org.apache.cocoon.util.log.CocoonLogFormatter;
0052:        import org.apache.cocoon.util.log.Log4JConfigurator;
0053:
0054:        import org.apache.commons.lang.BooleanUtils;
0055:        import org.apache.commons.lang.SystemUtils;
0056:        import org.apache.commons.lang.time.StopWatch;
0057:        import org.apache.excalibur.instrument.InstrumentManager;
0058:        import org.apache.excalibur.instrument.manager.impl.DefaultInstrumentManagerImpl;
0059:        import org.apache.log.ContextMap;
0060:        import org.apache.log.ErrorHandler;
0061:        import org.apache.log.Hierarchy;
0062:        import org.apache.log.Priority;
0063:        import org.apache.log.output.ServletOutputLogTarget;
0064:        import org.apache.log.util.DefaultErrorHandler;
0065:        import org.apache.log4j.LogManager;
0066:
0067:        import javax.servlet.ServletConfig;
0068:        import javax.servlet.ServletContext;
0069:        import javax.servlet.ServletException;
0070:        import javax.servlet.ServletOutputStream;
0071:        import javax.servlet.http.HttpServlet;
0072:        import javax.servlet.http.HttpServletRequest;
0073:        import javax.servlet.http.HttpServletResponse;
0074:        import java.io.File;
0075:        import java.io.FileInputStream;
0076:        import java.io.FileOutputStream;
0077:        import java.io.IOException;
0078:        import java.io.InputStream;
0079:        import java.io.OutputStream;
0080:        import java.lang.reflect.Constructor;
0081:        import java.net.MalformedURLException;
0082:        import java.net.URL;
0083:        import java.util.ArrayList;
0084:        import java.util.Arrays;
0085:        import java.util.HashMap;
0086:        import java.util.Iterator;
0087:        import java.util.List;
0088:        import java.util.StringTokenizer;
0089:        import java.util.jar.Attributes;
0090:        import java.util.jar.Manifest;
0091:
0092:        /**
0093:         * This is the entry point for Cocoon execution as an HTTP Servlet.
0094:         *
0095:         * @author <a href="mailto:pier@apache.org">Pierpaolo Fumagalli</a>
0096:         *         (Apache Software Foundation)
0097:         * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
0098:         * @author <a href="mailto:nicolaken@apache.org">Nicola Ken Barozzi</a>
0099:         * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
0100:         * @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
0101:         * @author <a href="mailto:leo.sutic@inspireinfrastructure.com">Leo Sutic</a>
0102:         * @version $Id: CocoonServlet.java 433543 2006-08-22 06:22:54Z crossley $
0103:         */
0104:        public class CocoonServlet extends HttpServlet {
0105:
0106:            /**
0107:             * Application <code>Context</code> Key for the servlet configuration
0108:             * @since 2.1.3
0109:             */
0110:            public static final String CONTEXT_SERVLET_CONFIG = "servlet-config";
0111:
0112:            // Processing time message
0113:            protected static final String PROCESSED_BY = "Processed by "
0114:                    + Constants.COMPLETE_NAME + " in ";
0115:
0116:            // Used by "show-time"
0117:            static final float SECOND = 1000;
0118:            static final float MINUTE = 60 * SECOND;
0119:            static final float HOUR = 60 * MINUTE;
0120:
0121:            private Logger log;
0122:            private LoggerManager loggerManager;
0123:
0124:            /**
0125:             * The time the cocoon instance was created
0126:             */
0127:            protected long creationTime;
0128:
0129:            /**
0130:             * The <code>Cocoon</code> instance
0131:             */
0132:            protected Cocoon cocoon;
0133:
0134:            /**
0135:             * Holds exception happened during initialization (if any)
0136:             */
0137:            protected Exception exception;
0138:
0139:            /**
0140:             * Avalon application context
0141:             */
0142:            protected DefaultContext appContext = new DefaultContext();
0143:
0144:            /**
0145:             * Default value for {@link #allowReload} parameter (false)
0146:             */
0147:            protected static final boolean ALLOW_RELOAD = false;
0148:
0149:            /**
0150:             * Allow reloading of cocoon by specifying the
0151:             * <code>cocoon-reload=true</code> parameter with a request
0152:             */
0153:            protected boolean allowReload;
0154:
0155:            /**
0156:             * Allow adding processing time to the response
0157:             */
0158:            protected boolean showTime;
0159:
0160:            /**
0161:             * If true, processing time will be added as an HTML comment
0162:             */
0163:            protected boolean hiddenShowTime;
0164:
0165:            /** Flag to enable/disable X-Cocoon-Version header */
0166:            private boolean showCocoonVersion;
0167:
0168:            /**
0169:             * Default value for {@link #enableUploads} parameter (false)
0170:             */
0171:            private static final boolean ENABLE_UPLOADS = false;
0172:            private static final boolean SAVE_UPLOADS_TO_DISK = true;
0173:            private static final int MAX_UPLOAD_SIZE = 10000000; // 10Mb
0174:
0175:            /**
0176:             * Allow processing of upload requests (mime/multipart)
0177:             */
0178:            private boolean enableUploads;
0179:            private boolean autoSaveUploads;
0180:            private boolean allowOverwrite;
0181:            private boolean silentlyRename;
0182:            private int maxUploadSize;
0183:
0184:            private File uploadDir;
0185:            private File workDir;
0186:            private File cacheDir;
0187:            private String containerEncoding;
0188:            private String defaultFormEncoding;
0189:
0190:            protected ServletContext servletContext;
0191:
0192:            /** The classloader that will be set as the context classloader if init-classloader is true */
0193:            protected ClassLoader classLoader = this .getClass()
0194:                    .getClassLoader();
0195:            protected boolean initClassLoader = false;
0196:
0197:            private String parentComponentManagerClass;
0198:            private String parentComponentManagerInitParam;
0199:
0200:            /** The parent ComponentManager, if any. Stored here in order to be able to dispose it in destroy(). */
0201:            private ComponentManager parentComponentManager;
0202:
0203:            protected String forceLoadParameter;
0204:            protected String forceSystemProperty;
0205:
0206:            /**
0207:             * If true or not set, this class will try to catch and handle all Cocoon exceptions.
0208:             * If false, it will rethrow them to the servlet container.
0209:             */
0210:            private boolean manageExceptions;
0211:
0212:            /**
0213:             * Flag to enable avalon excalibur instrumentation of Cocoon.
0214:             */
0215:            private boolean enableInstrumentation;
0216:
0217:            /**
0218:             * The <code>InstrumentManager</code> instance
0219:             */
0220:            private InstrumentManager instrumentManager;
0221:
0222:            /**
0223:             * This is the path to the servlet context (or the result
0224:             * of calling getRealPath('/') on the ServletContext.
0225:             * Note, that this can be null.
0226:             */
0227:            protected String servletContextPath;
0228:
0229:            /**
0230:             * This is the url to the servlet context directory
0231:             */
0232:            protected String servletContextURL;
0233:
0234:            /**
0235:             * The RequestFactory is responsible for wrapping multipart-encoded
0236:             * forms and for handing the file payload of incoming requests
0237:             */
0238:            protected RequestFactory requestFactory;
0239:
0240:            /**
0241:             * Initialize this <code>CocoonServlet</code> instance.  You will
0242:             * notice that I have broken the init into sub methods to make it
0243:             * easier to maintain (BL).  The context is passed to a couple of
0244:             * the subroutines.  This is also because it is better to explicitly
0245:             * pass variables than implicitely.  It is both more maintainable,
0246:             * and more elegant.
0247:             *
0248:             * @param conf The ServletConfig object from the servlet engine.
0249:             *
0250:             * @throws ServletException
0251:             */
0252:            public void init(ServletConfig conf) throws ServletException {
0253:
0254:                super .init(conf);
0255:
0256:                // Check the init-classloader parameter only if it's not already true.
0257:                // This is useful for subclasses of this servlet that override the value
0258:                // initially set by this class (i.e. false).
0259:                if (!this .initClassLoader) {
0260:                    this .initClassLoader = getInitParameterAsBoolean(
0261:                            "init-classloader", false);
0262:                }
0263:
0264:                if (this .initClassLoader) {
0265:                    // Force context classloader so that JAXP can work correctly
0266:                    // (see javax.xml.parsers.FactoryFinder.findClassLoader())
0267:                    try {
0268:                        Thread.currentThread().setContextClassLoader(
0269:                                this .classLoader);
0270:                    } catch (Exception e) {
0271:                        // ignore this
0272:                    }
0273:                }
0274:
0275:                try {
0276:                    // FIXME (VG): We shouldn't have to specify these. Need to override
0277:                    // jaxp implementation of weblogic before initializing logger.
0278:                    // This piece of code is also required in the Cocoon class.
0279:                    String value = System
0280:                            .getProperty("javax.xml.parsers.SAXParserFactory");
0281:                    if (value != null && value.startsWith("weblogic")) {
0282:                        System.setProperty(
0283:                                "javax.xml.parsers.SAXParserFactory",
0284:                                "org.apache.xerces.jaxp.SAXParserFactoryImpl");
0285:                        System
0286:                                .setProperty(
0287:                                        "javax.xml.parsers.DocumentBuilderFactory",
0288:                                        "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl");
0289:                    }
0290:                } catch (Exception e) {
0291:                    // Ignore security exception
0292:                    System.out
0293:                            .println("CocoonServlet: Could not check system properties, got: "
0294:                                    + e);
0295:                }
0296:
0297:                this .servletContext = conf.getServletContext();
0298:                this .appContext.put(Constants.CONTEXT_ENVIRONMENT_CONTEXT,
0299:                        new HttpContext(this .servletContext));
0300:                this .servletContextPath = this .servletContext.getRealPath("/");
0301:
0302:                // first init the work-directory for the logger.
0303:                // this is required if we are running inside a war file!
0304:                final String workDirParam = getInitParameter("work-directory");
0305:                if (workDirParam != null) {
0306:                    if (this .servletContextPath == null) {
0307:                        // No context path : consider work-directory as absolute
0308:                        this .workDir = new File(workDirParam);
0309:                    } else {
0310:                        // Context path exists : is work-directory absolute ?
0311:                        File workDirParamFile = new File(workDirParam);
0312:                        if (workDirParamFile.isAbsolute()) {
0313:                            // Yes : keep it as is
0314:                            this .workDir = workDirParamFile;
0315:                        } else {
0316:                            // No : consider it relative to context path
0317:                            this .workDir = new File(servletContextPath,
0318:                                    workDirParam);
0319:                        }
0320:                    }
0321:                } else {
0322:                    this .workDir = (File) this .servletContext
0323:                            .getAttribute("javax.servlet.context.tempdir");
0324:                    this .workDir = new File(workDir, "cocoon-files");
0325:                }
0326:                this .workDir.mkdirs();
0327:                this .appContext.put(Constants.CONTEXT_WORK_DIR, workDir);
0328:
0329:                String path = this .servletContextPath;
0330:                // these two variables are just for debugging. We can't log at this point
0331:                // as the logger isn't initialized yet.
0332:                String debugPathOne = null, debugPathTwo = null;
0333:                if (path == null) {
0334:                    // Try to figure out the path of the root from that of WEB-INF
0335:                    try {
0336:                        path = this .servletContext.getResource("/WEB-INF")
0337:                                .toString();
0338:                    } catch (MalformedURLException me) {
0339:                        throw new ServletException(
0340:                                "Unable to get resource 'WEB-INF'.", me);
0341:                    }
0342:                    debugPathOne = path;
0343:                    path = path
0344:                            .substring(0, path.length() - "WEB-INF".length());
0345:                    debugPathTwo = path;
0346:                }
0347:                try {
0348:                    if (path.indexOf(':') > 1) {
0349:                        this .servletContextURL = path;
0350:                    } else {
0351:                        this .servletContextURL = new File(path).toURL()
0352:                                .toExternalForm();
0353:                    }
0354:                } catch (MalformedURLException me) {
0355:                    // VG: Novell has absolute file names starting with the
0356:                    // volume name which is easily more then one letter.
0357:                    // Examples: sys:/apache/cocoon or sys:\apache\cocoon
0358:                    try {
0359:                        this .servletContextURL = new File(path).toURL()
0360:                                .toExternalForm();
0361:                    } catch (MalformedURLException ignored) {
0362:                        throw new ServletException(
0363:                                "Unable to determine servlet context URL.", me);
0364:                    }
0365:                }
0366:                try {
0367:                    this .appContext.put("context-root", new URL(
0368:                            this .servletContextURL));
0369:                } catch (MalformedURLException ignore) {
0370:                    // we simply ignore this
0371:                }
0372:
0373:                // Init logger
0374:                initLogger();
0375:
0376:                if (getLogger().isDebugEnabled()) {
0377:                    getLogger().debug(
0378:                            "getRealPath for /: " + this .servletContextPath);
0379:                    if (this .servletContextPath == null) {
0380:                        getLogger().debug(
0381:                                "getResource for /WEB-INF: " + debugPathOne);
0382:                        getLogger().debug("Path for Root: " + debugPathTwo);
0383:                    }
0384:                }
0385:
0386:                this .forceLoadParameter = getInitParameter("load-class", null);
0387:                this .forceSystemProperty = getInitParameter("force-property",
0388:                        null);
0389:
0390:                // Output some debug info
0391:                if (getLogger().isDebugEnabled()) {
0392:                    getLogger().debug(
0393:                            "Servlet Context URL: " + this .servletContextURL);
0394:                    if (workDirParam != null) {
0395:                        getLogger().debug(
0396:                                "Using work-directory " + this .workDir);
0397:                    } else {
0398:                        getLogger().debug(
0399:                                "Using default work-directory " + this .workDir);
0400:                    }
0401:                }
0402:
0403:                final String uploadDirParam = conf
0404:                        .getInitParameter("upload-directory");
0405:                if (uploadDirParam != null) {
0406:                    if (this .servletContextPath == null) {
0407:                        this .uploadDir = new File(uploadDirParam);
0408:                    } else {
0409:                        // Context path exists : is upload-directory absolute ?
0410:                        File uploadDirParamFile = new File(uploadDirParam);
0411:                        if (uploadDirParamFile.isAbsolute()) {
0412:                            // Yes : keep it as is
0413:                            this .uploadDir = uploadDirParamFile;
0414:                        } else {
0415:                            // No : consider it relative to context path
0416:                            this .uploadDir = new File(servletContextPath,
0417:                                    uploadDirParam);
0418:                        }
0419:                    }
0420:                    if (getLogger().isDebugEnabled()) {
0421:                        getLogger().debug(
0422:                                "Using upload-directory " + this .uploadDir);
0423:                    }
0424:                } else {
0425:                    this .uploadDir = new File(workDir, "upload-dir"
0426:                            + File.separator);
0427:                    if (getLogger().isDebugEnabled()) {
0428:                        getLogger().debug(
0429:                                "Using default upload-directory "
0430:                                        + this .uploadDir);
0431:                    }
0432:                }
0433:                this .uploadDir.mkdirs();
0434:                this .appContext.put(Constants.CONTEXT_UPLOAD_DIR,
0435:                        this .uploadDir);
0436:
0437:                this .enableUploads = getInitParameterAsBoolean(
0438:                        "enable-uploads", ENABLE_UPLOADS);
0439:
0440:                this .autoSaveUploads = getInitParameterAsBoolean(
0441:                        "autosave-uploads", SAVE_UPLOADS_TO_DISK);
0442:
0443:                String overwriteParam = getInitParameter("overwrite-uploads",
0444:                        "rename");
0445:                // accepted values are deny|allow|rename - rename is default.
0446:                if ("deny".equalsIgnoreCase(overwriteParam)) {
0447:                    this .allowOverwrite = false;
0448:                    this .silentlyRename = false;
0449:                } else if ("allow".equalsIgnoreCase(overwriteParam)) {
0450:                    this .allowOverwrite = true;
0451:                    this .silentlyRename = false; // ignored in this case
0452:                } else {
0453:                    // either rename is specified or unsupported value - default to rename.
0454:                    this .allowOverwrite = false;
0455:                    this .silentlyRename = true;
0456:                }
0457:
0458:                this .maxUploadSize = getInitParameterAsInteger(
0459:                        "upload-max-size", MAX_UPLOAD_SIZE);
0460:
0461:                String cacheDirParam = conf.getInitParameter("cache-directory");
0462:                if (cacheDirParam != null) {
0463:                    if (this .servletContextPath == null) {
0464:                        this .cacheDir = new File(cacheDirParam);
0465:                    } else {
0466:                        // Context path exists : is cache-directory absolute ?
0467:                        File cacheDirParamFile = new File(cacheDirParam);
0468:                        if (cacheDirParamFile.isAbsolute()) {
0469:                            // Yes : keep it as is
0470:                            this .cacheDir = cacheDirParamFile;
0471:                        } else {
0472:                            // No : consider it relative to context path
0473:                            this .cacheDir = new File(servletContextPath,
0474:                                    cacheDirParam);
0475:                        }
0476:                    }
0477:                    if (getLogger().isDebugEnabled()) {
0478:                        getLogger().debug(
0479:                                "Using cache-directory " + this .cacheDir);
0480:                    }
0481:                } else {
0482:                    this .cacheDir = IOUtils.createFile(workDir, "cache-dir"
0483:                            + File.separator);
0484:                    if (getLogger().isDebugEnabled()) {
0485:                        getLogger().debug(
0486:                                "cache-directory was not set - defaulting to "
0487:                                        + this .cacheDir);
0488:                    }
0489:                }
0490:                this .cacheDir.mkdirs();
0491:                this .appContext.put(Constants.CONTEXT_CACHE_DIR, this .cacheDir);
0492:
0493:                this .appContext.put(Constants.CONTEXT_CONFIG_URL,
0494:                        getConfigFile(conf.getInitParameter("configurations")));
0495:                if (conf.getInitParameter("configurations") == null) {
0496:                    if (getLogger().isDebugEnabled()) {
0497:                        getLogger()
0498:                                .debug(
0499:                                        "configurations was not set - defaulting to... ?");
0500:                    }
0501:                }
0502:
0503:                // get allow reload parameter, default is true
0504:                this .allowReload = getInitParameterAsBoolean("allow-reload",
0505:                        ALLOW_RELOAD);
0506:
0507:                String value = conf.getInitParameter("show-time");
0508:                this .showTime = BooleanUtils.toBoolean(value)
0509:                        || (this .hiddenShowTime = "hide".equals(value));
0510:                if (value == null) {
0511:                    if (getLogger().isDebugEnabled()) {
0512:                        getLogger().debug(
0513:                                "show-time was not set - defaulting to false");
0514:                    }
0515:                }
0516:
0517:                this .showCocoonVersion = getInitParameterAsBoolean(
0518:                        "show-cocoon-version", true);
0519:
0520:                parentComponentManagerClass = getInitParameter(
0521:                        "parent-component-manager", null);
0522:                if (parentComponentManagerClass != null) {
0523:                    int dividerPos = parentComponentManagerClass.indexOf('/');
0524:                    if (dividerPos != -1) {
0525:                        parentComponentManagerInitParam = parentComponentManagerClass
0526:                                .substring(dividerPos + 1);
0527:                        parentComponentManagerClass = parentComponentManagerClass
0528:                                .substring(0, dividerPos);
0529:                    }
0530:                }
0531:
0532:                this .containerEncoding = getInitParameter("container-encoding",
0533:                        "ISO-8859-1");
0534:                this .defaultFormEncoding = getInitParameter("form-encoding",
0535:                        "ISO-8859-1");
0536:                this .appContext.put(Constants.CONTEXT_DEFAULT_ENCODING,
0537:                        this .defaultFormEncoding);
0538:
0539:                this .manageExceptions = getInitParameterAsBoolean(
0540:                        "manage-exceptions", true);
0541:
0542:                this .enableInstrumentation = getInitParameterAsBoolean(
0543:                        "enable-instrumentation", false);
0544:
0545:                this .requestFactory = new RequestFactory(this .autoSaveUploads,
0546:                        this .uploadDir, this .allowOverwrite,
0547:                        this .silentlyRename, this .maxUploadSize,
0548:                        this .containerEncoding);
0549:                // Add the servlet configuration
0550:                this .appContext.put(CONTEXT_SERVLET_CONFIG, conf);
0551:                this .createCocoon();
0552:            }
0553:
0554:            /**
0555:             * Dispose Cocoon when servlet is destroyed
0556:             */
0557:            public void destroy() {
0558:                if (this .initClassLoader) {
0559:                    try {
0560:                        Thread.currentThread().setContextClassLoader(
0561:                                this .classLoader);
0562:                    } catch (Exception e) {
0563:                        // Ignored
0564:                    }
0565:                }
0566:
0567:                if (this .cocoon != null) {
0568:                    if (getLogger().isDebugEnabled()) {
0569:                        getLogger().debug(
0570:                                "Servlet destroyed - disposing Cocoon");
0571:                    }
0572:                    disposeCocoon();
0573:                }
0574:
0575:                if (this .instrumentManager instanceof  Disposable) {
0576:                    ((Disposable) this .instrumentManager).dispose();
0577:                }
0578:
0579:                if (this .parentComponentManager != null
0580:                        && this .parentComponentManager instanceof  Disposable) {
0581:                    ((Disposable) this .parentComponentManager).dispose();
0582:                }
0583:
0584:                this .appContext = null;
0585:                this .classLoader = null;
0586:                this .log = null;
0587:                this .loggerManager = null;
0588:            }
0589:
0590:            /**
0591:             * Adds an URL to the classloader. Does nothing here, but is
0592:             * overriden in {@link ParanoidCocoonServlet}.
0593:             */
0594:            protected void addClassLoaderURL(URL URL) {
0595:                // Nothing
0596:            }
0597:
0598:            /**
0599:             * Adds a directory to the classloader. Does nothing here, but is
0600:             * overriden in {@link ParanoidCocoonServlet}.
0601:             */
0602:            protected void addClassLoaderDirectory(String dir) {
0603:                // Nothing
0604:            }
0605:
0606:            /**
0607:             * This builds the important ClassPath used by this Servlet.  It
0608:             * does so in a Servlet Engine neutral way.  It uses the
0609:             * <code>ServletContext</code>'s <code>getRealPath</code> method
0610:             * to get the Servlet 2.2 identified classes and lib directories.
0611:             * It iterates in alphabetical order through every file in the
0612:             * lib directory and adds it to the classpath.
0613:             *
0614:             * Also, we add the files to the ClassLoader for the Cocoon system.
0615:             * In order to protect ourselves from skitzofrantic classloaders,
0616:             * we need to work with a known one.
0617:             *
0618:             * We need to get this to work properly when Cocoon is in a war.
0619:             *
0620:             * @throws ServletException
0621:             */
0622:            protected String getClassPath() throws ServletException {
0623:                StringBuffer buildClassPath = new StringBuffer();
0624:
0625:                File root = null;
0626:                if (servletContextPath != null) {
0627:                    // Old method.  There *MUST* be a better method than this...
0628:
0629:                    String classDir = this .servletContext
0630:                            .getRealPath("/WEB-INF/classes");
0631:                    String libDir = this .servletContext
0632:                            .getRealPath("/WEB-INF/lib");
0633:
0634:                    if (libDir != null) {
0635:                        root = new File(libDir);
0636:                    }
0637:
0638:                    if (classDir != null) {
0639:                        buildClassPath.append(classDir);
0640:
0641:                        addClassLoaderDirectory(classDir);
0642:                    }
0643:                } else {
0644:                    // New(ish) method for war'd deployments
0645:                    URL classDirURL = null;
0646:                    URL libDirURL = null;
0647:
0648:                    try {
0649:                        classDirURL = this .servletContext
0650:                                .getResource("/WEB-INF/classes");
0651:                    } catch (MalformedURLException me) {
0652:                        if (getLogger().isWarnEnabled()) {
0653:                            this 
0654:                                    .getLogger()
0655:                                    .warn(
0656:                                            "Unable to add WEB-INF/classes to the classpath",
0657:                                            me);
0658:                        }
0659:                    }
0660:
0661:                    try {
0662:                        libDirURL = this .servletContext
0663:                                .getResource("/WEB-INF/lib");
0664:                    } catch (MalformedURLException me) {
0665:                        if (getLogger().isWarnEnabled()) {
0666:                            this 
0667:                                    .getLogger()
0668:                                    .warn(
0669:                                            "Unable to add WEB-INF/lib to the classpath",
0670:                                            me);
0671:                        }
0672:                    }
0673:
0674:                    if (libDirURL != null
0675:                            && libDirURL.toExternalForm().startsWith("file:")) {
0676:                        root = new File(libDirURL.toExternalForm().substring(
0677:                                "file:".length()));
0678:                    }
0679:
0680:                    if (classDirURL != null) {
0681:                        buildClassPath.append(classDirURL.toExternalForm());
0682:
0683:                        addClassLoaderURL(classDirURL);
0684:                    }
0685:                }
0686:
0687:                // Unable to find lib directory. Going the hard way.
0688:                if (root == null) {
0689:                    root = extractLibraries();
0690:                }
0691:
0692:                if (root != null && root.isDirectory()) {
0693:                    File[] libraries = root.listFiles();
0694:                    Arrays.sort(libraries);
0695:                    for (int i = 0; i < libraries.length; i++) {
0696:                        String fullName = IOUtils.getFullFilename(libraries[i]);
0697:                        buildClassPath.append(File.pathSeparatorChar).append(
0698:                                fullName);
0699:
0700:                        addClassLoaderDirectory(fullName);
0701:                    }
0702:                }
0703:
0704:                buildClassPath.append(File.pathSeparatorChar).append(
0705:                        SystemUtils.JAVA_CLASS_PATH);
0706:
0707:                buildClassPath.append(File.pathSeparatorChar).append(
0708:                        getExtraClassPath());
0709:                return buildClassPath.toString();
0710:            }
0711:
0712:            private File extractLibraries() {
0713:                try {
0714:                    URL manifestURL = this .servletContext
0715:                            .getResource("/META-INF/MANIFEST.MF");
0716:                    if (manifestURL == null) {
0717:                        this .getLogger().fatalError("Unable to get Manifest");
0718:                        return null;
0719:                    }
0720:
0721:                    Manifest mf = new Manifest(manifestURL.openStream());
0722:                    Attributes attr = mf.getMainAttributes();
0723:                    String libValue = attr.getValue("Cocoon-Libs");
0724:                    if (libValue == null) {
0725:                        this 
0726:                                .getLogger()
0727:                                .fatalError(
0728:                                        "Unable to get 'Cocoon-Libs' attribute from the Manifest");
0729:                        return null;
0730:                    }
0731:
0732:                    List libList = new ArrayList();
0733:                    for (StringTokenizer st = new StringTokenizer(libValue, " "); st
0734:                            .hasMoreTokens();) {
0735:                        libList.add(st.nextToken());
0736:                    }
0737:
0738:                    File root = new File(this .workDir, "lib");
0739:                    root.mkdirs();
0740:
0741:                    File[] oldLibs = root.listFiles();
0742:                    for (int i = 0; i < oldLibs.length; i++) {
0743:                        String oldLib = oldLibs[i].getName();
0744:                        if (!libList.contains(oldLib)) {
0745:                            this .getLogger().debug(
0746:                                    "Removing old library " + oldLibs[i]);
0747:                            oldLibs[i].delete();
0748:                        }
0749:                    }
0750:
0751:                    this .getLogger().warn("Extracting libraries into " + root);
0752:                    byte[] buffer = new byte[65536];
0753:                    for (Iterator i = libList.iterator(); i.hasNext();) {
0754:                        String libName = (String) i.next();
0755:
0756:                        long lastModified = -1;
0757:                        try {
0758:                            lastModified = Long.parseLong(attr
0759:                                    .getValue("Cocoon-Lib-"
0760:                                            + libName.replace('.', '_')));
0761:                        } catch (Exception e) {
0762:                            this .getLogger().debug(
0763:                                    "Failed to parse lastModified: "
0764:                                            + attr
0765:                                                    .getValue("Cocoon-Lib-"
0766:                                                            + libName.replace(
0767:                                                                    '.', '_')));
0768:                        }
0769:
0770:                        File lib = new File(root, libName);
0771:                        if (lib.exists() && lib.lastModified() != lastModified) {
0772:                            this .getLogger().debug(
0773:                                    "Removing modified library " + lib);
0774:                            lib.delete();
0775:                        }
0776:
0777:                        InputStream is = null;
0778:                        OutputStream os = null;
0779:                        try {
0780:                            is = this .servletContext
0781:                                    .getResourceAsStream("/WEB-INF/lib/"
0782:                                            + libName);
0783:                            if (is != null) {
0784:                                this .getLogger().debug("Extracting " + libName);
0785:                                os = new FileOutputStream(lib);
0786:                                int count;
0787:                                while ((count = is.read(buffer)) > 0) {
0788:                                    os.write(buffer, 0, count);
0789:                                }
0790:                            } else {
0791:                                this .getLogger().warn("Skipping " + libName);
0792:                            }
0793:                        } finally {
0794:                            if (os != null)
0795:                                os.close();
0796:                            if (is != null)
0797:                                is.close();
0798:                        }
0799:
0800:                        if (lastModified != -1) {
0801:                            lib.setLastModified(lastModified);
0802:                        }
0803:                    }
0804:
0805:                    return root;
0806:                } catch (IOException e) {
0807:                    this .getLogger().fatalError(
0808:                            "Exception while processing Manifest file", e);
0809:                    return null;
0810:                }
0811:            }
0812:
0813:            /**
0814:             * Retreives the "extra-classpath" attribute, that needs to be
0815:             * added to the class path.
0816:             *
0817:             * @throws ServletException
0818:             */
0819:            protected String getExtraClassPath() throws ServletException {
0820:                String extraClassPath = this 
0821:                        .getInitParameter("extra-classpath");
0822:                if (extraClassPath != null) {
0823:                    StringBuffer sb = new StringBuffer();
0824:                    StringTokenizer st = new StringTokenizer(extraClassPath,
0825:                            SystemUtils.PATH_SEPARATOR, false);
0826:                    int i = 0;
0827:                    while (st.hasMoreTokens()) {
0828:                        String s = st.nextToken();
0829:                        if (i++ > 0) {
0830:                            sb.append(File.pathSeparatorChar);
0831:                        }
0832:                        if ((s.charAt(0) == File.separatorChar)
0833:                                || (s.charAt(1) == ':')) {
0834:                            if (getLogger().isDebugEnabled()) {
0835:                                getLogger().debug(
0836:                                        "extraClassPath is absolute: " + s);
0837:                            }
0838:                            sb.append(s);
0839:
0840:                            addClassLoaderDirectory(s);
0841:                        } else {
0842:                            if (s.indexOf("${") != -1) {
0843:                                String path = StringUtils.replaceToken(s);
0844:                                sb.append(path);
0845:                                if (getLogger().isDebugEnabled()) {
0846:                                    getLogger().debug(
0847:                                            "extraClassPath is not absolute replacing using token: ["
0848:                                                    + s + "] : " + path);
0849:                                }
0850:                                addClassLoaderDirectory(path);
0851:                            } else {
0852:                                String path = null;
0853:                                if (this .servletContextPath != null) {
0854:                                    path = this .servletContextPath + s;
0855:                                    if (getLogger().isDebugEnabled()) {
0856:                                        getLogger().debug(
0857:                                                "extraClassPath is not absolute pre-pending context path: "
0858:                                                        + path);
0859:                                    }
0860:                                } else {
0861:                                    path = this .workDir.toString() + s;
0862:                                    if (getLogger().isDebugEnabled()) {
0863:                                        getLogger().debug(
0864:                                                "extraClassPath is not absolute pre-pending work-directory: "
0865:                                                        + path);
0866:                                    }
0867:                                }
0868:                                sb.append(path);
0869:                                addClassLoaderDirectory(path);
0870:                            }
0871:                        }
0872:                    }
0873:                    return sb.toString();
0874:                }
0875:                return "";
0876:            }
0877:
0878:            /**
0879:             * Set up the log level and path.  The default log level is
0880:             * Priority.ERROR, although it can be overwritten by the parameter
0881:             * "log-level".  The log system goes to both a file and the Servlet
0882:             * container's log system.  Only messages that are Priority.ERROR
0883:             * and above go to the servlet context.  The log messages can
0884:             * be as restrictive (Priority.FATAL_ERROR and above) or as liberal
0885:             * (Priority.DEBUG and above) as you want that get routed to the
0886:             * file.
0887:             */
0888:            protected void initLogger() {
0889:                final String logLevel = getInitParameter("log-level", "INFO");
0890:
0891:                final String accesslogger = getInitParameter("servlet-logger",
0892:                        "cocoon");
0893:
0894:                final Priority logPriority = Priority
0895:                        .getPriorityForName(logLevel);
0896:
0897:                final CocoonLogFormatter formatter = new CocoonLogFormatter();
0898:                formatter
0899:                        .setFormat("%7.7{priority} %{time}   [%8.8{category}] "
0900:                                + "(%{uri}) %{thread}/%{class:short}: %{message}\\n%{throwable}");
0901:                final ServletOutputLogTarget servTarget = new ServletOutputLogTarget(
0902:                        this .servletContext, formatter);
0903:
0904:                final Hierarchy defaultHierarchy = Hierarchy
0905:                        .getDefaultHierarchy();
0906:                final ErrorHandler errorHandler = new DefaultErrorHandler();
0907:                defaultHierarchy.setErrorHandler(errorHandler);
0908:                defaultHierarchy.setDefaultLogTarget(servTarget);
0909:                defaultHierarchy.setDefaultPriority(logPriority);
0910:                final Logger logger = new LogKitLogger(Hierarchy
0911:                        .getDefaultHierarchy().getLoggerFor(""));
0912:                final String loggerManagerClass = this .getInitParameter(
0913:                        "logger-class", LogKitLoggerManager.class.getName());
0914:
0915:                // the log4j support requires currently that the log4j system is already configured elsewhere
0916:
0917:                final LoggerManager loggerManager = newLoggerManager(
0918:                        loggerManagerClass, defaultHierarchy);
0919:                ContainerUtil.enableLogging(loggerManager, logger);
0920:
0921:                final DefaultContext subcontext = new DefaultContext(
0922:                        this .appContext);
0923:                subcontext.put("servlet-context", this .servletContext);
0924:                subcontext.put("context-work", this .workDir);
0925:                if (this .servletContextPath == null) {
0926:                    File logSCDir = new File(this .workDir, "log");
0927:                    logSCDir.mkdirs();
0928:                    if (logger.isWarnEnabled()) {
0929:                        logger.warn("Setting context-root for LogKit to "
0930:                                + logSCDir);
0931:                    }
0932:                    subcontext.put("context-root", logSCDir.toString());
0933:                } else {
0934:                    subcontext.put("context-root", this .servletContextPath);
0935:                }
0936:
0937:                try {
0938:                    ContainerUtil.contextualize(loggerManager, subcontext);
0939:                    this .loggerManager = loggerManager;
0940:
0941:                    if (loggerManager instanceof  Configurable) {
0942:                        //Configure the logkit management
0943:                        String logkitConfig = getInitParameter("logkit-config",
0944:                                "/WEB-INF/logkit.xconf");
0945:
0946:                        // test if this is a qualified url
0947:                        InputStream is = null;
0948:                        if (logkitConfig.indexOf(':') == -1) {
0949:                            is = this .servletContext
0950:                                    .getResourceAsStream(logkitConfig);
0951:                            if (is == null)
0952:                                is = new FileInputStream(logkitConfig);
0953:                        } else {
0954:                            URL logkitURL = new URL(logkitConfig);
0955:                            is = logkitURL.openStream();
0956:                        }
0957:                        final DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
0958:                        final Configuration conf = builder.build(is);
0959:                        ContainerUtil.configure(loggerManager, conf);
0960:                    }
0961:
0962:                    // let's configure log4j
0963:                    final String log4jConfig = getInitParameter("log4j-config",
0964:                            null);
0965:                    if (log4jConfig != null) {
0966:                        final Log4JConfigurator configurator = new Log4JConfigurator(
0967:                                subcontext);
0968:
0969:                        // test if this is a qualified url
0970:                        InputStream is = null;
0971:                        if (log4jConfig.indexOf(':') == -1) {
0972:                            is = this .servletContext
0973:                                    .getResourceAsStream(log4jConfig);
0974:                            if (is == null)
0975:                                is = new FileInputStream(log4jConfig);
0976:                        } else {
0977:                            final URL log4jURL = new URL(log4jConfig);
0978:                            is = log4jURL.openStream();
0979:                        }
0980:                        configurator.doConfigure(is, LogManager
0981:                                .getLoggerRepository());
0982:                    }
0983:
0984:                    ContainerUtil.initialize(loggerManager);
0985:                } catch (Exception e) {
0986:                    errorHandler
0987:                            .error(
0988:                                    "Could not set up Cocoon Logger, will use screen instead",
0989:                                    e, null);
0990:                }
0991:
0992:                this .log = this .loggerManager
0993:                        .getLoggerForCategory(accesslogger);
0994:
0995:                final String deprecationLevel = getInitParameter(
0996:                        "forbidden-deprecation-level", "ERROR");
0997:                Deprecation.setForbiddenLevel(Deprecation.LogLevel
0998:                        .getLevel(deprecationLevel));
0999:            }
1000:
1001:            private LoggerManager newLoggerManager(String loggerManagerClass,
1002:                    Hierarchy hierarchy) {
1003:                if (loggerManagerClass.equals(LogKitLoggerManager.class
1004:                        .getName())) {
1005:                    return new LogKitLoggerManager(hierarchy);
1006:                } else if (loggerManagerClass.equals(Log4JLoggerManager.class
1007:                        .getName())
1008:                        || loggerManagerClass.equalsIgnoreCase("LOG4J")) {
1009:                    return new Log4JLoggerManager();
1010:                } else {
1011:                    try {
1012:                        Class clazz = Class.forName(loggerManagerClass);
1013:                        return (LoggerManager) clazz.newInstance();
1014:                    } catch (Exception e) {
1015:                        return new LogKitLoggerManager(hierarchy);
1016:                    }
1017:                }
1018:            }
1019:
1020:            /**
1021:             * Set the ConfigFile for the Cocoon object.
1022:             *
1023:             * @param configFileName The file location for the cocoon.xconf
1024:             *
1025:             * @throws ServletException
1026:             */
1027:            private URL getConfigFile(final String configFileName)
1028:                    throws ServletException {
1029:                final String usedFileName;
1030:
1031:                if (configFileName == null) {
1032:                    if (getLogger().isWarnEnabled()) {
1033:                        getLogger()
1034:                                .warn(
1035:                                        "Servlet initialization argument 'configurations' not specified, attempting to use '/WEB-INF/cocoon.xconf'");
1036:                    }
1037:                    usedFileName = "/WEB-INF/cocoon.xconf";
1038:                } else {
1039:                    usedFileName = configFileName;
1040:                }
1041:
1042:                if (getLogger().isDebugEnabled()) {
1043:                    getLogger().debug(
1044:                            "Using configuration file: " + usedFileName);
1045:                }
1046:
1047:                URL result;
1048:                try {
1049:                    // test if this is a qualified url
1050:                    if (usedFileName.indexOf(':') == -1) {
1051:                        result = this .servletContext.getResource(usedFileName);
1052:                    } else {
1053:                        result = new URL(usedFileName);
1054:                    }
1055:                } catch (Exception mue) {
1056:                    String msg = "Init parameter 'configurations' is invalid : "
1057:                            + usedFileName;
1058:                    getLogger().error(msg, mue);
1059:                    throw new ServletException(msg, mue);
1060:                }
1061:
1062:                if (result == null) {
1063:                    File resultFile = new File(usedFileName);
1064:                    if (resultFile.isFile()) {
1065:                        try {
1066:                            result = resultFile.getCanonicalFile().toURL();
1067:                        } catch (Exception e) {
1068:                            String msg = "Init parameter 'configurations' is invalid : "
1069:                                    + usedFileName;
1070:                            getLogger().error(msg, e);
1071:                            throw new ServletException(msg, e);
1072:                        }
1073:                    }
1074:                }
1075:
1076:                if (result == null) {
1077:                    String msg = "Init parameter 'configuration' doesn't name an existing resource : "
1078:                            + usedFileName;
1079:                    getLogger().error(msg);
1080:                    throw new ServletException(msg);
1081:                }
1082:                return result;
1083:            }
1084:
1085:            /**
1086:             * Handle the <code>load-class</code> parameter. This overcomes
1087:             * limits in many classpath issues. One of the more notorious
1088:             * ones is a bug in WebSphere that does not load the URL handler
1089:             * for the <code>classloader://</code> protocol. In order to
1090:             * overcome that bug, set <code>load-class</code> parameter to
1091:             * the <code>com.ibm.servlet.classloader.Handler</code> value.
1092:             *
1093:             * <p>If you need to load more than one class, then separate each
1094:             * entry with whitespace, a comma, or a semi-colon. Cocoon will
1095:             * strip any whitespace from the entry.</p>
1096:             */
1097:            private void forceLoad() {
1098:                if (this .forceLoadParameter != null) {
1099:                    StringTokenizer fqcnTokenizer = new StringTokenizer(
1100:                            forceLoadParameter, " \t\r\n\f;,", false);
1101:
1102:                    while (fqcnTokenizer.hasMoreTokens()) {
1103:                        final String fqcn = fqcnTokenizer.nextToken().trim();
1104:
1105:                        try {
1106:                            if (getLogger().isDebugEnabled()) {
1107:                                getLogger().debug("Loading: " + fqcn);
1108:                            }
1109:                            ClassUtils.loadClass(fqcn).newInstance();
1110:                        } catch (Exception e) {
1111:                            if (getLogger().isWarnEnabled()) {
1112:                                getLogger().warn(
1113:                                        "Could not load class: " + fqcn, e);
1114:                            }
1115:                            // Do not throw an exception, because it is not a fatal error.
1116:                        }
1117:                    }
1118:                }
1119:            }
1120:
1121:            /**
1122:             * Handle the "force-property" parameter.
1123:             *
1124:             * If you need to force more than one property to load, then
1125:             * separate each entry with whitespace, a comma, or a semi-colon.
1126:             * Cocoon will strip any whitespace from the entry.
1127:             */
1128:            private void forceProperty() {
1129:                if (this .forceSystemProperty != null) {
1130:                    StringTokenizer tokenizer = new StringTokenizer(
1131:                            forceSystemProperty, " \t\r\n\f;,", false);
1132:
1133:                    while (tokenizer.hasMoreTokens()) {
1134:                        final String property = tokenizer.nextToken().trim();
1135:                        if (property.indexOf('=') == -1) {
1136:                            continue;
1137:                        }
1138:                        try {
1139:                            String key = property.substring(0, property
1140:                                    .indexOf('='));
1141:                            String value = property.substring(property
1142:                                    .indexOf('=') + 1);
1143:                            if (value.indexOf("${") != -1) {
1144:                                value = StringUtils.replaceToken(value);
1145:                            }
1146:                            if (getLogger().isDebugEnabled()) {
1147:                                getLogger().debug(
1148:                                        "Setting " + key + "=" + value);
1149:                            }
1150:                            System.setProperty(key, value);
1151:                        } catch (Exception e) {
1152:                            if (getLogger().isWarnEnabled()) {
1153:                                getLogger().warn(
1154:                                        "Could not set property: " + property,
1155:                                        e);
1156:                            }
1157:                            // Do not throw an exception, because it is not a fatal error.
1158:                        }
1159:                    }
1160:                }
1161:            }
1162:
1163:            /**
1164:             * Process the specified <code>HttpServletRequest</code> producing output
1165:             * on the specified <code>HttpServletResponse</code>.
1166:             */
1167:            public void service(HttpServletRequest req, HttpServletResponse res)
1168:                    throws ServletException, IOException {
1169:
1170:                /* HACK for reducing class loader problems.                                     */
1171:                /* example: xalan extensions fail if someone adds xalan jars in tomcat3.2.1/lib */
1172:                if (this .initClassLoader) {
1173:                    try {
1174:                        Thread.currentThread().setContextClassLoader(
1175:                                this .classLoader);
1176:                    } catch (Exception e) {
1177:                    }
1178:                }
1179:
1180:                // used for timing the processing
1181:                StopWatch stopWatch = new StopWatch();
1182:                stopWatch.start();
1183:
1184:                // add the cocoon header timestamp
1185:                if (this .showCocoonVersion) {
1186:                    res.addHeader("X-Cocoon-Version", Constants.VERSION);
1187:                }
1188:
1189:                // get the request (wrapped if contains multipart-form data)
1190:                HttpServletRequest request;
1191:                try {
1192:                    if (this .enableUploads) {
1193:                        request = requestFactory.getServletRequest(req);
1194:                    } else {
1195:                        request = req;
1196:                    }
1197:                } catch (Exception e) {
1198:                    if (getLogger().isErrorEnabled()) {
1199:                        getLogger().error("Problem with Cocoon servlet", e);
1200:                    }
1201:
1202:                    manageException(req, res, null, null,
1203:                            HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
1204:                            "Problem in creating the Request", null, null, e);
1205:                    return;
1206:                }
1207:
1208:                // Get the cocoon engine instance
1209:
1210:                if (reloadCocoon(request.getPathInfo(), request
1211:                        .getParameter(Constants.RELOAD_PARAM))) {
1212:                    disposeCocoon();
1213:                    initLogger();
1214:                    createCocoon();
1215:                }
1216:
1217:                // Check if cocoon was initialized
1218:                if (this .cocoon == null) {
1219:                    manageException(
1220:                            request,
1221:                            res,
1222:                            null,
1223:                            null,
1224:                            HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
1225:                            "Initialization Problem",
1226:                            null /* "Cocoon was not initialized" */,
1227:                            null /* "Cocoon was not initialized, cannot process request" */,
1228:                            this .exception);
1229:                    return;
1230:                }
1231:
1232:                // We got it... Process the request
1233:                String uri = request.getServletPath();
1234:                if (uri == null) {
1235:                    uri = "";
1236:                }
1237:                String pathInfo = request.getPathInfo();
1238:                if (pathInfo != null) {
1239:                    // VG: WebLogic fix: Both uri and pathInfo starts with '/'
1240:                    // This problem exists only in WL6.1sp2, not in WL6.0sp2 or WL7.0b.
1241:                    if (uri.length() > 0 && uri.charAt(0) == '/') {
1242:                        uri = uri.substring(1);
1243:                    }
1244:                    uri += pathInfo;
1245:                }
1246:
1247:                if (uri.length() == 0) {
1248:                    /* empty relative URI
1249:                         -> HTTP-redirect from /cocoon to /cocoon/ to avoid
1250:                            StringIndexOutOfBoundsException when calling
1251:                            "".charAt(0)
1252:                       else process URI normally
1253:                     */
1254:                    String prefix = request.getRequestURI();
1255:                    if (prefix == null) {
1256:                        prefix = "";
1257:                    }
1258:
1259:                    res.sendRedirect(res.encodeRedirectURL(prefix + "/"));
1260:                    return;
1261:                }
1262:
1263:                String contentType = null;
1264:                ContextMap ctxMap = null;
1265:
1266:                Environment env;
1267:                try {
1268:                    if (uri.charAt(0) == '/') {
1269:                        uri = uri.substring(1);
1270:                    }
1271:                    // Pass uri into environment without URLDecoding, as it is already decoded.
1272:                    env = getEnvironment(uri, request, res);
1273:                } catch (Exception e) {
1274:                    if (getLogger().isErrorEnabled()) {
1275:                        getLogger().error("Problem with Cocoon servlet", e);
1276:                    }
1277:
1278:                    manageException(request, res, null, uri,
1279:                            HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
1280:                            "Problem in creating the Environment", null, null,
1281:                            e);
1282:                    return;
1283:                }
1284:
1285:                try {
1286:                    try {
1287:                        // Initialize a fresh log context containing the object model: it
1288:                        // will be used by the CocoonLogFormatter
1289:                        ctxMap = ContextMap.getCurrentContext();
1290:                        // Add thread name (default content for empty context)
1291:                        String threadName = Thread.currentThread().getName();
1292:                        ctxMap.set("threadName", threadName);
1293:                        // Add the object model
1294:                        ctxMap.set("objectModel", env.getObjectModel());
1295:                        // Add a unique request id (threadName + currentTime
1296:                        ctxMap.set("request-id", threadName
1297:                                + System.currentTimeMillis());
1298:
1299:                        if (this .cocoon.process(env)) {
1300:                            contentType = env.getContentType();
1301:                        } else {
1302:                            // We reach this when there is nothing in the processing change that matches
1303:                            // the request. For example, no matcher matches.
1304:                            getLogger()
1305:                                    .fatalError(
1306:                                            "The Cocoon engine failed to process the request.");
1307:                            manageException(
1308:                                    request,
1309:                                    res,
1310:                                    env,
1311:                                    uri,
1312:                                    HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
1313:                                    "Request Processing Failed",
1314:                                    "Cocoon engine failed in process the request",
1315:                                    "The processing engine failed to process the request. This could be due to lack of matching or bugs in the pipeline engine.",
1316:                                    null);
1317:                            return;
1318:                        }
1319:                    } catch (ResourceNotFoundException e) {
1320:                        if (getLogger().isDebugEnabled()) {
1321:                            getLogger().warn(e.getMessage(), e);
1322:                        } else if (getLogger().isWarnEnabled()) {
1323:                            getLogger().warn(e.getMessage());
1324:                        }
1325:
1326:                        manageException(request, res, env, uri,
1327:                                HttpServletResponse.SC_NOT_FOUND,
1328:                                "Resource Not Found", "Resource Not Found",
1329:                                "The requested resource \""
1330:                                        + request.getRequestURI()
1331:                                        + "\" could not be found", e);
1332:                        return;
1333:
1334:                    } catch (ConnectionResetException e) {
1335:                        if (getLogger().isDebugEnabled()) {
1336:                            getLogger().debug(e.toString(), e);
1337:                        } else if (getLogger().isWarnEnabled()) {
1338:                            getLogger().warn(e.toString());
1339:                        }
1340:
1341:                    } catch (IOException e) {
1342:                        // Tomcat5 wraps SocketException into ClientAbortException which extends IOException.
1343:                        if (getLogger().isDebugEnabled()) {
1344:                            getLogger().debug(e.toString(), e);
1345:                        } else if (getLogger().isWarnEnabled()) {
1346:                            getLogger().warn(e.toString());
1347:                        }
1348:
1349:                    } catch (Exception e) {
1350:                        if (getLogger().isErrorEnabled()) {
1351:                            getLogger().error("Internal Cocoon Problem", e);
1352:                        }
1353:
1354:                        manageException(request, res, env, uri,
1355:                                HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
1356:                                "Internal Server Error", null, null, e);
1357:                        return;
1358:                    }
1359:
1360:                    stopWatch.stop();
1361:                    String timeString = null;
1362:                    if (getLogger().isInfoEnabled()) {
1363:                        timeString = processTime(stopWatch.getTime());
1364:                        getLogger().info("'" + uri + "' " + timeString);
1365:                    }
1366:
1367:                    if (contentType != null && contentType.equals("text/html")) {
1368:                        String showTime = request
1369:                                .getParameter(Constants.SHOWTIME_PARAM);
1370:                        boolean show = this .showTime;
1371:                        if (showTime != null) {
1372:                            show = !showTime.equalsIgnoreCase("no");
1373:                        }
1374:                        if (show) {
1375:                            if (timeString == null) {
1376:                                timeString = processTime(stopWatch.getTime());
1377:                            }
1378:                            boolean hide = this .hiddenShowTime;
1379:                            if (showTime != null) {
1380:                                hide = showTime.equalsIgnoreCase("hide");
1381:                            }
1382:                            ServletOutputStream out = res.getOutputStream();
1383:                            out.print((hide) ? "<!-- " : "<p>");
1384:                            out.print(timeString);
1385:                            out.println((hide) ? " -->" : "</p>");
1386:                        }
1387:                    }
1388:                } finally {
1389:                    if (ctxMap != null) {
1390:                        ctxMap.clear();
1391:                    }
1392:
1393:                    try {
1394:                        if (request instanceof  MultipartHttpServletRequest) {
1395:                            if (getLogger().isDebugEnabled()) {
1396:                                getLogger().debug("Deleting uploaded file(s).");
1397:                            }
1398:                            ((MultipartHttpServletRequest) request).cleanup();
1399:                        }
1400:                    } catch (IOException e) {
1401:                        getLogger()
1402:                                .error(
1403:                                        "Cocoon got an Exception while trying to cleanup the uploaded files.",
1404:                                        e);
1405:                    }
1406:
1407:                    /*
1408:                     * Servlet Specification 2.2, 6.5 Closure of Response Object:
1409:                     *
1410:                     *   A number of events can indicate that the servlet has provided all of the
1411:                     *   content to satisfy the request and that the response object can be
1412:                     *   considered to be closed. The events are:
1413:                     *     o The termination of the service method of the servlet.
1414:                     *     o When the amount of content specified in the setContentLength method
1415:                     *       of the response has been written to the response.
1416:                     *     o The sendError method is called.
1417:                     *     o The sendRedirect method is called.
1418:                     *   When a response is closed, all content in the response buffer, if any remains,
1419:                     *   must be immediately flushed to the client.
1420:                     *
1421:                     * Due to the above, out.flush() and out.close() are not necessary, and sometimes
1422:                     * (if sendError or sendRedirect were used) request may be already closed.
1423:                     */
1424:                }
1425:            }
1426:
1427:            protected void manageException(HttpServletRequest req,
1428:                    HttpServletResponse res, Environment env, String uri,
1429:                    int errorStatus, String title, String message,
1430:                    String description, Exception e) throws IOException {
1431:                if (this .manageExceptions) {
1432:                    if (env != null) {
1433:                        env.tryResetResponse();
1434:                    } else {
1435:                        res.reset();
1436:                    }
1437:
1438:                    String type = Notifying.FATAL_NOTIFICATION;
1439:                    HashMap extraDescriptions = null;
1440:
1441:                    if (errorStatus == HttpServletResponse.SC_NOT_FOUND) {
1442:                        type = "resource-not-found";
1443:                        // Do not show the exception stacktrace for such common errors.
1444:                        e = null;
1445:                    } else {
1446:                        extraDescriptions = new HashMap(2);
1447:                        extraDescriptions.put(Notifying.EXTRA_REQUESTURI, req
1448:                                .getRequestURI());
1449:                        if (uri != null) {
1450:                            extraDescriptions.put("Request URI", uri);
1451:                        }
1452:
1453:                        // Do not show exception stack trace when log level is WARN or above. Show only message.
1454:                        if (!getLogger().isInfoEnabled()) {
1455:                            Throwable t = DefaultNotifyingBuilder
1456:                                    .getRootCause(e);
1457:                            if (t != null)
1458:                                extraDescriptions.put(Notifying.EXTRA_CAUSE, t
1459:                                        .getMessage());
1460:                            e = null;
1461:                        }
1462:                    }
1463:
1464:                    Notifying n = new DefaultNotifyingBuilder().build(this , e,
1465:                            type, title, "Cocoon Servlet", message,
1466:                            description, extraDescriptions);
1467:
1468:                    res.setContentType("text/html");
1469:                    res.setStatus(errorStatus);
1470:                    Notifier.notify(n, res.getOutputStream(), "text/html");
1471:                } else {
1472:                    res.sendError(errorStatus, title);
1473:                    res.flushBuffer();
1474:                }
1475:            }
1476:
1477:            /**
1478:             * Create the environment for the request
1479:             */
1480:            protected Environment getEnvironment(String uri,
1481:                    HttpServletRequest req, HttpServletResponse res)
1482:                    throws Exception {
1483:                HttpEnvironment env;
1484:
1485:                String formEncoding = req.getParameter("cocoon-form-encoding");
1486:                if (formEncoding == null) {
1487:                    formEncoding = this .defaultFormEncoding;
1488:                }
1489:                env = new HttpEnvironment(uri, this .servletContextURL, req,
1490:                        res, this .servletContext, (HttpContext) this .appContext
1491:                                .get(Constants.CONTEXT_ENVIRONMENT_CONTEXT),
1492:                        this .containerEncoding, formEncoding);
1493:                env.enableLogging(getLogger());
1494:                return env;
1495:            }
1496:
1497:            /**
1498:             * Instatiates the parent component manager, as specified in the
1499:             * parent-component-manager init parameter.
1500:             *
1501:             * If none is specified, the method returns <code>null</code>.
1502:             *
1503:             * @return the parent component manager, or <code>null</code>.
1504:             */
1505:            protected synchronized ComponentManager getParentComponentManager() {
1506:                if (parentComponentManager != null
1507:                        && parentComponentManager instanceof  Disposable) {
1508:                    ((Disposable) parentComponentManager).dispose();
1509:                }
1510:
1511:                parentComponentManager = null;
1512:                if (parentComponentManagerClass != null) {
1513:                    try {
1514:                        Class pcm = ClassUtils
1515:                                .loadClass(parentComponentManagerClass);
1516:                        Constructor pcmc = pcm
1517:                                .getConstructor(new Class[] { String.class });
1518:                        parentComponentManager = (ComponentManager) pcmc
1519:                                .newInstance(new Object[] { parentComponentManagerInitParam });
1520:
1521:                        if (parentComponentManager instanceof  LogEnabled) {
1522:                            ((LogEnabled) parentComponentManager)
1523:                                    .enableLogging(getLogger());
1524:                        }
1525:                        if (parentComponentManager instanceof  Contextualizable) {
1526:                            ((Contextualizable) parentComponentManager)
1527:                                    .contextualize(this .appContext);
1528:                        }
1529:                        if (parentComponentManager instanceof  Initializable) {
1530:                            ((Initializable) parentComponentManager)
1531:                                    .initialize();
1532:                        }
1533:                    } catch (Exception e) {
1534:                        if (getLogger().isErrorEnabled()) {
1535:                            getLogger()
1536:                                    .error(
1537:                                            "Could not initialize parent component manager.",
1538:                                            e);
1539:                        }
1540:                    }
1541:                }
1542:                return parentComponentManager;
1543:            }
1544:
1545:            /**
1546:             * Creates the Cocoon object and handles exception handling.
1547:             */
1548:            protected synchronized void createCocoon() throws ServletException {
1549:
1550:                // Recheck that we need to create the cocoon object. It can have been created by
1551:                // a concurrent invocation to this method.
1552:                if (this .cocoon != null) {
1553:                    return;
1554:                }
1555:
1556:                /* HACK for reducing class loader problems.                                     */
1557:                /* example: xalan extensions fail if someone adds xalan jars in tomcat3.2.1/lib */
1558:                if (this .initClassLoader) {
1559:                    try {
1560:                        Thread.currentThread().setContextClassLoader(
1561:                                this .classLoader);
1562:                    } catch (Exception e) {
1563:                    }
1564:                }
1565:
1566:                updateEnvironment();
1567:                forceLoad();
1568:                forceProperty();
1569:
1570:                try {
1571:                    this .exception = null;
1572:                    URL configFile = (URL) this .appContext
1573:                            .get(Constants.CONTEXT_CONFIG_URL);
1574:                    if (getLogger().isInfoEnabled()) {
1575:                        getLogger().info(
1576:                                "Reloading from: "
1577:                                        + configFile.toExternalForm());
1578:                    }
1579:                    Cocoon c = (Cocoon) ClassUtils
1580:                            .newInstance("org.apache.cocoon.Cocoon");
1581:                    ContainerUtil.enableLogging(c, getCocoonLogger());
1582:                    c.setLoggerManager(getLoggerManager());
1583:                    ContainerUtil.contextualize(c, this .appContext);
1584:                    final ComponentManager parent = this 
1585:                            .getParentComponentManager();
1586:                    if (parent != null) {
1587:                        ContainerUtil.compose(c, parent);
1588:                    }
1589:                    if (this .enableInstrumentation) {
1590:                        c.setInstrumentManager(getInstrumentManager());
1591:                    }
1592:                    ContainerUtil.initialize(c);
1593:                    this .creationTime = System.currentTimeMillis();
1594:
1595:                    this .cocoon = c;
1596:                } catch (Exception e) {
1597:                    if (getLogger().isErrorEnabled()) {
1598:                        getLogger().error("Exception reloading", e);
1599:                    }
1600:                    this .exception = e;
1601:                    disposeCocoon();
1602:                }
1603:            }
1604:
1605:            private Logger getCocoonLogger() {
1606:                final String rootlogger = getInitParameter("cocoon-logger");
1607:                if (rootlogger != null) {
1608:                    return this .getLoggerManager().getLoggerForCategory(
1609:                            rootlogger);
1610:                } else {
1611:                    return getLogger();
1612:                }
1613:            }
1614:
1615:            /**
1616:             * Method to update the environment before Cocoon instances are created.
1617:             *
1618:             * This is also useful if you wish to customize any of the 'protected'
1619:             * variables from this class before a Cocoon instance is built in a derivative
1620:             * of this class (eg. Cocoon Context).
1621:             */
1622:            protected void updateEnvironment() throws ServletException {
1623:                this .appContext
1624:                        .put(Constants.CONTEXT_CLASS_LOADER, classLoader);
1625:                this .appContext
1626:                        .put(Constants.CONTEXT_CLASSPATH, getClassPath());
1627:            }
1628:
1629:            /**
1630:             * Helper method to obtain an <code>InstrumentManager</code> instance
1631:             *
1632:             * @return an <code>InstrumentManager</code> instance
1633:             */
1634:            private InstrumentManager getInstrumentManager() throws Exception {
1635:                String imConfig = getInitParameter("instrumentation-config");
1636:                if (imConfig == null) {
1637:                    throw new ServletException(
1638:                            "Please define the init-param 'instrumentation-config' in your web.xml");
1639:                }
1640:
1641:                final InputStream is = this .servletContext
1642:                        .getResourceAsStream(imConfig);
1643:                final DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
1644:                final Configuration conf = builder.build(is);
1645:
1646:                // Get the logger for the instrument manager
1647:                final String imLoggerCategory = conf.getAttribute("logger",
1648:                        "core.instrument");
1649:                Logger imLogger = this .loggerManager
1650:                        .getLoggerForCategory(imLoggerCategory);
1651:
1652:                // Set up the Instrument Manager
1653:                DefaultInstrumentManagerImpl instrumentManager = new DefaultInstrumentManagerImpl();
1654:                instrumentManager.enableLogging(imLogger);
1655:                instrumentManager.configure(conf);
1656:                instrumentManager.initialize();
1657:
1658:                if (getLogger().isDebugEnabled()) {
1659:                    getLogger().debug(
1660:                            "Instrument manager created " + instrumentManager);
1661:                }
1662:
1663:                this .instrumentManager = instrumentManager;
1664:                return instrumentManager;
1665:            }
1666:
1667:            private String processTime(long time) {
1668:                StringBuffer out = new StringBuffer(PROCESSED_BY);
1669:                if (time <= SECOND) {
1670:                    out.append(time);
1671:                    out.append(" milliseconds.");
1672:                } else if (time <= MINUTE) {
1673:                    out.append(time / SECOND);
1674:                    out.append(" seconds.");
1675:                } else if (time <= HOUR) {
1676:                    out.append(time / MINUTE);
1677:                    out.append(" minutes.");
1678:                } else {
1679:                    out.append(time / HOUR);
1680:                    out.append(" hours.");
1681:                }
1682:                return out.toString();
1683:            }
1684:
1685:            /**
1686:             * Gets the current cocoon object.  Reload cocoon if configuration
1687:             * changed or we are reloading.
1688:             */
1689:            private boolean reloadCocoon(final String pathInfo,
1690:                    final String reloadParam) throws ServletException {
1691:                if (this .allowReload) {
1692:                    boolean reload = false;
1693:
1694:                    if (this .cocoon != null) {
1695:                        if (this .cocoon.modifiedSince(this .creationTime)) {
1696:                            if (getLogger().isInfoEnabled()) {
1697:                                getLogger().info(
1698:                                        "Configuration changed reload attempt");
1699:                            }
1700:                            reload = true;
1701:                        } else if (pathInfo == null && reloadParam != null) {
1702:                            if (getLogger().isInfoEnabled()) {
1703:                                getLogger().info("Forced reload attempt");
1704:                            }
1705:                            reload = true;
1706:                        }
1707:                    } else if (pathInfo == null && reloadParam != null) {
1708:                        if (getLogger().isInfoEnabled()) {
1709:                            getLogger().info("Invalid configurations reload");
1710:                        }
1711:                        reload = true;
1712:                    }
1713:
1714:                    return reload;
1715:                } else {
1716:                    return false;
1717:                }
1718:            }
1719:
1720:            /**
1721:             * Destroy Cocoon
1722:             */
1723:            protected final void disposeCocoon() {
1724:                if (this .cocoon != null) {
1725:                    ContainerUtil.dispose(this .cocoon);
1726:                    this .cocoon = null;
1727:                }
1728:            }
1729:
1730:            /**
1731:             * Get an initialisation parameter. The value is trimmed, and null is returned if the trimmed value
1732:             * is empty.
1733:             */
1734:            public String getInitParameter(String name) {
1735:                String result = super .getInitParameter(name);
1736:                if (result != null) {
1737:                    result = result.trim();
1738:                    if (result.length() == 0) {
1739:                        result = null;
1740:                    }
1741:                }
1742:
1743:                return result;
1744:            }
1745:
1746:            /** Convenience method to access servlet parameters */
1747:            protected String getInitParameter(String name, String defaultValue) {
1748:                String result = getInitParameter(name);
1749:                if (result == null) {
1750:                    if (getLogger() != null && getLogger().isDebugEnabled()) {
1751:                        getLogger().debug(
1752:                                name + " was not set - defaulting to '"
1753:                                        + defaultValue + "'");
1754:                    }
1755:                    return defaultValue;
1756:                } else {
1757:                    return result;
1758:                }
1759:            }
1760:
1761:            /** Convenience method to access boolean servlet parameters */
1762:            protected boolean getInitParameterAsBoolean(String name,
1763:                    boolean defaultValue) {
1764:                String value = getInitParameter(name);
1765:                if (value == null) {
1766:                    if (getLogger() != null && getLogger().isDebugEnabled()) {
1767:                        getLogger().debug(
1768:                                name + " was not set - defaulting to '"
1769:                                        + defaultValue + "'");
1770:                    }
1771:                    return defaultValue;
1772:                }
1773:
1774:                return BooleanUtils.toBoolean(value);
1775:            }
1776:
1777:            protected int getInitParameterAsInteger(String name,
1778:                    int defaultValue) {
1779:                String value = getInitParameter(name);
1780:                if (value == null) {
1781:                    if (getLogger() != null && getLogger().isDebugEnabled()) {
1782:                        getLogger().debug(
1783:                                name + " was not set - defaulting to '"
1784:                                        + defaultValue + "'");
1785:                    }
1786:                    return defaultValue;
1787:                } else {
1788:                    return Integer.parseInt(value);
1789:                }
1790:            }
1791:
1792:            protected Logger getLogger() {
1793:                return this .log;
1794:            }
1795:
1796:            protected LoggerManager getLoggerManager() {
1797:                return this.loggerManager;
1798:            }
1799:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.