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.context;
0006:
0007: import com.iplanet.sso.SSOToken;
0008: import com.sun.portal.community.mc.CMCException;
0009: import com.sun.portal.community.mc.CMCFactory;
0010: import com.sun.portal.community.mc.CMCUser;
0011: import com.sun.portal.community.mc.ConfigTable;
0012: import com.sun.portal.desktop.DesktopParameters;
0013: import com.sun.portal.desktop.DesktopRequestThreadLocalizer;
0014: import com.sun.portal.desktop.RequestThreadLocalizer;
0015: import com.sun.portal.desktop.dp.DPRoot;
0016: import com.sun.portal.desktop.template.ParsedTagArray;
0017: import com.sun.portal.log.common.PortalLogger;
0018: import com.sun.portal.providers.Provider;
0019: import com.sun.portal.providers.ProviderException;
0020: import com.sun.portal.providers.containers.ContainerProvider;
0021: import com.sun.portal.providers.context.ContainerProviderContext;
0022: import netscape.ldap.LDAPDN;
0023:
0024: import javax.servlet.http.Cookie;
0025: import javax.servlet.http.HttpServletRequest;
0026: import javax.servlet.http.HttpServletResponse;
0027: import java.io.File;
0028: import java.util.Collection;
0029: import java.util.Collections;
0030: import java.util.HashMap;
0031: import java.util.Hashtable;
0032: import java.util.Iterator;
0033: import java.util.LinkedHashSet;
0034: import java.util.List;
0035: import java.util.Locale;
0036: import java.util.Map;
0037: import java.util.Set;
0038: import java.util.StringTokenizer;
0039: import java.util.TreeSet;
0040: import java.util.logging.Level;
0041: import java.util.logging.LogRecord;
0042: import java.util.logging.Logger;
0043: import java.util.Arrays;
0044:
0045: public class PSDesktopContext implements DesktopContext, UserListener,
0046: ProviderClassLoaderListener {
0047: private static Logger logger = PortalLogger
0048: .getLogger(PSDesktopContext.class);
0049:
0050: private static LogRecord getLogRecord(Level level, String message,
0051: Object[] parameters, Throwable t) {
0052: LogRecord result = new LogRecord(level, message);
0053: result.setLoggerName(logger.getName());
0054: result.setParameters(parameters);
0055: result.setThrown(t);
0056: return result;
0057: }
0058:
0059: protected static DesktopAppContext desktopAppContext = null;
0060: protected SessionContext session = null;
0061: protected ServiceContext service = null;
0062: protected static DPContext dpContext = null;
0063: protected DPUserContext dpUserContext = null;
0064: protected ContainerProviderContext containerProviderContext = null;
0065:
0066: // BEGIN CR6344207
0067: private boolean initDone = false;
0068: // END CR6344207
0069:
0070: protected Locale locale = null;
0071: protected String charset = null;
0072: private long lastAccess = 0;
0073: private boolean isStale = false;
0074: protected Map clientProperties = Collections
0075: .synchronizedMap(new HashMap());
0076:
0077: //
0078: // used to cache the client type, in the case where this
0079: // class backs an authenticated user
0080: //
0081: private String clientType = null;
0082:
0083: private DPRoot dpRoot = null;
0084: private long lastUserDPScanTime;
0085: private static ThreadLocal tlCMCUser = new ThreadLocal();
0086: private static final String WSRP_REMOTE_TOKEN = "desktop.wsrp.ssotoken";
0087:
0088: public void init(HttpServletRequest req) {
0089: DesktopContextThreadLocalizer.set(this );
0090:
0091: if (desktopAppContext == null) {
0092: desktopAppContext = DesktopAppContextThreadLocalizer.get();
0093: }
0094: if (desktopAppContext == null) {
0095: throw new ContextError(
0096: "PSDesktopContext.init(): could not get desktop app context");
0097: }
0098:
0099: //
0100: // order matters here!
0101: //
0102: initServiceContext(req);
0103: initSessionContext(req, desktopAppContext.getPortalId());
0104:
0105: addUserListener(this );
0106:
0107: initDPContext();
0108: initDPUserContext(req);
0109: initLocale();
0110:
0111: //subscript to ProviderClassLoaderListener, so the authless context
0112: //get notified when it should pick up a new ProviderClassLoader.
0113: if (isAuthless(req)) {
0114: ProviderClassLoader pcl = ProviderClassLoader
0115: .getInstance(getProviderClassBaseDir());
0116: pcl.addListener(this );
0117: }
0118:
0119: initDone = true;
0120: }
0121:
0122: // BEGIN CR6344207
0123: public boolean isInitDone() {
0124: return initDone;
0125: }
0126:
0127: // END CR6344207
0128:
0129: protected SessionContext getSessionContext() {
0130: if (session == null) {
0131: throw new ContextError(
0132: "PSDesktopContext.getSessionContext(): not initialized");
0133: }
0134:
0135: return session;
0136: }
0137:
0138: private SessionContext initSessionContext(HttpServletRequest req,
0139: String portalId) {
0140: if (session == null) {
0141: String sessionContextClassName;
0142: if (isWSRP(req)) {
0143: sessionContextClassName = getWSRPSessionContextClassName();
0144: } else if (isAuthless(req)) {
0145: sessionContextClassName = getAuthlessSessionContextClassName();
0146: } else {
0147: sessionContextClassName = getSessionContextClassName();
0148: }
0149:
0150: try {
0151: session = (SessionContext) (Class
0152: .forName(sessionContextClassName).newInstance());
0153: } catch (ClassNotFoundException cnfe) {
0154: throw new ContextError(
0155: "DesktopContext.getSessionContext()", cnfe);
0156: } catch (NoClassDefFoundError ncdfe) {
0157: throw new ContextError(
0158: "DesktopContext.getSessionContext()", ncdfe);
0159: } catch (IllegalAccessException iae) {
0160: throw new ContextError(
0161: "DesktopContext.getSessionContext()", iae);
0162: } catch (ClassCastException cce) {
0163: throw new ContextError(
0164: "DesktopContext.getSessionContext()", cce);
0165: } catch (InstantiationException ie) {
0166: throw new ContextError(
0167: "DesktopContext.getSessionContext()", ie);
0168: } catch (SecurityException se) {
0169: throw new ContextError(
0170: "DesktopContext.getSessionContext()", se);
0171: }
0172:
0173: session.init(req, portalId);
0174: }
0175:
0176: return session;
0177: }
0178:
0179: private DPContext getDPContext() {
0180: if (dpContext == null) {
0181: throw new ContextError(
0182: "PSDesktopContext.getDPContext(): not initialized");
0183: }
0184:
0185: return dpContext;
0186: }
0187:
0188: private DPContext initDPContext() {
0189: synchronized (PSDesktopContext.class) {
0190: if (dpContext == null) {
0191: String dpContextClassName = getDPContextClassName();
0192: if (dpContextClassName == null) {
0193: throw new ContextError(
0194: "DesktopContext.getDPContext(): class name was null");
0195: }
0196:
0197: try {
0198: dpContext = (DPContext) (Class
0199: .forName(dpContextClassName).newInstance());
0200: } catch (ClassNotFoundException cnfe) {
0201: throw new ContextError(
0202: "DesktopContext.getDPContext()", cnfe);
0203: } catch (NoClassDefFoundError ncdfe) {
0204: throw new ContextError(
0205: "DesktopContext.getDPContext()", ncdfe);
0206: } catch (IllegalAccessException iae) {
0207: throw new ContextError(
0208: "DesktopContext.getDPContext()", iae);
0209: } catch (ClassCastException cce) {
0210: throw new ContextError(
0211: "DesktopContext.getDPContext()", cce);
0212: } catch (InstantiationException ie) {
0213: throw new ContextError(
0214: "DesktopContext.getDPContext()", ie);
0215: } catch (SecurityException se) {
0216: throw new ContextError(
0217: "DesktopContext.getDPContext()", se);
0218: }
0219:
0220: dpContext.init(RequestThreadLocalizer.getRequest());
0221: } else {
0222: // nothing
0223: }
0224: }
0225:
0226: return dpContext;
0227: }
0228:
0229: protected DPUserContext getDPUserContext() {
0230: if (dpUserContext == null) {
0231: throw new ContextError(
0232: "PSDesktopContext.getDPUserContext(): not initialized");
0233: }
0234:
0235: return dpUserContext;
0236: }
0237:
0238: protected DPUserContext initDPUserContext(HttpServletRequest req) {
0239: if (dpUserContext == null) {
0240: String dpUserContextClassName = getDPUserContextClassName();
0241: if (dpUserContextClassName == null) {
0242: throw new ContextError(
0243: "DesktopContext.getDPUserContext(): class name was null");
0244: }
0245:
0246: try {
0247: dpUserContext = (DPUserContext) (Class
0248: .forName(dpUserContextClassName).newInstance());
0249: } catch (ClassNotFoundException cnfe) {
0250: throw new ContextError(
0251: "DesktopContext.getDPUserContext()", cnfe);
0252: } catch (NoClassDefFoundError ncdfe) {
0253: throw new ContextError(
0254: "DesktopContext.getDPUserContext()", ncdfe);
0255: } catch (IllegalAccessException iae) {
0256: throw new ContextError(
0257: "DesktopContext.getDPUserContext()", iae);
0258: } catch (ClassCastException cce) {
0259: throw new ContextError(
0260: "DesktopContext.getDPUserContext()", cce);
0261: } catch (InstantiationException ie) {
0262: throw new ContextError(
0263: "DesktopContext.getDPUserContext()", ie);
0264: } catch (SecurityException se) {
0265: throw new ContextError(
0266: "DesktopContext.getDPUserContext()", se);
0267: }
0268:
0269: if (isWSRP(req)) {
0270: //
0271: // TBD: do we want some security here? validate
0272: // this is a WSRP user? have list of authorized
0273: // WSRP users?
0274: //
0275: SSOToken ssoToken = getRemoteSSOToken(req);
0276: if (ssoToken != null) {
0277: dpUserContext.init(ssoToken);
0278: } else {
0279: String uid = desktopAppContext.getSessionID(req);
0280: dpUserContext.init(req, uid, uid);
0281: }
0282: } else if (isAuthless(req)) {
0283: //
0284: // get pw for authless uid, so we can init
0285: // services for it
0286: //
0287: String uid = desktopAppContext.getSessionID(req);
0288: Map authorized = desktopAppContext
0289: .getAuthorizedAuthlessUIDs();
0290: uid = uid.toLowerCase();
0291: if (!authorized.containsKey(uid)) {
0292: throw new ContextError(
0293: "DesktopContext.initDPUserContext(): no password for authless uid="
0294: + uid);
0295: }
0296: String pw = (String) authorized.get(uid);
0297: dpUserContext.init(req, uid, pw);
0298: } else {
0299: dpUserContext.init(req);
0300: }
0301: }
0302:
0303: return dpUserContext;
0304: }
0305:
0306: protected ServiceContext getServiceContext() {
0307: if (service == null) {
0308: throw new ContextError(
0309: "PSDesktopContext.getServiceContext(): not initialized");
0310: }
0311:
0312: return service;
0313: }
0314:
0315: private ServiceContext initServiceContext(HttpServletRequest req) {
0316: if (service == null) {
0317: String serviceContextClassName = getServiceContextClassName();
0318: if (serviceContextClassName == null) {
0319: throw new ContextError(
0320: "DesktopContext.getServiceContext(): class name was null");
0321: }
0322:
0323: try {
0324: service = (ServiceContext) (Class
0325: .forName(serviceContextClassName).newInstance());
0326: } catch (ClassNotFoundException cnfe) {
0327: throw new ContextError(
0328: "DesktopContext.getServiceContext()", cnfe);
0329: } catch (NoClassDefFoundError ncdfe) {
0330: throw new ContextError(
0331: "DesktopContext.getServiceContext()", ncdfe);
0332: } catch (IllegalAccessException iae) {
0333: throw new ContextError(
0334: "DesktopContext.getServiceContext()", iae);
0335: } catch (ClassCastException cce) {
0336: throw new ContextError(
0337: "DesktopContext.getServiceContext()", cce);
0338: } catch (InstantiationException ie) {
0339: throw new ContextError(
0340: "DesktopContext.getServiceContext()", ie);
0341: } catch (SecurityException se) {
0342: throw new ContextError(
0343: "DesktopContext.getServiceContext()", se);
0344: }
0345:
0346: if (isWSRP(req)) {
0347: //
0348: // TBD: do we want some security here? validate
0349: // this is a WSRP user? have list of authorized
0350: // WSRP users?
0351: //
0352: SSOToken ssoToken = getRemoteSSOToken(req);
0353: if (ssoToken != null) {
0354: service.init(ssoToken);
0355: } else {
0356: String uid = desktopAppContext.getSessionID(req);
0357: service.init(req, uid, uid);
0358: }
0359: } else if (isAuthless(req)) {
0360: String uid = desktopAppContext.getSessionID(req);
0361: Map authorized = desktopAppContext
0362: .getAuthorizedAuthlessUIDs();
0363: uid = uid.toLowerCase();
0364: if (!authorized.containsKey(uid)) {
0365: throw new ContextError(
0366: "DesktopContext.initServiceContext(): no password for authless uid="
0367: + uid);
0368: }
0369: String pw = (String) authorized.get(uid);
0370: service.init(req, uid, pw);
0371: } else {
0372: service.init(req);
0373: }
0374: }
0375:
0376: return service;
0377: }
0378:
0379: public ContainerProviderContext getContainerProviderContext() {
0380: if (containerProviderContext == null) {
0381: throw new ContextError(
0382: "PSDesktopContext.getContainerProviderContext(): not initialized");
0383: }
0384:
0385: return containerProviderContext;
0386: }
0387:
0388: public synchronized ContainerProviderContext initContainerProviderContext() {
0389: if (containerProviderContext == null) {
0390: String providerContextClassName = getContainerProviderContextClassName();
0391:
0392: if (providerContextClassName == null) {
0393: throw new ContextError(
0394: "DesktopContext.getContainerProviderContext(): provider context class name was null");
0395: }
0396:
0397: try {
0398: containerProviderContext = (ContainerProviderContext) (Class
0399: .forName(providerContextClassName)
0400: .newInstance());
0401: } catch (ClassNotFoundException cnfe) {
0402: throw new ContextError(
0403: "DesktopContext.getProviderContext(): ", cnfe);
0404: } catch (NoClassDefFoundError ncdfe) {
0405: throw new ContextError(
0406: "DesktopContext.getProviderContext(): ", ncdfe);
0407: } catch (IllegalAccessException iae) {
0408: throw new ContextError(
0409: "DesktopContext.getProviderContext(): ", iae);
0410: } catch (ClassCastException cce) {
0411: throw new ContextError(
0412: "DesktopContext.getProviderContext(): ", cce);
0413: } catch (InstantiationException ie) {
0414: throw new ContextError(
0415: "DesktopContext.getProviderContext(): ", ie);
0416: } catch (SecurityException se) {
0417: throw new ContextError(
0418: "DesktopContext.getProviderContext(): ", se);
0419: }
0420:
0421: containerProviderContext.init(RequestThreadLocalizer
0422: .getRequest());
0423: }
0424:
0425: return containerProviderContext;
0426: }
0427:
0428: public void store() {
0429: //
0430: // store DP user document, if necessary
0431: //
0432: DPRoot dpr = getDPRoot();
0433:
0434: if (dpr.isDirty()) {
0435: synchronized (dpr) {
0436: if (dpr.isDirty()) {
0437: if (!isDPRootCustomized()) {
0438: throw new ContextError(
0439: "PSDesktopContext.store(): attempt to store non-customized dpRoot="
0440: + dpr.toString());
0441: }
0442:
0443: dpr.setDirty(false);
0444: DPUserContext dpuc = getDPUserContext();
0445: StringBuffer sb = new StringBuffer(256);
0446: dpr.toXML(sb, 0);
0447: dpuc.storeDPUserDocument(sb.toString());
0448:
0449: //
0450: // if we just wrote the document, we have the latest copy
0451: // mark it such that we just read it so avoid
0452: // re-reading because we just wrote it out
0453: //
0454: DPCacheManager.setUserDocumentLastRead(getUserID());
0455: }
0456: }
0457: }
0458: }
0459:
0460: protected boolean isDPUserRootModified() {
0461: boolean modified = false;
0462:
0463: long userLastModified = getDPUserContext()
0464: .getDPUserDocumentLastModified();
0465: long userLastRead = DPCacheManager
0466: .getUserDocumentLastRead(getUserID());
0467:
0468: //
0469: // logic here is:
0470: // if the user document has not been read and the ldap attr is set
0471: // that means that the user doc has changed (from not being set to being set)
0472: // and we will consider it modified
0473: // OR if the modified time is greater than the last time we read the doc
0474: // we will consider is modified
0475: //
0476: if ((userLastRead == -1 && isDPRootSet())
0477: || userLastModified > userLastRead) {
0478: modified = true;
0479: }
0480:
0481: return modified;
0482: }
0483:
0484: public long getLastAccess() {
0485: return lastAccess;
0486: }
0487:
0488: public void setLastAccess(long ms) {
0489: lastAccess = ms;
0490: }
0491:
0492: public boolean getIsStale() {
0493: return isStale;
0494: }
0495:
0496: public void setIsStale(boolean stale) {
0497: isStale = stale;
0498: }
0499:
0500: public void providerClassLoaderOutdated() {
0501: setIsStale(true);
0502: }
0503:
0504: private void updateLastUserDPScanTime() {
0505: if ((desktopAppContext.getDPScanInterval() == DPCacheManager.DP_SCAN_INTERVAL_NEVER)
0506: || (desktopAppContext.getDPScanInterval() == DPCacheManager.DP_SCAN_INTERVAL_ALWAYS)) {
0507: return;
0508: }
0509:
0510: lastUserDPScanTime = System.currentTimeMillis();
0511: }
0512:
0513: private boolean doScanUserDP() {
0514: if (desktopAppContext.getDPScanInterval() == DPCacheManager.DP_SCAN_INTERVAL_NEVER) {
0515: return false;
0516: }
0517:
0518: if (desktopAppContext.getDPScanInterval() == DPCacheManager.DP_SCAN_INTERVAL_ALWAYS) {
0519: return true;
0520: }
0521:
0522: return ((System.currentTimeMillis() - lastUserDPScanTime) > desktopAppContext
0523: .getDPScanInterval() * 1000);
0524: }
0525:
0526: public void refresh() {
0527: boolean membershipChanged = updateMembership();
0528:
0529: boolean modified = false;
0530: boolean doScanUserDP = doScanUserDP();
0531: if (doScanUserDP) {
0532: if (personalize()) {
0533: modified = isDPUserRootModified();
0534: updateLastUserDPScanTime();
0535: }
0536: }
0537:
0538: // Call to sharedDPRootsModified updates Shared-DPs if they've been modified in data source
0539: modified |= DPCacheManager.sharedDPRootsModified(getCMCUser(),
0540: getEffectiveMembership(getSessionContext()),
0541: getDPContext(), desktopAppContext.getDPScanInterval());
0542:
0543: // Make sure we do have dpRoot
0544: if (modified || membershipChanged) {
0545: // Let gearUpDPRoot() init DPRoot again as relevant DPs have changed
0546: dpRoot = null;
0547: DPCacheManager.removeUserDPRoot(getUserID());
0548: }
0549: gearUpDPRoot();
0550:
0551: // Make sure we do have containerProvidercontext
0552: initContainerProviderContext();
0553:
0554: if (modified || membershipChanged) {
0555: getContainerProviderContext().refresh();
0556: }
0557: ProviderContextThreadLocalizer
0558: .set(getContainerProviderContext());
0559: }
0560:
0561: public void setDPRootCustomized(boolean state) {
0562: DPCacheManager.setCustomized(getUserID(), state);
0563: }
0564:
0565: public boolean isDPRootCustomized() {
0566: return DPCacheManager.hasCustomized(getUserID());
0567: }
0568:
0569: protected boolean isDPRootSet() {
0570: DPUserContext dpuc = getDPUserContext();
0571: byte[] doc = dpuc.getDPUserDocument();
0572:
0573: if (doc != null) {
0574: if (doc.length > 0) {
0575: return true;
0576: }
0577: }
0578:
0579: return false;
0580: }
0581:
0582: private static CMCUser getCMCUser() {
0583: return (CMCUser) tlCMCUser.get();
0584: }
0585:
0586: private static void setCMCUser(CMCUser cu) {
0587: tlCMCUser.set(cu);
0588: }
0589:
0590: private void gearUpCMCUser() {
0591: if (getCMCUser() == null) {
0592: // Set for every new request; only once during request processing.
0593: // Understand what happens a) when Login, b) when Desktop Reload.
0594: try {
0595: CMCFactory cf = CMCFactory.getInstance();
0596: setCMCUser(cf.getCMCUser(LDAPDN.normalize(getUserID()
0597: .toLowerCase())));
0598: } catch (CMCException e) {
0599: throw new ContextError(
0600: "PSDesktopContext.gearUpCMCUser()", e);
0601: }
0602: }
0603: }
0604:
0605: private static void setMembership(String userId, Set membership) {
0606: CommunityUserMembershipThreadLocalizer.set(userId, membership);
0607: }
0608:
0609: private static Set filterMembership(Collection membership,
0610: Set realMembership) {
0611: Set result = new TreeSet();
0612: List communityContributorTypes = desktopAppContext
0613: .getCommunityContributorTypes();
0614:
0615: if (membership != null) {
0616: Iterator iterator = membership.iterator();
0617: while (iterator.hasNext()) {
0618: ConfigTable.ConfigKey configKey = (ConfigTable.ConfigKey) iterator
0619: .next();
0620:
0621: if (!realMembership.contains(configKey)) {
0622: if (logger.isLoggable(Level.CONFIG)) {
0623: logger.log(getLogRecord(Level.CONFIG,
0624: "PSDT_CSPDC0036", new Object[] {
0625: membership, realMembership },
0626: null));
0627: }
0628: continue;
0629: }
0630:
0631: if (!communityContributorTypes.contains(configKey
0632: .getCommunityPrincipal().getType())) {
0633: if (logger.isLoggable(Level.CONFIG)) {
0634: logger
0635: .log(getLogRecord(
0636: Level.CONFIG,
0637: "PSDT_CSPDC0037",
0638: new Object[] {
0639: configKey
0640: .getCommunityPrincipal()
0641: .getType(),
0642: communityContributorTypes
0643: .toString() },
0644: null));
0645: }
0646: continue;
0647: }
0648: result.add(configKey);
0649: }
0650: }
0651:
0652: return result;
0653: }
0654:
0655: //
0656: // This returns a Set of Strings. Each string being the community principal id of the current set of interested community
0657: // as found in the request parameter or in the session.
0658: // Normally, we'll get only one string based on community url generation right now. But logic is here to support
0659: // more than one.
0660: private static Set getCurrentMembership(
0661: SessionContext sessionContext) {
0662: Set result = new TreeSet();
0663:
0664: String currentMembership = null;
0665: HttpServletRequest req = DesktopRequestThreadLocalizer
0666: .getRequest();
0667: if (req != null) {
0668: currentMembership = req
0669: .getParameter(DesktopParameters.CURRENT_MEMBERSHIP);
0670: }
0671: if (currentMembership == null) {
0672: currentMembership = sessionContext
0673: .getStringProperty(DesktopParameters.CURRENT_MEMBERSHIP);
0674: }
0675:
0676: if (currentMembership != null) {
0677: if (!currentMembership
0678: .equals(DesktopParameters.CURRENT_MEMBERSHIP_VALUE_NONE)) {
0679: // supply default community provider if not specified...
0680: Set temp = new TreeSet();
0681: temp
0682: .addAll(Arrays
0683: .asList(currentMembership
0684: .split(DesktopParameters.COLLECTION_SEPARATOR)));
0685: for (Iterator i = temp.iterator(); i.hasNext();) {
0686: String cid = (String) i.next();
0687: if (cid.indexOf("__") != -1)
0688: result.add(cid);
0689: else
0690: result.add("jdo__" + cid); // XXX need config for this
0691: }
0692: if (result.size() == 0) {
0693: // Membership doesn't exist! So, remove it from session context.
0694: sessionContext
0695: .setStringProperty(
0696: DesktopParameters.CURRENT_MEMBERSHIP,
0697: DesktopParameters.CURRENT_MEMBERSHIP_VALUE_NONE);
0698: } else {
0699: sessionContext.setStringProperty(
0700: DesktopParameters.CURRENT_MEMBERSHIP,
0701: currentMembership);
0702: }
0703: } else {
0704: sessionContext
0705: .setStringProperty(
0706: DesktopParameters.CURRENT_MEMBERSHIP,
0707: DesktopParameters.CURRENT_MEMBERSHIP_VALUE_NONE);
0708: }
0709: }
0710:
0711: return (result.size() == 0) ? null : result;
0712: }
0713:
0714: //
0715: // realMembership is set of ConfigKeys.
0716: // currentMembership is set of Strings.
0717: //
0718: private static Set prepareEffectiveMembership(Set realMembership,
0719: Set currentMembership) throws CMCException {
0720: return CommunityDesktopMembership.getDesktopMembership(
0721: realMembership, currentMembership);
0722: }
0723:
0724: private static Set getEffectiveMembership(
0725: SessionContext sessionContext) {
0726: String effectiveMembership = sessionContext
0727: .getStringProperty(DesktopParameters.EFFECTIVE_MEMBERSHIP);
0728: if (effectiveMembership == null) {
0729: return null;
0730: } else {
0731: return new TreeSet(ConfigTable.ConfigKey
0732: .asCollection(effectiveMembership));
0733: }
0734: }
0735:
0736: private static void setEffectiveMembership(
0737: SessionContext sessionContext, Set effectiveMembership) {
0738: if (effectiveMembership != null) {
0739: sessionContext
0740: .setStringProperty(
0741: DesktopParameters.EFFECTIVE_MEMBERSHIP,
0742: ConfigTable.ConfigKey
0743: .asString(effectiveMembership));
0744: }
0745: }
0746:
0747: private static boolean gearUpMembership(String userId,
0748: SessionContext sessionContext) {
0749: boolean membershipChanged = false;
0750:
0751: Set oldEffectiveMembership = getEffectiveMembership(sessionContext);
0752: try {
0753: Set realMembership = new TreeSet(getCMCUser()
0754: .getMembership());
0755: Set currentMembership = getCurrentMembership(sessionContext);
0756: Set newEffectiveMembership = prepareEffectiveMembership(
0757: realMembership, currentMembership);
0758: setEffectiveMembership(sessionContext,
0759: newEffectiveMembership);
0760:
0761: if (oldEffectiveMembership == null) {
0762: // do nothing! effective membership not set implies dpRoot null. dpRoot will be constructed
0763: } else if (!oldEffectiveMembership
0764: .equals(newEffectiveMembership)) {
0765: membershipChanged = true;
0766: }
0767: setMembership(userId, realMembership);
0768:
0769: } catch (CMCException e) {
0770: throw new ContextError(
0771: "PSDesktopContext.gearUpMembership()", e);
0772: }
0773:
0774: return membershipChanged;
0775: }
0776:
0777: private boolean updateMembership() {
0778: setCMCUser(null);
0779: gearUpCMCUser();
0780: return gearUpMembership(getUserID(), getSessionContext());
0781: }
0782:
0783: private boolean personalize() {
0784: return isDPRootCustomized() || isDPRootSet();
0785: }
0786:
0787: private void gearUpDPRoot() {
0788: if (dpRoot == null) {
0789: // New PSDesktopContext is being initialized; Login-or-Cache-Reaper-cleaned PSDesktopContext
0790: // Or, sharedDPRoots have been updated, and this dpRoot needs to be re-created.
0791: if (personalize()) {
0792: dpRoot = DPCacheManager.getUserDPRoot(getUserID());
0793: if (dpRoot == null) {
0794: dpRoot = DPCacheManager
0795: .getDPRoot(
0796: getEffectiveMembership(getSessionContext()),
0797: getDPContext(), getDPUserContext(),
0798: true);
0799: DPCacheManager.putUserDPRoot(getUserID(), dpRoot);
0800: setDPRootCustomized(true); // just make sure as isDPRootSet() might still be false
0801: }
0802: } else {
0803: dpRoot = DPCacheManager.getDPRoot(
0804: getEffectiveMembership(getSessionContext()),
0805: getDPContext(), getDPUserContext(), false);
0806: setDPRootCustomized(false); // just make sure
0807: }
0808: }
0809: }
0810:
0811: public DPRoot getDPRoot() {
0812: if (isDPRootCustomized() && !isDPRootSet()) {
0813: // DPRoot is to be personalized.
0814: // Make a copy of shared-DPRoot, and use it going forward as user-DP.
0815: dpRoot = null;
0816: gearUpDPRoot();
0817: }
0818:
0819: return dpRoot;
0820: }
0821:
0822: public Set getAncestors(HttpServletRequest req, String name) {
0823: String topName = getDefaultChannelName();
0824: return getAncestors(req, name, topName);
0825: }
0826:
0827: private Set getAncestors(HttpServletRequest req, String child,
0828: String current) {
0829: // base case, this means we found the path to the child
0830: if (child.equals(current)) {
0831: return new LinkedHashSet();
0832: }
0833:
0834: List selected;
0835: try {
0836: // else, we are not at the base case
0837: // see if current is a container
0838: Provider currentProvider = getProvider(req, current);
0839: if (currentProvider == null) {
0840: // this causes us to go to the catch block below, and
0841: // log the problem
0842: throw new ProviderException(
0843: "error getting anccestors for child: "
0844: + child
0845: + ", could not get provider object for ancestor: "
0846: + current);
0847: }
0848:
0849: // if the current channel is not a container, return null
0850: // this means we found a leaf, but the leaf is not
0851: // the child we are looking for
0852: if (!(currentProvider instanceof ContainerProvider)) {
0853: return null;
0854: }
0855:
0856: // else, it is a container, so we need to run through its
0857: // selected channels looking for the leaf
0858: ContainerProvider currentContainerProvider = (ContainerProvider) currentProvider;
0859: selected = currentContainerProvider.getSelectedChannels();
0860:
0861: Set children = null;
0862: for (Iterator i = selected.iterator(); i.hasNext();) {
0863: String selectedName = (String) i.next();
0864: // recurse on each selected channel
0865: Set selectedChildren = getAncestors(req, child,
0866: selectedName);
0867: if (selectedChildren != null) {
0868: // this means we found the child
0869: // and that current is in the path to that
0870: // child
0871: if (children == null) {
0872: children = selectedChildren;
0873: } else {
0874: children.addAll(selectedChildren);
0875: }
0876: }
0877: }
0878: if (children != null) {
0879: children.add(current);
0880: }
0881: return children;
0882: } catch (ProviderException pe) {
0883: // we had a problem somewhere calling provider methods
0884: // in this case, it's better to log the problem than to
0885: // give the user an error page. the only harm is that the
0886: // content may not get refreshed properly from the call to
0887: // ProviderContext.contentChanged()
0888: if (logger.isLoggable(Level.WARNING)) {
0889: logger.log(getLogRecord(Level.WARNING,
0890: "PSDT_CSPDC0035",
0891: new Object[] { child, current }, pe));
0892: }
0893: return null;
0894: }
0895: }
0896:
0897: //
0898: // service methods
0899: //
0900: public String getPropertiesContextClassName() {
0901: return getServiceContext().getPropertiesContextClassName();
0902: }
0903:
0904: public String getContainerProviderContextClassName() {
0905: return getServiceContext()
0906: .getContainerProviderContextClassName();
0907: }
0908:
0909: protected String getSessionContextClassName() {
0910: return getServiceContext().getSessionContextClassName();
0911: }
0912:
0913: protected String getAuthlessSessionContextClassName() {
0914: return getServiceContext().getAuthlessSessionContextClassName();
0915: }
0916:
0917: protected String getWSRPSessionContextClassName() {
0918: return getServiceContext().getWSRPSessionContextClassName();
0919: }
0920:
0921: protected String getDPContextClassName() {
0922: return getServiceContext().getDPContextClassName();
0923: }
0924:
0925: protected String getDPUserContextClassName() {
0926: return getServiceContext().getDPUserContextClassName();
0927: }
0928:
0929: protected String getServiceContextClassName() {
0930: return desktopAppContext.getServiceContextClassName();
0931: }
0932:
0933: public Set getRoles() {
0934: return getServiceContext().getRoles();
0935: }
0936:
0937: public String getLocaleString() {
0938: return getServiceContext().getLocaleString();
0939: }
0940:
0941: private boolean isLocaleChanged() {
0942: String newLocale = getLocaleString();
0943: return (newLocale != null)
0944: && (!newLocale.equals(locale.toString()));
0945: }
0946:
0947: public Locale getLocale() {
0948: if (locale == null) {
0949: throw new ContextError(
0950: "PSDesktopContext.getLocale(): not initialized");
0951: }
0952: if (isLocaleChanged()) {
0953: locale = initLocale(getLocaleString());
0954: }
0955:
0956: return locale;
0957: }
0958:
0959: protected Locale initLocale() {
0960:
0961: locale = initLocale(getLocaleString());
0962:
0963: // use default if not specified
0964: if (locale == null) {
0965: locale = Locale.getDefault();
0966: }
0967:
0968: return locale;
0969: }
0970:
0971: protected static Locale initLocale(String stringformat) {
0972: if (stringformat == null) {
0973: return null;
0974: }
0975:
0976: StringTokenizer tokenizer = new StringTokenizer(stringformat,
0977: "_");
0978: String lang = "";
0979: String country = "";
0980: String variant = "";
0981: if (tokenizer.hasMoreTokens()) {
0982: lang = tokenizer.nextToken();
0983: }
0984: if (tokenizer.hasMoreTokens()) {
0985: country = tokenizer.nextToken();
0986: }
0987: if (tokenizer.hasMoreTokens()) {
0988: variant = tokenizer.nextToken();
0989: }
0990:
0991: return new Locale(lang, country, variant);
0992: }
0993:
0994: public String getDesktopType() {
0995: return getServiceContext().getDesktopType();
0996: }
0997:
0998: public String getDesktopURL(HttpServletRequest req) {
0999: return encodeURL(desktopAppContext.getDesktopURL(req));
1000: }
1001:
1002: public String getDesktopURL(HttpServletRequest req, Map query,
1003: Map pathInfo) {
1004: return encodeURL(desktopAppContext.getDesktopURL(req, query,
1005: pathInfo));
1006: }
1007:
1008: public String getDesktopURL(HttpServletRequest req, String query) {
1009: return encodeURL(desktopAppContext.getDesktopURL(req, query));
1010: }
1011:
1012: public String getLogoutURL() {
1013: return encodeURL(getServiceContext().getLogoutURL());
1014: }
1015:
1016: public String getLoginURL() {
1017: return getServiceContext().getLoginURL();
1018: }
1019:
1020: public String getDefaultChannelName() {
1021: String name = getClientProperty("lastChannelName");
1022: if ((name == null)
1023: || (name.length() == 0)
1024: || (getProvider(DesktopRequestThreadLocalizer
1025: .getRequest(), name) == null)) {
1026: name = getServiceContext().getDefaultChannelName();
1027: }
1028: return name;
1029: }
1030:
1031: public void setDefaultChannelName(String channel) {
1032: setClientProperty("lastChannelName", channel);
1033: }
1034:
1035: public String getEditProviderContainerName() {
1036: return getServiceContext().getEditProviderContainerName();
1037: }
1038:
1039: public String getTemplateBaseDir() {
1040: return desktopAppContext.getTemplateBaseDir();
1041: }
1042:
1043: public String getStringAttribute(String name) {
1044: return getServiceContext().getStringAttribute(name);
1045: }
1046:
1047: public String getStringAttribute(String name, Locale locale) {
1048: return getServiceContext().getStringAttribute(name, locale);
1049: }
1050:
1051: public void setStringAttribute(String name, String val) {
1052: getServiceContext().setStringAttribute(name, val);
1053: }
1054:
1055: public String getTopChannelName(HttpServletRequest req) {
1056: String name = (String) req.getAttribute("topChannelName");
1057: if (name == null || name.length() == 0) {
1058: name = getDefaultChannelName();
1059: }
1060: return name;
1061: }
1062:
1063: public void setTopChannelName(HttpServletRequest req, String channel) {
1064: req.setAttribute("topChannelName", channel);
1065: }
1066:
1067: //
1068: // server request
1069: //
1070: public StringBuffer getRequestServer(HttpServletRequest req) {
1071: return desktopAppContext.getRequestServer(req);
1072: }
1073:
1074: //
1075: // client type methods
1076: //
1077: public String getClientType() {
1078: String ct;
1079: HttpServletRequest req = RequestThreadLocalizer.getRequest();
1080:
1081: if (clientType != null) {
1082: //
1083: // client type was not null. this means we are not
1084: // authless and we've already queried the DAC for
1085: // the client type
1086: //
1087: ct = clientType;
1088: } else if (!desktopAppContext.isAuthless(req)) {
1089: //
1090: // we are not authless, but we have not queried for
1091: // the client type yet. set the instance member
1092: // clientType so we can remember this decision
1093: // next time
1094: //
1095:
1096: //
1097: // first, see if the client type is set as a client
1098: // property. this call maps to check for an SSO
1099: // token property
1100: //
1101: clientType = ct = getClientProperty("clientType");
1102: if (ct == null) {
1103: //
1104: // query for it based on the request, as a last
1105: // resort
1106: //
1107: clientType = ct = desktopAppContext.getClientType(req);
1108: }
1109: } else {
1110: //
1111: // we are authless, query for the client type, but
1112: // don't set the instance member client type. this
1113: // is so next time through, we will not assume a client
1114: // type
1115: //
1116: ct = desktopAppContext.getClientType(req);
1117: }
1118: return ct;
1119:
1120: }
1121:
1122: public String getContentType() {
1123: return desktopAppContext.getContentType(getClientType());
1124: }
1125:
1126: public String getCharset() {
1127: if (isLocaleChanged()) {
1128: locale = initLocale(getLocaleString());
1129: }
1130: return desktopAppContext.getCharset(getClientType(), locale);
1131: }
1132:
1133: public String getDefaultClientType() {
1134: return desktopAppContext.getDefaultClientType();
1135: }
1136:
1137: public String getClientPath() {
1138: return desktopAppContext.getClientPath(getClientType());
1139: }
1140:
1141: public String getClientTypeProperty(String key) {
1142: return getClientTypeProperty(getClientType(), key);
1143: }
1144:
1145: public String getClientTypeProperty(String clientType, String key) {
1146: return desktopAppContext.getClientTypeProperty(clientType, key);
1147: }
1148:
1149: public Set getClientTypeProperties(String clientType, String key) {
1150: return desktopAppContext.getClientTypeProperties(clientType,
1151: key);
1152: }
1153:
1154: public String getEncoderClassName() {
1155: return desktopAppContext.getEncoderClassName(getClientType());
1156: }
1157:
1158: //
1159: // session methods
1160: //
1161:
1162: public Object getSessionProperty(String name) {
1163: return clientProperties.get(name);
1164: }
1165:
1166: public void setSessionProperty(String name, Object val) {
1167: clientProperties.put(name, val);
1168: }
1169:
1170: public String getSessionID() {
1171: String sid = getSessionContext().getSessionID();
1172: if (sid == null) {
1173: sid = desktopAppContext.getDefaultAuthlessUID();
1174: }
1175:
1176: return sid;
1177: }
1178:
1179: public boolean isAuthless(HttpServletRequest req) {
1180: return desktopAppContext.isAuthless(req);
1181: }
1182:
1183: public boolean isWSRP(HttpServletRequest req) {
1184: return desktopAppContext.isWSRP(req);
1185: }
1186:
1187: public void addSessionListener(SessionListener sl) {
1188: getSessionContext().addSessionListener(sl);
1189: }
1190:
1191: public String encodeURL(String url) {
1192: return getSessionContext().encodeURL(url);
1193: }
1194:
1195: public String getUserID() {
1196: String uid = getSessionContext().getUserID();
1197: if (uid == null) {
1198: uid = desktopAppContext.getDefaultAuthlessUID();
1199: }
1200:
1201: return uid;
1202: }
1203:
1204: public void addUserListener(UserListener ul) {
1205: getSessionContext().addUserListener(ul);
1206: }
1207:
1208: /*
1209: public void addReference(UserListener ul) {
1210: getSessionContext().addUserReference();
1211: }
1212: */
1213:
1214: public String getAuthenticationType() {
1215: return getSessionContext().getAuthenticationType();
1216: }
1217:
1218: //
1219: // client properties
1220: //
1221: public Cookie getClientProperties() {
1222: return getSessionContext().getClientProperties();
1223: }
1224:
1225: //
1226: // client properties methods
1227: //
1228: public String getClientProperty(String name) {
1229: return getSessionContext().getStringProperty(name);
1230: }
1231:
1232: public void setClientProperty(String name, String value) {
1233: getSessionContext().setStringProperty(name, value);
1234: }
1235:
1236: //
1237: // container provider methods
1238: //
1239: public Provider getProvider(HttpServletRequest req, String name) {
1240: //
1241: // passing in null for the container name because it is not
1242: // used in the impl. at some point the impl needs to be changed
1243: // to not accept the container name (since it's not used).
1244: //
1245: return getContainerProviderContext().getProvider(req, null,
1246: name);
1247: }
1248:
1249: public StringBuffer getContent(HttpServletRequest req,
1250: HttpServletResponse res, String name)
1251: throws ProviderException {
1252: return getContainerProviderContext().getContent(req, res, null,
1253: name);
1254: }
1255:
1256: public Map getContent(HttpServletRequest req,
1257: HttpServletResponse res, List providers, int timeout)
1258: throws ProviderException {
1259: return getContainerProviderContext().getContent(req, res, null,
1260: providers, timeout);
1261: }
1262:
1263: //
1264: // template methods
1265: //
1266: public ParsedTagArray getTemplate(String app, String provider,
1267: String file) {
1268: return desktopAppContext.getTemplate(getServiceContext()
1269: .getDesktopType(), getLocaleString(), app, provider,
1270: getClientPath(), file, getTemplateBaseDir());
1271: }
1272:
1273: public ParsedTagArray getTemplate(String desktopType,
1274: String locale, String app, String provider,
1275: String clientPath, String file, String baseDir) {
1276: return desktopAppContext.getTemplate(desktopType, locale, app,
1277: provider, clientPath, file, baseDir);
1278: }
1279:
1280: public StringBuffer getTemplate(String app, String provider,
1281: String file, Hashtable table) {
1282: ContainerProviderContext pc = null;
1283: try {
1284: pc = getContainerProviderContext();
1285: } catch (ContextError e) {
1286: //don't throw it
1287: }
1288: return desktopAppContext.getTemplate(getServiceContext()
1289: .getDesktopType(), getLocaleString(), app, provider,
1290: getClientPath(), file, table, getTemplateBaseDir(), pc);
1291:
1292: }
1293:
1294: public StringBuffer getTemplate(String desktopType, String locale,
1295: String app, String provider, String clientPath,
1296: String file, Hashtable table, String baseDir) {
1297: ContainerProviderContext pc = null;
1298: try {
1299: pc = getContainerProviderContext();
1300: } catch (ContextError e) {
1301: //don't throw it
1302: }
1303: return desktopAppContext.getTemplate(desktopType, locale, app,
1304: provider, clientPath, file, table, baseDir, pc);
1305:
1306: }
1307:
1308: public File getTemplatePath(String app, String provider, String file) {
1309: return desktopAppContext.getTemplatePath(getServiceContext()
1310: .getDesktopType(), getLocaleString(), app, provider,
1311: getClientPath(), file, getTemplateBaseDir());
1312: }
1313:
1314: public File getTemplatePath(String desktopType, String locale,
1315: String app, String provider, String clientPath,
1316: String file, String baseDir) {
1317: return desktopAppContext.getTemplatePath(desktopType, locale,
1318: app, provider, clientPath, file, baseDir);
1319: }
1320:
1321: public File getTemplateMostSpecificPath(String app,
1322: String provider, String file) {
1323: return desktopAppContext.getTemplateMostSpecificPath(
1324: getServiceContext().getDesktopType(),
1325: getLocaleString(), app, provider, getClientPath(),
1326: file, getTemplateBaseDir());
1327: }
1328:
1329: public File getTemplateMostSpecificPath(String desktopType,
1330: String locale, String app, String provider,
1331: String clientPath, String file, String baseDir) {
1332: return desktopAppContext.getTemplateMostSpecificPath(
1333: desktopType, locale, app, provider, clientPath, file,
1334: baseDir);
1335: }
1336:
1337: //
1338: // listeners
1339: //
1340: public void userLogout(UserEvent ue) {
1341: DPCacheManager.removeUserDPRoot(ue.getUserID());
1342: }
1343:
1344: //
1345: // config
1346: //
1347: public String getProviderClassBaseDir() {
1348: return desktopAppContext.getProviderClassBaseDir();
1349: }
1350:
1351: public String getJSPScratchDir() {
1352: return desktopAppContext.getJSPScratchDir();
1353: }
1354:
1355: public String getJSPCompilerWARClassPath() {
1356: return desktopAppContext.getJSPCompilerWARClassPath();
1357: }
1358:
1359: public String getStaticContentPath() {
1360: return desktopAppContext.getStaticContentPath();
1361: }
1362:
1363: public String getConfigProperty(String key) {
1364: return desktopAppContext.getConfigProperty(key);
1365: }
1366:
1367: private SSOToken getRemoteSSOToken(HttpServletRequest req) {
1368: Object ssoToken = req.getAttribute(WSRP_REMOTE_TOKEN);
1369: if (ssoToken == null) {
1370: return null;
1371: } else {
1372: return (SSOToken) ssoToken;
1373: }
1374: }
1375: }
|