001: /*
002: * Copyright 2002 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.portlet.impl;
014:
015: import java.net.URL;
016: import java.net.MalformedURLException;
017:
018: import java.io.IOException;
019:
020: import javax.servlet.http.HttpServletRequest;
021: import javax.servlet.http.HttpServletResponse;
022:
023: import java.util.Map;
024: import java.util.HashMap;
025: import java.util.Collections;
026: import java.util.Iterator;
027:
028: import javax.portlet.PortletMode;
029: import javax.portlet.ActionRequest;
030: import javax.portlet.ActionResponse;
031: import javax.portlet.WindowState;
032: import javax.portlet.WindowStateException;
033: import javax.portlet.PortletModeException;
034:
035: import java.util.logging.Logger;
036:
037: import com.sun.portal.portletcontainercommon.PortletContainerActionRequest;
038: import com.sun.portal.portletcontainercommon.PortletContainerActionResponse;
039:
040: import com.sun.portal.portletappengine.PortletAppEngineUtils;
041:
042: import com.sun.portal.portletcontainercommon.descriptor.PortletDescriptor;
043:
044: /**
045: * This class provides implementation of the ActionResponse interface.
046: */
047: public class ActionResponseImpl extends PortletResponseImpl implements
048: ActionResponse {
049:
050: private PortletContainerActionRequest _pContReq;
051: private PortletContainerActionResponse _pContRes;
052: private ActionRequest _aReq;
053: private boolean _sendRedirectIsCalled = false;
054: private boolean _setMethodIsCalled = false;
055: private static Logger _logger;
056:
057: /**
058: * Initialize the global variables.
059: * <P>
060: * @param aReq The <code>ActionRequest</code>
061: * @param pContReq The <code>PortletContainerRequest</code>
062: * @param pContRes The <code>PortletContainerResponse</code>
063: * @param pDescriptor The <code>PortletDescriptor</code> for the
064: * portlet
065: */
066: void init(HttpServletRequest req, HttpServletResponse res,
067: ActionRequest aReq, PortletContainerActionRequest pContReq,
068: PortletContainerActionResponse pContRes, Logger logger) {
069: super .init(req, res, aReq, pContReq, pContRes, logger);
070: _aReq = aReq;
071: _pContReq = pContReq;
072: _pContRes = pContRes;
073: _logger = logger;
074: _sendRedirectIsCalled = false;
075: _setMethodIsCalled = false;
076: }
077:
078: /**
079: * Clears the global variables.
080: */
081: void clear() {
082: super .clear();
083: _aReq = null;
084: _pContReq = null;
085: _pContRes = null;
086: _logger = null;
087: _sendRedirectIsCalled = false;
088: _setMethodIsCalled = false;
089: }
090:
091: /**
092: * Set the portlet window state to the given portlet window state.
093: * <p>
094: * Possible values are the standard window states and any custom
095: * window states supported by the portal and the portlet.
096: * Standard window states are:
097: * <ul>
098: * <li>MINIMIZED
099: * <li>NORMAL
100: * <li>MAXIMIZED
101: * </ul>
102: *
103: * @param windowState the new portlet window state
104: *
105: * @exception WindowStateException
106: * if the portlet cannot switch to the specified
107: * windowstate.
108: * To avoid this exception the portlet can check the allowed
109: * window states with <code>Request.isWindowStateAllowed()</code>.
110: * @exception java.lang.IllegalStateException
111: * if the method is invoked after <code>sendRedirect</code> has been called.
112: *
113: * @see WindowState
114: */
115: public void setWindowState(WindowState windowState)
116: throws WindowStateException {
117:
118: if (!_aReq.isWindowStateAllowed(windowState)) {
119: throw new WindowStateException(
120: "Invalid setting window state", windowState);
121: }
122:
123: if (_sendRedirectIsCalled) {
124: throw new IllegalStateException(
125: "Illegal to set window state after sendRedirect is called.");
126: }
127:
128: _setMethodIsCalled = true;
129:
130: _pContRes.setNewWindowState(PortletAppEngineUtils
131: .getWindowState(windowState));
132: }
133:
134: /**
135: * Sets the portlet mode of a portlet to the given portlet mode.
136: * <p>
137: * Possible values are the standard portlet modes and any custom
138: * portlet modes supported by the portal and the portlet. Portlets
139: * must declare in the deployment descriptor the portlet modes they
140: * support for each markup type.
141: * Standard portlet modes are:
142: * <ul>
143: * <li>EDIT
144: * <li>HELP
145: * <li>VIEW
146: * </ul>
147: * <p>
148: * Note: The portlet may still be called in a different window
149: * state in the next render call, depending on the portlet container / portal.
150: *
151: * @param portletMode the new portlet mode
152: *
153: * @exception PortletModeException
154: * if the portlet cannot switch to this mode,
155: * because the portlet does not support it for this markup,
156: * or the current user is not allowed to switch
157: * to this portal mode
158: * To avoid this exception the portlet can check the allowed
159: * portlet modes with <code>Request.isPortletModeAllowed()</code>.
160: * @exception java.lang.IllegalStateException
161: * if the method is invoked after <code>sendRedirect</code> has been called.
162: */
163: public void setPortletMode(PortletMode portletMode)
164: throws PortletModeException {
165: if (!_aReq.isPortletModeAllowed(portletMode)) {
166: throw new PortletModeException(
167: "Attempt to set an invalid portlet mode: ",
168: portletMode);
169: }
170:
171: if (_sendRedirectIsCalled) {
172: throw new IllegalStateException(
173: "Illegal to set portlet mode after sendRedirect is called.");
174: }
175:
176: _setMethodIsCalled = true;
177: _pContRes.setNewChannelMode(PortletAppEngineUtils
178: .getChannelMode(portletMode));
179:
180: }
181:
182: /**
183: * Instructs the portlet container to send a redirect response
184: * to the client using the specified redirect location URL.
185: * <p>
186: * This method only accepts an absolute URL (e.g.
187: * <code>http://my.co/myportal/mywebap/myfolder/myresource.gif</code>)
188: * or a full path URI (e.g. <code>/myportal/mywebap/myfolder/myresource.gif</code>).
189: * If required,
190: * the portlet container may encode the given URL before the
191: * redirection is issued to the client.
192: * <p>
193: * The sendRedirect method can not be invoked after any of the
194: * following methods of the ActionResponse interface has been called:
195: * <ul>
196: * <li>setPortletMode
197: * <li>setWindowState
198: * <li>setRenderParameter
199: * <li>setRenderParameters
200: * </ul>
201: *
202: *
203: * @param location the redirect location URL
204: *
205: * @exception IOException
206: * If an input or output exception occurs.
207: * @exception java.lang.IllegalArgumentException
208: * If a relative path URL is given
209: * @exception java.lang.IllegalStateException If the method
210: * is invoked after any of above mentioned methods of
211: * the ActionResponse interface has been called.
212: */
213: public void sendRedirect(String location) throws IOException {
214:
215: if (_setMethodIsCalled) {
216: throw new IllegalStateException(
217: "Illegal to sendRedirect after setting window state, portlet mode, or render parameters.");
218: }
219:
220: URL retURL = null;
221:
222: //Prepend servlet schema, host, and port
223: if (location.indexOf("://") == -1) {
224: StringBuffer b = new StringBuffer(128);
225:
226: b.append(_pContReq.getHttpServletRequest().getScheme());
227: b.append("://");
228: b.append(_pContReq.getHttpServletRequest().getServerName());
229: b.append(":");
230: b.append(_pContReq.getHttpServletRequest().getServerPort());
231: b.append(location);
232: location = b.toString();
233: }
234:
235: try {
236: retURL = new URL(location);
237: } catch (MalformedURLException mfue) {
238: throw new IllegalArgumentException(mfue.getMessage());
239: }
240:
241: _sendRedirectIsCalled = true;
242: _pContRes.setRedirectURL(retURL);
243: }
244:
245: /**
246: * Sets a parameter map for the render request.
247: * <p>
248: * All previous set render parameters are cleared.
249: * <p>
250: * These parameters will be accessible in all
251: * sub-sequent render calls via the
252: * <code>PortletRequest.getParameter</code> call until
253: * a new request is targeted to the portlet.
254: * <p>
255: * The given parameters do not need to be encoded
256: * prior to calling this method.
257: *
258: * @param parameters Map containing parameter names for
259: * the render phase as
260: * keys and parameter values as map
261: * values. The keys in the parameter
262: * map must be of type String. The values
263: * in the parameter map must be of type
264: * String array (<code>String[]</code>).
265: *
266: * @exception java.lang.IllegalArgumentException
267: * if parameters is <code>null</code>, if
268: * any of the key/values in the Map are <code>null</code>,
269: * if any of the keys is not a String, or if any of
270: * the values is not a String array.
271: * @exception java.lang.IllegalStateException
272: * if the method is invoked after <code>sendRedirect</code> has been called.
273: */
274:
275: public void setRenderParameters(java.util.Map parameters) {
276: if (_sendRedirectIsCalled) {
277: throw new IllegalStateException(
278: "Illegal to set parameters after sendRedirect is called.");
279: }
280:
281: if (parameters == null) {
282: throw new IllegalArgumentException(
283: "The passed in map should not be null");
284:
285: }
286: //Check if all the params are Strings and corresponding values are String[]
287: Iterator keys = parameters.keySet().iterator();
288: while (keys.hasNext()) {
289: Object key = keys.next();
290: if (!(key instanceof String))
291: throw new IllegalArgumentException(
292: "The keys in the map must be of type String");
293: Object value = parameters.get(key);
294: if (!(value instanceof String[]))
295: throw new IllegalArgumentException(
296: "The values in the map must be of type String[]");
297: }
298: _setMethodIsCalled = true;
299: _pContRes.setRenderParameters(parameters);
300: }
301:
302: /**
303: * Sets a String parameter for the render request.
304: * <p>
305: * These parameters will be accessible in all
306: * sub-sequent render calls via the
307: * <code>PortletRequest.getParameter</code> call until
308: * a request is targeted to the portlet.
309: * <p>
310: * This method replaces all parameters with the given key.
311: * <p>
312: * The given parameter do not need to be encoded
313: * prior to calling this method.
314: *
315: * @param key key of the render parameter
316: * @param value value of the render parameter
317: * @exception java.lang.IllegalArgumentException
318: * if key or value is <code>null</code>.
319: * @exception java.lang.IllegalStateException
320: * if the method is invoked after <code>sendRedirect</code> has been called.
321: */
322:
323: public void setRenderParameter(String key, String value) {
324: if (_sendRedirectIsCalled) {
325: throw new IllegalStateException(
326: "Illegal to set parameter after sendRedirect is called.");
327: }
328:
329: if (key == null || value == null) {
330: throw new IllegalArgumentException(
331: "Key or value argument should not be null.");
332: }
333:
334: _setMethodIsCalled = true;
335: Map renderMap = _pContRes.getRenderParameters();
336: String[] values = new String[1];
337: values[0] = value;
338: if (renderMap == null || renderMap == Collections.EMPTY_MAP) {
339: renderMap = new HashMap();
340: renderMap.put(key, values);
341: _pContRes.setRenderParameters(renderMap);
342: } else {
343: renderMap.put(key, values);
344: }
345: }
346:
347: /**
348: * Sets a String array parameter for the render request.
349: * <p>
350: * These parameters will be accessible in all
351: * sub-sequent render calls via the
352: * <code>PortletRequest.getParameter</code> call until
353: * a request is targeted to the portlet.
354: * <p>
355: * This method replaces all parameters with the given key.
356: * <p>
357: * The given parameter do not need to be encoded
358: * prior to calling this method.
359: *
360: * @param key key of the render parameter
361: * @param values values of the render parameter
362: * @exception java.lang.IllegalArgumentException
363: * if key or value is <code>null</code>.
364: * @exception java.lang.IllegalStateException
365: * if the method is invoked after <code>sendRedirect</code> has been called.
366: */
367:
368: public void setRenderParameter(String key, String[] values) {
369: if (_sendRedirectIsCalled) {
370: throw new IllegalStateException(
371: "Illegal to set parameter after sendRedirect is called.");
372: }
373:
374: if (key == null || values == null) {
375: throw new IllegalArgumentException(
376: "Key or values argument should not be null.");
377: }
378:
379: _setMethodIsCalled = true;
380: Map renderMap = _pContRes.getRenderParameters();
381: if (renderMap == null || renderMap == Collections.EMPTY_MAP) {
382: renderMap = new HashMap();
383: renderMap.put(key, values);
384: _pContRes.setRenderParameters(renderMap);
385: } else {
386: renderMap.put(key, values);
387: }
388: }
389:
390: }
|