blob: 6646a6234355d73e3e61a36bfd1ef817d47d8dc1 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.sling.servlethelpers;
import static org.apache.sling.servlethelpers.MockSlingHttpServletResponse.CHARSET_SEPARATOR;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.Principal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.ListResourceBundle;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
import javax.servlet.AsyncContext;
import javax.servlet.DispatcherType;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.http.Part;
import org.apache.commons.collections.IteratorUtils;
import org.apache.commons.lang3.CharEncoding;
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.adapter.SlingAdaptable;
import org.apache.sling.api.request.RequestDispatcherOptions;
import org.apache.sling.api.request.RequestParameter;
import org.apache.sling.api.request.RequestParameterMap;
import org.apache.sling.api.request.RequestPathInfo;
import org.apache.sling.api.request.RequestProgressTracker;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.servlets.HttpConstants;
import aQute.bnd.annotation.ConsumerType;
/**
* Mock {@link SlingHttpServletRequest} implementation.
*/
@ConsumerType
public class MockSlingHttpServletRequest extends SlingAdaptable implements SlingHttpServletRequest {
private final ResourceResolver resourceResolver;
private final RequestPathInfo requestPathInfo;
private Map<String, Object> attributeMap = new HashMap<String, Object>();
private Map<String, String[]> parameterMap = new LinkedHashMap<String, String[]>();
private HttpSession session;
private Resource resource;
private String authType;
private String contextPath;
private String queryString;
private String scheme = "http";
private String serverName = "localhost";
private int serverPort = 80;
private String servletPath = StringUtils.EMPTY;
private String pathInfo = null;
private String method = HttpConstants.METHOD_GET;
private final HeaderSupport headerSupport = new HeaderSupport();
private final CookieSupport cookieSupport = new CookieSupport();
private String contentType;
private String characterEncoding;
private byte[] content;
private String remoteUser;
private String remoteAddr;
private String remoteHost;
private int remotePort;
private Locale locale = Locale.US;
private MockRequestDispatcherFactory requestDispatcherFactory;
protected static final ResourceBundle EMPTY_RESOURCE_BUNDLE = new ListResourceBundle() {
@Override
protected Object[][] getContents() {
return new Object[0][0];
}
};
/**
* @param resourceResolver Resource resolver
*/
public MockSlingHttpServletRequest(ResourceResolver resourceResolver) {
this.resourceResolver = resourceResolver;
this.requestPathInfo = newMockRequestPathInfo();
}
protected MockHttpSession newMockHttpSession() {
return new MockHttpSession();
}
protected MockRequestPathInfo newMockRequestPathInfo() {
return new MockRequestPathInfo();
}
@Override
public ResourceResolver getResourceResolver() {
return this.resourceResolver;
}
@Override
public HttpSession getSession() {
return getSession(true);
}
@Override
public HttpSession getSession(boolean create) {
if (this.session == null && create) {
this.session = newMockHttpSession();
}
return this.session;
}
@Override
public RequestPathInfo getRequestPathInfo() {
return this.requestPathInfo;
}
@Override
public Object getAttribute(String name) {
return this.attributeMap.get(name);
}
@SuppressWarnings("unchecked")
@Override
public Enumeration<String> getAttributeNames() {
return IteratorUtils.asEnumeration(this.attributeMap.keySet().iterator());
}
@Override
public void removeAttribute(String name) {
this.attributeMap.remove(name);
}
@Override
public void setAttribute(String name, Object object) {
this.attributeMap.put(name, object);
}
@Override
public Resource getResource() {
return this.resource;
}
public void setResource(Resource resource) {
this.resource = resource;
}
@Override
public String getParameter(String name) {
Object object = this.parameterMap.get(name);
if (object instanceof String) {
return (String) object;
} else if (object instanceof String[]) {
String[] values = (String[]) object;
if (values.length > 0) {
return values[0];
}
}
return null;
}
@Override
public Map<String, String[]> getParameterMap() {
return this.parameterMap;
}
@SuppressWarnings("unchecked")
@Override
public Enumeration<String> getParameterNames() {
return IteratorUtils.asEnumeration(this.parameterMap.keySet().iterator());
}
@Override
public String[] getParameterValues(String name) { // NOPMD
Object object = this.parameterMap.get(name);
if (object instanceof String) {
return new String[] { (String) object };
} else if (object instanceof String[]) {
return (String[]) object;
}
return null; // NOPMD
}
/**
* @param parameterMap Map of parameters
*/
public void setParameterMap(Map<String, Object> parameterMap) {
this.parameterMap.clear();
for (Map.Entry<String, Object> entry : parameterMap.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
if (value instanceof String[]) {
this.parameterMap.put(key, (String[]) value);
} else if (value != null) {
this.parameterMap.put(key, new String[] { value.toString() });
} else {
this.parameterMap.put(key, null);
}
}
try {
this.queryString = formatQueryString(this.parameterMap);
} catch (UnsupportedEncodingException ex) {
throw new RuntimeException(ex);
}
}
private String formatQueryString(Map<String, String[]> map) throws UnsupportedEncodingException {
StringBuilder querystring = new StringBuilder();
for (Map.Entry<String, String[]> entry : this.parameterMap.entrySet()) {
if (entry.getValue() != null) {
for (String value : entry.getValue()) {
if (querystring.length() != 0) {
querystring.append('&');
}
querystring.append(URLEncoder.encode(entry.getKey(), CharEncoding.UTF_8));
querystring.append('=');
if (value != null) {
querystring.append(URLEncoder.encode(value, CharEncoding.UTF_8));
}
}
}
}
if (querystring.length() > 0) {
return querystring.toString();
} else {
return null;
}
}
@Override
public Locale getLocale() {
return locale;
}
/**
* @param loc Request locale
*/
public void setLocale(Locale loc) {
this.locale = loc;
}
@Override
public String getContextPath() {
return this.contextPath;
}
/**
* @param contextPath Webapp context path
*/
public void setContextPath(String contextPath) {
this.contextPath = contextPath;
}
/**
* @param queryString Query string (with proper URL encoding)
*/
public void setQueryString(String queryString) {
this.queryString = queryString;
try {
parseQueryString(this.parameterMap, this.queryString);
} catch (UnsupportedEncodingException ex) {
throw new RuntimeException(ex);
}
}
private void parseQueryString(Map<String, String[]> map, String query) throws UnsupportedEncodingException {
Map<String, List<String>> queryPairs = new LinkedHashMap<String, List<String>>();
String[] pairs = query.split("&");
for (String pair : pairs) {
int idx = pair.indexOf('=');
String key = idx > 0 ? URLDecoder.decode(pair.substring(0, idx), CharEncoding.UTF_8) : pair;
if (!queryPairs.containsKey(key)) {
queryPairs.put(key, new ArrayList<String>());
}
String value = idx > 0 && pair.length() > idx + 1 ? URLDecoder.decode(pair.substring(idx + 1),
CharEncoding.UTF_8) : null;
queryPairs.get(key).add(value);
}
map.clear();
for (Map.Entry<String, List<String>> entry : queryPairs.entrySet()) {
map.put(entry.getKey(), entry.getValue().toArray(new String[entry.getValue().size()]));
}
}
@Override
public String getQueryString() {
return this.queryString;
}
@Override
public String getScheme() {
return this.scheme;
}
public void setScheme(String scheme) {
this.scheme = scheme;
}
@Override
public String getServerName() {
return this.serverName;
}
public void setServerName(String serverName) {
this.serverName = serverName;
}
@Override
public int getServerPort() {
return this.serverPort;
}
public void setServerPort(int serverPort) {
this.serverPort = serverPort;
}
@Override
public boolean isSecure() {
return StringUtils.equals("https", getScheme());
}
@Override
public String getMethod() {
return this.method;
}
public void setMethod(String method) {
this.method = method;
}
@Override
public long getDateHeader(String name) {
return headerSupport.getDateHeader(name);
}
@Override
public String getHeader(String name) {
return headerSupport.getHeader(name);
}
@Override
public Enumeration<String> getHeaderNames() {
return HeaderSupport.toEnumeration(headerSupport.getHeaderNames());
}
@Override
public Enumeration<String> getHeaders(String name) {
return HeaderSupport.toEnumeration(headerSupport.getHeaders(name));
}
@Override
public int getIntHeader(String name) {
return headerSupport.getIntHeader(name);
}
/**
* Add header, keep existing ones with same name.
* @param name Header name
* @param value Header value
*/
public void addHeader(String name, String value) {
headerSupport.addHeader(name, value);
}
/**
* Add header, keep existing ones with same name.
* @param name Header name
* @param value Header value
*/
public void addIntHeader(String name, int value) {
headerSupport.addIntHeader(name, value);
}
/**
* Add header, keep existing ones with same name.
* @param name Header name
* @param date Header value
*/
public void addDateHeader(String name, long date) {
headerSupport.addDateHeader(name, date);
}
/**
* Set header, overwrite existing ones with same name.
* @param name Header name
* @param value Header value
*/
public void setHeader(String name, String value) {
headerSupport.setHeader(name, value);
}
/**
* Set header, overwrite existing ones with same name.
* @param name Header name
* @param value Header value
*/
public void setIntHeader(String name, int value) {
headerSupport.setIntHeader(name, value);
}
/**
* Set header, overwrite existing ones with same name.
* @param name Header name
* @param date Header value
*/
public void setDateHeader(String name, long date) {
headerSupport.setDateHeader(name, date);
}
@Override
public Cookie getCookie(String name) {
return cookieSupport.getCookie(name);
}
@Override
public Cookie[] getCookies() {
return cookieSupport.getCookies();
}
/**
* Set cookie
* @param cookie Cookie
*/
public void addCookie(Cookie cookie) {
cookieSupport.addCookie(cookie);
}
@Override
public ResourceBundle getResourceBundle(Locale locale) {
return getResourceBundle(null, locale);
}
@Override
public ResourceBundle getResourceBundle(String baseName, Locale locale) {
return EMPTY_RESOURCE_BUNDLE;
}
@Override
public RequestParameter getRequestParameter(String name) {
String value = getParameter(name);
if (value != null) {
return new MockRequestParameter(name, value);
}
return null;
}
@Override
public RequestParameterMap getRequestParameterMap() {
MockRequestParameterMap map = new MockRequestParameterMap();
for (Map.Entry<String,String[]> entry : getParameterMap().entrySet()) {
map.put(entry.getKey(), getRequestParameters(entry.getKey()));
}
return map;
}
@Override
public RequestParameter[] getRequestParameters(String name) {
String[] values = getParameterValues(name);
if (values == null) {
return null;
}
RequestParameter[] requestParameters = new RequestParameter[values.length];
for (int i = 0; i < values.length; i++) {
requestParameters[i] = new MockRequestParameter(name, values[i]);
}
return requestParameters;
}
// part of Sling API 2.7
public List<RequestParameter> getRequestParameterList() {
List<RequestParameter> params = new ArrayList<RequestParameter>();
for (RequestParameter[] requestParameters : getRequestParameterMap().values()) {
params.addAll(Arrays.asList(requestParameters));
}
return params;
}
@Override
public String getCharacterEncoding() {
return this.characterEncoding;
}
@Override
public void setCharacterEncoding(String charset) {
this.characterEncoding = charset;
}
@Override
public String getContentType() {
if (this.contentType == null) {
return null;
} else {
return this.contentType
+ (StringUtils.isNotBlank(characterEncoding) ? CHARSET_SEPARATOR + characterEncoding : "");
}
}
public void setContentType(String type) {
this.contentType = type;
if (StringUtils.contains(this.contentType, CHARSET_SEPARATOR)) {
this.characterEncoding = StringUtils.substringAfter(this.contentType, CHARSET_SEPARATOR);
this.contentType = StringUtils.substringBefore(this.contentType, CHARSET_SEPARATOR);
}
}
@Override
public ServletInputStream getInputStream() {
if (content == null) {
return null;
}
return new ServletInputStream() {
private final InputStream is = new ByteArrayInputStream(content);
@Override
public int read() throws IOException {
return is.read();
}
};
}
@Override
public int getContentLength() {
if (content == null) {
return 0;
}
return content.length;
}
public void setContent(byte[] content) {
this.content = content;
}
@Override
public RequestDispatcher getRequestDispatcher(String path) {
if (requestDispatcherFactory == null) {
throw new IllegalStateException("Please provdide a MockRequestDispatcherFactory (setRequestDispatcherFactory).");
}
return requestDispatcherFactory.getRequestDispatcher(path, null);
}
@Override
public RequestDispatcher getRequestDispatcher(String path, RequestDispatcherOptions options) {
if (requestDispatcherFactory == null) {
throw new IllegalStateException("Please provdide a MockRequestDispatcherFactory (setRequestDispatcherFactory).");
}
return requestDispatcherFactory.getRequestDispatcher(path, options);
}
@Override
public RequestDispatcher getRequestDispatcher(Resource resource) {
if (requestDispatcherFactory == null) {
throw new IllegalStateException("Please provdide a MockRequestDispatcherFactory (setRequestDispatcherFactory).");
}
return requestDispatcherFactory.getRequestDispatcher(resource, null);
}
@Override
public RequestDispatcher getRequestDispatcher(Resource resource, RequestDispatcherOptions options) {
if (requestDispatcherFactory == null) {
throw new IllegalStateException("Please provdide a MockRequestDispatcherFactory (setRequestDispatcherFactory).");
}
return requestDispatcherFactory.getRequestDispatcher(resource, options);
}
public void setRequestDispatcherFactory(MockRequestDispatcherFactory requestDispatcherFactory) {
this.requestDispatcherFactory = requestDispatcherFactory;
}
@Override
public String getRemoteUser() {
return remoteUser;
}
public void setRemoteUser(String remoteUser) {
this.remoteUser = remoteUser;
}
@Override
public String getRemoteAddr() {
return remoteAddr;
}
public void setRemoteAddr(String remoteAddr) {
this.remoteAddr = remoteAddr;
}
@Override
public String getRemoteHost() {
return remoteHost;
}
public void setRemoteHost(String remoteHost) {
this.remoteHost = remoteHost;
}
@Override
public int getRemotePort() {
return remotePort;
}
public void setRemotePort(int remotePort) {
this.remotePort = remotePort;
}
@Override
public String getServletPath() {
return this.servletPath;
}
public void setServletPath(String servletPath) {
this.servletPath = servletPath;
}
@Override
public String getPathInfo() {
if (this.pathInfo != null) {
return this.pathInfo;
}
RequestPathInfo requestPathInfo = this.getRequestPathInfo();
if (StringUtils.isEmpty(requestPathInfo.getResourcePath())) {
return null;
}
StringBuilder pathInfo = new StringBuilder();
pathInfo.append(requestPathInfo.getResourcePath());
if (StringUtils.isNotEmpty(requestPathInfo.getSelectorString())) {
pathInfo.append('.');
pathInfo.append(requestPathInfo.getSelectorString());
}
if (StringUtils.isNotEmpty(requestPathInfo.getExtension())) {
pathInfo.append('.');
pathInfo.append(requestPathInfo.getExtension());
}
if (StringUtils.isNotEmpty(requestPathInfo.getSuffix())) {
pathInfo.append(requestPathInfo.getSuffix());
}
return pathInfo.toString();
}
public void setPathInfo(String pathInfo) {
this.pathInfo = pathInfo;
}
@Override
public String getRequestURI() {
StringBuilder requestUri = new StringBuilder();
if (StringUtils.isNotEmpty(this.getServletPath())) {
requestUri.append(this.getServletPath());
}
if (StringUtils.isNotEmpty(this.getPathInfo())) {
requestUri.append(this.getPathInfo());
}
if (StringUtils.isEmpty(requestUri)) {
return "/";
} else {
return requestUri.toString();
}
}
@Override
public StringBuffer getRequestURL() {
StringBuffer requestUrl = new StringBuffer();
requestUrl.append(this.getScheme());
requestUrl.append("://");
requestUrl.append(getServerName());
if ((StringUtils.equals(this.getScheme(), "http") && this.getServerPort() != 80) ||
(StringUtils.equals(this.getScheme(), "https") && this.getServerPort() != 443)) {
requestUrl.append(':');
requestUrl.append(getServerPort());
}
requestUrl.append(getRequestURI());
return requestUrl;
}
@Override
public String getAuthType() {
return this.authType;
}
public void setAuthType(String authType) {
this.authType = authType;
}
// --- unsupported operations ---
@Override
public RequestProgressTracker getRequestProgressTracker() {
throw new UnsupportedOperationException();
}
@Override
public String getResponseContentType() {
throw new UnsupportedOperationException();
}
@Override
public Enumeration<String> getResponseContentTypes() {
throw new UnsupportedOperationException();
}
@Override
public String getPathTranslated() {
throw new UnsupportedOperationException();
}
@Override
public String getRequestedSessionId() {
throw new UnsupportedOperationException();
}
@Override
public Principal getUserPrincipal() {
throw new UnsupportedOperationException();
}
@Override
public boolean isRequestedSessionIdFromCookie() {
throw new UnsupportedOperationException();
}
@Override
public boolean isRequestedSessionIdFromURL() {
throw new UnsupportedOperationException();
}
@Override
public boolean isRequestedSessionIdFromUrl() {
throw new UnsupportedOperationException();
}
@Override
public boolean isRequestedSessionIdValid() {
throw new UnsupportedOperationException();
}
@Override
public boolean isUserInRole(String role) {
throw new UnsupportedOperationException();
}
@Override
public String getLocalAddr() {
throw new UnsupportedOperationException();
}
@Override
public String getLocalName() {
throw new UnsupportedOperationException();
}
@Override
public int getLocalPort() {
throw new UnsupportedOperationException();
}
@Override
public Enumeration<Locale> getLocales() {
throw new UnsupportedOperationException();
}
@Override
public String getProtocol() {
throw new UnsupportedOperationException();
}
@Override
public BufferedReader getReader() {
throw new UnsupportedOperationException();
}
@Override
public String getRealPath(String path) {
throw new UnsupportedOperationException();
}
@Override
public boolean authenticate(HttpServletResponse response) {
throw new UnsupportedOperationException();
}
@Override
public void login(String pUsername, String password) {
throw new UnsupportedOperationException();
}
@Override
public void logout() throws ServletException {
throw new UnsupportedOperationException();
}
@Override
public Collection<Part> getParts() {
throw new UnsupportedOperationException();
}
@Override
public Part getPart(String name) {
throw new UnsupportedOperationException();
}
@Override
public ServletContext getServletContext() {
throw new UnsupportedOperationException();
}
@Override
public AsyncContext startAsync() {
throw new UnsupportedOperationException();
}
@Override
public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse) {
throw new UnsupportedOperationException();
}
@Override
public boolean isAsyncStarted() {
throw new UnsupportedOperationException();
}
@Override
public boolean isAsyncSupported() {
throw new UnsupportedOperationException();
}
@Override
public AsyncContext getAsyncContext() {
throw new UnsupportedOperationException();
}
@Override
public DispatcherType getDispatcherType() {
throw new UnsupportedOperationException();
}
}