001: /**
002: * Copyright 2003 Sun Microsystems, Inc. All
003: * rights reserved. Use of this product is subject
004: * to license terms. Federal Acquisitions:
005: * Commercial Software -- Government Users
006: * Subject to Standard License Terms and
007: * Conditions.
008: *
009: * Sun, Sun Microsystems, the Sun logo, and Sun ONE
010: * are trademarks or registered trademarks of Sun Microsystems,
011: * Inc. in the United States and other countries.
012: */package com.sun.portal.wsrp.consumer.wsrpwindow;
013:
014: import java.net.URL;
015: import java.net.MalformedURLException;
016: import java.rmi.RemoteException;
017:
018: import java.util.List;
019: import java.util.ArrayList;
020: import java.util.Arrays;
021: import java.util.Enumeration;
022: import java.util.Map;
023: import java.util.Set;
024: import java.util.HashMap;
025: import java.util.Hashtable;
026: import java.util.Iterator;
027: import java.util.Collections;
028: import java.util.StringTokenizer;
029: import java.util.MissingResourceException;
030: import java.util.logging.Level;
031: import java.util.logging.Logger;
032:
033: import javax.servlet.http.HttpServletRequest;
034: import javax.servlet.http.HttpServletResponse;
035: import com.sun.portal.container.Container;
036: import com.sun.portal.container.ContainerException;
037: import com.sun.portal.container.ContentException;
038: import com.sun.portal.container.ChannelURLFactory;
039: import com.sun.portal.container.ChannelMode;
040: import com.sun.portal.container.WindowState;
041: import com.sun.portal.container.ErrorCode;
042:
043: import com.sun.portal.desktop.DesktopRequestThreadLocalizer;
044: import com.sun.portal.desktop.context.DesktopAppContext;
045:
046: import com.sun.portal.desktop.DesktopRequest;
047:
048: import com.sun.portal.desktop.util.Integers;
049:
050: import com.sun.portal.providers.ProviderException;
051: import com.sun.portal.providers.context.ProviderContextException;
052: import com.sun.portal.providers.context.ProviderContext;
053:
054: import com.sun.portal.wsrp.common.stubs.PortletDescription;
055: import com.sun.portal.wsrp.common.stubs.LocalizedString;
056: import com.sun.portal.wsrp.common.stubs.ResourceList;
057: import com.sun.portal.wsrp.common.stubs.MarkupType;
058:
059: import com.sun.portal.wsrp.common.WSRPToContainerMap;
060: import com.sun.portal.wsrp.consumer.common.WSRPProviderConstants;
061: import com.sun.portal.wsrp.consumer.common.WSRPConsumerUtil;
062: import com.sun.portal.wsrp.consumer.common.WSRPConsumerException;
063: import com.sun.portal.wsrp.consumer.common.WSRPConsumerRewriterException;
064: import com.sun.portal.wsrp.consumer.common.WSRPConsumerErrorCode;
065: import com.sun.portal.wsrp.consumer.producermanager.ProducerEntity;
066: import com.sun.portal.wsrp.consumer.producermanager.ProducerEntityManager;
067: import com.sun.portal.wsrp.consumer.producermanager.ProducerEntityManagerFactory;
068: import com.sun.portal.wsrp.consumer.markup.MarkupManagerFactory;
069: import com.sun.portal.wsrp.consumer.markup.MarkupContentException;
070: import com.sun.portal.providers.window.WindowProvider;
071: import com.sun.portal.providers.window.WindowRequestReader;
072: import com.sun.portal.providers.window.WindowErrorCode;
073: import com.sun.portal.log.common.PortalLogger;
074:
075: /**
076: * WSRP Provider, is dervied from the abstract base class
077: * WindowProvider.
078: *
079: */
080: public class WSRPWindowProvider extends WindowProvider {
081:
082: private static Container _container = (Container) MarkupManagerFactory
083: .getInstance();
084:
085: private static WindowRequestReader _windowRequestReader = new WSRPWindowRequestReader();
086:
087: private static ProducerEntityManagerFactory _pemFactory = ProducerEntityManagerFactory
088: .getInstance();
089:
090: private static Logger logger = PortalLogger
091: .getLogger(WSRPWindowProvider.class);
092:
093: public void init(String n, HttpServletRequest req)
094: throws ProviderException {
095: super .init(n, req);
096:
097: }
098:
099: /**
100: * Check the method description in the base class.
101: *
102: * @exception com.sun.portal.providers.ProviderException
103: */
104: public String getDefaultTitle() throws ProviderException {
105:
106: HttpServletRequest req = DesktopRequestThreadLocalizer
107: .getRequest();
108:
109: ProducerEntity producerEntity = getProducerEntity(req);
110:
111: String portletHandle = getStringProperty(WSRPProviderConstants.PORTLET_ID);
112:
113: PortletDescription portletDesc = producerEntity
114: .getPortletDescription(portletHandle);
115:
116: LocalizedString localizedTitle = portletDesc.getTitle();
117:
118: String title = null;
119: String lang = null;
120:
121: if (localizedTitle != null) {
122: String xmlLocale = WSRPConsumerUtil
123: .getXMLLocale(getProviderContext()
124: .getLocaleString());
125: title = localizedTitle.getValue();
126: //
127: // look up resource list only if the user's locale does not
128: // match the default locale of the title
129: //
130: lang = localizedTitle.getLang();
131:
132: if (lang != null && (!(lang.equals(xmlLocale)))) {
133: ResourceList resourceList = producerEntity
134: .getServiceDescription().getResourceList();
135: String resourceName = localizedTitle.getResourceName();
136: String titleResource = WSRPConsumerUtil.getResource(
137: resourceList, resourceName, xmlLocale);
138: if (titleResource != null) {
139: title = titleResource;
140: }
141: }
142: }
143:
144: //
145: // if no title is found, return empty string w/ a warning
146: //
147: if (title == null) {
148: title = "";
149: if (logger.isLoggable(Level.WARNING)) {
150: String[] param = { producerEntity.toString(),
151: portletHandle };
152: logger.log(Level.WARNING, "PSWS_CSPWCW0002", param);
153: }
154: }
155:
156: return title;
157: }
158:
159: /**
160: * Check the method description in the base class.
161: *
162: * @exception com.sun.portal.providers.ProviderException
163: */
164: public String getDescription() throws ProviderException {
165:
166: HttpServletRequest req = DesktopRequestThreadLocalizer
167: .getRequest();
168:
169: ProducerEntity producerEntity = getProducerEntity(req);
170:
171: String portletHandle = getStringProperty(WSRPProviderConstants.PORTLET_ID);
172:
173: PortletDescription portletDesc = producerEntity
174: .getPortletDescription(portletHandle);
175:
176: LocalizedString localizedDescription = portletDesc
177: .getDescription();
178: if (localizedDescription == null) {
179: return null;
180: }
181: String xmlLocale = WSRPConsumerUtil
182: .getXMLLocale(getProviderContext().getLocaleString());
183: String description = localizedDescription.getValue();
184: //
185: // look up resource list only if the user's locale does not
186: // match the default locale of the description
187: //
188: if (!(localizedDescription.getLang().equals(xmlLocale))) {
189: ResourceList resourceList = producerEntity
190: .getServiceDescription().getResourceList();
191: String resourceName = localizedDescription
192: .getResourceName();
193: String descriptionResource = WSRPConsumerUtil.getResource(
194: resourceList, resourceName, xmlLocale);
195: if (descriptionResource != null) {
196: description = descriptionResource;
197: }
198: }
199:
200: return description;
201: }
202:
203: //
204: // Get the list of logical roles that the current user
205: // belongs to. The implementation uses the configured
206: // logical to physical role mapping configured at
207: // deployment time to calculate this.
208: //
209:
210: public List getRoleList(HttpServletRequest request)
211: throws ProviderException {
212: //
213: // set logical roles only if roleMapping is not empty
214: //
215:
216: List rolesList = null;
217: try {
218: Map roleMap = getConfiguredRoleMap(request);
219: if (roleMap != null) {
220: Set roles = getProviderContext().getRoles();
221: if (roles == null || roles.isEmpty()) {
222: rolesList = Collections.EMPTY_LIST;
223: } else {
224: rolesList = new ArrayList();
225: for (Iterator i = roleMap.keySet().iterator(); i
226: .hasNext();) {
227: String logicalRole = (String) i.next();
228: List physicalRoles = (List) roleMap
229: .get(logicalRole);
230: for (Iterator j = physicalRoles.iterator(); j
231: .hasNext();) {
232: String physicalRole = (String) j.next();
233: if (roles.contains(physicalRole)) {
234: rolesList.add(logicalRole);
235: break;
236: }
237: }
238: }
239: }
240: } else {
241: rolesList = Collections.EMPTY_LIST;
242: }
243: } catch (ProviderContextException pce) {
244: throw new ProviderException(
245: "WSRPWindowProvider.getRoleList():", pce);
246: }
247:
248: //getProviderContext().debugError("WWP.getRoleList(): rolesList=" + rolesList);
249: return rolesList;
250: }
251:
252: //
253: // Get the user profile information for the current user.
254: // The implementation uses the configured
255: // logical to physical user info mapping configured at
256: // deployment time to calculate this.
257: //
258: public Map getUserInfoMap(HttpServletRequest request)
259: throws ProviderException {
260:
261: //
262: // set userinfo if userinfo map is not empty.
263: //
264:
265: Map userInfo = null;
266: try {
267: Map userInfoMap = getConfiguredUserInfoMap(request);
268: if (userInfoMap != null) {
269: userInfo = new HashMap();
270: Set keys = userInfoMap.keySet();
271: for (Iterator i = keys.iterator(); i.hasNext();) {
272: String portletAttr = (String) i.next();
273: String dsameAttr = (String) userInfoMap
274: .get(portletAttr);
275: String attrValue = getProviderContext()
276: .getStringAttribute(dsameAttr);
277: if (attrValue != null) {
278: userInfo.put(portletAttr, attrValue);
279: }
280: }
281: } else {
282: userInfo = Collections.EMPTY_MAP;
283: }
284: } catch (ProviderContextException pce) {
285: throw new ProviderException(
286: "WSRPWindowProvider.getUserInfoMap():", pce);
287: }
288:
289: //getProviderContext().debugError("WWP.getUserInfoMap(): userInfo=" + userInfo);
290: return userInfo;
291: }
292:
293: /**
294: * Check the method description in the base class.
295: *
296: * @param req
297: * @exception com.sun.portal.providers.context.ProviderContextException
298: * @exception com.sun.portal.providers.ProviderException
299: */
300: private Map getConfiguredRoleMap(HttpServletRequest req)
301: throws ProviderContextException, ProviderException {
302:
303: //
304: // get user category mapping from the producer entity
305: //
306: ProducerEntity producerEntity = getProducerEntity(req);
307: Map ucMap = producerEntity.getUserCategoryMapping();
308:
309: //
310: // filter only the ones used by the portlet
311: //
312: Map roleMap = null;
313: if (ucMap != null && ucMap.size() > 0) {
314: String portletHandle = getStringProperty(WSRPProviderConstants.PORTLET_ID);
315: PortletDescription portletDesc = producerEntity
316: .getPortletDescription(portletHandle);
317: List userCategories = Arrays.asList(portletDesc
318: .getUserCategories());
319:
320: roleMap = new HashMap();
321: for (Iterator i = ucMap.keySet().iterator(); i.hasNext();) {
322: String userCategory = (String) i.next();
323: if (userCategories.contains(userCategory)) {
324: roleMap.put(userCategory, ucMap.get(userCategory));
325: }
326: }
327: }
328:
329: //getProviderContext().debugError("WWP.getConfiguredRoleMap(): returning role map=" + roleMap);
330:
331: return roleMap;
332: }
333:
334: /**
335: * Check the method description in the base class.
336: *
337: * @param req
338: * @exception com.sun.portal.providers.context.ProviderContextException
339: * @exception com.sun.portal.providers.ProviderException
340: */
341: private Map getConfiguredUserInfoMap(HttpServletRequest req)
342: throws ProviderContextException, ProviderException {
343:
344: //
345: // get user profile items from the portlet description
346: //
347: ProducerEntity producerEntity = getProducerEntity(req);
348:
349: String consumerId = getStringProperty(WSRPProviderConstants.CONSUMER_ID);
350:
351: String portletHandle = getStringProperty(WSRPProviderConstants.PORTLET_ID);
352:
353: PortletDescription portletDesc = producerEntity
354: .getPortletDescription(portletHandle);
355:
356: String[] items = portletDesc.getUserProfileItems();
357:
358: //
359: // TBD: to be replaced by SPI in later releases
360: // for now, just use the standard user profile mapping
361: //
362: Map stdMap = null;
363: try {
364: ProducerEntityManager pem = _pemFactory
365: .getProducerEntityManager(consumerId, req);
366:
367: stdMap = pem.getStandardUserProfileMapping();
368:
369: } catch (WSRPConsumerException ex) {
370: throw new ProviderException(ex.getMessage(), ex);
371: }
372:
373: Map uiMap = new HashMap();
374: if (items != null && stdMap != null) {
375: for (int i = 0; i < items.length; i++) {
376: if (stdMap.containsKey(items[i])) {
377: uiMap.put(items[i], stdMap.get(items[i]));
378: }
379: }
380: }
381:
382: return uiMap;
383: }
384:
385: /**
386: * Implementation of the abstract method
387: *
388: * @param req
389: */
390: public Container getContainer(HttpServletRequest req) {
391: return _container;
392:
393: }
394:
395: /**
396: * Implementation of the abstract method
397: *
398: * @param req
399: * @exception com.sun.portal.providers.ProviderException
400: */
401: public String getEntityID(HttpServletRequest req)
402: throws ProviderException {
403: return getName();
404: }
405:
406: /**
407: * Implementation of the abstract method
408: */
409: public WindowRequestReader getWindowRequestReader()
410: throws ProviderException {
411: return _windowRequestReader;
412: }
413:
414: /**
415: * Implementation of the abstract method
416: */
417: public ChannelURLFactory getChannelURLFactory(
418: String desktopURLPrefix, HttpServletRequest request)
419: throws ProviderException {
420:
421: String securityErrorURL = getErrorCodeURL(
422: WSRPConsumerErrorCode.RUNTIME_NOT_IN_SECURE_MODE,
423: request).toString();
424:
425: return new WSRPWindowChannelURLFactory(desktopURLPrefix,
426: securityErrorURL);
427: }
428:
429: private ProducerEntity getProducerEntity(HttpServletRequest req)
430: throws ProviderException {
431:
432: String consumerId = getStringProperty(WSRPProviderConstants.CONSUMER_ID);
433:
434: String producerEntityId = getStringProperty(WSRPProviderConstants.PRODUCER_ENTITY_ID);
435:
436: String portletID = getStringProperty(WSRPProviderConstants.PORTLET_ID);
437: try {
438: ProducerEntityManager pem = _pemFactory
439: .getProducerEntityManager(consumerId, req);
440: //
441: // check accessibility on PEM
442: //
443: if (!pem.isActivated()) {
444: throw new ProviderException(
445: "WSRP Consumer is currently disabled.");
446: //
447: // TBD: would like to throw window exception here
448: //
449: //throw new WindowException(WSRPConsumerErrorCode.CONSUMER_DISABLED, "WSRP Consumer is currently disabled.");
450: }
451:
452: ProducerEntity producerEntity = pem
453: .getProducerEntity(producerEntityId);
454:
455: if (producerEntity == null) {
456: throw new ProviderException(
457: "Couldn't find the producer entity for the portlet.");
458: }
459: if (producerEntity.getPortletDescription(portletID) == null) {
460: throw new ProviderException(
461: "Couldn't find the portletDescription for the portlet.");
462: }
463:
464: return producerEntity;
465:
466: } catch (WSRPConsumerException ex) {
467: throw new ProviderException(ex.getMessage(), ex);
468: }
469:
470: }
471:
472: /**
473: * Implementation of an abstract method
474: * Returns true if the portlet supports the markup for
475: * given contentType, mode, state and locale.
476: */
477: public boolean isMarkupSupported(String contentType, String locale,
478: ChannelMode mode, WindowState windowState)
479: throws ProviderException {
480:
481: //
482: // Get handle to portlet description
483: //
484: HttpServletRequest req = DesktopRequestThreadLocalizer
485: .getRequest();
486:
487: ProducerEntity producerEntity = getProducerEntity(req);
488:
489: String portletHandle = getStringProperty(WSRPProviderConstants.PORTLET_ID);
490:
491: PortletDescription portletDesc = producerEntity
492: .getPortletDescription(portletHandle);
493:
494: //
495: // Look in the markupType array for an entry that match
496: // the criteria for contentType, mode, windowstate and locale
497: //
498:
499: MarkupType[] markupTypes = portletDesc.getMarkupTypes();
500: if (markupTypes == null || markupTypes.length == 0) {
501: return false;
502: }
503:
504: String wsrpMode = WSRPToContainerMap.mapChannelModeToWSRP(mode);
505: String wsrpWindowState = WSRPToContainerMap
506: .mapWindowStateToWSRP(windowState);
507:
508: if (logger.isLoggable(Level.FINEST)) {
509: String[] param = { "MarkupTypes ID", portletHandle };
510: param[0] = "contentType";
511: param[1] = contentType;
512: logger.log(Level.FINEST, "PSWS_CSPWCW0001", param);
513: param[0] = "mode";
514: param[1] = wsrpMode;
515: logger.log(Level.FINEST, "PSWS_CSPWCW0001", param);
516: param[0] = "wsrpWindowState";
517: param[1] = wsrpWindowState;
518: logger.log(Level.FINEST, "PSWS_CSPWCW0001", param);
519: param[0] = "locale";
520: param[1] = locale;
521: logger.log(Level.FINEST, "PSWS_CSPWCW0001", param);
522:
523: }
524:
525: for (int i = 0; i < markupTypes.length; i++) {
526: if (markupTypes[i].getMimeType().equals(contentType)
527: || markupTypes[i].getMimeType().equals("text/*")
528: || markupTypes[i].getMimeType().equals("*/*")) {
529:
530: /* if (getProviderContext().isDebugMessageEnabled()) {
531: getProviderContext().debugMessage(
532: "mode match for:" + wsrpMode + ":" +
533: exists( wsrpMode, markupTypes[i].getModes(),true));
534: getProviderContext().debugMessage(
535: "window state match for:" + wsrpWindowState + ":" +
536: exists( wsrpWindowState, markupTypes[i].getWindowStates(),
537: true));
538: getProviderContext().debugMessage(
539: "locale match for:" + locale + ":" +
540: exists(locale, markupTypes[i].getLocales(), false));
541: }
542:
543: */
544: if (exists(wsrpMode, markupTypes[i].getModes(), true)
545: && exists(wsrpWindowState, markupTypes[i]
546: .getWindowStates(), true)) {
547:
548: //
549: // locale list is optional and substring match is ok too
550: //
551: if (markupTypes[i].getLocales() == null
552: || markupTypes[i].getLocales().length == 0) {
553: return true;
554: } else {
555: if (exists(locale, markupTypes[i].getLocales(),
556: false)) {
557: return true;
558: }
559: }
560: }
561: }
562: }
563: return false;
564: }
565:
566: /**
567: * Check if a string exists in the string array.
568: * If exactMatch is false, match for substring or caseinsensitive
569: */
570:
571: private boolean exists(String str, String[] values,
572: boolean exactMatch) {
573: if (values == null || str == null) {
574: return false;
575: }
576: for (int i = 0; i < values.length; i++) {
577: if (exactMatch) {
578: if (str.equals(values[i])) {
579: return true;
580: }
581: } else {
582: if (str.toLowerCase().indexOf(values[i].toLowerCase()) != -1) {
583: return true;
584: }
585: }
586: }
587: return false;
588: }
589:
590: /**
591: * Return more fine grained error code if available for ContentException
592: *
593: * thrown by WSRP framework.
594: */
595:
596: protected ErrorCode getErrorCode(ContentException ex) {
597:
598: if (ex instanceof MarkupContentException) {
599: return ((MarkupContentException) ex).getErrorCode();
600: } else {
601: return WindowErrorCode.CONTENT_EXCEPTION;
602: }
603:
604: }
605:
606: //
607: // Overwritten method to get the error message out of
608: // the resource bundle
609: //
610: protected StringBuffer getErrorMessageContent(ErrorCode errorCode)
611: throws ProviderException {
612:
613: try {
614: return new StringBuffer(getResourceBundle(
615: "WSRPConsumerErrorCode").getString(
616: errorCode.toString()));
617:
618: } catch (MissingResourceException ex) {
619: return super.getErrorMessageContent(errorCode);
620: }
621: }
622: }
|