001: /**
002: * $Id: Context.java,v 1.32 2005/10/18 22:28:22 js143762 Exp $
003: * Copyright 2002 Sun Microsystems, Inc. All
004: * rights reserved. Use of this product is subject
005: * to license terms. Federal Acquisitions:
006: * Commercial Software -- Government Users
007: * Subject to Standard License Terms and
008: * Conditions.
009: *
010: * Sun, Sun Microsystems, the Sun logo, and Sun ONE
011: * are trademarks or registered trademarks of Sun Microsystems,
012: * Inc. in the United States and other countries.
013: */package com.sun.portal.wireless.taglibs.base;
014:
015: import java.util.*;
016: import java.text.*;
017: import java.net.*;
018: import java.io.*;
019: import java.lang.reflect.*;
020:
021: import javax.servlet.*;
022: import javax.servlet.http.*;
023: import javax.servlet.jsp.*;
024:
025: import com.iplanet.sso.*;
026: import com.iplanet.am.sdk.*;
027: import com.sun.ssoadapter.SSOAdapter;
028: import com.sun.ssoadapter.SSOAdapterSession;
029: import com.sun.ssoadapter.SSOAdapterFactory;
030:
031: import com.sun.ssoadapter.config.PSClientAwareContextFactory;
032: import com.sun.ssoadapter.config.ClientAwareAppContext;
033: import com.sun.ssoadapter.config.ClientAwareUserContext;
034:
035: import com.iplanet.am.util.AMClientDetector;
036: import com.iplanet.services.cdm.*;
037:
038: import com.sun.portal.wireless.util.AppConfigConstants;
039:
040: /**
041: * Context - track state across requests.
042: *
043: * This class implements a simple context mechanism
044: * that may be used for tracking user state across
045: * multiple requests.
046: *
047: * @author John Saare
048: * @version 2.0
049: * @see ContextCache
050: */
051:
052: public class Context implements SSOTokenListener {
053:
054: protected SSOToken session = null;
055:
056: // Note: This needs to be overwritten by those service contexts
057: // that provide locale specific info (which is all of them).
058: // Pay special attention to UtilContext in the "no-session"
059: // case.
060: private Locale userLocale = com.iplanet.am.util.Locale
061: .getLocale("en_US");
062:
063: private String userLocaleString = null;
064: protected String charSetString = null;
065: private String userLangString = null;
066: private String userCountryString = null;
067: private String userVariantString = null;
068:
069: protected TimeZone timezone = null;
070: protected String errorCode = null;
071:
072: private String clientType = null;
073:
074: private Map serviceMap = null;
075: private PSClientAwareContextFactory contextFactory = null;
076: private ClientAwareUserContext userContext = null;
077:
078: protected SSOAdapter ssoAdapter = null;
079:
080: protected Context parentContext = null;
081:
082: /**
083: * For Context implementations associated with an IS service.
084: *
085: */
086: public void init(HttpServletRequest request, SSOToken session,
087: String serviceName, SSOAdapter ssoAdapter) throws Exception {
088: /**
089: * Check whether the user is authorized to use the service
090: * If he is not authorized throw NoServiceAssignedException
091: * which is an derived class of JspException.
092: */
093:
094: if (serviceMap == null || serviceMap.get(serviceName) != null) {
095: AMStoreConnection connection = new AMStoreConnection(
096: session);
097: AMUser loggedinUser = connection.getUser(session
098: .getPrincipal().getName());
099: Set vals = loggedinUser.getAssignedServices();
100: if (vals == null || vals.isEmpty()) {
101: throw new NoServiceAssignedException("No-"
102: + serviceName);
103: }
104: boolean serviceNotFound = true;
105: Iterator iter = vals.iterator();
106: while (iter.hasNext()) {
107: String assignedService = (String) iter.next();
108: if (serviceName.equals(assignedService)) {
109: serviceNotFound = false;
110: break;
111: }
112: }
113:
114: if (serviceNotFound) {
115: throw new NoServiceAssignedException("No-"
116: + serviceName);
117: }
118: }
119:
120: serviceMap = new HashMap();
121: serviceMap.put("serviceName", serviceName);
122: contextInit(request, session, ssoAdapter);
123: }
124:
125: /**
126: * For Context implementations not associated with an IS service.
127: *
128: */
129: public void init(HttpServletRequest request, SSOToken session,
130: SSOAdapter ssoAdapter) throws Exception {
131: contextInit(request, session, ssoAdapter);
132: }
133:
134: /**
135: * The default init...
136: *
137: * @param session
138: */
139: private void contextInit(HttpServletRequest request,
140: SSOToken session, SSOAdapter ssoAdapter) throws Exception {
141: this .session = session;
142: session.addSSOTokenListener(this );
143:
144: this .ssoAdapter = ssoAdapter;
145:
146: contextFactory = PSClientAwareContextFactory.getInstance();
147: userContext = contextFactory
148: .getClientAwareUserContext(new SSOAdapterSession(
149: request));
150:
151: AMClientDetector mapCD = new AMClientDetector();
152: clientType = mapCD.getClientType(request);
153:
154: userLocaleString = "en_US";
155: if (session != null) {
156: userLocaleString = session.getProperty("Locale");
157: }
158:
159: StringTokenizer localeTokens = new StringTokenizer(
160: userLocaleString, "_");
161: userLangString = (localeTokens.hasMoreTokens() ? localeTokens
162: .nextToken() : "");
163: userCountryString = (localeTokens.hasMoreTokens() ? localeTokens
164: .nextToken()
165: : "");
166: userVariantString = (localeTokens.hasMoreTokens() ? localeTokens
167: .nextToken()
168: : "");
169:
170: userLocale = new java.util.Locale(userLangString,
171: userCountryString, userVariantString);
172: loadTimeZone();
173: }
174:
175: public void setParentContext(Context context) {
176: parentContext = context;
177: }
178:
179: public Context getParentContext() {
180: return parentContext;
181: }
182:
183: /**
184: * Gets a service context...
185: * Does so in the following steps:
186: * 1. Retrieve from pageContext, if not present...
187: * 2. Retrieve from contextCache, if not present...
188: * 3. Create a new context.
189: *
190: * Manipulates/uses the following page context attributes:
191: *
192: * - <contextClassName>configName: Stores the name of the configuration pertinent to the context
193: * to be retrieved. This is a hack..., intended to workaround limitations imposed by backwards
194: * compatability. It is set by the various ContextTag implementations, prior to making
195: * their respective getContext(...) calls.
196: * - <contextType>: Stores a context, keyed by categorical name, e.g., "abcontext", "mailcontext", or "calcontext".
197: * - ps.session: The current SSOToken/session.
198: *
199: * @param request
200: * @param pageContext
201: * @param contextClassName
202: * @param contextCacheClassName
203: * @param contextType
204: */
205: static public Context getContext(PageContext pageContext,
206: String contextClassName, String contextCacheClassName,
207: String contextType)
208:
209: throws Exception {
210: try {
211: Context context = (Context) pageContext
212: .getAttribute(contextType);
213:
214: if (context != null) {
215: if (Class.forName(contextClassName).isInstance(context)) {
216: context.reloadUserPreferences();
217: return context;
218: }
219: }
220:
221: String configNameKey = contextType + "configName";
222: String configName = (String) pageContext
223: .getAttribute(configNameKey);
224:
225: HttpServletRequest request = (HttpServletRequest) pageContext
226: .getRequest();
227:
228: SSOToken session = (SSOToken) pageContext.getAttribute(
229: "ps.session", PageContext.REQUEST_SCOPE);
230: if (session == null) {
231: SSOTokenManager tokenManager = SSOTokenManager
232: .getInstance();
233: session = tokenManager.createSSOToken(request);
234:
235: pageContext.setAttribute("ps.session", session,
236: PageContext.REQUEST_SCOPE);
237: }
238:
239: Class contextCacheClass = Class
240: .forName(contextCacheClassName);
241: Class[] argClassArray = { Class.forName("java.lang.String") };
242: Method getInstanceMethod = contextCacheClass.getMethod(
243: "getInstance", argClassArray);
244: Object[] objArray = { contextCacheClassName };
245: ContextCache contextCache = (ContextCache) getInstanceMethod
246: .invoke(null, objArray);
247:
248: context = contextCache.get(session, configName);
249: Context parentContext = null;
250: if (context != null) {
251: if (Class.forName(contextClassName).isInstance(context)) {
252: pageContext.setAttribute(contextType, context);
253: return context;
254: }
255: parentContext = context;
256: }
257: if (configName == null && parentContext != null) {
258: configName = parentContext.getConfigName();
259: }
260: context = (Context) (Class.forName(contextClassName))
261: .newInstance();
262: context.setParentContext(parentContext);
263: SSOAdapter ssoAdapter = (SSOAdapter) pageContext
264: .getAttribute(contextType + "ssoAdapter");
265: if (ssoAdapter == null) {
266: try {
267: SSOAdapterFactory ssoFactory = SSOAdapterFactory
268: .getInstance();
269: ssoAdapter = ssoFactory
270: .getSSOAdapter(
271: configName,
272: new SSOAdapterSession(
273: request,
274: null,
275: null,
276: AppConfigConstants.MAP_INSTANCE_NAME));
277: } catch (Exception ee) {
278: ssoAdapter = null;
279: }
280: }
281: context.init(request, session, ssoAdapter);
282: contextCache.put(context, configName);
283: pageContext.setAttribute(contextType, context);
284:
285: return context;
286:
287: } catch (Exception e) {
288: //Util.logWarning("com.sun.portal.wireless.taglibs.base.Context.getContext() failed.", e);
289: throw e;
290: }
291:
292: }
293:
294: /**
295: *Read if any attributes needs to be read
296: *Lets say the user has modified time zone , we have no clue.
297: *hence read it again
298: */
299: public void reloadUserPreferences() {
300: loadTimeZone();
301:
302: }
303:
304: /**
305: * Get an attribute string from the user's profile.
306: *
307: * @return attr string.
308: */
309: public String getAttributeString(String name) {
310: return getAttributeString(name, null);
311: }
312:
313: public String getAttributeString(String name, String value) {
314: try {
315: String ret = userContext.getStringAttribute(serviceMap,
316: name);
317: return (ret == null) ? value : ret;
318: } catch (Exception e) {
319: return value;
320: }
321: }
322:
323: public Set getAttributeSet(String name) {
324: try {
325: return userContext.getAttribute(serviceMap, name);
326: } catch (Exception e) {
327: }
328: return null;
329: }
330:
331: /**
332: * Get a Set valued attribute on the user context for a specific client type.
333: * @param name
334: * @param clientType
335: * @return
336: */
337: public Set getAttributeSet(String name, String clientType) {
338: Set values = null;
339: try {
340: values = userContext.getAttribute(serviceMap, clientType,
341: name);
342: } catch (IOException e) {
343: e.printStackTrace();
344: }
345: return values;
346: }
347:
348: /**
349: * Set a String valued attribute on the user context.
350: * @param name
351: * @param value
352: */
353: public void setAttributeString(String name, String value) {
354: try {
355: userContext.setStringAttribute(serviceMap, name, value);
356: } catch (IOException e) {
357: //TODO: handle exception more elegantly !
358: e.printStackTrace();
359: }
360: }
361:
362: /**
363: * Set a Set valued attribute on the user context.
364: * @param name
365: * @param value
366: */
367: public void setAttribute(String name, Set value) {
368: try {
369: userContext.setAttribute(serviceMap, name, value);
370: } catch (IOException e) {
371: e.printStackTrace();
372: }
373: }
374:
375: /**
376: * Set a Set valued attribute on the user context, based on client type.
377: * @param clientType
378: * @param name
379: * @param value
380: */
381: public void setAttribute(String clientType, String name, Set value) {
382: try {
383: userContext.setAttribute(serviceMap, clientType, name,
384: value);
385: } catch (IOException e) {
386: e.printStackTrace();
387: }
388: }
389:
390: /**
391: * Return the session.
392: *
393: * @return session object.
394: */
395: public SSOToken getSession() {
396: return session;
397: }
398:
399: /**
400: * Return the session id.
401: *
402: * @return session id.
403: */
404: public SSOTokenID getSessionID() {
405: return (session != null) ? session.getTokenID() : null;
406: }
407:
408: /**
409: * Return the user's locale.
410: *
411: * @return locale
412: */
413: public Locale getLocale() {
414: return userLocale;
415: }
416:
417: /**
418: * Return the user's timezone.
419: *
420: * @return timezone
421: */
422: public TimeZone getTimeZone() {
423: return timezone;
424: }
425:
426: /**
427: * Return the errorCode.
428: *
429: * @return errorCode String.
430: */
431: public String getErrorCode() {
432: return errorCode;
433: }
434:
435: /**
436: * Set the errorCode
437: *
438: * @param errorCode - String.
439: */
440: public void setErrorCode(String errorCode) {
441: this .errorCode = errorCode;
442: }
443:
444: /**
445: * Handle SessionChanged events from the Portal Session.
446: * Cleanup the context when the session goes invalid.
447: *
448: * @param se session change event
449: */
450: public void ssoTokenChanged(SSOTokenEvent evt) {
451: }
452:
453: public SSOAdapter getSSOAdapter() {
454: return ssoAdapter;
455: }
456:
457: public String getClientType() {
458: return clientType;
459: }
460:
461: public String getUserLocaleString() {
462: return userLocaleString;
463: }
464:
465: public Locale getUserLocale() {
466: if (userLocale == null) {
467: try {
468: userLocale = new java.util.Locale(userLangString,
469: userCountryString, userVariantString);
470: } catch (Exception e) {
471: userLocale = new java.util.Locale("en", "US");
472: }
473: }
474: return userLocale;
475: }
476:
477: public String getCharset() {
478:
479: if (charSetString != null) {
480: return charSetString;
481: }
482:
483: try {
484: Client clientObj = Client.getInstance(getClientType());
485: charSetString = clientObj.getCharset(getUserLocale());
486: } catch (Exception e) {
487: }
488:
489: return charSetString;
490: }
491:
492: public String getContentType() {
493:
494: String contentType = null;
495: try {
496: Client clientObj = Client.getInstance(getClientType());
497: contentType = clientObj.getProperty("contentType");
498: } catch (Exception e) {
499: }
500:
501: return contentType;
502: }
503:
504: public String getConfigName() {
505: return ssoAdapter.getName();
506: }
507:
508: /**
509: * Resets a service context...
510: * Does so in the following steps:
511: * 1. Remove from pageContext if present
512: * 2. Remove from contextCache if present
513: * 3. Remove ssoadapter from pageContext if present
514: */
515: static public void reset(PageContext pageContext,
516: String contextClassName, String contextCacheClassName,
517: String contextType) {
518:
519: Context context = (Context) pageContext
520: .getAttribute(contextType);
521: // Remove the context from the pageContext
522: if (context != null) {
523: pageContext.removeAttribute(contextType);
524: }
525:
526: String configNameKey = contextType + "configName";
527: String configName = (String) pageContext
528: .getAttribute(configNameKey);
529:
530: HttpServletRequest request = (HttpServletRequest) pageContext
531: .getRequest();
532:
533: SSOToken session = (SSOToken) pageContext.getAttribute(
534: "ps.session", PageContext.REQUEST_SCOPE);
535: if (session == null) {
536: try {
537: SSOTokenManager tokenManager = SSOTokenManager
538: .getInstance();
539: session = tokenManager.createSSOToken(request);
540: pageContext.setAttribute("ps.session", session,
541: PageContext.REQUEST_SCOPE);
542: } catch (SSOException ssoe) {
543: // Unable to create tokens
544: }
545: }
546:
547: try {
548: Class contextCacheClass = Class
549: .forName(contextCacheClassName);
550: Class[] argClassArray = { Class.forName("java.lang.String") };
551: Method getInstanceMethod = contextCacheClass.getMethod(
552: "getInstance", argClassArray);
553: Object[] objArray = { contextCacheClassName };
554: ContextCache contextCache = (ContextCache) getInstanceMethod
555: .invoke(null, objArray);
556: if (contextCache != null) {
557: context = contextCache.get(session, configName);
558: if (context != null) {
559: // Remove the context from the cache
560: contextCache.remove(context, configName);
561: }
562: }
563: } catch (ClassNotFoundException cnfe) {
564: // Unable to create cache class
565: } catch (NoSuchMethodException nsme) {
566: // Method not in class
567: } catch (IllegalAccessException iae) {
568: // Do not have access rights
569: } catch (InvocationTargetException ite) {
570: // Those damn targets aren't invoking properly
571: }
572:
573: SSOAdapter ssoAdapter = (SSOAdapter) pageContext
574: .getAttribute(contextType + "ssoAdapter");
575: if (ssoAdapter != null) {
576: // Make sure this ssoadapter is not left open
577: ssoAdapter.closeConnection();
578: // Remove the ssoadapter from the pageContext
579: pageContext.removeAttribute(contextType + "ssoAdapter");
580: }
581: }
582:
583: public void loadTimeZone() {
584: // get the user's timezone
585: String tz = getAttributeString("preferredtimezone");
586: if (tz != null) {
587: timezone = TimeZone.getTimeZone(tz);
588: } else {
589: timezone = TimeZone.getDefault();
590: }
591:
592: }
593:
594: public void closeConnection() {
595: }
596:
597: }
|