0001: /*
0002: * Licensed to the Apache Software Foundation (ASF) under one or more
0003: * contributor license agreements. See the NOTICE file distributed with
0004: * this work for additional information regarding copyright ownership.
0005: * The ASF licenses this file to You under the Apache License, Version 2.0
0006: * (the "License"); you may not use this file except in compliance with
0007: * the License. You may obtain a copy of the License at
0008: *
0009: * http://www.apache.org/licenses/LICENSE-2.0
0010: *
0011: * Unless required by applicable law or agreed to in writing, software
0012: * distributed under the License is distributed on an "AS IS" BASIS,
0013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014: * See the License for the specific language governing permissions and
0015: * limitations under the License.
0016: */
0017: package org.apache.wicket.protocol.http;
0018:
0019: import java.io.BufferedReader;
0020: import java.io.ByteArrayInputStream;
0021: import java.io.CharArrayReader;
0022: import java.io.FileInputStream;
0023: import java.io.IOException;
0024: import java.io.StringWriter;
0025: import java.io.UnsupportedEncodingException;
0026: import java.net.URLEncoder;
0027: import java.security.Principal;
0028: import java.text.DateFormat;
0029: import java.text.ParseException;
0030: import java.util.ArrayList;
0031: import java.util.Collections;
0032: import java.util.Enumeration;
0033: import java.util.HashMap;
0034: import java.util.Iterator;
0035: import java.util.List;
0036: import java.util.Locale;
0037: import java.util.Map;
0038:
0039: import javax.servlet.RequestDispatcher;
0040: import javax.servlet.ServletContext;
0041: import javax.servlet.ServletInputStream;
0042: import javax.servlet.http.Cookie;
0043: import javax.servlet.http.HttpServletRequest;
0044: import javax.servlet.http.HttpSession;
0045:
0046: import org.apache.wicket.Application;
0047: import org.apache.wicket.Component;
0048: import org.apache.wicket.IPageMap;
0049: import org.apache.wicket.IRedirectListener;
0050: import org.apache.wicket.IResourceListener;
0051: import org.apache.wicket.Page;
0052: import org.apache.wicket.WicketRuntimeException;
0053: import org.apache.wicket.markup.html.form.Form;
0054: import org.apache.wicket.markup.html.form.FormComponent;
0055: import org.apache.wicket.markup.html.form.IFormSubmitListener;
0056: import org.apache.wicket.markup.html.form.IOnChangeListener;
0057: import org.apache.wicket.markup.html.link.BookmarkablePageLink;
0058: import org.apache.wicket.markup.html.link.ILinkListener;
0059: import org.apache.wicket.protocol.http.request.WebRequestCodingStrategy;
0060: import org.apache.wicket.util.file.File;
0061: import org.apache.wicket.util.lang.Classes;
0062: import org.apache.wicket.util.upload.FileUploadBase;
0063: import org.apache.wicket.util.value.ValueMap;
0064: import org.slf4j.Logger;
0065: import org.slf4j.LoggerFactory;
0066:
0067: /**
0068: * Mock servlet request. Implements all of the methods from the standard
0069: * HttpServletRequest class plus helper methods to aid setting up a request.
0070: *
0071: * @author Chris Turner
0072: */
0073: public class MockHttpServletRequest implements HttpServletRequest {
0074: /**
0075: * A holder class for an uploaded file.
0076: *
0077: * @author Frank Bille (billen)
0078: */
0079: private class UploadedFile {
0080: private String fieldName;
0081: private File file;
0082: private String contentType;
0083:
0084: /**
0085: * Construct.
0086: *
0087: * @param fieldName
0088: * @param file
0089: * @param contentType
0090: */
0091: public UploadedFile(String fieldName, File file,
0092: String contentType) {
0093: this .fieldName = fieldName;
0094: this .file = file;
0095: this .contentType = contentType;
0096: }
0097:
0098: /**
0099: * @return The content type of the file. Mime type.
0100: */
0101: public String getContentType() {
0102: return contentType;
0103: }
0104:
0105: /**
0106: * @param contentType
0107: * The content type.
0108: */
0109: public void setContentType(String contentType) {
0110: this .contentType = contentType;
0111: }
0112:
0113: /**
0114: * @return The field name.
0115: */
0116: public String getFieldName() {
0117: return fieldName;
0118: }
0119:
0120: /**
0121: * @param fieldName
0122: */
0123: public void setFieldName(String fieldName) {
0124: this .fieldName = fieldName;
0125: }
0126:
0127: /**
0128: * @return The uploaded file.
0129: */
0130: public File getFile() {
0131: return file;
0132: }
0133:
0134: /**
0135: * @param file
0136: */
0137: public void setFile(File file) {
0138: this .file = file;
0139: }
0140: }
0141:
0142: /** Logging object */
0143: private static final Logger log = LoggerFactory
0144: .getLogger(MockHttpServletRequest.class);
0145:
0146: /** The application */
0147: private final Application application;
0148:
0149: private final ValueMap attributes = new ValueMap();
0150:
0151: private String authType;
0152:
0153: private String characterEncoding;
0154:
0155: private final ServletContext context;
0156:
0157: private final List cookies = new ArrayList();
0158:
0159: private final ValueMap headers = new ValueMap();
0160:
0161: private String method;
0162:
0163: private final ValueMap parameters = new ValueMap();
0164:
0165: private String path;
0166:
0167: private final HttpSession session;
0168:
0169: private String url;
0170:
0171: private Map/* <String, UploadedFile> */uploadedFiles;
0172:
0173: /**
0174: * Create the request using the supplied session object.
0175: *
0176: * @param application
0177: * The application that this request is for
0178: * @param session
0179: * The session object
0180: * @param context
0181: * The current servlet context
0182: */
0183: public MockHttpServletRequest(final Application application,
0184: final HttpSession session, final ServletContext context) {
0185: this .application = application;
0186: this .session = session;
0187: this .context = context;
0188: initialize();
0189: }
0190:
0191: /**
0192: * Add a new cookie.
0193: *
0194: * @param cookie
0195: * The cookie
0196: */
0197: public void addCookie(final Cookie cookie) {
0198: cookies.add(cookie);
0199: }
0200:
0201: /**
0202: * Add an uploaded file to the request. Use this to simulate a file that has
0203: * been uploaded to a field.
0204: *
0205: * @param fieldName
0206: * The fieldname of the upload field.
0207: * @param file
0208: * The file to upload.
0209: * @param contentType
0210: * The content type of the file. Must be a correct mimetype.
0211: */
0212: public void addFile(String fieldName, File file, String contentType) {
0213: if (file == null) {
0214: throw new IllegalArgumentException("File must not be null");
0215: }
0216:
0217: if (file.exists() == false) {
0218: throw new IllegalArgumentException(
0219: "File does not exists. You must provide an existing file: "
0220: + file.getAbsolutePath());
0221: }
0222:
0223: if (file.isFile() == false) {
0224: throw new IllegalArgumentException(
0225: "You can only add a File, which is not a directory. Only files can be uploaded.");
0226: }
0227:
0228: if (uploadedFiles == null) {
0229: uploadedFiles = new HashMap/* <String, UploadedFile> */();
0230: }
0231:
0232: UploadedFile uf = new UploadedFile(fieldName, file, contentType);
0233:
0234: uploadedFiles.put(fieldName, uf);
0235: }
0236:
0237: /**
0238: * Add a header to the request.
0239: *
0240: * @param name
0241: * The name of the header to add
0242: * @param value
0243: * The value
0244: */
0245: public void addHeader(String name, String value) {
0246: List list = (List) headers.get(name);
0247: if (list == null) {
0248: list = new ArrayList(1);
0249: headers.put(name, list);
0250: }
0251: list.add(value);
0252: }
0253:
0254: /**
0255: * Get an attribute.
0256: *
0257: * @param name
0258: * The attribute name
0259: * @return The value, or null
0260: */
0261: public Object getAttribute(final String name) {
0262: return attributes.get(name);
0263: }
0264:
0265: /**
0266: * Get the names of all of the values.
0267: *
0268: * @return The names
0269: */
0270: public Enumeration getAttributeNames() {
0271: return Collections.enumeration(attributes.keySet());
0272: }
0273:
0274: // HttpServletRequest methods
0275:
0276: /**
0277: * Get the auth type.
0278: *
0279: * @return The auth type
0280: */
0281: public String getAuthType() {
0282: return authType;
0283: }
0284:
0285: /**
0286: * Get the current character encoding.
0287: *
0288: * @return The character encoding
0289: */
0290: public String getCharacterEncoding() {
0291: return characterEncoding;
0292: }
0293:
0294: /**
0295: * Return the length of the content. This is always -1 except if there has
0296: * been added uploaded files. Then the length will be the length of the
0297: * generated request.
0298: *
0299: * @return -1 if no uploaded files has been added. Else the length of the
0300: * generated request.
0301: */
0302: public int getContentLength() {
0303: if (uploadedFiles != null && uploadedFiles.size() > 0) {
0304: String request = buildRequest();
0305: return request.length();
0306: }
0307:
0308: return -1;
0309: }
0310:
0311: /**
0312: * If there has been added uploaded files return the correct content-type.
0313: *
0314: * @return The correct multipart content-type if there has been added
0315: * uploaded files. Else null.
0316: */
0317: public String getContentType() {
0318: if (uploadedFiles != null && uploadedFiles.size() > 0) {
0319: return FileUploadBase.MULTIPART_FORM_DATA
0320: + "; boundary=abcdefgABCDEFG";
0321: }
0322:
0323: return null;
0324: }
0325:
0326: /**
0327: * Get the context path. For this mock implementation the name of the
0328: * application is always returned.
0329: *
0330: * @return The context path
0331: */
0332: public String getContextPath() {
0333: return "/" + application.getName();
0334: }
0335:
0336: /**
0337: * Get all of the cookies for this request.
0338: *
0339: * @return The cookies
0340: */
0341: public Cookie[] getCookies() {
0342: if (cookies.size() == 0) {
0343: return null;
0344: }
0345: Cookie[] result = new Cookie[cookies.size()];
0346: return (Cookie[]) cookies.toArray(result);
0347: }
0348:
0349: /**
0350: * Get the given header as a date.
0351: *
0352: * @param name
0353: * The header name
0354: * @return The date, or -1 if header not found
0355: * @throws IllegalArgumentException
0356: * If the header cannot be converted
0357: */
0358: public long getDateHeader(final String name)
0359: throws IllegalArgumentException {
0360: String value = getHeader(name);
0361: if (value == null) {
0362: return -1;
0363: }
0364:
0365: DateFormat df = DateFormat.getDateInstance(DateFormat.FULL);
0366: try {
0367: return df.parse(value).getTime();
0368: } catch (ParseException e) {
0369: throw new IllegalArgumentException(
0370: "Can't convert header to date " + name + ": "
0371: + value);
0372: }
0373: }
0374:
0375: /**
0376: * Get the given header value.
0377: *
0378: * @param name
0379: * The header name
0380: * @return The header value or null
0381: */
0382: public String getHeader(final String name) {
0383: final List l = (List) headers.get(name);
0384: if (l == null || l.size() < 1) {
0385: return null;
0386: } else {
0387: return (String) l.get(0);
0388: }
0389: }
0390:
0391: /**
0392: * Get the names of all of the headers.
0393: *
0394: * @return The header names
0395: */
0396: public Enumeration getHeaderNames() {
0397: return Collections.enumeration(headers.keySet());
0398: }
0399:
0400: /**
0401: * Get enumeration of all header values with the given name.
0402: *
0403: * @param name
0404: * The name
0405: * @return The header values
0406: */
0407: public Enumeration getHeaders(final String name) {
0408: List list = (List) headers.get(name);
0409: if (list == null) {
0410: list = new ArrayList();
0411: }
0412: return Collections.enumeration(list);
0413: }
0414:
0415: /**
0416: * Returns an input stream if there has been added some uploaded files. Use
0417: * {@link #addFile(String, File, String)} to add some uploaded files.
0418: *
0419: * @return The input stream
0420: * @throws IOException
0421: * If an I/O related problem occurs
0422: */
0423: public ServletInputStream getInputStream() throws IOException {
0424: if (uploadedFiles != null && uploadedFiles.size() > 0) {
0425: String request = buildRequest();
0426:
0427: // Ok lets make an input stream to return
0428: final ByteArrayInputStream bais = new ByteArrayInputStream(
0429: request.getBytes("ISO-8859-1"));
0430:
0431: return new ServletInputStream() {
0432: public int read() {
0433: return bais.read();
0434: }
0435: };
0436: } else {
0437: return new ServletInputStream() {
0438: public int read() {
0439: return -1;
0440: }
0441: };
0442: }
0443: }
0444:
0445: /**
0446: * Get the given header as an int.
0447: *
0448: * @param name
0449: * The header name
0450: * @return The header value or -1 if header not found
0451: * @throws NumberFormatException
0452: * If the header is not formatted correctly
0453: */
0454: public int getIntHeader(final String name) {
0455: String value = getHeader(name);
0456: if (value == null) {
0457: return -1;
0458: }
0459: return Integer.valueOf(value).intValue();
0460: }
0461:
0462: /**
0463: * Get the locale of the request. Attempts to decode the Accept-Language
0464: * header and if not found returns the default locale of the JVM.
0465: *
0466: * @return The locale
0467: */
0468: public Locale getLocale() {
0469: final String header = getHeader("Accept-Language");
0470: if (header == null) {
0471: return Locale.getDefault();
0472: }
0473:
0474: final String[] firstLocale = header.split(",");
0475: if (firstLocale.length < 1) {
0476: return Locale.getDefault();
0477: }
0478:
0479: final String[] bits = firstLocale[0].split("-");
0480: if (bits.length < 1) {
0481: return Locale.getDefault();
0482: }
0483:
0484: final String language = bits[0].toLowerCase();
0485: if (bits.length > 1) {
0486: final String country = bits[1].toUpperCase();
0487: return new Locale(language, country);
0488: } else {
0489: return new Locale(language);
0490: }
0491: }
0492:
0493: /**
0494: * Return all the accepted locales. This implementation always returns just
0495: * one.
0496: *
0497: * @return The locales
0498: */
0499: public Enumeration getLocales() {
0500: List list = new ArrayList(1);
0501: list.add(getLocale());
0502: return Collections.enumeration(list);
0503: }
0504:
0505: /**
0506: * Get the method.
0507: *
0508: * @return The method
0509: */
0510: public String getMethod() {
0511: return method;
0512: }
0513:
0514: /**
0515: * Get the request parameter with the given name.
0516: *
0517: * @param name
0518: * The parameter name
0519: * @return The parameter value, or null
0520: */
0521: public String getParameter(final String name) {
0522: return parameters.getString(name);
0523: }
0524:
0525: /**
0526: * Get the map of all of the parameters.
0527: *
0528: * @return The parameters
0529: */
0530: public Map getParameterMap() {
0531: return parameters;
0532: }
0533:
0534: /**
0535: * Get the names of all of the parameters.
0536: *
0537: * @return The parameter names
0538: */
0539: public Enumeration getParameterNames() {
0540: return Collections.enumeration(parameters.keySet());
0541: }
0542:
0543: /**
0544: * Get the values for the given parameter.
0545: *
0546: * @param name
0547: * The name of the parameter
0548: * @return The return values
0549: */
0550: public String[] getParameterValues(final String name) {
0551: Object value = parameters.get(name);
0552: if (value == null) {
0553: return new String[0];
0554: }
0555:
0556: if (value instanceof String[]) {
0557: return (String[]) value;
0558: } else {
0559: String[] result = new String[1];
0560: result[0] = value.toString();
0561: return result;
0562: }
0563: }
0564:
0565: /**
0566: * Get the path info.
0567: *
0568: * @return The path info
0569: */
0570: public String getPathInfo() {
0571: return path;
0572: }
0573:
0574: /**
0575: * Always returns null.
0576: *
0577: * @return null
0578: */
0579: public String getPathTranslated() {
0580: return null;
0581: }
0582:
0583: /**
0584: * Get the protocol.
0585: *
0586: * @return Always HTTP/1.1
0587: */
0588: public String getProtocol() {
0589: return "HTTP/1.1";
0590: }
0591:
0592: /**
0593: * Get the query string part of the request.
0594: *
0595: * @return The query string
0596: */
0597: public String getQueryString() {
0598: if (parameters.size() == 0) {
0599: return null;
0600: } else {
0601: final StringBuffer buf = new StringBuffer();
0602: try {
0603: for (Iterator iterator = parameters.keySet().iterator(); iterator
0604: .hasNext();) {
0605: final String name = (String) iterator.next();
0606: final String value = parameters.getString(name);
0607: buf.append(URLEncoder.encode(name, "UTF-8"));
0608: buf.append('=');
0609: buf.append(URLEncoder.encode(value, "UTF-8"));
0610: if (iterator.hasNext()) {
0611: buf.append('&');
0612: }
0613: }
0614: } catch (UnsupportedEncodingException e) {
0615: // Should never happen!
0616: }
0617: return buf.toString();
0618: }
0619: }
0620:
0621: /**
0622: * This feature is not implemented at this time as we are not supporting
0623: * binary servlet input. This functionality may be added in the future.
0624: *
0625: * @return The reader
0626: * @throws IOException
0627: * If an I/O related problem occurs
0628: */
0629: public BufferedReader getReader() throws IOException {
0630: return new BufferedReader(new CharArrayReader(new char[0]));
0631: }
0632:
0633: /**
0634: * Deprecated method - should not be used.
0635: *
0636: * @param name
0637: * The name
0638: * @return The path
0639: * @deprecated Use ServletContext.getRealPath(String) instead.
0640: */
0641: public String getRealPath(String name) {
0642: return context.getRealPath(name);
0643: }
0644:
0645: /**
0646: * Get the remote address of the client.
0647: *
0648: * @return Always 127.0.0.1
0649: */
0650: public String getRemoteAddr() {
0651: return "127.0.0.1";
0652: }
0653:
0654: /**
0655: * Get the remote host.
0656: *
0657: * @return Always localhost
0658: */
0659: public String getRemoteHost() {
0660: return "localhost";
0661: }
0662:
0663: /**
0664: * Get the name of the remote user from the REMOTE_USER header.
0665: *
0666: * @return The name of the remote user
0667: */
0668: public String getRemoteUser() {
0669: return getHeader("REMOTE_USER");
0670: }
0671:
0672: /**
0673: * Return a dummy dispatcher that just records that dispatch has occured
0674: * without actually doing anything.
0675: *
0676: * @param name
0677: * The name to dispatch to
0678: * @return The dispatcher
0679: */
0680: public RequestDispatcher getRequestDispatcher(String name) {
0681: return context.getRequestDispatcher(name);
0682: }
0683:
0684: /**
0685: * Get the requested session id. Always returns the id of the current
0686: * session.
0687: *
0688: * @return The session id
0689: */
0690: public String getRequestedSessionId() {
0691: return session.getId();
0692: }
0693:
0694: /**
0695: * Returns context path and servlet path concatenated, typically /applicationClassName/applicationClassName
0696: *
0697: * @return The path value
0698: * @see javax.servlet.http.HttpServletRequest#getRequestURI()
0699: */
0700: public String getRequestURI() {
0701: if (url == null) {
0702: return getContextPath() + getServletPath();
0703: }
0704: return url;
0705: }
0706:
0707: /**
0708: * Try to build a rough URL.
0709: *
0710: * @return The url
0711: */
0712: public StringBuffer getRequestURL() {
0713: final StringBuffer buf = new StringBuffer();
0714: buf.append("http://localhost");
0715: buf.append(getContextPath());
0716: if (getPathInfo() != null) {
0717: buf.append(getPathInfo());
0718: }
0719:
0720: final String query = getQueryString();
0721: if (query != null) {
0722: buf.append('?');
0723: buf.append(query);
0724: }
0725: return buf;
0726: }
0727:
0728: /**
0729: * Get the scheme.
0730: *
0731: * @return Always http
0732: */
0733: public String getScheme() {
0734: return "http";
0735: }
0736:
0737: /**
0738: * Get the server name.
0739: *
0740: * @return Always localhost
0741: */
0742: public String getServerName() {
0743: return "localhost";
0744: }
0745:
0746: /**
0747: * Get the server port.
0748: *
0749: * @return Always 80
0750: */
0751: public int getServerPort() {
0752: return 80;
0753: }
0754:
0755: /**
0756: * The servlet path may either be the application name or /. For test
0757: * purposes we always return the servlet name.
0758: *
0759: * @return The servlet path
0760: */
0761: public String getServletPath() {
0762: return getContextPath();
0763: }
0764:
0765: /**
0766: * Get the sessions.
0767: *
0768: * @return The session
0769: */
0770: public HttpSession getSession() {
0771: return session;
0772: }
0773:
0774: /**
0775: * Get the session.
0776: *
0777: * @param b
0778: * Ignored, there is always a session
0779: * @return The session
0780: */
0781: public HttpSession getSession(boolean b) {
0782: return session;
0783: }
0784:
0785: /**
0786: * Get the user principal.
0787: *
0788: * @return A user principal
0789: */
0790: public Principal getUserPrincipal() {
0791: final String user = getRemoteUser();
0792: if (user == null) {
0793: return null;
0794: } else {
0795: return new Principal() {
0796: public String getName() {
0797: return user;
0798: }
0799: };
0800: }
0801: }
0802:
0803: /**
0804: * @return True if there has been added files to this request using
0805: * {@link #addFile(String, File, String)}
0806: */
0807: public boolean hasUploadedFiles() {
0808: return uploadedFiles != null;
0809: }
0810:
0811: /**
0812: * Reset the request back to a default state.
0813: */
0814: public void initialize() {
0815: authType = null;
0816: method = "post";
0817: cookies.clear();
0818: setDefaultHeaders();
0819: path = null;
0820: url = null;
0821: characterEncoding = "UTF-8";
0822: parameters.clear();
0823: attributes.clear();
0824: }
0825:
0826: /**
0827: * Check whether session id is from a cookie. Always returns true.
0828: *
0829: * @return Always true
0830: */
0831: public boolean isRequestedSessionIdFromCookie() {
0832: return true;
0833: }
0834:
0835: /**
0836: * Check whether session id is from a url rewrite. Always returns false.
0837: *
0838: * @return Always false
0839: */
0840: public boolean isRequestedSessionIdFromUrl() {
0841: return false;
0842: }
0843:
0844: /**
0845: * Check whether session id is from a url rewrite. Always returns false.
0846: *
0847: * @return Always false
0848: */
0849: public boolean isRequestedSessionIdFromURL() {
0850: return false;
0851: }
0852:
0853: /**
0854: * Check whether the session id is valid.
0855: *
0856: * @return Always true
0857: */
0858: public boolean isRequestedSessionIdValid() {
0859: return true;
0860: }
0861:
0862: /**
0863: * Always returns false.
0864: *
0865: * @return Always false
0866: */
0867: public boolean isSecure() {
0868: return false;
0869: }
0870:
0871: /**
0872: * NOT IMPLEMENTED.
0873: *
0874: * @param name
0875: * The role name
0876: * @return Always false
0877: */
0878: public boolean isUserInRole(String name) {
0879: return false;
0880: }
0881:
0882: /**
0883: * Remove the given attribute.
0884: *
0885: * @param name
0886: * The name of the attribute
0887: */
0888: public void removeAttribute(final String name) {
0889: attributes.remove(name);
0890: }
0891:
0892: /**
0893: * Set the given attribute.
0894: *
0895: * @param name
0896: * The attribute name
0897: * @param o
0898: * The value to set
0899: */
0900: public void setAttribute(final String name, final Object o) {
0901: attributes.put(name, o);
0902: }
0903:
0904: /**
0905: * Set the auth type.
0906: *
0907: * @param authType
0908: * The auth type
0909: */
0910: public void setAuthType(final String authType) {
0911: this .authType = authType;
0912: }
0913:
0914: /**
0915: * Set the character encoding.
0916: *
0917: * @param encoding
0918: * The character encoding
0919: * @throws UnsupportedEncodingException
0920: * If encoding not supported
0921: */
0922: public void setCharacterEncoding(final String encoding)
0923: throws UnsupportedEncodingException {
0924: this .characterEncoding = encoding;
0925: }
0926:
0927: /**
0928: * Set the cookies.
0929: *
0930: * @param theCookies
0931: * The cookies
0932: */
0933: public void setCookies(final Cookie[] theCookies) {
0934: cookies.clear();
0935: for (int i = 0; i < theCookies.length; i++) {
0936: cookies.add(theCookies[i]);
0937: }
0938: }
0939:
0940: /**
0941: * Set the method.
0942: *
0943: * @param method
0944: * The method
0945: */
0946: public void setMethod(final String method) {
0947: this .method = method;
0948: }
0949:
0950: /**
0951: * Set a parameter.
0952: *
0953: * @param name
0954: * The name
0955: * @param value
0956: * The value
0957: */
0958: public void setParameter(final String name, final String value) {
0959: parameters.put(name, value);
0960: }
0961:
0962: /**
0963: * Sets a map of parameters.
0964: *
0965: * @param parameters
0966: * the parameters to set
0967: */
0968: public void setParameters(final Map parameters) {
0969: this .parameters.putAll(parameters);
0970: }
0971:
0972: /**
0973: * Set the path that this request is supposed to be serving. The path is
0974: * relative to the web application root and should start with a / charater
0975: *
0976: * @param path
0977: */
0978: public void setPath(final String path) {
0979: this .path = path;
0980: }
0981:
0982: /**
0983: * Set the complete url for this request. The url will be analyzed.
0984: *
0985: * @param url
0986: */
0987: public void setURL(String url) {
0988: if (url.startsWith("http://")) {
0989: int index = url.indexOf("/", 7);
0990: url = url.substring(index);
0991: }
0992: this .url = url;
0993: if (url.startsWith(getContextPath())) {
0994: url = url.substring(getContextPath().length());
0995: }
0996: if (url.startsWith(getServletPath())) {
0997: url = url.substring(getServletPath().length());
0998: }
0999:
1000: int index = url.indexOf("?");
1001: if (index == -1) {
1002: path = url;
1003: } else {
1004: path = url.substring(0, index);
1005:
1006: String queryString = url.substring(index + 1);
1007: RequestUtils.decodeParameters(queryString, parameters);
1008: }
1009: }
1010:
1011: /**
1012: * Initialise the request parameters to point to the given bookmarkable
1013: * page.
1014: *
1015: * @param page
1016: * The page to point to
1017: * @param params
1018: * Additional parameters
1019: */
1020: public void setRequestToBookmarkablePage(final Page page,
1021: final Map params) {
1022: parameters.putAll(params);
1023: parameters
1024: .put(
1025: WebRequestCodingStrategy.BOOKMARKABLE_PAGE_PARAMETER_NAME,
1026: page.getClass().getName());
1027: }
1028:
1029: /**
1030: * Initialise the request parameters to point to the given component.
1031: *
1032: * @param component
1033: * The component
1034: */
1035: public void setRequestToComponent(final Component component) {
1036: final IPageMap pageMap = component.getPage().getPageMap();
1037: final String pageMapName = pageMap.isDefault() ? "" : pageMap
1038: .getName();
1039: if (component instanceof BookmarkablePageLink) {
1040: final Class clazz = ((BookmarkablePageLink) component)
1041: .getPageClass();
1042: parameters
1043: .put(
1044: WebRequestCodingStrategy.BOOKMARKABLE_PAGE_PARAMETER_NAME,
1045: pageMapName + ':' + clazz.getName());
1046: } else {
1047: int version = component.getPage().getCurrentVersionNumber();
1048: Class clazz = null;
1049: if (component instanceof IRedirectListener) {
1050: clazz = IRedirectListener.class;
1051: } else if (component instanceof IResourceListener) {
1052: clazz = IResourceListener.class;
1053: } else if (component instanceof IFormSubmitListener) {
1054: clazz = IFormSubmitListener.class;
1055: } else if (component instanceof ILinkListener) {
1056: clazz = ILinkListener.class;
1057: } else if (component instanceof IOnChangeListener) {
1058: clazz = IOnChangeListener.class;
1059: } else {
1060: throw new IllegalArgumentException(
1061: "The component class doesn't seem to implement any of the known *Listener interfaces: "
1062: + component.getClass());
1063: }
1064:
1065: parameters.put(
1066: WebRequestCodingStrategy.INTERFACE_PARAMETER_NAME,
1067: pageMapName + ':' + component.getPath() + ':'
1068: + (version == 0 ? "" : "" + version) + ':'
1069: + Classes.simpleName(clazz) + "::");
1070:
1071: if (component.isStateless()
1072: && component.getPage().isBookmarkable()) {
1073: parameters
1074: .put(
1075: WebRequestCodingStrategy.BOOKMARKABLE_PAGE_PARAMETER_NAME,
1076: pageMapName
1077: + ':'
1078: + component.getPage()
1079: .getClass().getName());
1080: }
1081: }
1082: }
1083:
1084: /**
1085: * Initialise the request parameters to point to the given form component.
1086: * The additional map should contain mappings between individual components
1087: * that appear in the form and the string value that should be submitted for
1088: * each of these components.
1089: *
1090: * @param form
1091: * The for to send the request to
1092: * @param values
1093: * The values for each of the form components
1094: */
1095: public void setRequestToFormComponent(final Form form,
1096: final Map values) {
1097: setRequestToComponent(form);
1098:
1099: final Map valuesApplied = new HashMap();
1100: form.visitChildren(new Component.IVisitor() {
1101: public Object component(final Component component) {
1102: if (component instanceof FormComponent) {
1103: String value = (String) values.get(component);
1104: if (value != null) {
1105: parameters.put(((FormComponent) component)
1106: .getInputName(), values.get(component));
1107: valuesApplied.put(component.getId(), component);
1108: }
1109: }
1110: return CONTINUE_TRAVERSAL;
1111: }
1112: });
1113:
1114: if (values.size() != valuesApplied.size()) {
1115: Map diff = new HashMap();
1116: diff.putAll(values);
1117:
1118: Iterator iter = valuesApplied.keySet().iterator();
1119: while (iter.hasNext()) {
1120: diff.remove(iter.next());
1121: }
1122:
1123: log
1124: .error("Parameter mismatch: didn't find all components referenced in parameter 'values': "
1125: + diff.keySet());
1126: }
1127: }
1128:
1129: /**
1130: * Initialise the request parameters from the given redirect string that
1131: * redirects back to a particular component for display.
1132: *
1133: * @param redirect
1134: * The redirect string to display from
1135: */
1136: public void setRequestToRedirectString(final String redirect) {
1137: parameters.clear();
1138:
1139: final String queryString = redirect.substring(redirect
1140: .indexOf('?') + 1);
1141: RequestUtils.decodeParameters(queryString, parameters);
1142: }
1143:
1144: /**
1145: * Helper method to create some default headers for the request
1146: */
1147: private void setDefaultHeaders() {
1148: headers.clear();
1149: addHeader(
1150: "Accept",
1151: "text/xml,application/xml,application/xhtml+xml,"
1152: + "text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5");
1153: addHeader("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
1154: Locale l = Locale.getDefault();
1155: addHeader("Accept-Language", l.getLanguage().toLowerCase()
1156: + "-" + l.getCountry().toLowerCase() + ","
1157: + l.getLanguage().toLowerCase() + ";q=0.5");
1158: addHeader(
1159: "User-Agent",
1160: "Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.7) Gecko/20040707 Firefox/0.9.2");
1161: }
1162:
1163: /**
1164: * Build the request based on the uploaded files and the parameters.
1165: *
1166: * @return The request as a string.
1167: */
1168: private String buildRequest() {
1169: // Build up the input stream based on the files and parameters
1170: StringBuffer issb = new StringBuffer();
1171: String crlf = "\r\n";
1172: String boundary = "--abcdefgABCDEFG";
1173:
1174: // Add parameters
1175: for (Iterator iterator = parameters.keySet().iterator(); iterator
1176: .hasNext();) {
1177: final String name = (String) iterator.next();
1178: issb.append(boundary).append(crlf);
1179: issb.append("Content-Disposition: form-data; name=\"")
1180: .append(name).append("\"").append(crlf)
1181: .append(crlf);
1182: issb.append(parameters.get(name)).append(crlf);
1183: }
1184:
1185: try {
1186: // Add files
1187: if (uploadedFiles != null) {
1188: for (Iterator iterator = uploadedFiles.keySet()
1189: .iterator(); iterator.hasNext();) {
1190: String fieldName = (String) iterator.next();
1191:
1192: UploadedFile uf = (UploadedFile) uploadedFiles
1193: .get(fieldName);
1194:
1195: issb.append(boundary).append(crlf);
1196: issb.append(
1197: "Content-Disposition: form-data; name=\"")
1198: .append(fieldName)
1199: .append("\"; filename=\"").append(
1200: uf.getFile().getName())
1201: .append("\"").append(crlf);
1202: issb.append("Content-Type: ").append(
1203: uf.getContentType()).append(crlf).append(
1204: crlf);
1205:
1206: // Load the file and put it into the the inputstream
1207: FileInputStream fis = new FileInputStream(uf
1208: .getFile());
1209: StringWriter sw = new StringWriter();
1210:
1211: byte[] data = new byte[1024];
1212: int read = 0;
1213: while ((read = fis.read(data)) > 0) {
1214: sw.write(new String(data, 0, read));
1215: }
1216:
1217: fis.close();
1218:
1219: issb.append(sw.getBuffer()).append(crlf);
1220:
1221: sw.close();
1222: }
1223: }
1224: } catch (IOException e) {
1225: // NOTE: IllegalStateException(Throwable) only exists since Java 1.5
1226: throw new WicketRuntimeException(e);
1227: }
1228:
1229: issb.append(boundary).append("--").append(crlf);
1230:
1231: return issb.toString();
1232: }
1233: }
|