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.desktop;
0006:
0007: import com.sun.portal.desktop.context.ContextError;
0008: import com.sun.portal.desktop.context.DesktopAppContext;
0009: import com.sun.portal.desktop.context.DesktopContext;
0010: import com.sun.portal.desktop.context.DesktopContextFactory;
0011: import com.sun.portal.desktop.context.DesktopContextThreadLocalizer;
0012: import com.sun.portal.desktop.context.PSDesktopContextFactoryManager;
0013: import com.sun.portal.desktop.context.PropertiesConfigContext;
0014: import com.sun.portal.desktop.dp.DPHelper;
0015: import com.sun.portal.desktop.dp.FQCN;
0016: import com.sun.portal.desktop.monitoring.DesktopRequestStatistic;
0017: import com.sun.portal.desktop.monitoring.MonitoringSubsystem;
0018: import com.sun.portal.desktop.monitoring.MonitoringSubsystemWrapper;
0019: import com.sun.portal.desktop.ubt.DesktopEvents;
0020: import com.sun.portal.desktop.ubt.ProviderLogRecord;
0021: import com.sun.portal.desktop.util.I18n;
0022: import com.sun.portal.log.common.PortalLogger;
0023: import com.sun.portal.monitoring.MonitoringException;
0024: import com.sun.portal.monitoring.utilities.ActivityTime;
0025: import com.sun.portal.providers.InvalidEditFormDataException;
0026: import com.sun.portal.providers.Provider;
0027: import com.sun.portal.providers.ProviderEditTypes;
0028: import com.sun.portal.providers.containers.jsp.tab.JSPTabContainerProvider;
0029: import com.sun.portal.providers.error.ErrorProvider;
0030: import com.sun.portal.providers.util.ProviderProperties;
0031: import com.sun.portal.ubt.UBTEvent;
0032: import com.sun.portal.ubt.UBTLogField;
0033: import com.sun.portal.ubt.UBTLogManager;
0034: import com.sun.portal.desktop.context.DSAMEMultiPortalConstants;
0035:
0036: import javax.servlet.ServletConfig;
0037: import javax.servlet.ServletContext;
0038: import javax.servlet.ServletException;
0039: import javax.servlet.http.Cookie;
0040: import javax.servlet.http.HttpServlet;
0041: import javax.servlet.http.HttpServletRequest;
0042: import javax.servlet.http.HttpServletResponse;
0043: import javax.servlet.http.HttpSession;
0044: import java.io.IOException;
0045: import java.io.OutputStreamWriter;
0046: import java.io.Writer;
0047: import java.net.URL;
0048: import java.net.URLEncoder;
0049: import java.util.Enumeration;
0050: import java.util.Hashtable;
0051: import java.util.Locale;
0052: import java.util.Properties;
0053: import java.util.logging.Level;
0054: import java.util.logging.LogRecord;
0055: import java.util.logging.Logger;
0056:
0057: /**
0058: * The Desktop Servlet is a router of request. It catches request for content
0059: * and processing and passes them on to the specific provider object.
0060: * <p/>
0061: * Desktop Servlet understands several actions. Every action has an associated
0062: * channel name to perform the action on. Actions understood by the Desktop
0063: * servlet are:
0064: * <ul>
0065: * <li>content - get the named channel's main content
0066: * <li>edit - get the named channel's edit content
0067: * <li>process - allow the named channel to process form data
0068: * <li>logout - end the user session
0069: * </ul>
0070: * <p/>
0071: * Actions are passed to the servlet via GET or POST parameters. The
0072: * associated channel name is also passed as a parameter. For example,
0073: * to perform the <i>content</i> action on the channel name <i>foo</i>,
0074: * pass in the following parameters to the servlet:<br><br>
0075: * <code>[url to servlet]?action=content&provider=foo</code><br><br>
0076: * <p/>
0077: * The content, edit, and process actions map directly to method calls into
0078: * the Provider API (PAPI). For example, for an action equal to <i>process</i>
0079: * and a channel name equal to <i>foo</i>, the Desktop servlet will
0080: * get a handle to the provider object associated with the channel name <i>foo</i>,
0081: * and call the <i>Provider.processEdit()</i> method.<br><br>
0082: * <p/>
0083: * For such desktop actions that map to PAPI method calls,
0084: * the servlet passes an HTTP request and response object to the respective
0085: * Provider method. These objects are not the same objects passed into
0086: * the servlet. The request and response objects passed to provider
0087: * objects from the servlet
0088: * are wrappers around the original request and response
0089: * passed into the servlet. This is because there is certain functionality
0090: * that is available from request and response objects that is not
0091: * applicable to a provider. See the Javadocs for the class
0092: * <code>Provider</code> for more
0093: * information.<br><br>
0094: * <p/>
0095: * The HTTP parameters in the original request object are processed
0096: * before they are copied to the "wrapper" servlet request and response
0097: * objects.
0098: * As part of this processing, the parameters
0099: * are decoded from the character set encoding used to represent the page
0100: * into Unicode that is used in Java String objects. Therefore, the
0101: * parameters that are passed to the providers are all
0102: * stored as Unicode, and the provider does not have to do any decoding of
0103: * its own related to the character encoding for the page.However, the Unicode
0104: * Strings passed into a query string have to be encoded by the
0105: * provider using <i>ProviderContext.encodeURLParameter()</i> method.<br><br>
0106: * <p/>
0107: * The servlet also keeps track of the last top-level container/channel that is
0108: * accessed. It does it as following: <br>
0109: * If the "provider" parameter is absent in the request, the servlet assumes it
0110: * is equal to the value of the last request where the "action" parameter's
0111: * value was "content". If there is no such last request, then a default
0112: * channel is assumed. Specifying the parameter "action=content" causes the
0113: * servlet to set the last accessed channel name to the value of the "provider"
0114: * parameter. This can be overriden by additionally specifying the parameter
0115: * "last" in the request. When set to false, the servlet will not set the last
0116: * channel to the value of the "provider" parameter. If not specified, the
0117: * default setting is "last=true", and the last accessed channel is set to the
0118: * value of the "provider" parameter. Note: This only applies when the "action"
0119: * parameter is equal to "content"; the last accessed channel is only set when
0120: * the "action" parameter is equal to "content". <br><br>
0121: * <p/>
0122: * Various scenarios: <br><br>
0123: * <ol>
0124: * <li> <desktopURL> (= <desktopURL>?provider=<default channel>) <br>
0125: * <p/>
0126: * No last accessed channel set. The "provider" parameter is assumed to be
0127: * the default channel. The last accessed channel is set to the name of the
0128: * default channel. <br>
0129: * <p/>
0130: * <li> <desktopURL> (= <desktopURL>?provider=<last acccessed channel>) <br>
0131: * <p/>
0132: * The "provider" parameter is absent, so it is assumed to be the value of the
0133: * last accecssed channel set in step #1.
0134: * <p/>
0135: * <li> <desktopURL>?action=content&provider=foo <br>
0136: * <p/>
0137: * The last accessed channel is set to <i>foo</i>.
0138: * <p/>
0139: * <li> <desktopURL> <br>
0140: * <p/>
0141: * The "provider" parameter is absent, so it is assumed to be the value of the
0142: * last accessed channel set in step #3 (<i>foo</i>). <br>
0143: * <p/>
0144: * <li> <desktopURL>?action=edit&provider=bar <br>
0145: * <p/>
0146: * Last accessed channel is NOT set to <i>bar</i>, since the "action" was "edit".
0147: * <br>
0148: * <p/>
0149: * <li> <desktopURL>?action=process OR <desktopURL>?action=edit <br>
0150: * <p/>
0151: * Invalid, must specify a "provider" parameter. Default or last accessed
0152: * channel is not assumed when "action" equals "edit" or "process".
0153: * <br><br>
0154: * </ol>
0155: * This class also creates a single instance of error provider object, that is
0156: * used by all the providers.
0157: * Whenever a provider throws an exception it is populated all the way up to
0158: * the DesktopServlet which in turn invokes the error provider which displays
0159: * a generic error template. The stack trace can also be viewed by looking at
0160: * the source of the error template (it is defined as a markup but commented
0161: * out so that it does not appear on the browser).<br><br>
0162: *
0163: * @see com.sun.portal.providers.Provider
0164: */
0165: public class DesktopServlet extends HttpServlet implements
0166: ProviderEditTypes {
0167:
0168: private static Provider errorProvider = new ErrorProvider();
0169: private static DesktopAppContext appContext = null;
0170: private static DesktopContextFactory dcFactory = null;
0171: private static final String LIBERTY_SSO_FAILED_QUERY_PARAM = "libertySSOFailed";
0172:
0173: private static Logger logger = PortalLogger
0174: .getLogger(DesktopServlet.class);
0175:
0176: private LogRecord getLogRecord(Level level, String message,
0177: Object[] parameters, Throwable t) {
0178: LogRecord result = new LogRecord(level, message);
0179: result.setLoggerName(logger.getName());
0180: result.setParameters(parameters);
0181: result.setThrown(t);
0182: return result;
0183: }
0184:
0185: private static void printSystemProperties() {
0186: Properties envProps = System.getProperties();
0187: if (logger.isLoggable(Level.CONFIG)) {
0188: logger.log(Level.CONFIG, "PSDT_CSPD0002");
0189: for (Enumeration e = envProps.propertyNames(); e
0190: .hasMoreElements();) {
0191: String prop = (String) e.nextElement();
0192: // no localized key here as the entire message is coming
0193: // from environment
0194: logger.log(Level.CONFIG, prop + " : "
0195: + envProps.getProperty(prop));
0196: }
0197: logger.log(Level.CONFIG, "PSDT_CSPD0003");
0198: }
0199: }
0200:
0201: protected static DesktopContextFactory getDesktopContextFactory(
0202: ServletConfig sc) {
0203: if (dcFactory == null) {
0204: dcFactory = PSDesktopContextFactoryManager.getFactory(sc
0205: .getServletContext());
0206: }
0207:
0208: return dcFactory;
0209: }
0210:
0211: private void printConfigAttributes() {
0212: printConfigAttributes(getServletConfig().getServletContext());
0213: }
0214:
0215: public static void printConfigAttributes(ServletContext sc) {
0216: if (logger.isLoggable(Level.CONFIG)) {
0217: logger.log(Level.CONFIG, "PSDT_CSPD0004");
0218:
0219: for (Enumeration e = sc.getAttributeNames(); e
0220: .hasMoreElements();) {
0221: String name = (String) e.nextElement();
0222: Object val = sc.getAttribute(name);
0223: logger.log(Level.CONFIG, name + "=" + val);
0224: }
0225: logger.log(Level.CONFIG, "PSDT_CSPD0005");
0226: }
0227:
0228: }
0229:
0230: private void printInitParameters() {
0231: if (logger.isLoggable(Level.CONFIG)) {
0232: logger.log(Level.CONFIG, "PSDT_CSPD0006");
0233:
0234: for (Enumeration e = getServletConfig()
0235: .getInitParameterNames(); e.hasMoreElements();) {
0236: String name = (String) e.nextElement();
0237: String val = getServletConfig().getInitParameter(name);
0238: logger.log(Level.CONFIG, name + "=" + val);
0239: }
0240: logger.log(Level.CONFIG, "PSDT_CSPD0007");
0241: }
0242: }
0243:
0244: private String urlencode(String s) {
0245: try {
0246: return URLEncoder.encode(s, "UTF-8");
0247: } catch (Exception wonthappen) {
0248: }
0249: return s;
0250: }
0251:
0252: public void init(ServletConfig config) throws ServletException {
0253: super .init(config);
0254:
0255: getDesktopContextFactory(config);
0256: appContext = dcFactory.getDesktopAppContext();
0257:
0258: UBTLogManager.getInstance();
0259: }
0260:
0261: public void destroy() {
0262: synchronized (MonitoringSubsystemWrapper.class) {
0263: if (MonitoringSubsystemWrapper.gearedUp()) {
0264: try {
0265: MonitoringSubsystemWrapper
0266: .getDesktopMonitoringSubsystem().destroy();
0267: MonitoringSubsystemWrapper
0268: .setDesktopMonitoringSubsystem(null);
0269: } catch (MonitoringException e) {
0270: if (logger.isLoggable(Level.SEVERE)) {
0271: logger.log(getLogRecord(Level.SEVERE,
0272: "PSDT_CSPD0026", new Object[] { e
0273: .getLocalizedMessage() }, e));
0274: }
0275: }
0276: }
0277: }
0278: }
0279:
0280: private void setUBTSesID(HttpServletRequest req) {
0281: HttpSession sess = req.getSession(false);
0282: sess = (sess != null) ? sess : req.getSession(true);
0283: req.setAttribute(UBTLogManager.UBT_SESSION_ID_ATTRIBUTE, sess
0284: .getId());
0285: }
0286:
0287: private void handleFederation(boolean authlessEnabled,
0288: HttpServletRequest req, HttpServletResponse res,
0289: DesktopRequest dreq, DesktopResponse dres, Writer out,
0290: String clientType, String contentType, String charset)
0291: throws DesktopException, IOException, ServletException {
0292: /*
0293: * Check for the query param libertySSOFailed=true. If this is
0294: * true, then it means that the liberty route has been
0295: * traversed once and no need to invoke preLogin again.
0296: * If this param is not found, then this is a fresh request, and
0297: * since the federation is enabled, preLogin should do the work.
0298: */
0299: String libSSOFailedParam = dreq
0300: .getParameter(LIBERTY_SSO_FAILED_QUERY_PARAM);
0301: if ("true".equalsIgnoreCase(libSSOFailedParam)) {
0302: if (authlessEnabled
0303: && appContext.validateAuthlessSession(dreq)) {
0304: doGetPost(req, res);
0305: } else {
0306: MonitoringSubsystemWrapper
0307: .getDesktopMonitoringSubsystem()
0308: .startDesktopServiceTransaction(
0309: DesktopRequestStatistic.DESKTOP_REQUEST_LOCALAUTH);
0310: showLocalAuth(req, res, dreq, out, clientType,
0311: contentType, charset);
0312: MonitoringSubsystemWrapper
0313: .getDesktopMonitoringSubsystem()
0314: .stopDesktopServiceTransaction(
0315: DesktopRequestStatistic.DESKTOP_REQUEST_LOCALAUTH);
0316: MonitoringSubsystemWrapper
0317: .getDesktopMonitoringSubsystem()
0318: .getDesktopRequestStatistic()
0319: .measure(
0320: DesktopRequestStatistic.DESKTOP_REQUEST_LOCALAUTH);
0321: }
0322: } else {
0323: MonitoringSubsystemWrapper
0324: .getDesktopMonitoringSubsystem()
0325: .startDesktopServiceTransaction(
0326: DesktopRequestStatistic.DESKTOP_REQUEST_PRELOGIN);
0327: invokePreLogin(req, res, dreq, out, clientType,
0328: contentType, charset);
0329: MonitoringSubsystemWrapper
0330: .getDesktopMonitoringSubsystem()
0331: .stopDesktopServiceTransaction(
0332: DesktopRequestStatistic.DESKTOP_REQUEST_PRELOGIN);
0333: MonitoringSubsystemWrapper
0334: .getDesktopMonitoringSubsystem()
0335: .getDesktopRequestStatistic()
0336: .measure(
0337: DesktopRequestStatistic.DESKTOP_REQUEST_PRELOGIN);
0338: }
0339: }
0340:
0341: private void handleNoSessionRequest(boolean authlessEnabled,
0342: boolean federationEnabled, HttpServletRequest req,
0343: HttpServletResponse res, DesktopRequest dreq,
0344: DesktopResponse dres, Writer out, String clientType,
0345: String contentType, String charset)
0346: throws DesktopException, IOException, ServletException {
0347: // Currently, only authenticated users can access a community
0348: // because most cty features do not support authless (yet)
0349: String community = req
0350: .getParameter(DesktopParameters.COMMUNITY_ACCESS);
0351: boolean communityrequest = community != null
0352: && community.length() > 0;
0353: if (!federationEnabled && authlessEnabled) {
0354: if (!communityrequest
0355: && appContext.validateAuthlessSession(dreq)) {
0356: doGetPost(req, res); //show authless desktop
0357: } else {
0358: MonitoringSubsystemWrapper
0359: .getDesktopMonitoringSubsystem()
0360: .startDesktopServiceTransaction(
0361: DesktopRequestStatistic.DESKTOP_REQUEST_LOCALAUTH);
0362: showLocalAuth(req, res, dreq, out, clientType,
0363: contentType, charset);
0364: MonitoringSubsystemWrapper
0365: .getDesktopMonitoringSubsystem()
0366: .stopDesktopServiceTransaction(
0367: DesktopRequestStatistic.DESKTOP_REQUEST_LOCALAUTH);
0368: MonitoringSubsystemWrapper
0369: .getDesktopMonitoringSubsystem()
0370: .getDesktopRequestStatistic()
0371: .measure(
0372: DesktopRequestStatistic.DESKTOP_REQUEST_LOCALAUTH);
0373: }
0374: } else if (federationEnabled) {
0375: handleFederation(authlessEnabled && !communityrequest, req,
0376: res, dreq, dres, out, clientType, contentType,
0377: charset);
0378: } else {
0379: //neither federation nor authless enabled
0380: MonitoringSubsystemWrapper
0381: .getDesktopMonitoringSubsystem()
0382: .startDesktopServiceTransaction(
0383: DesktopRequestStatistic.DESKTOP_REQUEST_LOCALAUTH);
0384: showLocalAuth(req, res, dreq, out, clientType, contentType,
0385: charset);
0386: MonitoringSubsystemWrapper
0387: .getDesktopMonitoringSubsystem()
0388: .stopDesktopServiceTransaction(
0389: DesktopRequestStatistic.DESKTOP_REQUEST_LOCALAUTH);
0390: MonitoringSubsystemWrapper
0391: .getDesktopMonitoringSubsystem()
0392: .getDesktopRequestStatistic()
0393: .measure(
0394: DesktopRequestStatistic.DESKTOP_REQUEST_LOCALAUTH);
0395: }
0396: }
0397:
0398: /**
0399: * handle community access
0400: * - set default community provider type if not specified
0401: * - go to the named community, or to the community home page if community is ""
0402: * - redirect to login page if user is not logged in and is trying to access a named community
0403: */
0404: public void handleCommunity(HttpServletRequest request,
0405: HttpServletResponse response) throws DesktopException,
0406: IOException, ServletException {
0407: String defaultCommunityType = "jdo";
0408: DesktopContext dc = getDesktopContext(request);
0409: String communityName = request
0410: .getParameter(DesktopParameters.COMMUNITY_ACCESS);
0411: boolean namedCommunity = communityName != null
0412: && communityName.length() > 0;
0413:
0414: // set the default community type if not specified
0415: DesktopRequest dreq = (DesktopRequest) request;
0416: String communityId = null;
0417: if (namedCommunity) {
0418: if (communityName.indexOf("__") == -1) {
0419: communityId = defaultCommunityType + "__"
0420: + communityName;
0421: dreq
0422: .setDesktopParameter(
0423: DesktopParameters.COMMUNITY_ACCESS,
0424: communityId);
0425: } else {
0426: communityId = communityName;
0427: communityName = communityName.substring(communityName
0428: .indexOf("__") + 2);
0429: }
0430: }
0431:
0432: // insert desktop parameters to select the community container and to make it visible
0433: DSAMEMultiPortalConstants dmpc = DSAMEMultiPortalConstants
0434: .getInstance();
0435: String communityParentContainerArg = dc
0436: .getStringAttribute(dmpc.MP_ATTR_COMMUNITY_PARENT_CONTAINER_URL_PARAMETER);
0437: String communityContainer;
0438: if (namedCommunity) {
0439: communityContainer = communityId + "_Container";
0440: } else {
0441: communityContainer = dc
0442: .getStringAttribute(dmpc.MP_ATTR_COMMUNITY_HOME_CONTAINER_NAME);
0443: }
0444: String urlargs = communityParentContainerArg + "="
0445: + communityContainer;
0446:
0447: // there might be several visibility args - add all of them to the request
0448: String[] argarray = urlargs.split("&");
0449: for (int i = 0; i < argarray.length; ++i) {
0450: String[] nameval = argarray[i].split("=");
0451: dreq.setDesktopParameter(nameval[0], nameval[1]); // these names and values should not need url decoding...
0452: }
0453:
0454: return;
0455: }
0456:
0457: /**
0458: * Overriden to check for valid session.
0459: */
0460: protected void service(HttpServletRequest req,
0461: HttpServletResponse res) throws ServletException,
0462: IOException {
0463: String charset = I18n.DEFAULT_CHARSET;
0464: String contentType = null;
0465: Writer out = null;
0466:
0467: try {
0468: if (appContext == null) {
0469: if (logger.isLoggable(Level.SEVERE)) {
0470: logger.log(Level.SEVERE, "PSDT_CSPD0008",
0471: "DesktopServlet.service()");
0472: }
0473: throw new DesktopException(
0474: "DesktopServlet.service(): app context was null");
0475: }
0476:
0477: /*
0478: * parse and make parameters available to doGet/Post() methods. they should be
0479: * responsible for calling decodeParams() (with the charset) before they use
0480: */
0481: DesktopRequest dreq = new DesktopRequest(req, appContext,
0482: false);
0483: DesktopResponse dres = new DesktopResponse(res);
0484:
0485: DesktopThreadLocalManager.init(appContext, dreq, dres, req,
0486: res, getServletConfig(), getServletConfig()
0487: .getServletContext());
0488:
0489: if (!MonitoringSubsystemWrapper.gearedUp()) {
0490: MonitoringSubsystemWrapper
0491: .getDesktopMonitoringSubsystem(
0492: appContext.getDesktopURL(req))
0493: .startDesktopServiceAccessURITransaction();
0494: } else {
0495: MonitoringSubsystemWrapper
0496: .getDesktopMonitoringSubsystem()
0497: .startDesktopServiceAccessURITransaction();
0498: }
0499: MonitoringSubsystemWrapper.getDesktopMonitoringSubsystem()
0500: .getDesktopRequestStatistic().mark();
0501: setUBTSesID(req);
0502:
0503: String clientType = appContext.getClientType(req);
0504: contentType = appContext.getContentType(clientType);
0505:
0506: String action = req.getParameter("action");
0507: if ((action != null) && action.equalsIgnoreCase("logout")) {
0508: doGetPost(req, res);
0509: return;
0510: }
0511:
0512: boolean authlessEnabled = appContext.isAuthlessEnabled();
0513: boolean federationEnabled = appContext
0514: .isFederationEnabled();
0515: boolean isValidSession = false;
0516: try {
0517: isValidSession = appContext.validateSession(dreq);
0518: } catch (DesktopError e) {
0519:
0520: // A valid session has become invalid for time-out or explicit termination on AMConsole.
0521:
0522: if (e.getType()
0523: .equals(TypedException.SESSION_TIMED_OUT)) {
0524:
0525: // if reqest was from ajax, we want to return error msg
0526: // instead of redirect to login
0527: String requestType = dreq
0528: .getParameter("requestType");
0529: if ((requestType != null)
0530: && requestType.equalsIgnoreCase("ajax")) {
0531:
0532: if (out == null) {
0533: out = getWriter(res, contentType, charset);
0534: }
0535: handleException(req, res, out, e);
0536: return;
0537:
0538: } else {
0539:
0540: // AM handles timeout correctly
0541: if (federationEnabled) {
0542: handleFederation(false, req, res, dreq,
0543: dres, out, clientType, contentType,
0544: charset);
0545: return;
0546: } else {
0547: MonitoringSubsystemWrapper
0548: .getDesktopMonitoringSubsystem()
0549: .startDesktopServiceTransaction(
0550: DesktopRequestStatistic.DESKTOP_REQUEST_LOCALAUTH);
0551: showLocalAuth(req, res, dreq, out,
0552: clientType, contentType, charset);
0553: MonitoringSubsystemWrapper
0554: .getDesktopMonitoringSubsystem()
0555: .stopDesktopServiceTransaction(
0556: DesktopRequestStatistic.DESKTOP_REQUEST_LOCALAUTH);
0557: MonitoringSubsystemWrapper
0558: .getDesktopMonitoringSubsystem()
0559: .getDesktopRequestStatistic()
0560: .measure(
0561: DesktopRequestStatistic.DESKTOP_REQUEST_LOCALAUTH);
0562: return;
0563: }
0564: }
0565: }
0566:
0567: if ("true".equals(getCookieValue(req, "auth"))) {
0568: Cookie authCookie = new Cookie("auth", "false");
0569: res.addCookie(authCookie);
0570: throw e;
0571: } else {
0572: // let it go to handleNoSessionRequest
0573: isValidSession = false;
0574: }
0575:
0576: }
0577:
0578: if (isValidSession) {
0579:
0580: if (authCookieNotSet(req)) {
0581: Cookie authCookie = new Cookie("auth", "true");
0582: res.addCookie(authCookie);
0583: }
0584:
0585: doGetPost(req, res);
0586:
0587: } else {
0588: handleNoSessionRequest(authlessEnabled,
0589: federationEnabled, req, res, dreq, dres, out,
0590: clientType, contentType, charset);
0591: }
0592:
0593: } catch (IOException ioe) {
0594: // do nothing
0595: } catch (Throwable t) {
0596: MonitoringSubsystemWrapper
0597: .getDesktopMonitoringSubsystem()
0598: .startDesktopServiceTransaction(
0599: DesktopRequestStatistic.DESKTOP_REQUEST_EXCEPTION);
0600: if (out == null) {
0601: out = getWriter(res, contentType, charset);
0602: }
0603: handleException(req, res, out, t);
0604: MonitoringSubsystemWrapper
0605: .getDesktopMonitoringSubsystem()
0606: .stopDesktopServiceTransaction(
0607: DesktopRequestStatistic.DESKTOP_REQUEST_EXCEPTION);
0608: MonitoringSubsystemWrapper
0609: .getDesktopMonitoringSubsystem()
0610: .getDesktopRequestStatistic()
0611: .measure(
0612: DesktopRequestStatistic.DESKTOP_REQUEST_EXCEPTION);
0613: } finally {
0614: if (out != null) {
0615: try {
0616: out.close();
0617: } catch (IOException ioe) {
0618: // nothing
0619: }
0620: }
0621:
0622: DesktopThreadLocalManager.release();
0623: MonitoringSubsystemWrapper.getDesktopMonitoringSubsystem()
0624: .stopDesktopServiceAccessURITransaction();
0625: }
0626: }
0627:
0628: /**
0629: * Invokes preLogin servlet of IS by redirecting to the preLogin URL returned
0630: * by the appContext.
0631: */
0632: private void invokePreLogin(HttpServletRequest req,
0633: HttpServletResponse res, DesktopRequest dreq, Writer out,
0634: String clientType, String contentType, String charset)
0635: throws IOException, DesktopException {
0636: StringBuffer returnURL = new StringBuffer(getAbsURL(dreq,
0637: appContext, dreq.getRequestURI()));
0638: boolean queryExists = false;
0639: if (dreq.getParameterMap().size() > 0) {
0640: String query = dreq.getQueryString();
0641: returnURL.append("?").append(query);
0642: queryExists = true;
0643: }
0644:
0645: String preLoginURL = appContext.getPreLoginURL(returnURL
0646: .toString(), LIBERTY_SSO_FAILED_QUERY_PARAM);
0647:
0648: if (preLoginURL == null) {
0649: /* This is liberty misconfiguration. So fail gracefully by
0650: * treating liberty sign on as failed and log error. So the user
0651: * will either see authless desktop or the local auth page.
0652: */
0653: if (logger.isLoggable(Level.WARNING)) {
0654: logger.log(Level.WARNING, "PSDT_CSPD0009");
0655: }
0656: if (queryExists) {
0657: returnURL.append("&");
0658: } else {
0659: returnURL.append("?");
0660: }
0661: returnURL.append(LIBERTY_SSO_FAILED_QUERY_PARAM).append(
0662: "=true");
0663: preLoginURL = returnURL.toString();
0664: }
0665: if (logger.isLoggable(Level.CONFIG)) {
0666: logger.log(Level.CONFIG, "PSDT_CSPD0010", preLoginURL);
0667: }
0668:
0669: out = getWriter(res, contentType, charset);
0670: sendRedirect(req, res, out, preLoginURL);
0671: }
0672:
0673: private void showLocalAuth(HttpServletRequest req,
0674: HttpServletResponse res, DesktopRequest dreq, Writer out,
0675: String clientType, String contentType, String charset)
0676: throws IOException, DesktopException {
0677: String noSessionURL = appContext.getNoSessionURL();
0678: if (noSessionURL == null) {
0679: if (logger.isLoggable(Level.WARNING)) {
0680: logger.log(Level.WARNING, "PSDT_CSPD0011");
0681: }
0682: noSessionURL = "/";
0683: }
0684:
0685: StringBuffer redirectURL = new StringBuffer(noSessionURL);
0686:
0687: // Attach return URL as query string
0688: String returnParam = appContext.getSessionReturnURLParamName();
0689: if (returnParam != null && returnParam.length() > 0) {
0690: StringBuffer returnURL = new StringBuffer(getAbsURL(dreq,
0691: appContext, dreq.getRequestURI()));
0692: if (dreq.getParameterMap().size() > 0) {
0693: //
0694: // avoid evaluating the query string until
0695: // we know we need it
0696: //
0697: String query = dreq.getQueryString();
0698: returnURL.append("?").append(query);
0699: }
0700:
0701: redirectURL.append(noSessionURL.indexOf('?') < 0 ? "?"
0702: : "&");
0703: redirectURL.append(returnParam).append("=").append(
0704: URLEncoder.encode(returnURL.toString()));
0705: }
0706: if (logger.isLoggable(Level.FINE)) {
0707: logger.log(Level.FINE, "PSDT_CSPD0012", redirectURL);
0708: }
0709:
0710: out = getWriter(res, contentType, charset);
0711: sendRedirect(req, res, out, redirectURL.toString());
0712: }
0713:
0714: private static Writer getWriter(HttpServletResponse res,
0715: String contentType, String charset) throws IOException {
0716: if (contentType != null) {
0717: if (charset != null) {
0718: res
0719: .setContentType(contentType + "; charset="
0720: + charset);
0721: } else {
0722: res.setContentType(contentType);
0723: }
0724: }
0725:
0726: return new OutputStreamWriter(res.getOutputStream(), charset);
0727: }
0728:
0729: protected DesktopContext getDesktopContext(HttpServletRequest req)
0730: throws DesktopException {
0731: return dcFactory.getDesktopContext(req);
0732: }
0733:
0734: public void doGet(HttpServletRequest req, HttpServletResponse res)
0735: throws ServletException, IOException {
0736: doGetPost(req, res);
0737: }
0738:
0739: public void doPost(HttpServletRequest req, HttpServletResponse res)
0740: throws ServletException, IOException {
0741: doGetPost(req, res);
0742: }
0743:
0744: private void addLBCookie(DesktopResponse dres) {
0745: if ((appContext.getLBCookieName() != null)
0746: && (appContext.getLBCookieName().length() != 0)) {
0747: dres.addCookie(new Cookie(appContext.getLBCookieName(),
0748: appContext.getPortalId() + "."
0749: + appContext.getInstanceId()));
0750: }
0751: }
0752:
0753: private void doGetPost(HttpServletRequest req,
0754: HttpServletResponse res) throws IOException {
0755: Writer out = null;
0756:
0757: String charset = I18n.DEFAULT_CHARSET;
0758: String contentType = null;
0759:
0760: DesktopContext context = null;
0761: String name = null;
0762: FQCN fqcn = null;
0763: String action = null;
0764:
0765: try {
0766: setCacheHeaders(res);
0767: context = getDesktopContext(req);
0768: context.refresh();
0769:
0770: charset = getCharset(req);
0771:
0772: if (context == null) {
0773: MonitoringSubsystemWrapper
0774: .getDesktopMonitoringSubsystem()
0775: .startDesktopServiceTransaction(
0776: DesktopRequestStatistic.DESKTOP_REQUEST_EXCEPTION);
0777: out = getWriter(res, contentType, charset);
0778: handleException(req, res, out, new Exception());
0779: MonitoringSubsystemWrapper
0780: .getDesktopMonitoringSubsystem()
0781: .stopDesktopServiceTransaction(
0782: DesktopRequestStatistic.DESKTOP_REQUEST_EXCEPTION);
0783: MonitoringSubsystemWrapper
0784: .getDesktopMonitoringSubsystem()
0785: .getDesktopRequestStatistic()
0786: .measure(
0787: DesktopRequestStatistic.DESKTOP_REQUEST_EXCEPTION);
0788: return;
0789: }
0790:
0791: //
0792: // request is a desktop request from the service method
0793: // get charset and decode the parameters
0794: //
0795: DesktopRequest dreq = (DesktopRequest) DesktopRequestThreadLocalizer
0796: .getRequest();
0797: String reqEncoding = req.getCharacterEncoding();
0798: if (reqEncoding != null) {
0799: dreq.decodeParams(reqEncoding);
0800: } else {
0801: dreq.decodeParams(charset);
0802: }
0803:
0804: String clientType = appContext.getClientType(req);
0805: contentType = appContext.getContentType(clientType);
0806:
0807: DesktopResponse dres = (DesktopResponse) DesktopRequestThreadLocalizer
0808: .getResponse();
0809: if (!appContext.isAuthless(req)) {
0810: addLBCookie(dres);
0811: }
0812:
0813: // handle a community access
0814: if (dreq.getParameter(DesktopParameters.COMMUNITY_ACCESS) != null) {
0815: handleCommunity(dreq, res);
0816: }
0817:
0818: //
0819: // default action is content
0820: //
0821: action = dreq.getParameter("action");
0822: if ((action == null) || (action.length() == 0)) {
0823: action = "content";
0824: }
0825:
0826: StringBuffer outBuffer = null;
0827:
0828: res.setContentType(context.getContentType() + "; charset="
0829: + charset);
0830:
0831: if (logger.isLoggable(Level.FINEST)) {
0832: logger.log(Level.FINEST, "PSDT_CSPD0012", "action");
0833: logger.log(Level.FINEST, "PSDT_CSPD0013", "name");
0834: }
0835: name = getChannelName(dreq, true);
0836: if (name == null) {
0837: throw new DesktopException(
0838: "DesktopServlet.doGetPost(): no privilege to execute desktop",
0839: TypedException.NO_PRIVILEGE_TYPE);
0840: }
0841: // set top channel name in the request
0842: context.setTopChannelName(dreq, name);
0843:
0844: //
0845: // ptr for redirect url, if this is a post
0846: //
0847: URL next = null;
0848:
0849: //
0850: // handle main actions
0851: //
0852: if (action.equalsIgnoreCase("content")) {
0853: MonitoringSubsystemWrapper
0854: .getDesktopMonitoringSubsystem()
0855: .startDesktopServiceTransaction(
0856: DesktopRequestStatistic.DESKTOP_REQUEST_CONTENT);
0857: Provider p = context.getProvider(dreq, name);
0858: if (p == null) {
0859: throw new DesktopException(
0860: "attempt to reference unknown channel="
0861: + name,
0862: TypedException.UNKNOWN_CHANNEL_TYPE);
0863: }
0864: if (p.isPresentable(dreq)) {
0865: String last = dreq.getParameter("last");
0866:
0867: // Set the lastChannelName property
0868: if ((last == null)
0869: || (last.equalsIgnoreCase("true"))) {
0870: context.setDefaultChannelName(name);
0871: }
0872:
0873: outBuffer = context.getContent(dreq, dres, name);
0874: } else {
0875: res.sendError(406);
0876: }
0877: } else if (action.equalsIgnoreCase("edit")) {
0878: MonitoringSubsystemWrapper
0879: .getDesktopMonitoringSubsystem()
0880: .startDesktopServiceTransaction(
0881: DesktopRequestStatistic.DESKTOP_REQUEST_EDIT);
0882: name = getChannelName(dreq, false);
0883: Provider p = context.getProvider(dreq, name);
0884: if (p == null) {
0885: throw new DesktopException(
0886: "attempt to reference unknown channel="
0887: + name,
0888: TypedException.UNKNOWN_CHANNEL_TYPE);
0889: }
0890: if (!p.isEditable()) {
0891: throw new DesktopException(
0892: "attempt to edit non-editable channel="
0893: + name,
0894: TypedException.NON_EDITABLE_TYPE);
0895: }
0896: ActivityTime activityTime = new ActivityTime();
0897: MonitoringSubsystemWrapper
0898: .getDesktopMonitoringSubsystem()
0899: .getEditChannelActionStatistic().mark(
0900: activityTime);
0901: if (dreq.getParameter("targetprovider") == null) {
0902: fqcn = DPHelper.getFQCN(context.getDPRoot(), name);
0903: MonitoringSubsystemWrapper
0904: .getDesktopMonitoringSubsystem()
0905: .startProviderServiceTransaction(
0906: fqcn.encoded(),
0907: MonitoringSubsystem.CHANNEL_ACTION_EDIT);
0908: } else {
0909: fqcn = DPHelper.getFQCN(context.getDPRoot(), dreq
0910: .getParameter("targetprovider"));
0911: MonitoringSubsystemWrapper
0912: .getDesktopMonitoringSubsystem()
0913: .startProviderServiceTransaction(
0914: fqcn.encoded(),
0915: MonitoringSubsystem.CHANNEL_ACTION_EDIT);
0916: }
0917:
0918: if (p.getEditType() == EDIT_SUBSET) {
0919: String containerName = context
0920: .getEditProviderContainerName();
0921: Provider editProvider = context.getProvider(dreq,
0922: containerName);
0923: dreq.getParameterMap().put("targetprovider",
0924: new String[] { p.getName() });
0925: outBuffer = editProvider.getEdit(dreq, dres);
0926: } else {
0927: outBuffer = p.getEdit(dreq, dres);
0928: }
0929:
0930: if (dreq.getParameter("targetprovider") == null) {
0931: MonitoringSubsystemWrapper
0932: .getDesktopMonitoringSubsystem()
0933: .stopProviderServiceTransaction(
0934: fqcn.encoded(),
0935: MonitoringSubsystem.CHANNEL_ACTION_EDIT);
0936: MonitoringSubsystemWrapper
0937: .getDesktopMonitoringSubsystem()
0938: .getEditChannelActionStatistic().measure(
0939: activityTime, fqcn.plain());
0940: } else {
0941: MonitoringSubsystemWrapper
0942: .getDesktopMonitoringSubsystem()
0943: .stopProviderServiceTransaction(
0944: fqcn.encoded(),
0945: MonitoringSubsystem.CHANNEL_ACTION_EDIT);
0946: MonitoringSubsystemWrapper
0947: .getDesktopMonitoringSubsystem()
0948: .getEditChannelActionStatistic().measure(
0949: activityTime, fqcn.plain());
0950: }
0951: } else if (action.equalsIgnoreCase("process")) {
0952: MonitoringSubsystemWrapper
0953: .getDesktopMonitoringSubsystem()
0954: .startDesktopServiceTransaction(
0955: DesktopRequestStatistic.DESKTOP_REQUEST_PROCESS);
0956: name = getChannelName(dreq, false);
0957: Provider p = context.getProvider(dreq, name);
0958: if (p == null) {
0959: throw new DesktopException(
0960: "attempt to reference unknown channel="
0961: + name,
0962: TypedException.UNKNOWN_CHANNEL_TYPE);
0963: }
0964:
0965: if (isSetTabRequest(req, p) || p.isEditable()) {
0966: ActivityTime activityTime = new ActivityTime();
0967: MonitoringSubsystemWrapper
0968: .getDesktopMonitoringSubsystem()
0969: .getProcessChannelActionStatistic().mark(
0970: activityTime);
0971: if (dreq.getParameter("targetprovider") != null) {
0972: fqcn = DPHelper.getFQCN(context.getDPRoot(),
0973: dreq.getParameter("targetprovider"));
0974: MonitoringSubsystemWrapper
0975: .getDesktopMonitoringSubsystem()
0976: .startProviderServiceTransaction(
0977: fqcn.encoded(),
0978: MonitoringSubsystem.CHANNEL_ACTION_PROCESS);
0979: } else if (dreq
0980: .getParameter("windowProvider.targetPortletChannel") != null) {
0981: fqcn = DPHelper
0982: .getFQCN(
0983: context.getDPRoot(),
0984: dreq
0985: .getParameter("windowProvider.targetPortletChannel"));
0986: MonitoringSubsystemWrapper
0987: .getDesktopMonitoringSubsystem()
0988: .startProviderServiceTransaction(
0989: fqcn.encoded(),
0990: MonitoringSubsystem.CHANNEL_ACTION_PROCESS);
0991: } else {
0992: fqcn = DPHelper.getFQCN(context.getDPRoot(),
0993: name);
0994: MonitoringSubsystemWrapper
0995: .getDesktopMonitoringSubsystem()
0996: .startProviderServiceTransaction(
0997: fqcn.encoded(),
0998: MonitoringSubsystem.CHANNEL_ACTION_PROCESS);
0999: }
1000:
1001: try {
1002: next = p.processEdit(dreq, dres);
1003: } catch (InvalidEditFormDataException e) {
1004: if (logger.isLoggable(Level.WARNING)) {
1005: logger.log(Level.WARNING, "PSDT_CSPD0015",
1006: e);
1007: }
1008: String error = I18n.IURLEncode(e.getMessage());
1009: StringBuffer args = new StringBuffer(64);
1010: args.append("?action=edit&provider=").append(
1011: name).append("&error=").append(error);
1012:
1013: next = new URL(context.getDesktopURL(dreq)
1014: + args.toString());
1015: }
1016:
1017: if (dreq.getParameter("targetprovider") != null) {
1018: MonitoringSubsystemWrapper
1019: .getDesktopMonitoringSubsystem()
1020: .stopProviderServiceTransaction(
1021: fqcn.encoded(),
1022: MonitoringSubsystem.CHANNEL_ACTION_PROCESS);
1023: MonitoringSubsystemWrapper
1024: .getDesktopMonitoringSubsystem()
1025: .getProcessChannelActionStatistic()
1026: .measure(activityTime, fqcn.plain());
1027: } else if (dreq
1028: .getParameter("windowProvider.targetPortletChannel") != null) {
1029: MonitoringSubsystemWrapper
1030: .getDesktopMonitoringSubsystem()
1031: .stopProviderServiceTransaction(
1032: fqcn.encoded(),
1033: MonitoringSubsystem.CHANNEL_ACTION_PROCESS);
1034: MonitoringSubsystemWrapper
1035: .getDesktopMonitoringSubsystem()
1036: .getProcessChannelActionStatistic()
1037: .measure(activityTime, fqcn.plain());
1038: } else {
1039: MonitoringSubsystemWrapper
1040: .getDesktopMonitoringSubsystem()
1041: .stopProviderServiceTransaction(
1042: fqcn.encoded(),
1043: MonitoringSubsystem.CHANNEL_ACTION_PROCESS);
1044: MonitoringSubsystemWrapper
1045: .getDesktopMonitoringSubsystem()
1046: .getProcessChannelActionStatistic()
1047: .measure(activityTime, fqcn.plain());
1048: }
1049: } else {
1050: throw new DesktopException(
1051: "attempt to process non-editable channel="
1052: + name,
1053: TypedException.NON_EDITABLE_TYPE);
1054: }
1055:
1056: } else if (action.equalsIgnoreCase("ubt")) {
1057: String url = dreq.getParameter("url");
1058: out = getWriter(res, contentType, charset);
1059: sendRedirect(req, res, out, url);
1060: //UBT code - start
1061: try {
1062: UBTLogManager manager = UBTLogManager.getInstance();
1063: if (manager.isUBTEnabled()) {
1064: UBTEvent prov_ren = UBTEvent
1065: .getInstance(DesktopEvents.USER_CLICK_EX_LINK);
1066: prov_ren.put(UBTLogField.ACTION, "ExLink");
1067: prov_ren.put(UBTLogField.EX_PORTAL_LINK, url);
1068: manager.logEvent(new ProviderLogRecord(
1069: prov_ren, req, res, context
1070: .getContainerProviderContext()
1071: .getUserID()));
1072: }
1073: } catch (Exception e) {
1074: //ubt exception
1075: }
1076: //UBT code - end
1077: return;
1078: } else if (action.equalsIgnoreCase("logout")) {
1079: MonitoringSubsystemWrapper
1080: .getDesktopMonitoringSubsystem()
1081: .startDesktopServiceTransaction(
1082: DesktopRequestStatistic.DESKTOP_REQUEST_LOGOUT);
1083: context.store();
1084:
1085: Cookie authCookie = new Cookie("auth", "false");
1086: res.addCookie(authCookie);
1087:
1088: out = getWriter(res, contentType, charset);
1089:
1090: sendRedirect(req, res, out, context.getLogoutURL()
1091: + "?goto=" + context.getDesktopURL(req));
1092: return;
1093: } else {
1094: throw new DesktopException(
1095: "DestopServlet.doGetPost(): unknown action="
1096: + action + ", channel name=" + name);
1097: }
1098:
1099: //
1100: // if action was a process, redirect to url (next) returned from
1101: // provider's processEdit method
1102: //
1103: out = getWriter(res, contentType, charset);
1104: Cookie clientProperties = context.getClientProperties();
1105: if (clientProperties != null) {
1106: res.addCookie(clientProperties);
1107: }
1108: if (action.equalsIgnoreCase("process")) {
1109: if (next == null) {
1110: StringBuffer nextString = new StringBuffer(context
1111: .getDesktopURL(dreq));
1112: if (nextString.indexOf("?") != -1)
1113: nextString.append("&");
1114: else
1115: nextString.append("?");
1116: nextString.append("action=content&provider=")
1117: .append(context.getDefaultChannelName());
1118: String newargs = dreq.getParameter("dt.newargs");
1119: if (newargs != null)
1120: nextString.append("&" + newargs);
1121: sendRedirect(req, res, out, nextString.toString());
1122: } else {
1123: if (logger.isLoggable(Level.FINER)) {
1124: String[] param = { "DesktopServlet.doPost()",
1125: next.toString() };
1126: logger.log(Level.FINER, "PSDT_CSPD0016", param);
1127: }
1128: sendRedirect(req, res, out, next.toString());
1129: }
1130: } else {
1131: if (outBuffer != null) {
1132: out.write(outBuffer.toString());
1133: } else {
1134: throw new DesktopException(
1135: "Channel content is empty for " + name);
1136: }
1137: }
1138:
1139: //
1140: // for testing!!!
1141: //
1142: /*
1143: appContext.debugError("DesktopServlet.doGetPost(): dpRoot=" +
1144: context.getDPRoot().toString(false));
1145: */
1146:
1147: context.store();
1148: } catch (IOException ioe) {
1149: // nothing
1150: } catch (Throwable e) {
1151: // If the exception is wrapped in DesktopError get the wrapped exception
1152: if (e instanceof DesktopError) {
1153: logger.log(Level.SEVERE, "PSDT_CSPD0017", e.getCause());
1154: }
1155:
1156: if (res.isCommitted()) {
1157: //
1158: // just log an error, we can't
1159: // write to the stream to return
1160: // an error message
1161: //
1162: if (logger.isLoggable(Level.SEVERE)) {
1163: logger.log(Level.SEVERE, "PSDT_CSPD0017", e);
1164: }
1165: } else {
1166: res.reset();
1167:
1168: try {
1169: setCacheHeaders(res);
1170: } catch (Throwable t) {
1171: // nothing we can do, root cause will
1172: // be reported in handleException()
1173: }
1174:
1175: out = getWriter(res, contentType, charset);
1176: handleException(req, res, out, e);
1177: }
1178: } finally {
1179: if (out != null) {
1180: try {
1181: out.close();
1182: } catch (IOException ioe) {
1183: // nothing
1184: }
1185: }
1186: if (action != null) {
1187: if (action.equalsIgnoreCase("content")) {
1188: MonitoringSubsystemWrapper
1189: .getDesktopMonitoringSubsystem()
1190: .stopDesktopServiceTransaction(
1191: DesktopRequestStatistic.DESKTOP_REQUEST_CONTENT);
1192: MonitoringSubsystemWrapper
1193: .getDesktopMonitoringSubsystem()
1194: .getDesktopRequestStatistic()
1195: .measure(
1196: DesktopRequestStatistic.DESKTOP_REQUEST_CONTENT);
1197: } else if (action.equalsIgnoreCase("edit")) {
1198: MonitoringSubsystemWrapper
1199: .getDesktopMonitoringSubsystem()
1200: .stopDesktopServiceTransaction(
1201: DesktopRequestStatistic.DESKTOP_REQUEST_EDIT);
1202: MonitoringSubsystemWrapper
1203: .getDesktopMonitoringSubsystem()
1204: .getDesktopRequestStatistic()
1205: .measure(
1206: DesktopRequestStatistic.DESKTOP_REQUEST_EDIT);
1207: } else if (action.equalsIgnoreCase("process")) {
1208: MonitoringSubsystemWrapper
1209: .getDesktopMonitoringSubsystem()
1210: .stopDesktopServiceTransaction(
1211: DesktopRequestStatistic.DESKTOP_REQUEST_PROCESS);
1212: MonitoringSubsystemWrapper
1213: .getDesktopMonitoringSubsystem()
1214: .getDesktopRequestStatistic()
1215: .measure(
1216: DesktopRequestStatistic.DESKTOP_REQUEST_PROCESS);
1217: } else if (action.equalsIgnoreCase("logout")) {
1218: MonitoringSubsystemWrapper
1219: .getDesktopMonitoringSubsystem()
1220: .stopDesktopServiceTransaction(
1221: DesktopRequestStatistic.DESKTOP_REQUEST_LOGOUT);
1222: MonitoringSubsystemWrapper
1223: .getDesktopMonitoringSubsystem()
1224: .getDesktopRequestStatistic()
1225: .measure(
1226: DesktopRequestStatistic.DESKTOP_REQUEST_LOGOUT);
1227: }
1228: }
1229: }
1230: }
1231:
1232: private static void sendRedirect(HttpServletRequest req,
1233: HttpServletResponse res, Writer out, String u)
1234: throws IOException, DesktopException {
1235: DesktopContext dc = null;
1236:
1237: try {
1238: dc = DesktopContextThreadLocalizer.get();
1239: } catch (ContextError c) {
1240: if (logger.isLoggable(Level.FINER)) {
1241: logger.log(Level.FINER, "PSDT_CSPD0018",
1242: "DesktopServlet.sendRedirect ()");
1243: }
1244: }
1245:
1246: u = getAbsURL(req, appContext, u);
1247:
1248: /*
1249: * HTTP 1.0 spec states that when sending a 302 response code "Unless it
1250: * was a HEAD request, the Entity-Body of the response should contain
1251: * a short note with a hyperlink to the new URI(s)."
1252: * (see RFC1945 Section 9.3 302)
1253: *
1254: * Some WAP gateway implementations of HTTP expect this body and will
1255: * fail without it (see 4452980).
1256: */
1257: if (!req.getMethod().equalsIgnoreCase("head")) {
1258: String clientType = appContext.getClientType(req);
1259: String clientPath = appContext.getClientPath(clientType);
1260:
1261: StringBuffer redirect = null;
1262:
1263: if (clientType != null) {
1264: String contentType = appContext
1265: .getContentType(clientType);
1266: String charset = getCharset(req);
1267: String type = appContext.getDefaultDesktopType();
1268:
1269: if (dc != null) {
1270: u = dc.encodeURL(u);
1271: type = dc.getDesktopType();
1272: }
1273:
1274: Hashtable tags = new Hashtable();
1275: tags.put("url", u);
1276:
1277: redirect = appContext.getTemplate(type, Locale
1278: .getDefault().toString(), null, null,
1279: clientPath, "redirect.template", tags,
1280: appContext.getTemplateBaseDir());
1281:
1282: if (logger.isLoggable(Level.FINER)) {
1283: logger.log(Level.FINER, "PSDT_CSPD0019", redirect);
1284: }
1285:
1286: if (redirect != null) {
1287: out.write(redirect.toString());
1288: } else {
1289: //
1290: // log error, but fail gracefully because the spec says "should"
1291: //
1292: if (logger.isLoggable(Level.SEVERE)) {
1293: logger.log(Level.SEVERE, "PSDT_CSPD0019",
1294: "DesktopServlet.sendRedirect ()");
1295: }
1296: }
1297: }
1298: }
1299:
1300: // Use setStatus() and setHeader() in lieu of sendRedirect() to get
1301: // around web server bug 4874475.
1302: // See bug 4891570.
1303:
1304: // res.sendRedirect(u);
1305:
1306: res.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
1307: res.setHeader("Location", u);
1308: }
1309:
1310: private static String getAbsURL(HttpServletRequest req,
1311: DesktopAppContext appContext, String u) throws IOException {
1312: if (!u.regionMatches(true, 0, "http://", 0, 7)
1313: && !u.regionMatches(true, 0, "https://", 0, 7)) {
1314: StringBuffer ru = appContext.getRequestServer(req);
1315: URL requestURL = new URL(ru.toString());
1316: String scheme = requestURL.getProtocol();
1317: StringBuffer absURL = new StringBuffer().append(scheme)
1318: .append("://").append(requestURL.getHost()).append(
1319: ":");
1320: int port = requestURL.getPort();
1321: // default port schemes need to fill in port
1322: if (scheme.equals("http") && port <= 0) {
1323: port = 80;
1324: } else if (scheme.equals("https") && port <= 0) {
1325: port = 443;
1326: }
1327:
1328: absURL.append(port).append(u);
1329:
1330: return absURL.toString();
1331:
1332: } else {
1333: return u;
1334: }
1335: }
1336:
1337: /**
1338: * this method handles exceptions in the desktop, throwing up a standard
1339: * error page and logging the exception.
1340: */
1341: private void handleException(HttpServletRequest req,
1342: HttpServletResponse res, Writer out, Throwable e) {
1343: DesktopContext dc = null;
1344: String lastChannelName = null;
1345:
1346: try {
1347: if (out == null) {
1348: throw new DesktopException(e);
1349: }
1350:
1351: try {
1352: lastChannelName = getChannelName(req, true);
1353: } catch (DesktopError derr) {
1354: // nothing, we want to avoid "server error" in the simple
1355: // case where we cannot get the last channel name. last
1356: // channel name is not required for error provider
1357: }
1358:
1359: if (DesktopContextThreadLocalizer.exists()) {
1360: dc = DesktopContextThreadLocalizer.get();
1361: } else {
1362: if (appContext.isAuthlessEnabled()) {
1363: // Show errors with authless locale, look-n-feel, etc.
1364: dc = dcFactory.getDesktopContext(req);
1365: // we don't want to refresh context at this point.
1366: }
1367: }
1368:
1369: if (dc != null) {
1370: req.setAttribute(errorProvider.getName()
1371: + ".desktopContext", dc);
1372: }
1373:
1374: if (appContext != null) {
1375: req.setAttribute(errorProvider.getName()
1376: + ".desktopAppContext", appContext);
1377: }
1378:
1379: if (lastChannelName != null) {
1380: req.setAttribute(errorProvider.getName()
1381: + ".lastChannelName", lastChannelName);
1382: }
1383:
1384: if (e != null) {
1385: req.setAttribute(
1386: errorProvider.getName() + ".exception", e);
1387: }
1388:
1389: if (e instanceof TypedException) {
1390: String propertiesFile = PropertiesConfigContext.DESKTOP_CONFIG_FILE;
1391: req.setAttribute(errorProvider.getName()
1392: + ".propertiesFile", propertiesFile);
1393: req.setAttribute(errorProvider.getName() + ".response",
1394: RequestThreadLocalizer.getResponse());
1395: }
1396: // Get the Contents from the Error Provider
1397: StringBuffer content = errorProvider.getContent(req, res);
1398:
1399: if (content != null) {
1400: out.write(content.toString());
1401: }
1402:
1403: boolean logException = true;
1404: if (e instanceof TypedException) {
1405: TypedException te = (TypedException) e;
1406: if (te.getType().equals(
1407: TypedException.SESSION_TIMED_OUT)) {
1408: logException = false;
1409: }
1410: }
1411: if (logger.isLoggable(Level.SEVERE) && logException) {
1412: logger.log(Level.SEVERE, "PSDT_CSPD0021", e);
1413: }
1414: } catch (Throwable e2) {
1415: //
1416: // this means we weren't able to return the error
1417: // page to the user. make sure the error appears
1418: // in the webserver log
1419: //
1420: if (logger.isLoggable(Level.SEVERE)) {
1421: String[] param = { e.getMessage(), e2.getMessage() };
1422: logger.log(Level.SEVERE, "PSDT_CSPD0022", param);
1423: logger.log(Level.SEVERE, "PSDT_CSPD0023", e2);
1424: logger.log(Level.SEVERE, "PSDT_CSPD0024", e);
1425: }
1426: try {
1427: res
1428: .sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
1429: } catch (IOException ioe) {
1430: if (logger.isLoggable(Level.SEVERE)) {
1431: logger.log(Level.SEVERE, "PSDT_CSPD0025", e);
1432: }
1433: }
1434: }
1435: }
1436:
1437: protected static void setCacheHeaders(HttpServletResponse res) {
1438: int cacheTime = appContext.getBrowserCacheInterval();
1439: if (cacheTime > 0) {
1440: res.setDateHeader("Expires", System.currentTimeMillis()
1441: + (1000 * cacheTime));
1442: res.setHeader("Cache-Control", "max-age=" + cacheTime);
1443: } else {
1444: res.setHeader("Pragma", "no-cache");
1445: res.setDateHeader("Expires", 0);
1446: res.setHeader("Cache-Control",
1447: "no-cache, must-revalidate, max-age=0");
1448: }
1449: }
1450:
1451: protected static String getCharset(HttpServletRequest req) {
1452: DesktopContext context = null;
1453: String charset = null;
1454:
1455: if (DesktopContextThreadLocalizer.exists()) {
1456: context = DesktopContextThreadLocalizer.get();
1457: charset = context.getCharset();
1458: } else {
1459: Locale locale = Locale.getDefault();
1460: charset = appContext.getCharset(appContext
1461: .getClientType(req), locale);
1462: }
1463:
1464: return charset;
1465: }
1466:
1467: private String getChannelName(HttpServletRequest req,
1468: boolean useDefaults) {
1469: //
1470: // we always take the url param over anything else
1471: // if the url param is absent, and we have been
1472: // instructed to use defaults, check and see
1473: // if there's a desktop context. if there is,
1474: // use the dc to get the channel name
1475: // from the session property. if it's not there
1476: // read it from the desktop context defaults.
1477: //
1478:
1479: String name = req.getParameter("provider");
1480: if (name == null && useDefaults) {
1481: if (DesktopContextThreadLocalizer.exists()) {
1482: DesktopContext dc = DesktopContextThreadLocalizer.get();
1483: name = dc.getDefaultChannelName();
1484: }
1485: }
1486: return name;
1487:
1488: }
1489:
1490: private boolean authCookieNotSet(HttpServletRequest req) {
1491: return !("true".equals(getCookieValue(req, "auth")));
1492: }
1493:
1494: private String getCookieValue(HttpServletRequest req, String name) {
1495:
1496: if (name == null) {
1497: return null;
1498: }
1499:
1500: Cookie[] cookies = req.getCookies();
1501:
1502: for (int loopIndex = 0; loopIndex < cookies.length; loopIndex++) {
1503: if (name.equals(cookies[loopIndex].getName())) {
1504: return cookies[loopIndex].getValue();
1505: }
1506: }
1507: return null;
1508: }
1509:
1510: private boolean isSetTabRequest(HttpServletRequest req, Provider p) {
1511:
1512: if (p instanceof JSPTabContainerProvider) {
1513: return ((JSPTabContainerProvider) p).isSetTabRequest(req);
1514: }
1515:
1516: return false;
1517: }
1518:
1519: }
|