0001: /*
0002: * Copyright 2001 Sun Microsystems, Inc. All rights reserved.
0003: * PROPRIETARY/CONFIDENTIAL. Use of this product is subject to license terms.
0004: */
0005: package com.sun.portal.providers.jsp;
0006:
0007: import com.sun.portal.providers.ProfileProviderAdapter;
0008: import com.sun.portal.providers.ProviderException;
0009: import com.sun.portal.providers.context.ProviderContext;
0010: import com.sun.portal.providers.context.ProviderContextException;
0011:
0012: import com.sun.portal.desktop.context.DesktopContext;
0013: import com.sun.portal.desktop.context.DesktopAppContext;
0014: import com.sun.portal.desktop.context.DesktopAppContextThreadLocalizer;
0015: import com.sun.portal.desktop.context.DesktopContextThreadLocalizer;
0016: import com.sun.portal.desktop.context.ContextException;
0017:
0018: import java.util.HashMap;
0019: import java.util.Map;
0020: import java.util.Hashtable;
0021: import java.util.Enumeration;
0022: import java.util.Properties;
0023: import java.util.logging.Logger;
0024: import java.util.logging.Level;
0025: import java.util.logging.LogRecord;
0026:
0027: import java.io.StringWriter;
0028: import java.io.PrintWriter;
0029: import java.io.FileInputStream;
0030: import java.io.IOException;
0031: import java.io.FileNotFoundException;
0032: import java.io.File;
0033:
0034: import java.net.URL;
0035: import java.net.MalformedURLException;
0036: import java.net.URLDecoder;
0037:
0038: import javax.servlet.ServletException;
0039: import javax.servlet.http.Cookie;
0040: import javax.servlet.http.HttpServletResponse;
0041: import javax.servlet.http.HttpServletRequest;
0042:
0043: //A@ we now import our own Jspfactory instead of the one from the JSP
0044: //spec in order to have our own singleton
0045: import com.sun.portal.providers.jsp.jasper3.jasper.JspFactory;
0046:
0047: import com.sun.portal.desktop.context.ProviderClassLoader;
0048: import com.sun.portal.desktop.ubt.DesktopEvents;
0049: import com.sun.portal.desktop.ubt.ProviderLogRecord;
0050: import com.sun.portal.desktop.TypedException;
0051: import com.sun.portal.ubt.UBTLogManager;
0052: import com.sun.portal.ubt.UBTEvent;
0053: import com.sun.portal.ubt.UBTLogField;
0054: import com.sun.portal.log.common.PortalLogger;
0055:
0056: /**
0057: * A <code>JSPProvider</code> is a content provider that can use <a
0058: * href="http://java.sun.com/products/jsp/" target=_top>JavaServer Pages</a>
0059: * (JSPs) to create the content for a channel on the desktop.
0060: * <p/>
0061: * <p>A <i>provider</i> is responsible for providing the HTML content
0062: * for a channel as well as defining the various attributes for a
0063: * channel (title, description, etc.) and optionally implementing edit
0064: * functionality (one or more edit pages and the logic for processing
0065: * changes to the channel).
0066: * <p/>
0067: * <p>JavaServer Pages is a alternative technology for defining web
0068: * pages that provides <a
0069: * href="http://java.sun.com/products/jsp/whitepaper.html" target=_top> several
0070: * advantages</a> over Java servlet development. These same advantages
0071: * apply to the idea of developing Portal Server desktop channels
0072: * using JavaServer Pages. Several key advantages include:
0073: * <p/>
0074: * <ul> <li> Separation of presentation from business logic. The
0075: * HTML tags associated with a channel can be placed in the JSP file,
0076: * while the Java code that is needed to generate the content can be
0077: * placed either in the provider or in a separate class.</li>
0078: * <p/>
0079: * <li>A standard template mechanism. Any proprietary templating mechanism
0080: * does not provide the flexibility that is available with the open standard of JSPs.</li>
0081: * <p/>
0082: * <li>Rapid development. Development of a JSP is easier from
0083: * the developer perspective than creation of a provider. The
0084: * <code>JSPProvider</code> can update a JSP without restarting the web
0085: * server.</li>
0086: * <p/>
0087: * </ul>
0088: * <p/>
0089: * The JSPProvider class provides the following features:
0090: * <ul>
0091: * <p/>
0092: * <li>Configuration of several JSPs to form a provider.</li>
0093: * <p/>
0094: * <li>Access to Sun ONE Portal Server platform services used by the
0095: * JSP. <code>JSPProvider</code> extends the
0096: * <code>ProfileProviderAdapter</code> class so it supports setting of
0097: * various other attributes for the channel.</li>
0098: * <p/>
0099: * <li>Support for efficient execution of JSP-based providers.
0100: * JSPProvider implements a JSP engine so that JSPs are executed
0101: * directly by the provider, not via another connection to a web
0102: * server.</li>
0103: * <p/>
0104: * </ul>
0105: * <p/>
0106: * <p>JSPProvider channels are typically created by using the channel
0107: * wizard in the administration console to add a JSP channel to the
0108: * desktop. Along with the attributes that are common to all
0109: * providers that are based on <code>ProviderContext</code>,
0110: * <code>JSPProvider</code> supports the following unique attributes:
0111: * <p/>
0112: * <ul>
0113: * <p/>
0114: * <li><b>contentPage</b> - the JSP that is used to generate the
0115: * channel content (via the getContent method)</li>
0116: * <p/>
0117: * <li><b>editPage</b> - the JSP that is used to generate the edit
0118: * page content (via the getEdit method)</li>
0119: * <p/>
0120: * <li><b>processPage</b> - the JSP that is used to process the
0121: * results of an edit page (via the processEdit method).</li>
0122: * <p/>
0123: * <li><b>showExceptions</b> - if true, <code>JSPProvider</code> shows
0124: * exceptions generated while processing the JSP as the channel output
0125: * for the <code>getContent</code> and <code>getEdit</code> methods.
0126: * This can be useful during development.
0127: * <p/>
0128: * </ul>
0129: * <p/>
0130: * <p>The contentPage JSP generates the HTML content for the
0131: * channel. The generated HTML must contain only those tags that
0132: * are appropriate for display within a channel. The JSP has
0133: * access to Sun ONE Portal Server platform services via the mechanisms described <a
0134: * href="#serviceAccess">below</a>.
0135: * <p/>
0136: * <p>The editPage JSP generates the internals for the edit form that
0137: * is displayed when the user clicks the Edit button for the
0138: * channel. This page is optional. As with the contentPage JSP,
0139: * the JSP has access to Sun ONE Portal Server platform services.
0140: * <p/>
0141: * <p>The contentPage and editPage JSPs can be used in various
0142: * combinations. For example, a JSP could be used to generate
0143: * the content while the edit page could be generated using Java code
0144: * in a class that extends <code>JSPProvider</code>.
0145: * <p/>
0146: * <p>There are several options for handling the processing of an edit
0147: * form for a JSP-based provider. Typically, processing of the
0148: * edit form consists of Java code that checks validity of the form
0149: * entry and updates user preferences for the channel. The
0150: * result is either a redisplay of the desktop (in the case of
0151: * success) or a redisplay of the edit page, possibly with some error
0152: * information for the user (in the case of a failure). To
0153: * handle the processing of an edit form, the JSP-based provider has
0154: * the following options:
0155: * <p/>
0156: * <ul>
0157: * <p/>
0158: * <li>Define a processPage JSP. If defined, this JSP is invoked
0159: * and the JSP can process the results, either using a scriptlet or a
0160: * bean or other Java class.
0161: * <ul>
0162: * <p/>
0163: * <li>If the JSP returns normally (an HTTP 200 response), the
0164: * <code>processEdit</code> method for the provider returns null, which causes a
0165: * redisplay of the desktop.</li>
0166: * <p/>
0167: * <li>Or, the JSP can produce a redirect in the response by calling
0168: * <code>response.sendRedirect</code>. In this case, the
0169: * <code>processEdit</code> method for the provider returns the value
0170: * of the redirect.</li>
0171: * <p/>
0172: * </ul>
0173: * <p/>
0174: * </li>
0175: * <p/>
0176: * <li>Extend the JSPProvider class and implement the processEdit
0177: * method. The processPage attribute is left blank.</li>
0178: * <p/>
0179: * </ul>
0180: * <p/>
0181: * <p><a name="fileSearch"></a><b>File Searching</b>
0182: * <p/>
0183: * <p>When specifying a JSP in one of the JSP attributes, the path
0184: * name is interpreted relative to the desktop template directory for
0185: * the user using the same algorithm as for other desktop templates
0186: * including inclusion of the desktop type and locale settings, providerName,
0187: * channelName and the clientPath. For example, if the user's locale is de_DE,
0188: * desktop type is SunBlue, provider name is myProvider, channel name is myChan,
0189: * clientPath is wml/noki
0190: * and a JSP attribute is set to chan.jsp, <code>JSPProvider</code>
0191: * searches for the following JSP files:
0192: * <p/>
0193: * <br> <code>/etc/opt/SUNWportal/desktop/SunBlue_de_DE/myChan/wml/noki/chan.jsp</code>
0194: * <br> <code>/etc/opt/SUNWportal/desktop/SunBlue_de_DE/myProvider/wml/noki/chan.jsp</code>
0195: * <br> <code>/etc/opt/SUNWportal/desktop/SunBlue_de_DE/myChan/wml/chan.jsp</code>
0196: * <br> <code>/etc/opt/SUNWportal/desktop/SunBlue_de_DE/myProvider/wml/chan.jsp</code>
0197: * <br> <code>/etc/opt/SUNWportal/desktop/SunBlue_de_DE/myChan/chan.jsp</code>
0198: * <br> <code>/etc/opt/SUNWportal/desktop/SunBlue_de_DE/myProvider/chan.jsp</code>
0199: * <br> <code>/etc/opt/SUNWportal/desktop/SunBlue_de_DE/chan.jsp</code>
0200: * <br> <code>/etc/opt/SUNWportal/desktop/SunBlue/myChan/wml/noki/chan.jsp</code>
0201: * <br> <code>/etc/opt/SUNWportal/desktop/SunBlue/myProvider/wml/noki/chan.jsp</code>
0202: * <br> <code>/etc/opt/SUNWportal/desktop/SunBlue/myChan/wml/chan.jsp</code>
0203: * <br> <code>/etc/opt/SUNWportal/desktop/SunBlue/myProvider/wml/chan.jsp</code>
0204: * <br> <code>/etc/opt/SUNWportal/desktop/SunBlue/myChan/chan.jsp</code>
0205: * <br> <code>/etc/opt/SUNWportal/desktop/SunBlue/myProvider/chan.jsp</code>
0206: * <br> <code>/etc/opt/SUNWportal/desktop/SunBlue/chan.jsp</code>
0207: * <br> <code>/etc/opt/SUNWportal/desktop/default_de_DE/myChan/wml/noki/chan.jsp</code>
0208: * <br> <code>/etc/opt/SUNWportal/desktop/default_de_DE/myProvider/wml/noki/chan.jsp</code>
0209: * <br> <code>/etc/opt/SUNWportal/desktop/default_de_DE/myChan/wml/chan.jsp</code>
0210: * <br> <code>/etc/opt/SUNWportal/desktop/default_de_DE/myProvider/wml/chan.jsp</code>
0211: * <br> <code>/etc/opt/SUNWportal/desktop/default_de_DE/myChan/chan.jsp</code>
0212: * <br> <code>/etc/opt/SUNWportal/desktop/default_de_DE/myProvider/chan.jsp</code>
0213: * <br> <code>/etc/opt/SUNWportal/desktop/default_de_DE/chan.jsp</code>
0214: * <br> <code>/etc/opt/SUNWportal/desktop/default/myChan/wml/noki/chan.jsp</code>
0215: * <br> <code>/etc/opt/SUNWportal/desktop/default/myProvider/wml/noki/chan.jsp</code>
0216: * <br> <code>/etc/opt/SUNWportal/desktop/default/myChan/wml/chan.jsp</code>
0217: * <br> <code>/etc/opt/SUNWportal/desktop/default/myProvider/wml/chan.jsp</code>
0218: * <br> <code>/etc/opt/SUNWportal/desktop/default/myChan/chan.jsp</code>
0219: * <br> <code>/etc/opt/SUNWportal/desktop/default/myProvider/chan.jsp</code>
0220: * <br> <code>/etc/opt/SUNWportal/desktop/default/chan.jsp</code>
0221: * <p/>
0222: * <p>The root of the search directory (default value: <code>/etc/opt/SUNWportal/desktop/</code>) can
0223: * be changed by modifying the <code>templateBaseDir</code> property in the "dtconfig.properties" file.
0224: * <p/>
0225: * <p><a name="compilationMode"></a><b>JSP Compilation Path</b>
0226: * <p/>
0227: * <p>
0228: * JSPProvider has two JSP compilation modes.
0229: * JSPs are either compiled to
0230: * the <i>most specific JSP path</i> or the <i>real JSP path</i>.
0231: * Most specific path mode ensures
0232: * that the correct statically
0233: * included JSPs are compiled into the JSP class.
0234: * JSP class packages are are based on their most specific path. See
0235: * javadocs for the method <code>getMostSpecificPath()</code> for details.
0236: * This allows both static includer and includee JSP source files to be shared
0237: * at various levels of specificity in the
0238: * <a href="#fileSearch">file search path</a>
0239: * of JSPProvider. The problem with this approach is that it does not allow
0240: * compiled JSP classes to be shared in situations where the JSP source is
0241: * the same physical JSP file.
0242: * <p>
0243: * Real path compilation mode allows
0244: * JSPProvider to share compiled JSP classes,
0245: * at the expense of less flexibility in sharing the source
0246: * JSPs. Specifically, the rule when operating in this mode is:
0247: * <i>if a JSP statically includes another JSP, the static includee must
0248: * be in the same directory path as the static includer.</i>
0249: * In cases where there is complex sharing arrangement, with different
0250: * versions of JSPs at different levels of specificity in the
0251: * <a href="#fileSearch">file search path</a>, this is undesirable,
0252: * and JSPProvider should be used in most specific path compilation mode.
0253: * However, if all JSPs are co-located in a single directory,
0254: * real path compilation mode
0255: * will optimize compilation, resulting in far fewer compiled JSP classes.
0256: * </p>
0257: * <p>
0258: * For an example where real path compilation mode is useful,
0259: * consider the case where all
0260: * JSPs are defined in a provider-specific directory, with no channel
0261: * specific directories for the many channels based on said provider.
0262: * In most specific path compilation mode, JSPProvider
0263: * will compile a new set of JSPs for every channel.
0264: * However, in real path compilation mode, JSPProvider will only
0265: * compile the JSPs once and will share
0266: * the compiled classes between all channels based on the provider.
0267: * </p>
0268: * <p>
0269: * Compilation mode is configured via JSPProvider's
0270: * <code>compileToRealPath</code> boolean property.
0271: * If the property's value is <i>true</i>, JSPProvider will
0272: * operate in real path compilation mode. If this property's value is
0273: * <i>false</i>, or if the property is non-existent, JSPProvider will
0274: * operate in most specific compiled path mode.
0275: * </p>
0276: * <p>
0277: * Extending classes may further modify JSP path derivation behavior
0278: * by overriding the <code>getMostSpecificJSPPath()</code>,
0279: * <code>getCompiledJSPPath()</code>,
0280: * and <code>getExistingJSPPath()</code> methods. See the javadocs
0281: * of these methods for details.
0282: * </p>
0283: * <p><a name=serviceAccess></a><b>Accessing Sun Portal Server Services</b>
0284: * <p/>
0285: * <p>A JSP-based provider may need access to service APIs that are
0286: * provided by the Portal Server platform. A Java-based provider
0287: * accesses these services by either using Provider API methods such
0288: * as ProfileProviderAdapter.getProperty or by invoking Sun ONE Portal Server APIs
0289: * directly Examples might include:
0290: * <p/>
0291: * <ul>
0292: * <li>reading display profile information (<code>ProfileProviderAdapter getStringProperty</code> method)</li>
0293: * <li>reading user profile information (<code>getProviderContext().getStringAttribute()</code>)</li>
0294: * <p/>
0295: * </ul>
0296: * <p/>
0297: * <p>Typically a JSP-based provider consists of one or more JSP
0298: * files, beans or other Java classes that implement business logic,
0299: * and possibly a Java class that extends JSPProvider. Access to
0300: * Sun Portal Server services is needed in all of these places. A Java class
0301: * that extends JSPProvider already has access to all of the APIs, so
0302: * that case is handled. For all other cases,
0303: * <code>JSPProvider</code> provides the <i>JSPProvider</i>
0304: * <code>pageContext</code> attribute for the JSP and other supporting
0305: * classes to access the Sun Portal Server services.
0306: * <p/>
0307: * <p>Every JSP has access to several implicit objects. One of
0308: * these, called <code>pageContext</code>, represents the context
0309: * within which the page executes. The
0310: * <code>pageContext.getAttribute</code> method allows an arbitrary
0311: * object to be retrieved from the <code>pageContext</code>. The
0312: * <code>JSPProvider</code> defines a <i>JSPProvider</i> attribute
0313: * that provides access to the provider object that is executing the
0314: * JSP. This may be a <code>JSPProvider</code> object or a class that
0315: * is extended from <code>JSPProvider</code>.
0316: * <p/>
0317: * <p>Once the JSP has access to the provider object, it can use
0318: * methods in the JSPProvider class to access Sun ONE Portal Server services,
0319: * or it can pass this object to other objects so that they can access
0320: * Sun ONE Portal Server services. Please refer to the Sample JSP Provider or
0321: * other Sun ONE Portal Server JSP Providers for code examples.
0322: * <p/>
0323: * <p><b>JSP Engine</b>
0324: * <p/>
0325: * <p>The JSP engine used by <code>JSPProvider</code> supports the
0326: * same set of JSP features as is supported by the Sun ONE Web Server
0327: * that is included with Portal Server.
0328: * <p/>
0329: * <p>Any classes or beans that are accessed by JSPs must be placed into
0330: * the directory that is specified in the <code>providerClassBaseDir</code> property
0331: * in the "dtconfig.properties" file (or the server specific configuration file).
0332: * <p/>
0333: * <a name=scratchdir></a><p>Each JSP is compiled by the JSP engine
0334: * into a Java file and then the Java file is compiled by the JDK into
0335: * class files. These files are saved in a scratch directory which is
0336: * the subdirectory "tmp" under servlet init parameter "server.root" specified
0337: * in the web.xml.
0338: * <p/>
0339: * <p><b>Troubleshooting</b>
0340: * <p/>
0341: * <p>During development of JSP-based channels, there are several
0342: * techniques available for debugging problems.
0343: * <p/>
0344: * <p>The <code>showExceptions</code> attribute can be turned on for a
0345: * channel. This will cause exception messages to be displayed in the user desktop for the
0346: * getContent and getEdit methods.
0347: * <p/>
0348: * <p>Error messages from <code>JSPProvider</code> are printed in
0349: * the <code>desktop.debug</code> file in <code>/var/opt/SUNWam/debug</code>. If the
0350: * <code>showExceptions</code> attribute is turned off, this is where
0351: * to look for exception messages.
0352: * <p/>
0353: * <p>When the JSP file is changed on disk, the JSP is automatically
0354: * recompiled and reloaded without restarting the web server or
0355: * logging out and logging back in. However, as with other channels
0356: * that use <code>ProfileProviderAdapter</code>, user attributes are
0357: * not reread unless you logout and log back in.
0358: * <p/>
0359: * <p>JSP are compiled into Java files and the output is put into the
0360: * <a href=#scratchdir>scratch directory</a>. Sometimes looking at the
0361: * Java code can reveal problems in the JSP.
0362: * <p/>
0363: * <p/>
0364: *
0365: * @see com.sun.portal.providers.Provider
0366: * @see com.sun.portal.providers.ProfileProviderAdapter
0367: */
0368:
0369: public class JSPProvider extends ProfileProviderAdapter {
0370: private static HashMap cachedJsps = new HashMap();
0371: private static JspFactory theJspFactory = new JspFactoryImpl();
0372: private static String jspCompilerClassPath = null;
0373:
0374: JspSession jspsession = new JspSession();
0375: JspServletEnvironment jspEnv = null;
0376: JspServletWrapper contentWrapper = null;
0377: JspServletWrapper editWrapper = null;
0378: JspServletWrapper processWrapper = null;
0379:
0380: //
0381: // presentability is cached and used only if the session
0382: // is not authless. otherwise, it is calculated
0383: // each request.
0384: //
0385: // another impl option would be to cache presentability
0386: // per client type. however, this would require use of
0387: // a synchronized table. it is unclear if this would help
0388: // performance overall.
0389: //
0390: private Boolean isPresentable = null;
0391:
0392: private boolean compileToRealPath;
0393:
0394: private String providerClassDir = null;
0395:
0396: private static Logger logger = PortalLogger
0397: .getLogger(JSPProvider.class);
0398:
0399: /**
0400: * Constructs a JSPProvider.
0401: */
0402: public JSPProvider() {
0403: }
0404:
0405: /**
0406: * Initializes the JSPProvider.
0407: * <p/>
0408: * If additional initialization is required by a provider that
0409: * extends JSPProvider, this method may be overriden. However, the
0410: * overriding <code>init()</code> call
0411: * must always have
0412: * <code>super.init()</code> as the first statement
0413: * executed.
0414: *
0415: * @param n The unique indentifying name for this channel.
0416: * @param httpreq HttpServletRequest wrapper.
0417: * @throws ProviderException If ProfileProviderAdapter.init throws an exception
0418: * @see com.sun.portal.providers.Provider#init
0419: */
0420:
0421: public void init(String n, HttpServletRequest httpreq)
0422: throws ProviderException {
0423: super .init(n, httpreq);
0424:
0425: if (existsBooleanProperty("compileToRealPath")) {
0426: compileToRealPath = getBooleanProperty("compileToRealPath");
0427: } else {
0428: compileToRealPath = false;
0429: }
0430:
0431: String clientType = null;
0432: String clientPath = null;
0433:
0434: clientType = getProviderContext().getClientType();
0435: if (clientType != null) {
0436: clientPath = getProviderContext().getClientProperty(
0437: "filePath");
0438: }
0439:
0440: //jspRootDir = .jsp template file directory, where the jsps live
0441: //jspScratchDir = where the temporary servlets created out of a jsp live
0442: //providerClassDir = where the provider class files live (not temp servlets)
0443:
0444: DesktopContext dc = DesktopContextThreadLocalizer.get();
0445: String jspScratchDir = dc.getJSPScratchDir();
0446: providerClassDir = dc.getProviderClassBaseDir();
0447:
0448: if (jspCompilerClassPath == null) {
0449: //
0450: // try to get the war classpath from the servlet context
0451: // object. iws sticks it here.
0452: //
0453: String jspCompilerWARClassPath = (String) getProviderContext()
0454: .getServletContext()
0455: .getAttribute(
0456: com.sun.portal.providers.jsp.jasper3.jasper.Constants.SERVLET_CLASSPATH);
0457:
0458: if (jspCompilerWARClassPath == null) {
0459: //
0460: // can't find it in the servlet context, we must be running
0461: // ias. try to read it from the config properties file.
0462: //
0463: jspCompilerWARClassPath = dc
0464: .getJSPCompilerWARClassPath();
0465: }
0466:
0467: if (jspCompilerWARClassPath == null) {
0468: //
0469: // can't get the war class path
0470: //
0471: if (logger.isLoggable(Level.SEVERE)) {
0472: logger.severe("PSDT_CSPPJ0001");
0473: }
0474: throw new ProviderException(
0475: "JSPProvider.init(): couldn't get WAR class path");
0476: }
0477:
0478: // create the jsp compiler class path from the war class path
0479: // plus the system class path
0480: //
0481: initCompilerCP(jspCompilerWARClassPath);
0482: }
0483:
0484: String desktopType = dc.getDesktopType();
0485: String userLocale = dc.getLocaleString();
0486:
0487: jspEnv = new JspServletEnvironment(this , getName(),
0488: jspScratchDir, desktopType, userLocale, clientPath,
0489: jspCompilerClassPath);
0490:
0491: jspsession.setServletContext(jspEnv);
0492:
0493: //
0494: // pre-calculate presentability
0495: // in the non-authless case in order to
0496: // prevent re-calc'ing it each request
0497: //
0498: if (!getProviderContext().isAuthless(httpreq)) {
0499: if (isPresentable(httpreq)) {
0500: isPresentable = Boolean.TRUE;
0501: } else {
0502: isPresentable = Boolean.FALSE;
0503: }
0504:
0505: }
0506: }
0507:
0508: private static synchronized void initCompilerCP(
0509: String jspCompilerWARClassPath) {
0510: String javaClassPath = System.getProperties().getProperty(
0511: "java.class.path");
0512: int len = 0;
0513: if (javaClassPath != null) {
0514: len = jspCompilerWARClassPath.length()
0515: + javaClassPath.length() + 1;
0516: jspCompilerClassPath = new StringBuffer(len).append(
0517: jspCompilerWARClassPath).append(
0518: File.pathSeparatorChar).append(javaClassPath)
0519: .toString();
0520: } else {
0521: jspCompilerClassPath = jspCompilerWARClassPath;
0522: }
0523: }
0524:
0525: /**
0526: * <p>Dictates whether the provider is presentable.
0527: * <p/>
0528: * <p>Searches for the JSP specified in the <code>contentPage</code>
0529: * attribute. If the JSP is found , then returns <code>true</code>.
0530: * If the <code>contentPage</code>
0531: * attribute is not specified, or if the JSP file is not found, then the
0532: * superclass method is called.
0533: *
0534: * @param req An HttpServletRequest that contains
0535: * the request the client made of the provider.
0536: * @return <code>boolean</code> value dictating presentability
0537: * @see com.sun.portal.providers.ProviderAdapter#isPresentable
0538: */
0539: public boolean isPresentable(HttpServletRequest req) {
0540: boolean ip = false;
0541:
0542: if (isPresentable != null) {
0543: ip = isPresentable.booleanValue();
0544: } else {
0545: ip = contentPageExists();
0546:
0547: //
0548: // if the jsp content page name was blank
0549: // or if the content page does not exist
0550: // then defer to super
0551: //
0552:
0553: if (ip == false) {
0554: ip = super .isPresentable(req);
0555: }
0556: }
0557:
0558: return ip;
0559: }
0560:
0561: private boolean contentPageExists() {
0562: boolean exists = false;
0563:
0564: try {
0565: String jsp = getStringProperty("contentPage");
0566: if (jsp.length() != 0) {
0567:
0568: //
0569: // seperate uri and query string
0570: //
0571:
0572: int index = jsp.indexOf('?');
0573: String uri = jsp;
0574:
0575: if (index != -1) {
0576: uri = jsp.substring(0, index);
0577: }
0578:
0579: File fullJspPath = getExistingJSPPath(
0580: getProviderContext(), getName(), uri);
0581: if (fullJspPath != null) {
0582: exists = true;
0583: }
0584: }
0585: } catch (ProviderException pe) {
0586: // nothing, ip is already initialized to false
0587: }
0588:
0589: return exists;
0590: }
0591:
0592: /**
0593: * Gets the name of the content page JSP for the provider.
0594: *
0595: * @return <code>String</code> value that is the name of content page JSP for the provider
0596: * @throws ProviderException If there is an exception thrown by getStringProperty
0597: */
0598:
0599: protected String getContentPage() throws ProviderException {
0600: return getStringProperty("contentPage");
0601: }
0602:
0603: /**
0604: * Gets the name of the edit page JSP for the provider.
0605: *
0606: * @return <code>String</code> value that is the name of edit page JSP for the provider
0607: * @throws ProviderException If there is an exception thrown by getStringProperty
0608: */
0609:
0610: protected String getEditPage() throws ProviderException {
0611: return getStringProperty("editPage");
0612: }
0613:
0614: /**
0615: * Gets the name of the process page JSP for the provider.
0616: *
0617: * @return <code>String</code> value that is the name of process page JSP for the provider
0618: * @throws ProviderException If there is an exception thrown by getStringProperty
0619: */
0620:
0621: protected String getProcessPage() throws ProviderException {
0622: return getStringProperty("processPage");
0623: }
0624:
0625: /**
0626: * Gets the provider's content by executing a JSP.
0627: * <p/>
0628: * If the <code>contentPage</code> attribute has a value, it is
0629: * used as the name of a JSP to execute per the search algorithm
0630: * defined above. The body of the response is returned as the
0631: * value for the method. If the <code>contentPage</code> attribute
0632: * is blank, the superclass method is called.
0633: * <p/>
0634: * The following values from the request are passed on to the JSP servlet:
0635: * <ul>
0636: * <li>cookies
0637: * <li>parameters
0638: * </ul>
0639: *
0640: * @param req An HttpServletRequest that contains information related to this
0641: * request for content.
0642: * @param res An HttpServletResponse that allows the provider to influence the
0643: * overall response for the desktop page (besides generating the content).
0644: * @return StringBuffer holding the channel content.
0645: * @throws ProviderException If there was an error generating the
0646: * content. Upon catching this error, the desktop application will
0647: * attempt to fetch a cached copy of the content. If a cached copy
0648: * does not exist, then an error message will be displayed in the body
0649: * of the provider.
0650: * @see com.sun.portal.providers.ProfileProviderAdapter#getContent
0651: */
0652: public StringBuffer getContent(HttpServletRequest req,
0653: HttpServletResponse res) throws ProviderException {
0654: String jsp = getContentPage();
0655: if (jsp.length() == 0 || jsp == null) {
0656: return super .getContent(req, res);
0657: }
0658:
0659: try {
0660: if (contentWrapper == null || contentWrapper.expired()
0661: || (!contentWrapper.getURI().equals(jsp))) {
0662: contentWrapper = getJspWrapper(jsp);
0663: }
0664:
0665: Response jres = processJspFile(contentWrapper, req, res);
0666: if (jres.getStatus() == HttpServletResponse.SC_OK) {
0667: return jres.getBody();
0668: } else if (jres.getStatus() == HttpServletResponse.SC_MOVED_TEMPORARILY) {
0669: try {
0670: res.sendRedirect(jres.getLocation().toString());
0671: return jres.getBody();
0672: } catch (IOException e) {
0673: if (logger.isLoggable(Level.INFO)) {
0674: LogRecord record = new LogRecord(Level.INFO,
0675: "PSDT_CSPPJ0003");
0676: record.setLoggerName(logger.getName());
0677: record.setParameters(new Object[] { jsp });
0678: record.setThrown(e);
0679: logger.log(record);
0680: }
0681: throw new ProviderException(getName()
0682: + ": contentPage JSP = " + jsp
0683: + ", status code = " + jres.getStatus(), e);
0684: }
0685: } else {
0686: logger.log(Level.INFO, "PSDT_CSPPJ0002", new Object[] {
0687: jsp, new Integer(jres.getStatus()) });
0688: throw new ProviderException(getName()
0689: + ": contentPage JSP =" + jsp
0690: + ", status code =" + jres.getStatus());
0691: }
0692: } catch (ProviderException pe) {
0693: if (logger.isLoggable(Level.INFO)) {
0694: LogRecord record = new LogRecord(Level.INFO,
0695: "PSDT_CSPPJ0003");
0696: record.setLoggerName(logger.getName());
0697: record.setParameters(new Object[] { jsp });
0698: record.setThrown(pe);
0699: logger.log(record);
0700: }
0701:
0702: return handleException(pe);
0703: }
0704: }
0705:
0706: /**
0707: * Gets the provider's edit page by executing a JSP.
0708: * <p/>
0709: * If the <code>editPage</code> attribute has a value, it is
0710: * used as the name of a JSP to execute per the search algorithm
0711: * defined above. The body of the response is returned as the
0712: * value for the method. If the <code>editPage</code> attribute
0713: * is blank, the superclass method is called.
0714: * <p/>
0715: * The following values from the request are passed on to the JSP servlet:
0716: * <ul>
0717: * <li>cookies
0718: * <li>parameters
0719: * </ul>
0720: *
0721: * @param req An HttpServletRequest that contains information related to this
0722: * request for content.
0723: * @param res An HttpServletResponse that allows the provider to influence the
0724: * overall response for the desktop page (besides generating the content).
0725: * @return StringBuffer holding the channel edit page.
0726: * @throws ProviderException If there was an error generating the content.
0727: * @see com.sun.portal.providers.ProfileProviderAdapter#getEdit
0728: */
0729: public StringBuffer getEdit(HttpServletRequest req,
0730: HttpServletResponse res) throws ProviderException {
0731: //UBT code - start
0732: try {
0733: UBTLogManager manager = UBTLogManager.getInstance();
0734: if (manager.isUBTEnabled()
0735: && !(this instanceof com.sun.portal.providers.window.WindowProvider)
0736: && !(req.getParameter("targetprovider") != null && req
0737: .getParameter("targetprovider").equals(
0738: getName()))) {
0739: UBTEvent prov_ren = UBTEvent
0740: .getInstance(DesktopEvents.USER_CLICK_CHN);
0741: prov_ren.put(UBTLogField.CHANNEL_NAME, req
0742: .getParameter("targetprovider"));
0743: prov_ren.put(UBTLogField.TARGET_PROVIDER, getName());
0744: prov_ren
0745: .put(UBTLogField.PROVIDER, getClass().getName());
0746: prov_ren.put(UBTLogField.CONTAINER_NAME,
0747: getProviderContext().getParentContainerName(
0748: req.getParameter("provider")));
0749: prov_ren.put(UBTLogField.ACTION, "Edit");
0750: prov_ren.put(UBTLogField.MODE, "Edit");
0751: manager.logEvent(new ProviderLogRecord(prov_ren, req,
0752: res, getProviderContext().getUserID()));
0753: }
0754: } catch (Exception e) {
0755: logger.log(Level.INFO, "PSDT_CSPPJ0004", e);
0756: }
0757: //UBT code - end
0758: String jsp = getEditPage();
0759:
0760: if (jsp.length() == 0 || jsp == null) {
0761: return super .getEdit(req, res);
0762: }
0763: try {
0764: if (editWrapper == null || editWrapper.expired()
0765: || (!editWrapper.getURI().equals(jsp))) {
0766: editWrapper = getJspWrapper(jsp);
0767: }
0768: Response jres = processJspFile(editWrapper, req, res);
0769: if (jres.getStatus() == HttpServletResponse.SC_OK) {
0770: return jres.getBody();
0771: } else {
0772: logger.log(Level.INFO, "PSDT_CSPPJ0002", new Object[] {
0773: jsp, new Integer(jres.getStatus()) });
0774: throw new ProviderException(getName()
0775: + ": editPage JSP=" + jsp + ", status code="
0776: + jres.getStatus());
0777: }
0778: } catch (ProviderException pe) {
0779: if (logger.isLoggable(Level.INFO)) {
0780: LogRecord record = new LogRecord(Level.INFO,
0781: "PSDT_CSPPJ0003");
0782: record.setLoggerName(logger.getName());
0783: record.setParameters(new Object[] { jsp });
0784: record.setThrown(pe);
0785: logger.log(record);
0786: }
0787: return handleException(pe);
0788: }
0789:
0790: }
0791:
0792: private StringBuffer handleException(ProviderException pe)
0793: throws ProviderException {
0794: if (getBooleanProperty("showExceptions")) {
0795: Exception e = pe;
0796:
0797: StringWriter swriter = new StringWriter(256);
0798: PrintWriter buf = new PrintWriter(swriter, true);
0799: buf.println("<div align=left><b>");
0800: buf.println(e.getMessage());
0801: buf.println("</b><p><pre>");
0802: e.printStackTrace(buf);
0803: buf.println("</pre></div>");
0804: buf.flush();
0805: return swriter.getBuffer();
0806: } else {
0807: throw pe;
0808: }
0809: }
0810:
0811: /**
0812: * Performs the provider's edit page processing by executing a JSP.
0813: * <p/>
0814: * If the <code>processPage</code> attribute has a value, it is
0815: * used as the name of a JSP to execute per the search algorithm
0816: * defined above. If the response from the JSP is a redirect, the
0817: * redirect location is returned as a URL. If the response from
0818: * the JSP is a normal OK response (200), null is returned
0819: * resulting in a redisplay of the desktop. Otherwise an
0820: * exception is thrown. If the <code>processPage</code> attribute
0821: * is blank, the superclass method is called.
0822: * <p/>
0823: * The following values from the request are passed on to the JSP servlet:
0824: * <ul>
0825: * <li>cookies
0826: * <li>parameters (already decoded into Unicode)
0827: * </ul>
0828: *
0829: * @param req An HttpServletRequest that contains information related to this
0830: * request for content.
0831: * @param res An HttpServletResponse that allows the provider to influence the
0832: * overall response for the desktop page (besides generating the content).
0833: * @return URL of the redirect location or null.
0834: * @throws ProviderException If there was an error processing the JSP.
0835: * @see com.sun.portal.providers.Provider#processEdit
0836: */
0837: public URL processEdit(HttpServletRequest req,
0838: HttpServletResponse res) throws ProviderException {
0839: //UBT code - start
0840: try {
0841: UBTLogManager manager = UBTLogManager.getInstance();
0842: if (manager.isUBTEnabled()) {
0843: UBTEvent prov_ren = UBTEvent
0844: .getInstance(DesktopEvents.PROCESS_EDIT);
0845: prov_ren.put(UBTLogField.CHANNEL_NAME, req
0846: .getParameter("targetprovider"));
0847: prov_ren.put(UBTLogField.TARGET_PROVIDER, getName());
0848: prov_ren
0849: .put(UBTLogField.PROVIDER, getClass().getName());
0850: prov_ren.put(UBTLogField.CONTAINER_NAME,
0851: getProviderContext().getParentContainerName(
0852: req.getParameter("provider")));
0853: prov_ren.put(UBTLogField.ACTION, "Process");
0854: prov_ren.put(UBTLogField.MODE, "Edit");
0855: manager.logEvent(new ProviderLogRecord(prov_ren, req,
0856: res, getProviderContext().getUserID()));
0857: }
0858: } catch (Exception e) {
0859: logger.log(Level.FINEST, "PSDT_CSPPJ0004", e);
0860: }
0861: //UBT code - end
0862:
0863: String jsp = getProcessPage();
0864:
0865: if (jsp.length() == 0 || jsp == null) {
0866: return super .processEdit(req, res);
0867: }
0868: if (processWrapper == null || processWrapper.expired()
0869: || (!processWrapper.getURI().equals(jsp))) {
0870: processWrapper = getJspWrapper(jsp);
0871: }
0872: Response jres = processJspFile(processWrapper, req, res);
0873: if (jres.getStatus() == HttpServletResponse.SC_MOVED_TEMPORARILY) {
0874: try {
0875: if (null != jres.getLocation()) {
0876: res.sendRedirect(jres.getLocation().toString());
0877: }
0878: return jres.getLocation();
0879: } catch (Exception mue) {
0880: if (logger.isLoggable(Level.INFO)) {
0881: LogRecord record = new LogRecord(Level.INFO,
0882: "PSDT_CSPPJ0003");
0883: record.setLoggerName(logger.getName());
0884: record.setParameters(new Object[] { jsp });
0885: record.setThrown(mue);
0886: logger.log(record);
0887: }
0888: throw new ProviderException(getName()
0889: + ": invalid URL from processPage JSP", mue);
0890: }
0891: } else if (jres.getStatus() == HttpServletResponse.SC_OK) {
0892: return null;
0893: } else {
0894: logger.log(Level.INFO, "PSDT_CSPPJ0002", new Object[] {
0895: jsp, new Integer(jres.getStatus()) });
0896: throw new ProviderException(getName()
0897: + ": processPage JSP=" + jsp + ", status code: "
0898: + jres.getStatus());
0899: }
0900: }
0901:
0902: private JspServletWrapper getJspWrapper(String jsp)
0903: throws ProviderException {
0904: // seperate uri and query string
0905: //
0906: int index = jsp.indexOf('?');
0907: String uri = jsp;
0908:
0909: if (index != -1) {
0910: uri = jsp.substring(0, index);
0911: }
0912:
0913: try {
0914: String fullJspPath = jspEnv.getRealPath(uri);
0915: if (fullJspPath == null) {
0916: if (logger.isLoggable(Level.SEVERE)) {
0917: logger.log(Level.SEVERE, "PSDT_CSPPJ0005",
0918: new Object[] { uri });
0919: }
0920: throw new ProviderException("JSP file not found: "
0921: + uri);
0922: }
0923: String compiledJspPath = getCompiledJSPPath(
0924: getProviderContext(), getName(), uri).toString();
0925:
0926: ProviderClassLoader pcl = ProviderClassLoader
0927: .getInstance(providerClassDir);
0928: JspServletWrapper wrapper = (JspServletWrapper) cachedJsps
0929: .get(compiledJspPath);
0930:
0931: // If the class loader stored in the wrapper is not the
0932: // same as the class loader that loaded this JSPProvider,
0933: // then it is time to invalidate the wrapper so it uses
0934: // the latest ProviderClassLoader.
0935:
0936: if (wrapper != null
0937: && wrapper.getProviderClassLoader() != pcl) {
0938: wrapper = null;
0939: }
0940:
0941: if (wrapper == null) {
0942: int scanInterval = 0;
0943: if (DesktopAppContextThreadLocalizer.exists()) {
0944: DesktopAppContext dac = DesktopAppContextThreadLocalizer
0945: .get();
0946: scanInterval = dac.getTemplateScanInterval();
0947: }
0948:
0949: synchronized (cachedJsps) {
0950: wrapper = (JspServletWrapper) cachedJsps
0951: .get(compiledJspPath);
0952: // If the class loader stored in the wrapper is not the
0953: // same as the class loader that loaded this JSPProvider,
0954: // then it is time to invalidate the wrapper so it uses
0955: // the latest ProviderClassLoader.
0956:
0957: if (wrapper != null
0958: && wrapper.getProviderClassLoader() != pcl) {
0959: wrapper = null;
0960: }
0961:
0962: if (wrapper == null) {
0963: wrapper = new JspServletWrapper(jsp, uri,
0964: fullJspPath, compiledJspPath, jspEnv,
0965: scanInterval, pcl);
0966: cachedJsps.put(compiledJspPath, wrapper);
0967: }
0968: }
0969: } else {
0970: // fullJspPath may have changed since last access
0971: wrapper.setFullJspFile(fullJspPath);
0972: }
0973: return wrapper;
0974: } catch (Throwable t) {
0975: if (logger.isLoggable(Level.INFO)) {
0976: LogRecord record = new LogRecord(Level.INFO,
0977: "PSDT_CSPPJ0006");
0978: record.setLoggerName(logger.getName());
0979: record.setParameters(new Object[] { jsp });
0980: record.setThrown(t);
0981: logger.log(record);
0982: }
0983: throw new ProviderException(
0984: "JSPProvider.getJspWrapper(): jsp=" + jsp + ", ", t);
0985: }
0986: }
0987:
0988: private Response processJspFile(JspServletWrapper jsp,
0989: HttpServletRequest hsreq, HttpServletResponse hsres)
0990: throws ProviderException {
0991: Hashtable parameters = new Hashtable();
0992: for (Enumeration pe = hsreq.getParameterNames(); pe
0993: .hasMoreElements();) {
0994: String pname = (String) pe.nextElement();
0995: parameters.put(pname, hsreq.getParameterValues(pname));
0996: }
0997: return processJspFile(jsp, hsreq, hsres, parameters, hsreq
0998: .getCookies(), new HashMap());
0999: }
1000:
1001: private Response processJspFile(JspServletWrapper wrapper,
1002: HttpServletRequest origReq, HttpServletResponse origRes,
1003: Hashtable params, Cookie ca[], Map attributes)
1004: throws ProviderException {
1005: //
1006: // add path info, if present, on to the jsp request
1007: // uri
1008: //
1009:
1010: String pathInfo = origReq.getPathInfo();
1011: String origURI = origReq.getRequestURI();
1012:
1013: //
1014: // check for semicolon data
1015: //
1016: int start = origURI.indexOf(';');
1017: String semiData = null;
1018: if (start != -1) {
1019: semiData = origURI.substring(start);
1020: }
1021:
1022: //
1023: // append semicolon data + path info, if present
1024: //
1025: String jsp = wrapper.getURI();
1026: if (semiData != null) {
1027: jsp += semiData;
1028: }
1029: if (pathInfo != null) {
1030: jsp += pathInfo;
1031: }
1032: //getProviderContext().debugError("JSPProvider.processJspFile(): jsp=" + jsp);
1033:
1034: Request req = new Request(origReq, jspsession, params, ca,
1035: attributes, jsp);
1036: Response res = new Response(req, origRes, getProviderContext());
1037:
1038: req.setAttribute(JspFactoryImpl.providerKey, this );
1039:
1040: JspFactory deffact = JspFactory.getPsFactory();
1041: if (deffact != theJspFactory) {
1042: JspFactory.setPsFactory(theJspFactory);
1043: }
1044:
1045: try {
1046: wrapper.service(req, res);
1047: } catch (RuntimeException e) {
1048: if (logger.isLoggable(Level.SEVERE)) {
1049: LogRecord record = new LogRecord(Level.SEVERE,
1050: "PSDT_CSPPJ0007");
1051: record.setLoggerName(logger.getName());
1052: record.setParameters(new Object[] { jsp });
1053: record.setThrown(e);
1054: logger.log(record);
1055: }
1056: throw new ProviderException("JSPProvider.getName(): ", e);
1057: } catch (ServletException e) {
1058: if (logger.isLoggable(Level.SEVERE)) {
1059: LogRecord record = new LogRecord(Level.SEVERE,
1060: "PSDT_CSPPJ0007");
1061: record.setLoggerName(logger.getName());
1062: record.setParameters(new Object[] { jsp });
1063: record.setThrown(e);
1064: logger.log(record);
1065: }
1066: Throwable t = e.getRootCause();
1067: if (t == null) {
1068: t = e;
1069: }
1070: //Throwable t = e;
1071:
1072: // rethrow ProviderExceptions thrown by JSP up the call chain
1073: if (t instanceof ProviderException) {
1074: ProviderException pe = (ProviderException) t;
1075: throw pe;
1076: } else if (t instanceof TypedException) {
1077: throw new ProviderException(t.getMessage(),
1078: ((TypedException) t).getType());
1079: }
1080: throw new ProviderException(
1081: "JSPProvider.processJSPFile(): jsp=" + jsp + ", ",
1082: t);
1083: } catch (Throwable t) {
1084: if (logger.isLoggable(Level.INFO)) {
1085: LogRecord record = new LogRecord(Level.INFO,
1086: "PSDT_CSPPJ0007");
1087: record.setLoggerName(logger.getName());
1088: record.setParameters(new Object[] { jsp });
1089: record.setThrown(t);
1090: logger.log(record);
1091: }
1092: throw new ProviderException(
1093: "JSPProvider.processJSPFile(): jsp=" + jsp + ", ",
1094: t);
1095: }
1096:
1097: return res;
1098: }
1099:
1100: /**
1101: * Retrieve content for an included JSP. This method is used primarily
1102: * by the JspRequestDispatcher.
1103: *
1104: * @param jsp The JSP to be included. If the query string is part
1105: * of the jsp uri it will be ignored.
1106: * @param parameters A hash of parameters that will be available to
1107: * the jsp.
1108: * @param req An HttpServletRequest that contains information related
1109: * to this request for content.
1110: * @param res An HttpServletResponse that allows the provider to
1111: * influence the overall response for the desktop page
1112: * (besides generating the content).
1113: * @return StringBuffer The content of the included JSP.
1114: * @throws ProviderException If there was an error processing the JSP.
1115: */
1116: protected StringBuffer includeJspPage(String jsp,
1117: Hashtable parameters, HttpServletRequest req,
1118: HttpServletResponse res) throws ProviderException {
1119:
1120: if ((jsp.length() == 0) || (jsp == null)) {
1121: return new StringBuffer();
1122: }
1123:
1124: try {
1125:
1126: Request request = (Request) req;
1127: Response jres = processJspFile(getJspWrapper(jsp), req,
1128: res, parameters, req.getCookies(), request
1129: .getAttributes());
1130:
1131: if (jres.getStatus() == HttpServletResponse.SC_MOVED_TEMPORARILY) {
1132: // set the redirect url in the calling jsp's response.
1133: try {
1134: res.sendRedirect(jres.getLocation().toString());
1135: } catch (MalformedURLException mue) {
1136: // do nothing
1137: if (logger.isLoggable(Level.FINE)) {
1138: LogRecord record = new LogRecord(Level.FINE,
1139: "PSDT_CSPPJ0008");
1140: record.setLoggerName(logger.getName());
1141: record.setParameters(new Object[] { jsp });
1142: record.setThrown(mue);
1143: logger.log(record);
1144: }
1145:
1146: } catch (IOException ioe) {
1147: if (logger.isLoggable(Level.FINE)) {
1148: LogRecord record = new LogRecord(Level.FINE,
1149: "PSDT_CSPPJ0008");
1150: record.setLoggerName(logger.getName());
1151: record.setParameters(new Object[] { jsp });
1152: record.setThrown(ioe);
1153: logger.log(record);
1154: }
1155: }
1156: }
1157: if (jres.getStatus() == HttpServletResponse.SC_OK
1158: || jres.getStatus() == HttpServletResponse.SC_MOVED_TEMPORARILY) {
1159: return jres.getBody();
1160: } else {
1161: logger.log(Level.INFO, "PSDT_CSPPJ0009", new Object[] {
1162: jsp, new Integer(jres.getStatus()) });
1163: throw new ProviderException(getName()
1164: + ": include JSP=" + jsp + ", status code="
1165: + jres.getStatus());
1166: }
1167: } catch (ProviderException pe) {
1168: if (logger.isLoggable(Level.INFO)) {
1169: LogRecord record = new LogRecord(Level.INFO,
1170: "PSDT_CSPPJ0010");
1171: record.setLoggerName(logger.getName());
1172: record.setParameters(new Object[] { jsp });
1173: record.setThrown(pe);
1174: logger.log(record);
1175: }
1176: return handleException(pe);
1177: }
1178: }
1179:
1180: /**
1181: * Get the most specific JSP path for the given channel name and
1182: * file name. The file returned is the most specific path possible
1183: * for the given file name for the lookup mechanism being used. The file
1184: * returned may not exist.
1185: * <p/>
1186: * <p>
1187: * The return value of this method determines the JSP compilation path
1188: * when JSPProvider is operating in most specific path
1189: * <a href="#compilationMode">compilation mode</a>. In
1190: * most specific path compilation mode, the default implementation of the
1191: * <code>getCompiledJspPath()</code>
1192: * method calls this method to determine its return value.
1193: * In real path compilation mode, this method is not called.
1194: * Classes that extend JSPProvider can override this method to control the
1195: * JSP compilation path.
1196: * </p>
1197: * <p>
1198: * The default implementation of this method
1199: * calls <code>ProviderContext.getTemplateMostSpecificPath()</code> to
1200: * derive its return value.
1201: *
1202: * @param channel The channel name.
1203: * @param file The template name.
1204: * @return a <code>String</code>, the most specific path to the template.
1205: * @throws ProviderException if an error occurs in getting the
1206: * template path.
1207: */
1208: protected File getMostSpecificJSPPath(ProviderContext pc,
1209: String channel, String file) throws ProviderException {
1210: try {
1211: return pc.getTemplateMostSpecificPath(channel, file);
1212: } catch (ProviderContextException pce) {
1213: if (logger.isLoggable(Level.INFO)) {
1214: LogRecord record = new LogRecord(Level.INFO,
1215: "PSDT_CSPPJ0011");
1216: record.setLoggerName(logger.getName());
1217: record.setParameters(new Object[] { channel, file });
1218: record.setThrown(pce);
1219: logger.log(record);
1220: }
1221: throw new ProviderException(
1222: "JSPProvider.getTemplateMostSpecificPath(): file= "
1223: + file + ", ", pce);
1224: }
1225: }
1226:
1227: /**
1228: * Get the compiled JSP path. This method is called by the JSPProvider
1229: * implementation to determine the JSP compilation path. Extending
1230: * classes can override this method to modify how compiled JSPs are shared
1231: * between different JSP Provider instances.
1232: * <p>
1233: * The default implementation of this method either returns the real
1234: * (physical) JSP path, or the most specific JSP path (by calling
1235: * <code>getMostSpecificJSPPath()</code>), depending on if the JSPProvider
1236: * is in real or most specification path
1237: * <a href="#compilationMode">compilation mode</a>,
1238: * repsectively.
1239: *
1240: * @param channel The channel name.
1241: * @param file The template name.
1242: * @return a <code>String</code>, the compiled JSP path.
1243: * @throws ProviderException if an error occurs in getting the path.
1244: */
1245: protected File getCompiledJSPPath(ProviderContext pc,
1246: String channel, String file) throws ProviderException {
1247: String compiledJspPath;
1248: if (compileToRealPath) {
1249: compiledJspPath = jspEnv.getRealPath(file);
1250: } else {
1251: compiledJspPath = getMostSpecificJSPPath(
1252: getProviderContext(), getName(), file).toString();
1253: }
1254: return new File(compiledJspPath);
1255: }
1256:
1257: /**
1258: * Get the most specific path for an <i>existing</i> JSP. This method is
1259: * contrasted with <code>getMostSpecificJSPPath()</code>,
1260: * which returns the most
1261: * specific path based on the given arguments, regardless of whether
1262: * the path resolves to an existing file. The JSP Provider implementation
1263: * calls this method to find the JSP source file.
1264: * <p/>
1265: * Classes that extend JSPProvider can override this method to use a
1266: * different JSP lookup mechanism. The default implementation
1267: * of this method
1268: * calls <code>ProviderContext.getTemplatePath()</code> to derive its
1269: * return value.
1270: *
1271: * @param channel The channel name.
1272: * @param file The template name.
1273: * @return a <code>String</code>, the path to the template.
1274: * @throws ProviderException if an error occurs in getting the
1275: * template path.
1276: * @see com.sun.portal.providers.jsp.JSPProvider#getTemplatePath
1277: */
1278: protected File getExistingJSPPath(ProviderContext pc,
1279: String channel, String file) throws ProviderException {
1280: try {
1281: return pc.getTemplatePath(channel, file);
1282: } catch (ProviderContextException pce) {
1283: if (logger.isLoggable(Level.INFO)) {
1284: LogRecord record = new LogRecord(Level.INFO,
1285: "PSDT_CSPPJ0012");
1286: record.setLoggerName(logger.getName());
1287: record.setParameters(new Object[] { channel, file });
1288: record.setThrown(pce);
1289: logger.log(record);
1290: }
1291: throw new ProviderException(
1292: "JSPProvider.getTemplatePath(): file= " + file
1293: + ", ", pce);
1294: }
1295: }
1296:
1297: }
|