1 package net.trajano.twiff.internal.servlet;
2
3 import java.util.Collections;
4 import java.util.HashMap;
5 import java.util.List;
6 import java.util.Map;
7 import java.util.Set;
8 import javax.servlet.http.HttpServletRequest;
9 import javax.servlet.http.HttpSession;
10 import net.trajano.twiff.MissingSessionException;
11 import net.trajano.twiff.MissingTokenException;
12 import net.trajano.twiff.adapter.RequestAdapter;
13 import org.apache.commons.collections.MultiHashMap;
14 import org.apache.commons.collections.MultiMap;
15 import org.apache.commons.fileupload.DiskFileUpload;
16 import org.apache.commons.fileupload.FileItem;
17 import org.apache.commons.fileupload.FileUpload;
18 import org.apache.commons.fileupload.FileUploadException;
19
20 /***
21 * This adapts a request so {@link net.trajano.twiff.web.ActionServlet} can use
22 * it in a more type safe manner.
23 *
24 * @author Archimedes Trajano
25 */
26 public class ActionServletRequestAdapter extends RequestAdapter {
27 /***
28 * POST data from the request.
29 */
30 private final Map<String, Object[]> postData;
31
32 /***
33 * The servlet request.
34 */
35 private final HttpServletRequest request;
36
37 /***
38 * Session ID.
39 */
40 private final String sessionId;
41
42 /***
43 * Token ID.
44 */
45 private final String tokenId;
46
47 /***
48 * Constructs the adapter and initializes all its data.
49 *
50 * @param request
51 * the servlet request.
52 * @param tokenFieldName
53 * the name of the field that contains the token ID.
54 * @throws FileUploadException
55 * @throws MissingSessionException
56 * thrown when there is no session data in the request.
57 * @throws MissingTokenException
58 * thrown when there is no token id in the request.
59 */
60 public ActionServletRequestAdapter(final HttpServletRequest request, final String tokenFieldName) throws FileUploadException {
61 super(request);
62 this.request = request;
63 final HttpSession session = request.getSession(false);
64 if (session == null) {
65 throw new MissingSessionException();
66 }
67 this.sessionId = session.getId();
68 this.postData = initPostData();
69 this.tokenId = (String) postData.get(tokenFieldName)[0];
70 if (tokenId == null) {
71 throw new MissingTokenException();
72 }
73 }
74
75 /***
76 * @return Returns the postData.
77 */
78 public final Map<String, Object[]> getPostData() {
79 return postData;
80 }
81
82 /***
83 * @return Returns the sessionId.
84 */
85 public final String getSessionId() {
86 return sessionId;
87 }
88
89 /***
90 * @return Returns the tokenId.
91 */
92 public final String getTokenId() {
93 return tokenId;
94 }
95
96 /***
97 * Extracts the POST data from the request. It supports multiple elements
98 * for a single key using the {@link MultiMap} structure. The map returned
99 * is unmodifiable.
100 *
101 * @return the map of POST data with a key of strings.
102 * @throws FileUploadException
103 */
104 private Map<String, Object[]> initPostData() throws FileUploadException {
105 Map<String, Object[]> resultMap;
106 if (FileUpload.isMultipartContent(request)) {
107 DiskFileUpload upload = new DiskFileUpload();
108 List<FileItem> fileItems = (List<FileItem>) upload.parseRequest(request);
109 MultiMap tempMap = new MultiHashMap(fileItems.size());
110 for (FileItem item : fileItems) {
111 if (item.isFormField()) {
112 tempMap.put(item.getFieldName(), item.getString());
113 } else {
114 tempMap.put(item.getFieldName(), item.get());
115 }
116 }
117 resultMap = new HashMap<String, Object[]>(tempMap.size());
118 for (String key : (Set<String>) tempMap.keySet()) {
119 resultMap.put(key, ((List) tempMap.get(key)).toArray());
120 }
121 } else {
122 Map<String, String[]> parameterMap = (Map<String, String[]>) request.getParameterMap();
123 resultMap = new HashMap<String, Object[]>(parameterMap.size());
124 for (String name : parameterMap.keySet()) {
125 resultMap.put(name, parameterMap.get(name));
126 }
127 }
128 return (Map<String, Object[]>) Collections.unmodifiableMap(resultMap);
129 }
130 }