Source Code Cross Referenced for Turbine.java in  » Project-Management » turbine » org » apache » turbine » 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 » Project Management » turbine » org.apache.turbine 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        package org.apache.turbine;
0002:
0003:        /*
0004:         * Copyright 2001-2005 The Apache Software Foundation.
0005:         *
0006:         * Licensed under the Apache License, Version 2.0 (the "License")
0007:         * you may not use this file except in compliance with the License.
0008:         * You may obtain a copy of the License at
0009:         *
0010:         *     http://www.apache.org/licenses/LICENSE-2.0
0011:         *
0012:         * Unless required by applicable law or agreed to in writing, software
0013:         * distributed under the License is distributed on an "AS IS" BASIS,
0014:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0015:         * See the License for the specific language governing permissions and
0016:         * limitations under the License.
0017:         */
0018:
0019:        import java.io.File;
0020:        import java.io.FileInputStream;
0021:        import java.io.FileNotFoundException;
0022:        import java.io.IOException;
0023:        import java.io.UnsupportedEncodingException;
0024:
0025:        import java.util.Properties;
0026:
0027:        import javax.servlet.ServletConfig;
0028:        import javax.servlet.ServletContext;
0029:        import javax.servlet.ServletException;
0030:        import javax.servlet.http.HttpServlet;
0031:        import javax.servlet.http.HttpServletRequest;
0032:        import javax.servlet.http.HttpServletResponse;
0033:
0034:        import org.apache.commons.configuration.Configuration;
0035:        import org.apache.commons.configuration.ConfigurationFactory;
0036:        import org.apache.commons.configuration.PropertiesConfiguration;
0037:
0038:        import org.apache.commons.lang.StringUtils;
0039:
0040:        import org.apache.commons.lang.exception.ExceptionUtils;
0041:
0042:        import org.apache.commons.logging.Log;
0043:        import org.apache.commons.logging.LogFactory;
0044:
0045:        import org.apache.log4j.PropertyConfigurator;
0046:
0047:        import org.apache.turbine.modules.ActionLoader;
0048:        import org.apache.turbine.modules.PageLoader;
0049:
0050:        import org.apache.turbine.services.ServiceManager;
0051:        import org.apache.turbine.services.TurbineServices;
0052:        import org.apache.turbine.services.avaloncomponent.AvalonComponentService;
0053:        import org.apache.turbine.services.component.ComponentService;
0054:        import org.apache.turbine.services.template.TemplateService;
0055:        import org.apache.turbine.services.template.TurbineTemplate;
0056:        import org.apache.turbine.services.rundata.RunDataService;
0057:        import org.apache.turbine.services.rundata.TurbineRunDataFacade;
0058:        import org.apache.turbine.services.velocity.VelocityService;
0059:
0060:        import org.apache.turbine.util.RunData;
0061:        import org.apache.turbine.util.ServerData;
0062:        import org.apache.turbine.util.TurbineConfig;
0063:        import org.apache.turbine.util.TurbineException;
0064:        import org.apache.turbine.util.security.AccessControlList;
0065:        import org.apache.turbine.util.template.TemplateInfo;
0066:        import org.apache.turbine.util.uri.URIConstants;
0067:
0068:        /**
0069:         * Turbine is the main servlet for the entire system. It is <code>final</code>
0070:         * because you should <i>not</i> ever need to subclass this servlet.  If you
0071:         * need to perform initialization of a service, then you should implement the
0072:         * Services API and let your code be initialized by it.
0073:         * If you need to override something in the <code>doGet()</code> or
0074:         * <code>doPost()</code> methods, edit the TurbineResources.properties file and
0075:         * specify your own classes there.
0076:         * <p>
0077:         * Turbine servlet recognizes the following initialization parameters.
0078:         * <ul>
0079:         * <li><code>properties</code> the path to TurbineResources.properties file
0080:         * used by the default implementation of <code>ResourceService</code>, relative
0081:         * to the application root.</li>
0082:         * <li><code>basedir</code> this parameter is used <strong>only</strong> if your
0083:         * application server does not support web applications, or the or does not
0084:         * support <code>ServletContext.getRealPath(String)</code> method correctly.
0085:         * You can use this parameter to specify the directory within the server's
0086:         * filesystem, that is the base of your web application.</li>
0087:         * </ul>
0088:         *
0089:         * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
0090:         * @author <a href="mailto:bmclaugh@algx.net">Brett McLaughlin</a>
0091:         * @author <a href="mailto:greg@shwoop.com">Greg Ritter</a>
0092:         * @author <a href="mailto:john.mcnally@clearink.com">John D. McNally</a>
0093:         * @author <a href="mailto:frank.kim@clearink.com">Frank Y. Kim</a>
0094:         * @author <a href="mailto:krzewski@e-point.pl">Rafal Krzewski</a>
0095:         * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
0096:         * @author <a href="mailto:sean@informage.net">Sean Legassick</a>
0097:         * @author <a href="mailto:mpoeschl@marmot.at">Martin Poeschl</a>
0098:         * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
0099:         * @author <a href="mailto:quintonm@bellsouth.net">Quinton McCombs</a>
0100:         * @author <a href="mailto:epugh@upstate.com">Eric Pugh</a>
0101:         * @version $Id: Turbine.java 264152 2005-08-29 14:50:22Z henning $
0102:         */
0103:        public class Turbine extends HttpServlet implements  TurbineConstants {
0104:            /** SerialVersionUID for serialization */
0105:            private static final long serialVersionUID = -6895381097045304308L;
0106:
0107:            /**
0108:             * Name of path info parameter used to indicate the redirected stage of
0109:             * a given user's initial Turbine request
0110:             */
0111:            public static final String REDIRECTED_PATHINFO_NAME = "redirected";
0112:
0113:            /** The base directory key */
0114:            public static final String BASEDIR_KEY = "basedir";
0115:
0116:            /**
0117:             * In certain situations the init() method is called more than once,
0118:             * somtimes even concurrently. This causes bad things to happen,
0119:             * so we use this flag to prevent it.
0120:             */
0121:            private static boolean firstInit = true;
0122:
0123:            /** Whether init succeeded or not. */
0124:            private static Throwable initFailure = null;
0125:
0126:            /**
0127:             * Should initialization activities be performed during doGet() execution?
0128:             */
0129:            private static boolean firstDoGet = true;
0130:
0131:            /**
0132:             * Keep all the properties of the web server in a convenient data
0133:             * structure
0134:             */
0135:            private static ServerData serverData = null;
0136:
0137:            /** The base from which the Turbine application will operate. */
0138:            private static String applicationRoot;
0139:
0140:            /** Servlet config for this Turbine webapp. */
0141:            private static ServletConfig servletConfig;
0142:
0143:            /** Servlet context for this Turbine webapp. */
0144:            private static ServletContext servletContext;
0145:
0146:            /**
0147:             * The webapp root where the Turbine application
0148:             * is running in the servlet container.
0149:             * This might differ from the application root.
0150:             */
0151:            private static String webappRoot;
0152:
0153:            /** Our internal configuration object */
0154:            private static Configuration configuration = null;
0155:
0156:            /** A reference to the Template Service */
0157:            private TemplateService templateService = null;
0158:
0159:            /** A reference to the RunData Service */
0160:            private RunDataService rundataService = null;
0161:
0162:            /** Default Input encoding if the servlet container does not report an encoding */
0163:            private String inputEncoding = null;
0164:
0165:            /** Logging class from commons.logging */
0166:            private static Log log = LogFactory.getLog(Turbine.class);
0167:
0168:            /**
0169:             * This init method will load the default resources from a
0170:             * properties file.
0171:             *
0172:             * This method is called by init(ServletConfig config)
0173:             *
0174:             * @exception ServletException a servlet exception.
0175:             */
0176:            public final void init() throws ServletException {
0177:                synchronized (this .getClass()) {
0178:                    super .init();
0179:                    ServletConfig config = getServletConfig();
0180:
0181:                    if (!firstInit) {
0182:                        log
0183:                                .info("Double initialization of Turbine was attempted!");
0184:                        return;
0185:                    }
0186:                    // executing init will trigger some static initializers, so we have
0187:                    // only one chance.
0188:                    firstInit = false;
0189:
0190:                    try {
0191:                        ServletContext context = config.getServletContext();
0192:
0193:                        configure(config, context);
0194:
0195:                        templateService = TurbineTemplate.getService();
0196:                        rundataService = TurbineRunDataFacade.getService();
0197:
0198:                        if (rundataService == null) {
0199:                            throw new TurbineException(
0200:                                    "No RunData Service configured!");
0201:                        }
0202:
0203:                    } catch (Exception e) {
0204:                        // save the exception to complain loudly later :-)
0205:                        initFailure = e;
0206:                        log.fatal("Turbine: init() failed: ", e);
0207:                        throw new ServletException("Turbine: init() failed", e);
0208:                    }
0209:                    log.info("Turbine: init() Ready to Rumble!");
0210:                }
0211:            }
0212:
0213:            /**
0214:             * Read the master configuration file in, configure logging
0215:             * and start up any early services.
0216:             *
0217:             * @param config The Servlet Configuration supplied by the container
0218:             * @param context The Servlet Context supplied by the container
0219:             *
0220:             * @throws Exception A problem occured while reading the configuration or performing early startup
0221:             */
0222:
0223:            private void configure(ServletConfig config, ServletContext context)
0224:                    throws Exception {
0225:                // Set the application root. This defaults to the webapp
0226:                // context if not otherwise set. This is to allow 2.1 apps
0227:                // to be developed from CVS. This feature will carry over
0228:                // into 3.0.
0229:                applicationRoot = findInitParameter(context, config,
0230:                        APPLICATION_ROOT_KEY, APPLICATION_ROOT_DEFAULT);
0231:
0232:                webappRoot = config.getServletContext().getRealPath("/");
0233:                // log.info("Web Application root is " + webappRoot);
0234:                // log.info("Application root is "     + applicationRoot);
0235:
0236:                if (applicationRoot == null
0237:                        || applicationRoot.equals(WEB_CONTEXT)) {
0238:                    applicationRoot = webappRoot;
0239:                    // log.info("got empty or 'webContext' Application root. Application root now: " + applicationRoot);
0240:                }
0241:
0242:                // Set the applicationRoot for this webapp.
0243:                setApplicationRoot(applicationRoot);
0244:
0245:                // Create any directories that need to be setup for
0246:                // a running Turbine application.
0247:                createRuntimeDirectories(context, config);
0248:
0249:                //
0250:                // Now we run the Turbine configuration code. There are two ways
0251:                // to configure Turbine:
0252:                //
0253:                // a) By supplying an web.xml init parameter called "configuration"
0254:                //
0255:                // <init-param>
0256:                //   <param-name>configuration</param-name>
0257:                //   <param-value>/WEB-INF/conf/turbine.xml</param-value>
0258:                // </init-param>
0259:                //
0260:                // This loads an XML based configuration file.
0261:                //
0262:                // b) By supplying an web.xml init parameter called "properties"
0263:                //
0264:                // <init-param>
0265:                //   <param-name>properties</param-name>
0266:                //   <param-value>/WEB-INF/conf/TurbineResources.properties</param-value>
0267:                // </init-param>
0268:                //
0269:                // This loads a Properties based configuration file. Actually, these are
0270:                // extended properties as provided by commons-configuration
0271:                //
0272:                // If neither a) nor b) is supplied, Turbine will fall back to the
0273:                // known behaviour of loading a properties file called
0274:                // /WEB-INF/conf/TurbineResources.properties relative to the
0275:                // web application root.
0276:
0277:                String confFile = findInitParameter(context, config,
0278:                        TurbineConfig.CONFIGURATION_PATH_KEY, null);
0279:
0280:                String confPath;
0281:                String confStyle = "unset";
0282:
0283:                if (StringUtils.isNotEmpty(confFile)) {
0284:                    confPath = getRealPath(confFile);
0285:                    ConfigurationFactory configurationFactory = new ConfigurationFactory(
0286:                            confPath);
0287:                    configurationFactory.setBasePath(getApplicationRoot());
0288:                    configuration = configurationFactory.getConfiguration();
0289:                    confStyle = "XML";
0290:                } else {
0291:                    confFile = findInitParameter(context, config,
0292:                            TurbineConfig.PROPERTIES_PATH_KEY,
0293:                            TurbineConfig.PROPERTIES_PATH_DEFAULT);
0294:
0295:                    confPath = getRealPath(confFile);
0296:
0297:                    // This should eventually be a Configuration
0298:                    // interface so that service and app configuration
0299:                    // can be stored anywhere.
0300:                    configuration = (Configuration) new PropertiesConfiguration(
0301:                            confPath);
0302:                    confStyle = "Properties";
0303:                }
0304:
0305:                //
0306:                // Set up logging as soon as possible
0307:                //
0308:                String log4jFile = configuration.getString(LOG4J_CONFIG_FILE,
0309:                        LOG4J_CONFIG_FILE_DEFAULT);
0310:
0311:                if (StringUtils.isNotEmpty(log4jFile)
0312:                        && !log4jFile.equalsIgnoreCase("none")) {
0313:                    log4jFile = getRealPath(log4jFile);
0314:
0315:                    //
0316:                    // Load the config file above into a Properties object and
0317:                    // fix up the Application root
0318:                    //
0319:                    Properties p = new Properties();
0320:                    try {
0321:                        p.load(new FileInputStream(log4jFile));
0322:                        p.setProperty(APPLICATION_ROOT_KEY,
0323:                                getApplicationRoot());
0324:                        PropertyConfigurator.configure(p);
0325:
0326:                        log.info("Configured log4j from " + log4jFile);
0327:                    } catch (FileNotFoundException fnf) {
0328:                        System.err
0329:                                .println("Could not open Log4J configuration file "
0330:                                        + log4jFile + ": ");
0331:                        fnf.printStackTrace();
0332:                    }
0333:                }
0334:
0335:                // Now report our successful configuration to the world
0336:                log.info("Loaded configuration  (" + confStyle + ") from "
0337:                        + confFile + " (" + confPath + ")");
0338:
0339:                setTurbineServletConfig(config);
0340:                setTurbineServletContext(context);
0341:
0342:                getServiceManager().setApplicationRoot(applicationRoot);
0343:
0344:                // We want to set a few values in the configuration so
0345:                // that ${variable} interpolation will work for
0346:                //
0347:                // ${applicationRoot}
0348:                // ${webappRoot}
0349:                configuration
0350:                        .setProperty(APPLICATION_ROOT_KEY, applicationRoot);
0351:                configuration.setProperty(WEBAPP_ROOT_KEY, webappRoot);
0352:
0353:                //
0354:                // Be sure, that our essential services get run early
0355:                //
0356:                configuration.setProperty(TurbineServices.SERVICE_PREFIX
0357:                        + ComponentService.SERVICE_NAME + ".earlyInit",
0358:                        Boolean.TRUE);
0359:
0360:                configuration.setProperty(TurbineServices.SERVICE_PREFIX
0361:                        + AvalonComponentService.SERVICE_NAME + ".earlyInit",
0362:                        Boolean.TRUE);
0363:
0364:                getServiceManager().setConfiguration(configuration);
0365:
0366:                // Initialize the service manager. Services
0367:                // that have its 'earlyInit' property set to
0368:                // a value of 'true' will be started when
0369:                // the service manager is initialized.
0370:                getServiceManager().init();
0371:
0372:                // Get the default input encoding
0373:                inputEncoding = configuration.getString(
0374:                        TurbineConstants.PARAMETER_ENCODING_KEY,
0375:                        TurbineConstants.PARAMETER_ENCODING_DEFAULT);
0376:
0377:                if (log.isDebugEnabled()) {
0378:                    log
0379:                            .debug("Input Encoding has been set to "
0380:                                    + inputEncoding);
0381:                }
0382:            }
0383:
0384:            /**
0385:             * Create any directories that might be needed during
0386:             * runtime. Right now this includes:
0387:             *
0388:             * <ul>
0389:             *
0390:             * <li>The directory to write the log files to (relative to the
0391:             * web application root), or <code>null</code> for the default of
0392:             * <code>/logs</code>.  The directory is specified via the {@link
0393:             * TurbineConstants#LOGGING_ROOT} parameter.</li>
0394:             *
0395:             * </ul>
0396:             *
0397:             * @param context Global initialization parameters.
0398:             * @param config Initialization parameters specific to the Turbine
0399:             * servlet.
0400:             */
0401:            private static void createRuntimeDirectories(
0402:                    ServletContext context, ServletConfig config) {
0403:                String path = findInitParameter(context, config,
0404:                        LOGGING_ROOT_KEY, LOGGING_ROOT_DEFAULT);
0405:
0406:                File logDir = new File(getRealPath(path));
0407:                if (!logDir.exists()) {
0408:                    // Create the logging directory
0409:                    if (!logDir.mkdirs()) {
0410:                        System.err.println("Cannot create directory for logs!");
0411:                    }
0412:                }
0413:            }
0414:
0415:            /**
0416:             * Finds the specified servlet configuration/initialization
0417:             * parameter, looking first for a servlet-specific parameter, then
0418:             * for a global parameter, and using the provided default if not
0419:             * found.
0420:             */
0421:            protected static final String findInitParameter(
0422:                    ServletContext context, ServletConfig config, String name,
0423:                    String defaultValue) {
0424:                String path = null;
0425:
0426:                // Try the name as provided first.
0427:                boolean usingNamespace = name.startsWith(CONFIG_NAMESPACE);
0428:                while (true) {
0429:                    path = config.getInitParameter(name);
0430:                    if (StringUtils.isEmpty(path)) {
0431:                        path = context.getInitParameter(name);
0432:                        if (StringUtils.isEmpty(path)) {
0433:                            // The named parameter didn't yield a value.
0434:                            if (usingNamespace) {
0435:                                path = defaultValue;
0436:                            } else {
0437:                                // Try again using Turbine's namespace.
0438:                                name = CONFIG_NAMESPACE + '.' + name;
0439:                                usingNamespace = true;
0440:                                continue;
0441:                            }
0442:                        }
0443:                    }
0444:                    break;
0445:                }
0446:
0447:                return path;
0448:            }
0449:
0450:            /**
0451:             * Initializes the services which need <code>RunData</code> to
0452:             * initialize themselves (post startup).
0453:             *
0454:             * @param data The first <code>GET</code> request.
0455:             */
0456:            public final void init(RunData data) {
0457:                synchronized (Turbine.class) {
0458:                    if (firstDoGet) {
0459:                        // All we want to do here is save some servlet
0460:                        // information so that services and processes
0461:                        // that don't have direct access to a RunData
0462:                        // object can still know something about
0463:                        // the servlet environment.
0464:                        saveServletInfo(data);
0465:
0466:                        // Mark that we're done.
0467:                        firstDoGet = false;
0468:                        log.info("Turbine: first Request successful");
0469:                    }
0470:                }
0471:            }
0472:
0473:            /**
0474:             * Return the current configuration with all keys included
0475:             *
0476:             * @return a Configuration Object
0477:             */
0478:            public static Configuration getConfiguration() {
0479:                return configuration;
0480:            }
0481:
0482:            /**
0483:             * Return the server name.
0484:             *
0485:             * @return String server name
0486:             */
0487:            public static String getServerName() {
0488:                return getDefaultServerData().getServerName();
0489:            }
0490:
0491:            /**
0492:             * Return the server scheme.
0493:             *
0494:             * @return String server scheme
0495:             */
0496:            public static String getServerScheme() {
0497:                return getDefaultServerData().getServerScheme();
0498:            }
0499:
0500:            /**
0501:             * Return the server port.
0502:             *
0503:             * @return String server port
0504:             */
0505:            public static String getServerPort() {
0506:                return Integer.toString(getDefaultServerData().getServerPort());
0507:            }
0508:
0509:            /**
0510:             * Get the script name. This is the initial script name.
0511:             * Actually this is probably not needed any more. I'll
0512:             * check. jvz.
0513:             *
0514:             * @return String initial script name.
0515:             */
0516:            public static String getScriptName() {
0517:                return getDefaultServerData().getScriptName();
0518:            }
0519:
0520:            /**
0521:             * Return the context path.
0522:             *
0523:             * @return String context path
0524:             */
0525:            public static String getContextPath() {
0526:                return getDefaultServerData().getContextPath();
0527:            }
0528:
0529:            /**
0530:             * Return all the Turbine Servlet information (Server Name, Port,
0531:             * Scheme in a ServerData structure. This is generated from the
0532:             * values set when initializing the Turbine and may not be correct
0533:             * if you're running in a clustered structure. This might be used
0534:             * if you need a DataURI and have no RunData object handy-
0535:             *
0536:             * @return An initialized ServerData object
0537:             */
0538:            public static ServerData getDefaultServerData() {
0539:                if (serverData == null) {
0540:                    log
0541:                            .error("ServerData Information requested from Turbine before first request!");
0542:                    // Will be overwritten once the first request is run;
0543:                    serverData = new ServerData(null, URIConstants.HTTP_PORT,
0544:                            URIConstants.HTTP, null, null);
0545:                }
0546:                return serverData;
0547:            }
0548:
0549:            /**
0550:             * Set the servlet config for this turbine webapp.
0551:             *
0552:             * @param config New servlet config
0553:             */
0554:            public static void setTurbineServletConfig(ServletConfig config) {
0555:                servletConfig = config;
0556:            }
0557:
0558:            /**
0559:             * Get the servlet config for this turbine webapp.
0560:             *
0561:             * @return ServletConfig
0562:             */
0563:            public static ServletConfig getTurbineServletConfig() {
0564:                return servletConfig;
0565:            }
0566:
0567:            /**
0568:             * Set the servlet context for this turbine webapp.
0569:             *
0570:             * @param context New servlet context.
0571:             */
0572:            public static void setTurbineServletContext(ServletContext context) {
0573:                servletContext = context;
0574:            }
0575:
0576:            /**
0577:             * Get the servlet context for this turbine webapp.
0578:             *
0579:             * @return ServletContext
0580:             */
0581:            public static ServletContext getTurbineServletContext() {
0582:                return servletContext;
0583:            }
0584:
0585:            /**
0586:             * The <code>Servlet</code> destroy method.  Invokes
0587:             * <code>ServiceBroker</code> tear down method.
0588:             */
0589:            public final void destroy() {
0590:                // Shut down all Turbine Services.
0591:                getServiceManager().shutdownServices();
0592:                System.gc();
0593:
0594:                firstInit = true;
0595:                firstDoGet = true;
0596:                log.info("Turbine: Done shutting down!");
0597:            }
0598:
0599:            /**
0600:             * The primary method invoked when the Turbine servlet is executed.
0601:             *
0602:             * @param req Servlet request.
0603:             * @param res Servlet response.
0604:             * @exception IOException a servlet exception.
0605:             * @exception ServletException a servlet exception.
0606:             */
0607:            public final void doGet(HttpServletRequest req,
0608:                    HttpServletResponse res) throws IOException,
0609:                    ServletException {
0610:                // set to true if the request is to be redirected by the page
0611:                boolean requestRedirected = false;
0612:
0613:                // Placeholder for the RunData object.
0614:                RunData data = null;
0615:                try {
0616:                    // Check to make sure that we started up properly.
0617:                    if (initFailure != null) {
0618:                        throw initFailure;
0619:                    }
0620:
0621:                    //
0622:                    // If the servlet container gives us no clear indication about the
0623:                    // Encoding of the contents, set it to our default value.
0624:                    if (req.getCharacterEncoding() == null) {
0625:                        if (log.isDebugEnabled()) {
0626:                            log.debug("Changing Input Encoding to "
0627:                                    + inputEncoding);
0628:                        }
0629:
0630:                        try {
0631:                            req.setCharacterEncoding(inputEncoding);
0632:                        } catch (UnsupportedEncodingException uee) {
0633:                            log.warn("Could not change request encoding to "
0634:                                    + inputEncoding, uee);
0635:                        }
0636:                    }
0637:
0638:                    // Get general RunData here...
0639:                    // Perform turbine specific initialization below.
0640:                    data = rundataService.getRunData(req, res,
0641:                            getServletConfig());
0642:
0643:                    // If this is the first invocation, perform some
0644:                    // initialization.  Certain services need RunData to initialize
0645:                    // themselves.
0646:                    if (firstDoGet) {
0647:                        init(data);
0648:                    }
0649:
0650:                    // set the session timeout if specified in turbine's properties
0651:                    // file if this is a new session
0652:                    if (data.getSession().isNew()) {
0653:                        int timeout = configuration.getInt(SESSION_TIMEOUT_KEY,
0654:                                SESSION_TIMEOUT_DEFAULT);
0655:
0656:                        if (timeout != SESSION_TIMEOUT_DEFAULT) {
0657:                            data.getSession().setMaxInactiveInterval(timeout);
0658:                        }
0659:                    }
0660:
0661:                    // Fill in the screen and action variables.
0662:                    data.setScreen(data.getParameters().getString(
0663:                            URIConstants.CGI_SCREEN_PARAM));
0664:                    data.setAction(data.getParameters().getString(
0665:                            URIConstants.CGI_ACTION_PARAM));
0666:
0667:                    // Special case for login and logout, this must happen before the
0668:                    // session validator is executed in order either to allow a user to
0669:                    // even login, or to ensure that the session validator gets to
0670:                    // mandate its page selection policy for non-logged in users
0671:                    // after the logout has taken place.
0672:                    if (data.hasAction()) {
0673:                        String action = data.getAction();
0674:                        log.debug("action = " + action);
0675:
0676:                        if (action.equalsIgnoreCase(configuration.getString(
0677:                                ACTION_LOGIN_KEY, ACTION_LOGIN_DEFAULT))) {
0678:                            loginAction(data);
0679:                        } else if (action.equalsIgnoreCase(configuration
0680:                                .getString(ACTION_LOGOUT_KEY,
0681:                                        ACTION_LOGOUT_DEFAULT))) {
0682:                            logoutAction(data);
0683:                        }
0684:                    }
0685:
0686:                    // This is where the validation of the Session information
0687:                    // is performed if the user has not logged in yet, then
0688:                    // the screen is set to be Login. This also handles the
0689:                    // case of not having a screen defined by also setting the
0690:                    // screen to Login. If you want people to go to another
0691:                    // screen other than Login, you need to change that within
0692:                    // TurbineResources.properties...screen.homepage; or, you
0693:                    // can specify your own SessionValidator action.
0694:                    ActionLoader.getInstance().exec(
0695:                            data,
0696:                            configuration.getString(
0697:                                    ACTION_SESSION_VALIDATOR_KEY,
0698:                                    ACTION_SESSION_VALIDATOR_DEFAULT));
0699:
0700:                    // Put the Access Control List into the RunData object, so
0701:                    // it is easily available to modules.  It is also placed
0702:                    // into the session for serialization.  Modules can null
0703:                    // out the ACL to force it to be rebuilt based on more
0704:                    // information.
0705:                    ActionLoader.getInstance().exec(
0706:                            data,
0707:                            configuration.getString(
0708:                                    ACTION_ACCESS_CONTROLLER_KEY,
0709:                                    ACTION_ACCESS_CONTROLLER_DEFAULT));
0710:
0711:                    // Start the execution phase. DefaultPage will execute the
0712:                    // appropriate action as well as get the Layout from the
0713:                    // Screen and then execute that. The Layout is then
0714:                    // responsible for executing the Navigation and Screen
0715:                    // modules.
0716:                    //
0717:                    // Note that by default, this cannot be overridden from
0718:                    // parameters passed in via post/query data. This is for
0719:                    // security purposes.  You should really never need more
0720:                    // than just the default page.  If you do, add logic to
0721:                    // DefaultPage to do what you want.
0722:
0723:                    String defaultPage = (templateService == null) ? null
0724:                            : templateService.getDefaultPageName(data);
0725:
0726:                    if (defaultPage == null) {
0727:                        /*
0728:                         * In this case none of the template services are running.
0729:                         * The application may be using ECS for views, or a
0730:                         * decendent of RawScreen is trying to produce output.
0731:                         * If there is a 'page.default' property in the TR.props
0732:                         * then use that, otherwise return DefaultPage which will
0733:                         * handle ECS view scenerios and RawScreen scenerios. The
0734:                         * app developer can still specify the 'page.default'
0735:                         * if they wish but the DefaultPage should work in
0736:                         * most cases.
0737:                         */
0738:                        defaultPage = configuration.getString(PAGE_DEFAULT_KEY,
0739:                                PAGE_DEFAULT_DEFAULT);
0740:                    }
0741:
0742:                    PageLoader.getInstance().exec(data, defaultPage);
0743:
0744:                    // If a module has set data.acl = null, remove acl from
0745:                    // the session.
0746:                    if (data.getACL() == null) {
0747:                        try {
0748:                            data.getSession().removeAttribute(
0749:                                    AccessControlList.SESSION_KEY);
0750:                        } catch (IllegalStateException ignored) {
0751:                        }
0752:                    }
0753:
0754:                    // handle a redirect request
0755:                    requestRedirected = ((data.getRedirectURI() != null) && (data
0756:                            .getRedirectURI().length() > 0));
0757:                    if (requestRedirected) {
0758:                        if (data.getResponse().isCommitted()) {
0759:                            requestRedirected = false;
0760:                            log
0761:                                    .warn("redirect requested, response already committed: "
0762:                                            + data.getRedirectURI());
0763:                        } else {
0764:                            data.getResponse().sendRedirect(
0765:                                    data.getRedirectURI());
0766:                        }
0767:                    }
0768:
0769:                    if (!requestRedirected) {
0770:                        try {
0771:                            if (data.isPageSet() == false
0772:                                    && data.isOutSet() == false) {
0773:                                throw new Exception("Nothing to output");
0774:                            }
0775:
0776:                            // We are all done! if isPageSet() output that way
0777:                            // otherwise, data.getOut() has already been written
0778:                            // to the data.getOut().close() happens below in the
0779:                            // finally.
0780:                            if (data.isPageSet() && data.isOutSet() == false) {
0781:                                // Modules can override these.
0782:                                data.getResponse().setLocale(data.getLocale());
0783:                                data.getResponse().setContentType(
0784:                                        data.getContentType());
0785:
0786:                                // Set the status code.
0787:                                data.getResponse().setStatus(
0788:                                        data.getStatusCode());
0789:                                // Output the Page.
0790:                                data.getPage().output(data.getOut());
0791:                            }
0792:                        } catch (Exception e) {
0793:                            // The output stream was probably closed by the client
0794:                            // end of things ie: the client clicked the Stop
0795:                            // button on the browser, so ignore any errors that
0796:                            // result.
0797:                            log.debug("Output stream closed? ", e);
0798:                        }
0799:                    }
0800:                } catch (Exception e) {
0801:                    handleException(data, res, e);
0802:                } catch (Throwable t) {
0803:                    handleException(data, res, t);
0804:                } finally {
0805:                    // Return the used RunData to the factory for recycling.
0806:                    rundataService.putRunData(data);
0807:                }
0808:            }
0809:
0810:            /**
0811:             * In this application doGet and doPost are the same thing.
0812:             *
0813:             * @param req Servlet request.
0814:             * @param res Servlet response.
0815:             * @exception IOException a servlet exception.
0816:             * @exception ServletException a servlet exception.
0817:             */
0818:            public final void doPost(HttpServletRequest req,
0819:                    HttpServletResponse res) throws IOException,
0820:                    ServletException {
0821:                doGet(req, res);
0822:            }
0823:
0824:            /**
0825:             * This method is executed if the configured Login action should be
0826:             * executed by Turbine.
0827:             * <p>
0828:             * This Action must be performed before the Session validation or we
0829:             * get sent in an endless loop back to the Login screen before
0830:             * the action can be performed
0831:             *
0832:             * @param data a RunData object
0833:             *
0834:             * @throws Exception A problem while logging in occured.
0835:             */
0836:            private void loginAction(RunData data) throws Exception {
0837:                ActionLoader.getInstance().exec(data, data.getAction());
0838:                cleanupTemplateContext(data);
0839:                data.setAction(null);
0840:            }
0841:
0842:            /**
0843:             * This method is executed if the configured Logout action should be
0844:             * executed by Turbine.
0845:             * <p>
0846:             * This Action must be performed before the Session validation for the
0847:             * session validator to send us back to the Login screen.
0848:             * <p>
0849:             * The existing session is invalidated before the logout action is
0850:             * executed.
0851:             *
0852:             * @param data a RunData object
0853:             *
0854:             * @throws Exception A problem while logging out occured.
0855:             */
0856:            private void logoutAction(RunData data) throws Exception {
0857:                ActionLoader.getInstance().exec(data, data.getAction());
0858:                cleanupTemplateContext(data);
0859:                data.setAction(null);
0860:                data.getSession().invalidate();
0861:            }
0862:
0863:            /**
0864:             * cleans the Velocity Context if available.
0865:             *
0866:             * @param data A RunData Object
0867:             *
0868:             * @throws Exception A problem while cleaning out the Template Context occured.
0869:             */
0870:            private void cleanupTemplateContext(RunData data) throws Exception {
0871:                // This is Velocity specific and shouldn't be done here.
0872:                // But this is a band aid until we get real listeners
0873:                // here.
0874:                TemplateInfo ti = data.getTemplateInfo();
0875:                if (ti != null) {
0876:                    ti.removeTemp(VelocityService.CONTEXT);
0877:                }
0878:            }
0879:
0880:            /**
0881:             * Return the servlet info.
0882:             *
0883:             * @return a string with the servlet information.
0884:             */
0885:            public final String getServletInfo() {
0886:                return "Turbine Servlet";
0887:            }
0888:
0889:            /**
0890:             * This method is about making sure that we catch and display
0891:             * errors to the screen in one fashion or another. What happens is
0892:             * that it will attempt to show the error using your user defined
0893:             * Error Screen. If that fails, then it will resort to just
0894:             * displaying the error and logging it all over the place
0895:             * including the servlet engine log file, the Turbine log file and
0896:             * on the screen.
0897:             *
0898:             * @param data A Turbine RunData object.
0899:             * @param res Servlet response.
0900:             * @param t The exception to report.
0901:             */
0902:            private void handleException(RunData data, HttpServletResponse res,
0903:                    Throwable t) {
0904:                // make sure that the stack trace makes it the log
0905:                log.error("Turbine.handleException: ", t);
0906:
0907:                String mimeType = "text/plain";
0908:                try {
0909:                    // This is where we capture all exceptions and show the
0910:                    // Error Screen.
0911:                    data.setStackTrace(ExceptionUtils.getStackTrace(t), t);
0912:
0913:                    // setup the screen
0914:                    data.setScreen(configuration.getString(SCREEN_ERROR_KEY,
0915:                            SCREEN_ERROR_DEFAULT));
0916:
0917:                    // do more screen setup for template execution if needed
0918:                    if (data.getTemplateInfo() != null) {
0919:                        data.getTemplateInfo().setScreenTemplate(
0920:                                configuration.getString(TEMPLATE_ERROR_KEY,
0921:                                        TEMPLATE_ERROR_VM));
0922:                    }
0923:
0924:                    // Make sure to not execute an action.
0925:                    data.setAction("");
0926:
0927:                    PageLoader.getInstance().exec(
0928:                            data,
0929:                            configuration.getString(PAGE_DEFAULT_KEY,
0930:                                    PAGE_DEFAULT_DEFAULT));
0931:
0932:                    data.getResponse().setContentType(data.getContentType());
0933:                    data.getResponse().setStatus(data.getStatusCode());
0934:                    if (data.isPageSet()) {
0935:                        data.getOut().print(data.getPage().toString());
0936:                    }
0937:                }
0938:                // Catch this one because it occurs if some code hasn't been
0939:                // completely re-compiled after a change..
0940:                catch (java.lang.NoSuchFieldError e) {
0941:                    try {
0942:                        data.getResponse().setContentType(mimeType);
0943:                        data.getResponse().setStatus(200);
0944:                    } catch (Exception ignored) {
0945:                        // Ignored
0946:                    }
0947:
0948:                    try {
0949:                        data
0950:                                .getOut()
0951:                                .print(
0952:                                        "java.lang.NoSuchFieldError: "
0953:                                                + "Please recompile all of your source code.");
0954:                    } catch (IOException ignored) {
0955:                    }
0956:
0957:                    log.error(data.getStackTrace(), e);
0958:                }
0959:                // Attempt to do *something* at this point...
0960:                catch (Throwable reallyScrewedNow) {
0961:                    StringBuffer msg = new StringBuffer();
0962:                    msg.append("Horrible Exception: ");
0963:                    if (data != null) {
0964:                        msg.append(data.getStackTrace());
0965:                    } else {
0966:                        msg.append(t);
0967:                    }
0968:                    try {
0969:                        res.setContentType(mimeType);
0970:                        res.setStatus(200);
0971:                        res.getWriter().print(msg.toString());
0972:                    } catch (Exception ignored) {
0973:                    }
0974:
0975:                    log.error(reallyScrewedNow.getMessage(), reallyScrewedNow);
0976:                }
0977:            }
0978:
0979:            /**
0980:             * Save some information about this servlet so that
0981:             * it can be utilized by object instances that do not
0982:             * have direct access to RunData.
0983:             *
0984:             * @param data
0985:             */
0986:            public static synchronized void saveServletInfo(RunData data) {
0987:                // Store the context path for tools like ContentURI and
0988:                // the UIManager that use webapp context path information
0989:                // for constructing URLs.
0990:
0991:                //
0992:                // Bundle all the information above up into a convenient structure
0993:                //
0994:                serverData = (ServerData) data.getServerData().clone();
0995:            }
0996:
0997:            /**
0998:             * Set the application root for the webapp.
0999:             *
1000:             * @param val New app root.
1001:             */
1002:            public static void setApplicationRoot(String val) {
1003:                applicationRoot = val;
1004:            }
1005:
1006:            /**
1007:             * Get the application root for this Turbine webapp. This
1008:             * concept was started in 3.0 and will allow an app to be
1009:             * developed from a standard CVS layout. With a simple
1010:             * switch the app will work fully within the servlet
1011:             * container for deployment.
1012:             *
1013:             * @return String applicationRoot
1014:             */
1015:            public static String getApplicationRoot() {
1016:                return applicationRoot;
1017:            }
1018:
1019:            /**
1020:             * Used to get the real path of configuration and resource
1021:             * information. This can be used by an app being
1022:             * developed in a standard CVS layout.
1023:             *
1024:             * @param path path translated to the application root
1025:             * @return the real path
1026:             */
1027:            public static String getRealPath(String path) {
1028:                if (path.startsWith("/")) {
1029:                    path = path.substring(1);
1030:                }
1031:
1032:                return new File(getApplicationRoot(), path).getAbsolutePath();
1033:            }
1034:
1035:            /**
1036:             * Return an instance of the currently configured Service Manager
1037:             *
1038:             * @return A service Manager instance
1039:             */
1040:            private ServiceManager getServiceManager() {
1041:                return TurbineServices.getInstance();
1042:            }
1043:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.