001: package com.sun.portal.desktop;
002:
003: import java.util.*;
004: import java.util.logging.Logger;
005: import java.util.logging.Level;
006: import java.text.*;
007: import java.net.*;
008: import java.io.*;
009: import javax.servlet.*;
010: import javax.servlet.http.*;
011:
012: import com.sun.portal.desktop.context.DesktopAppContext;
013: import com.sun.portal.desktop.util.I18n;
014: import com.sun.portal.desktop.util.NSStringBuffer;
015: import com.sun.portal.desktop.util.PIParser;
016: import com.sun.portal.log.common.PortalLogger;
017:
018: /**
019: * A DesktopRequest encapsulates the HttpServletRequest that is passed
020: * to the provider, hiding and redefining those methods that are
021: * inappropriate to be called by a provider.
022: */
023:
024: public class DesktopRequest extends HttpServletRequestWrapper {
025: public static final String PREFIX = "dt.";
026: public static final String IS_PORTLET_REQUEST = PREFIX
027: + "isPortletRequest";
028:
029: private Hashtable desktopParameterTable = null;
030: private Hashtable portletParameterTable = null;
031: private String charset = null;
032: private boolean isReadInputStream = false;
033: private DesktopAppContext dac = null;
034:
035: // Create a logger for this class
036: private static Logger debugLogger = PortalLogger
037: .getLogger(DesktopRequest.class);
038:
039: public DesktopRequest(HttpServletRequest request,
040: DesktopAppContext dac, boolean readFromParameters) {
041: super (request);
042: this .dac = dac;
043: parseParameters(readFromParameters);
044: }
045:
046: private boolean isPortletRequest() {
047: return Boolean.valueOf(super .getParameter(IS_PORTLET_REQUEST))
048: .booleanValue();
049: }
050:
051: protected void parseParameters(boolean readFromParameters) {
052: Hashtable parameterTable = null;
053:
054: if (readFromParameters) {
055: parameterTable = new Hashtable();
056: for (Enumeration e = super .getParameterNames(); e
057: .hasMoreElements();) {
058: String name = (String) e.nextElement();
059: String[] val = new String[1];
060: val[0] = super .getParameter(name);
061: parameterTable.put(name, val);
062: }
063: } else if (getMethod().equalsIgnoreCase("GET")
064: || (getContentType() == null)
065: || (getContentType().indexOf(
066: "application/x-www-form-urlencoded") == -1)
067: || (getMethod().equalsIgnoreCase("POST"))) {
068: parameterTable = new Hashtable();
069: Enumeration enumReq = super .getParameterNames();
070: while (enumReq.hasMoreElements()) {
071: String key = (String) enumReq.nextElement();
072: String[] val = (String[]) super .getParameterValues(key);
073: parameterTable.put(key, val);
074: }
075: }
076: // read from PathInfo
077: String pathInfo = getPathInfoValue();
078:
079: if (pathInfo != null && pathInfo.length() != 0) {
080: Map piMap = PIParser.parse(pathInfo);
081:
082: Map dtMap = (Map) piMap.get(PIParser.DESKTOP_ARGS);
083:
084: // merge PathInfoMap and QueryString Params.
085: // When there is a Param with the same name
086: // query String Param takes the precedence.
087: if (dtMap != null && !dtMap.isEmpty()) {
088: Map arrayDTMap = getArrayDTMap(dtMap);
089: parameterTable = mergeParams(parameterTable, arrayDTMap);
090: }
091: }
092: if (parameterTable == null) {
093: //
094: // even if parsing failed, make sure
095: // to avoid NPEs
096: //
097: parameterTable = new Hashtable();
098: }
099:
100: getDesktopParameterTable(parameterTable);
101: getPortletParameterTable(parameterTable);
102: }
103:
104: private void getDesktopParameterTable(Hashtable table) {
105: desktopParameterTable = new Hashtable();
106: for (Iterator i = table.keySet().iterator(); i.hasNext();) {
107: String key = (String) i.next();
108: String[] val = (String[]) table.get(key);
109:
110: if (key.startsWith(PREFIX)) {
111: //
112: // put the param in under both the prefixed and un-prefixed
113: // value. this allows client code to use the same constants
114: // for constructing URLs + fetching parameters, but
115: // makes it unecessary for all code to be aware of the prefix
116: //
117: desktopParameterTable.put(key, val);
118: // remove prefix
119: key = key.substring(PREFIX.length());
120: desktopParameterTable.put(key, val);
121: } else if (!isPortletRequest()) {
122: desktopParameterTable.put(key, val);
123: }
124: }
125: }
126:
127: private void getPortletParameterTable(Map table) {
128: if (!isPortletRequest()) {
129: portletParameterTable = new Hashtable();
130: return;
131: }
132:
133: portletParameterTable = new Hashtable();
134: for (Iterator i = table.keySet().iterator(); i.hasNext();) {
135: String key = (String) i.next();
136: if (!key.startsWith(PREFIX)) {
137: String[] val = (String[]) table.get(key);
138: portletParameterTable.put(key, val);
139: }
140: }
141: }
142:
143: private Map getArrayDTMap(Map dtMap) {
144: Map arrayDTMap = new HashMap();
145: Set entry = dtMap.entrySet();
146: Iterator i = entry.iterator();
147: while (i.hasNext()) {
148: Map.Entry me = (Map.Entry) i.next();
149: String Key = (String) me.getKey();
150: if ((Key == null) || (Key.length() == 0)) {
151: continue;
152: }
153: String value = (String) me.getValue();
154: if ((value == null) || (value.length() == 0)) {
155: continue;
156: }
157: String[] newval = new String[1];
158: newval[0] = value;
159: arrayDTMap.put(Key, newval);
160: }
161: return arrayDTMap;
162: }
163:
164: private String getPathInfoValue() {
165: String pi = getPathInfo();
166: // bug in web container. returns the servlet path for req.getPathInfo() call for relative urls.
167: if (pi != null && pi.equals(getServletPath())) {
168: pi = null;
169: }
170: return pi;
171: }
172:
173: private Hashtable mergeParams(Map target, Map source) {
174: Hashtable result = null;
175: if (target != null) {
176: result = new Hashtable(target);
177: }
178:
179: // merge values from source map to target map. For keys that exist
180: // in both maps, values from the target map are placed before values
181: // from the source map
182:
183: if ((target != null) && (source != null)) {
184: Set srcEntry = source.entrySet();
185: Iterator i = srcEntry.iterator();
186: while (i.hasNext()) {
187: Map.Entry me = (Map.Entry) i.next();
188: String fromKey = (String) me.getKey();
189: if ((fromKey == null) || (fromKey.length() == 0)) {
190: continue;
191: }
192: String[] fromVal = (String[]) me.getValue();
193: String[] toVal = (String[]) target.get(fromKey);
194: if ((toVal != null) && (toVal.length > 0)) {
195: if ((fromVal != null) && (fromVal.length > 0)) {
196: int len = toVal.length + fromVal.length;
197: String[] newval = new String[len];
198: System.arraycopy(toVal, 0, newval, 0,
199: toVal.length);
200: System.arraycopy(fromVal, 0, newval,
201: toVal.length, fromVal.length);
202: result.put(fromKey, newval);
203: }
204: } else {
205: result.put(fromKey, fromVal);
206: }
207: }
208: } else if (source != null) {
209: result = new Hashtable(source);
210: }
211: if (result == null) {
212: result = new Hashtable();
213: }
214: return result;
215: }
216:
217: public void decodeParams(String charset) {
218: this .charset = charset;
219:
220: desktopParameterTable = decodeParams(charset,
221: desktopParameterTable);
222: portletParameterTable = decodeParams(charset,
223: portletParameterTable);
224: }
225:
226: private static Hashtable decodeParams(String charset,
227: Hashtable table) {
228: Hashtable decodedTable = new Hashtable();
229: if (table != null) {
230: for (Enumeration e = table.keys(); e.hasMoreElements();) {
231: String key = (String) e.nextElement();
232: Object o = table.get(key);
233: String decodedkey = I18n.decodeCharset(key, charset);
234: if (o instanceof String[]) {
235: String vals[] = (String[]) o;
236: for (int j = 0; j < vals.length; j++) {
237: vals[j] = I18n.decodeCharset(vals[j], charset);
238: }
239: //put it back in the hashtable
240: decodedTable.put(decodedkey, vals);
241: } else {
242: String val = (String) o;
243: val = I18n.decodeCharset(val, charset);
244: decodedTable.put(decodedkey, val);
245: }
246: }
247: }
248:
249: return decodedTable;
250: }
251:
252: public DesktopPortletRequest getDesktopPortletRequest() {
253: if (!isPortletRequest()) {
254: throw new RuntimeException("is not a portlet request");
255: }
256: return new DesktopPortletRequest(this , portletParameterTable);
257: }
258:
259: /* HttpServletRequest methods */
260:
261: public Map getParameterMap() {
262: return desktopParameterTable;
263: }
264:
265: public String getRequestedSessionId() {
266: throw new UnsupportedOperationException(
267: "Use iPS session API to get session information");
268: }
269:
270: public HttpSession getSession() {
271: throw new UnsupportedOperationException(
272: "Use iPS session API to get session information");
273: }
274:
275: public HttpSession getSession(boolean create) {
276: throw new UnsupportedOperationException(
277: "Use iPS session API to get session information");
278: }
279:
280: public boolean isRequestedSessionIdFromCookie() {
281: throw new UnsupportedOperationException(
282: "Use iPS session API to get session information");
283: }
284:
285: /**
286: * @deprecated
287: */
288: public boolean isRequestedSessionIdFromUrl() {
289: throw new UnsupportedOperationException(
290: "Use iPS session API to get session information");
291: }
292:
293: public boolean isRequestedSessionIdFromURL() {
294: throw new UnsupportedOperationException(
295: "Use iPS session API to get session information");
296: }
297:
298: public boolean isRequestedSessionIdValid() {
299: throw new UnsupportedOperationException(
300: "Use iPS session API to get session information");
301: }
302:
303: /* ServletRequest methods */
304:
305: public String getCharacterEncoding() {
306: if (charset == null) {
307: //throw new UnsupportedOperationException("charset is not yet set");
308: return super .getCharacterEncoding();
309: }
310: return charset;
311: }
312:
313: public int getContentLength() {
314: if (getContentType() != null
315: && getContentType().indexOf(
316: "application/x-www-form-urlencoded") == -1) {
317: return super .getContentLength();
318: }
319: return -1;
320: }
321:
322: public ServletInputStream getInputStream() throws IOException {
323: if (getContentType() != null
324: && getContentType().indexOf(
325: "application/x-www-form-urlencoded") == -1) {
326: if (!isReadInputStream) {
327: synchronized (this ) {
328: isReadInputStream = true;
329: }
330: return super .getInputStream();
331: }
332: }
333: throw new UnsupportedOperationException(
334: "Request input is not available to providers");
335: }
336:
337: public String getParameter(String name) {
338: String values[] = (String[]) desktopParameterTable.get(name);
339: if (values != null && values.length >= 1) {
340: return values[0];
341: }
342: return null;
343: }
344:
345: public Enumeration getParameterNames() {
346: return desktopParameterTable.keys();
347: }
348:
349: public String[] getParameterValues(String name) {
350: return (String[]) desktopParameterTable.get(name);
351: }
352:
353: public synchronized BufferedReader getReader() throws IOException {
354: if (getContentType() != null
355: && getContentType().indexOf(
356: "application/x-www-form-urlencoded") == -1) {
357: return super .getReader();
358: }
359: throw new UnsupportedOperationException(
360: "Request input is not available to providers");
361: }
362:
363: /**
364: * @deprecated As of Version 2.1 of the Java Servlet API, use ServletContext.getRealPath(String) instead.
365: */
366: public String getRealPath(String path) {
367: throw new UnsupportedOperationException(
368: "getRealPath is deprecated");
369:
370: }
371:
372: public RequestDispatcher getRequestDispatcher(String path) {
373: throw new UnsupportedOperationException(
374: "RequestDispatcher is not available to providers");
375: }
376:
377: public void setDesktopParameter(String name, String value) {
378: String[] values = new String[1];
379: values[0] = value;
380: desktopParameterTable.put(name, values);
381: if (name.startsWith(PREFIX)) {
382: // also set non-prefixed version
383: desktopParameterTable.put(name.substring(PREFIX.length()),
384: values);
385: } else {
386: // also set prefixed version
387: desktopParameterTable.put(PREFIX + name, values);
388: }
389: }
390:
391: }
|