001: /*
002: * Copyright 2004-2005 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: */
013: package com.sun.portal.providers.portletwindow;
014:
015: import com.sun.portal.container.ChannelMode;
016: import com.sun.portal.container.ChannelURLFactory;
017: import com.sun.portal.container.Container;
018: import com.sun.portal.container.ContentException;
019: import com.sun.portal.container.ErrorCode;
020: import com.sun.portal.container.WindowState;
021: import com.sun.portal.desktop.ServletContextThreadLocalizer;
022: import com.sun.portal.desktop.RequestThreadLocalizer;
023: import com.sun.portal.desktop.context.DesktopAppContext;
024: import com.sun.portal.desktop.context.DesktopAppContextThreadLocalizer;
025: import com.sun.portal.log.common.PortalLogger;
026: import com.sun.portal.providers.ProviderException;
027: import com.sun.portal.providers.context.ProviderContextException;
028: import com.sun.portal.providers.window.WindowErrorCode;
029: import com.sun.portal.providers.window.WindowProvider;
030: import com.sun.portal.providers.window.WindowRequestReader;
031:
032: import javax.servlet.ServletContext;
033: import javax.servlet.RequestDispatcher;
034: import javax.servlet.ServletException;
035: import javax.servlet.http.HttpServletRequest;
036: import javax.servlet.http.HttpServletResponse;
037: import java.util.ArrayList;
038: import java.util.Collections;
039: import java.util.HashMap;
040: import java.util.Iterator;
041: import java.util.List;
042: import java.util.Map;
043: import java.util.Set;
044: import java.util.logging.Logger;
045: import java.util.logging.Level;
046: import java.util.logging.LogRecord;
047: import java.io.IOException;
048: import java.net.URL;
049: import java.util.HashSet;
050: import netscape.ldap.LDAPDN;
051:
052: /**
053: * PortletWindowProvider, is dervied from the abstract base class
054: * WindowProvider.
055: */
056:
057: public class PortletWindowProvider extends WindowProvider {
058: private static final char DELIMETER = '|';
059: private static final String PAE_SERVELET = "/servlet/PortletAppEngineServlet";
060: public static final String JAVAX_PORTLET_ENTITY_ID = "javax.portlet.entityID";
061: public static final String JAVAX_PORTLET_TITLE = "javax.portlet.title";
062: public static final String JAVAX_PORTLET_LOCALE = "javax.portlet.locale";
063: public static final String PORTLET_CONTAINER = "portlet_container";
064: private Container container = null;
065: private WindowRequestReader windowRequestReader = null;
066: private DesktopAppContext desktopAppContext = null;
067: private Integer maxEventGenerations;
068: private static Logger logger = PortalLogger
069: .getLogger(PortletWindowProvider.class);
070:
071: public void init(String n, HttpServletRequest req)
072: throws ProviderException {
073: super .init(n, req);
074: ServletContext sc = ServletContextThreadLocalizer.get();
075: container = (Container) sc.getAttribute(PORTLET_CONTAINER);
076: windowRequestReader = new PortletWindowRequestReader();
077: desktopAppContext = DesktopAppContextThreadLocalizer.get();
078: maxEventGenerations = new Integer(desktopAppContext
079: .getMaxEventGenerations());
080: }
081:
082: public URL processEdit(HttpServletRequest req,
083: HttpServletResponse res) throws ProviderException {
084:
085: // Set the MAX_EVENT_GENERATIONS in the request and not in the session.
086: // This ensures that the attribute is available only for portlets
087: req.setAttribute("MAX_EVENT_GENERATIONS", maxEventGenerations);
088: return super .processEdit(req, res);
089: }
090:
091: /**
092: * Implementation of the abstract method defined in the base class.
093: * Get the list of logical roles that the current user
094: * belongs to. The implementation uses the configured
095: * logical to physical role mapping configured at
096: * deployment time to calculate this.
097: */
098: public List getRoleList(HttpServletRequest request)
099: throws ProviderException {
100: //
101: // set logical roles only if roleMapping is not empty
102: //
103: List rolesList = null;
104: try {
105: Map roleMap = getConfiguredRoleMap(request);
106: if (roleMap != null) {
107: Set roles = getProviderContext().getRoles();
108: if (roles.isEmpty()) {
109: rolesList = Collections.EMPTY_LIST;
110: } else {
111: // Before comparing roles convert the roles obtained from AM
112: // and the roles obtained from DP to lowercase.
113: Map lowerCaseRoleMap = convertMapToLowerCase(roleMap);
114: Set lowerCaseDSAMERoles = convertSetToLowerCase(roles);
115: rolesList = new ArrayList();
116: Iterator itr = lowerCaseDSAMERoles.iterator();
117: while (itr.hasNext()) {
118: String dsameRole = (String) itr.next();
119: if (lowerCaseRoleMap.containsKey(dsameRole)) {
120: String logicalRole = (String) lowerCaseRoleMap
121: .get(dsameRole);
122: rolesList.add(logicalRole);
123: }
124: }
125: }
126: } else {
127: rolesList = Collections.EMPTY_LIST;
128: }
129: } catch (ProviderContextException pce) {
130: throw new ProviderException(
131: "PortletWindowProvider.assembleContainerRequest():"
132: + " couldn't check for exists on roleMap collection",
133: pce);
134: }
135: return rolesList;
136: }
137:
138: /**
139: * Implementation of the abstract method defined in the base class.
140: * Get the user profile information for the current user.
141: * The implementation uses the configured
142: * logical to physical user info mapping configured at
143: * deployment time to calculate this.
144: */
145: public Map getUserInfoMap(HttpServletRequest request)
146: throws ProviderException {
147: //
148: // set userinfo if userinfo map is not empty.
149: //
150: Map userInfo = null;
151: try {
152: Map userInfoMap = getConfiguredUserInfoMap(request);
153: if (userInfoMap != null) {
154: userInfo = new HashMap();
155: Set keys = userInfoMap.keySet();
156: for (Iterator i = keys.iterator(); i.hasNext();) {
157: String dsameAttr = (String) i.next();
158: String portletAttr = (String) userInfoMap
159: .get(dsameAttr);
160: String attrValue = getProviderContext()
161: .getStringAttribute(dsameAttr);
162: if (attrValue != null) {
163: userInfo.put(portletAttr, attrValue);
164: }
165: }
166: } else {
167: userInfo = Collections.EMPTY_MAP;
168: }
169: } catch (ProviderContextException pce) {
170: throw new ProviderException(
171: "PortletWindowProvider.assembleContainerRequest():"
172: + " couldn't check for exists on userInfoMap collection",
173: pce);
174: }
175: return userInfo;
176: }
177:
178: private Set convertSetToLowerCase(Set set) {
179: Set lowerCaseKeys = new HashSet();
180: Iterator itr = set.iterator();
181: while (itr.hasNext()) {
182: String role = (String) itr.next();
183: lowerCaseKeys.add(LDAPDN.normalize(role.toLowerCase()));
184: }
185: return lowerCaseKeys;
186: }
187:
188: private Map convertMapToLowerCase(Map map) {
189: Map lowerCaseMap = new HashMap();
190: Iterator itr = map.entrySet().iterator();
191: Map.Entry mapEntry;
192: String key;
193: while (itr.hasNext()) {
194: mapEntry = (Map.Entry) itr.next();
195: key = (String) mapEntry.getKey();
196: lowerCaseMap.put(LDAPDN.normalize(key.toLowerCase()),
197: mapEntry.getValue());
198: }
199: return lowerCaseMap;
200: }
201:
202: private Map getConfiguredRoleMap(HttpServletRequest req)
203: throws ProviderContextException, ProviderException {
204: return PortletWindowProviderUtils.getRoleMap(req, getName(),
205: getProviderContext());
206: }
207:
208: private Map getConfiguredUserInfoMap(HttpServletRequest req)
209: throws ProviderContextException, ProviderException {
210: return PortletWindowProviderUtils.getUserInfoMap(req,
211: getName(), getProviderContext());
212: }
213:
214: /**
215: * Implementation of the abstract method defined in the base class.
216: * Gets the container implementation configured to be used
217: */
218: public Container getContainer(HttpServletRequest req) {
219: return container;
220: }
221:
222: /**
223: * Implementation of the abstract method defined in the base class.
224: * EntityID is represented as
225: * <web application name>/<portlet name>/<channel name>
226: * <web application name>/<portlet name> is stored in the
227: * display profile during
228: * deployment time.
229: */
230: public String getEntityID(HttpServletRequest request)
231: throws ProviderException {
232: return PortletWindowProviderUtils.getEntityID(request,
233: getName(), getProviderContext());
234: }
235:
236: /**
237: * Implementation of the abstract method defined in the base class.
238: */
239: public ChannelURLFactory getChannelURLFactory(
240: String desktopURLPrefix, HttpServletRequest request)
241: throws ProviderException {
242: return new PortletWindowChannelURLFactory(desktopURLPrefix);
243: }
244:
245: /**
246: * Implementation of the abstract method defined in the base class.
247: */
248:
249: public WindowRequestReader getWindowRequestReader()
250: throws ProviderException {
251: return windowRequestReader;
252: }
253:
254: /**
255: * Implementation of the abstract method defined in the base class.
256: */
257: public boolean isMarkupSupported(String contentType, String locale,
258: ChannelMode mode, WindowState state)
259: throws ProviderException {
260: boolean supported = false;
261: if (ChannelMode.VIEW.equals(mode)) {
262: List supportedContentTypes = getListProperty("supportedContentTypes");
263: if (supportedContentTypes.contains(contentType)
264: || supportedContentTypes.contains("text/*")
265: || supportedContentTypes.contains("*/*")) {
266: supported = true;
267: }
268: } else if (ChannelMode.HELP.equals(mode)) {
269:
270: //
271: // According to Rama, this information should have stored as
272: // map of contentType to boolean, just like
273: // isEditableByMimeType.
274: // Right now, it is storing a default value "helpURL"
275: // as a value, which doesn't make sense.
276: //
277: String hu = null;
278: Map hasHelpMap = getMapProperty("hasHelpByMimeType");
279: if (hasHelpMap.containsKey(contentType)) {
280: hu = (String) hasHelpMap.get(contentType);
281: }
282: if ((hu != null) && (hu.length() > 0)) {
283: supported = true;
284: }
285: } else if (ChannelMode.EDIT.equals(mode)) {
286: Map isEditableMap = getMapProperty("isEditableByMimeType");
287: if (isEditableMap.containsKey(contentType)) {
288: supported = ((Boolean) isEditableMap.get(contentType))
289: .booleanValue();
290: }
291: }
292: return supported;
293: }
294:
295: public String getDefaultTitle() throws ProviderException {
296: //First obtain title from DP
297: String title = PortletWindowProviderUtils.getTitle(
298: getProviderContext(), getName(), true);
299: //If DP does not contain the title for the specified locale
300: //try to obtain the title from resource bundle.
301: if (title == null) {
302: //Obtain the title from resource bundle
303: title = getTitleFromRB();
304: //if resource bundle does not contain the title, then
305: //obtain the default title from DP.
306: if (title == null || title.length() == 0
307: || JAVAX_PORTLET_TITLE.equals(title)) {
308: title = PortletWindowProviderUtils.getTitle(
309: getProviderContext(), getName(), false);
310: }
311: }
312: return title;
313: }
314:
315: protected String getTitleFromRB() throws ProviderException {
316: String title = null;
317: HttpServletRequest req = RequestThreadLocalizer.getRequest();
318: HttpServletResponse res = RequestThreadLocalizer.getResponse();
319: String entityID = PortletWindowProviderUtils.getEntityID(req,
320: getName(), getProviderContext());
321: String appName = "/"
322: + entityID.substring(0, entityID.indexOf(DELIMETER));
323: ServletContext sctx = ServletContextThreadLocalizer.get()
324: .getContext(appName);
325: RequestDispatcher rd = sctx.getRequestDispatcher(PAE_SERVELET);
326: PAERequestWrapper reqRequestWrapper = new PAERequestWrapper(req);
327: PAEResponseWrapper responseWrapper = new PAEResponseWrapper(res);
328: try {
329: reqRequestWrapper.setAttribute(JAVAX_PORTLET_TITLE,
330: JAVAX_PORTLET_TITLE);
331: reqRequestWrapper.setAttribute(JAVAX_PORTLET_ENTITY_ID,
332: entityID);
333: reqRequestWrapper.setAttribute(JAVAX_PORTLET_LOCALE,
334: getProviderContext().getLocale());
335: rd.include(reqRequestWrapper, responseWrapper);
336: title = (String) reqRequestWrapper
337: .getAttribute(JAVAX_PORTLET_TITLE);
338: if (title != null && title.length() > 0)
339: return title;
340: } catch (ServletException se) {
341: if (logger.isLoggable(Level.INFO)) {
342: LogRecord record = new LogRecord(Level.INFO,
343: "PSDT_CSPPPW0001");
344: record.setLoggerName(logger.getName());
345: record.setParameters(new Object[] { getName() });
346: record.setThrown(se);
347: logger.log(record);
348: }
349: } catch (IOException ioe) {
350: if (logger.isLoggable(Level.INFO)) {
351: LogRecord record = new LogRecord(Level.INFO,
352: "PSDT_CSPPPW0002");
353: record.setLoggerName(logger.getName());
354: record.setParameters(new Object[] { getName() });
355: record.setThrown(ioe);
356: logger.log(record);
357: }
358: }
359: return title;
360: }
361:
362: protected ErrorCode getErrorCode(ContentException ex) {
363: return WindowErrorCode.CONTENT_EXCEPTION;
364: }
365: }
|