Support for Servlet 4.0 (PushBuilder argument, MockServletContext)
Issue: SPR-12674
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -26,9 +26,7 @@ import javax.servlet.jsp.tagext.BodyContent;
|
||||
|
||||
/**
|
||||
* Mock implementation of the {@link javax.servlet.jsp.tagext.BodyContent} class.
|
||||
*
|
||||
* <p>Used for testing the web framework; only necessary for testing
|
||||
* applications when testing custom JSP tags.
|
||||
* Only necessary for testing applications when testing custom JSP tags.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.5
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,12 +21,12 @@ import javax.servlet.jsp.PageContext;
|
||||
|
||||
import org.apache.taglibs.standard.lang.support.ExpressionEvaluatorManager;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Mock implementation of the JSP 2.0 {@link javax.servlet.jsp.el.ExpressionEvaluator}
|
||||
* interface, delegating to the Apache JSTL ExpressionEvaluatorManager.
|
||||
*
|
||||
* <p>Used for testing the web framework; only necessary for testing applications
|
||||
* when testing custom JSP tags.
|
||||
* Only necessary for testing applications when testing custom JSP tags.
|
||||
*
|
||||
* <p>Note that the Apache JSTL implementation (jstl.jar, standard.jar) has to be
|
||||
* available on the class path to use this expression evaluator.
|
||||
@@ -68,9 +68,7 @@ public class MockExpressionEvaluator extends javax.servlet.jsp.el.ExpressionEval
|
||||
public Object evaluate(String expression, Class expectedType, javax.servlet.jsp.el.VariableResolver variableResolver,
|
||||
javax.servlet.jsp.el.FunctionMapper functionMapper) throws javax.servlet.jsp.el.ELException {
|
||||
|
||||
if (variableResolver != null) {
|
||||
throw new IllegalArgumentException("Custom VariableResolver not supported");
|
||||
}
|
||||
Assert.isNull(variableResolver, "Custom VariableResolver not supported");
|
||||
return doEvaluate(expression, expectedType, functionMapper);
|
||||
}
|
||||
|
||||
@@ -78,9 +76,7 @@ public class MockExpressionEvaluator extends javax.servlet.jsp.el.ExpressionEval
|
||||
protected Object doEvaluate(String expression, Class expectedType, javax.servlet.jsp.el.FunctionMapper functionMapper)
|
||||
throws javax.servlet.jsp.el.ELException {
|
||||
|
||||
if (functionMapper != null) {
|
||||
throw new IllegalArgumentException("Custom FunctionMapper not supported");
|
||||
}
|
||||
Assert.isNull(functionMapper, "Custom FunctionMapper not supported");
|
||||
try {
|
||||
return ExpressionEvaluatorManager.evaluate("JSP EL expression", expression, expectedType, this.pageContext);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -33,9 +33,7 @@ import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* <p>Mock implementation of the {@link javax.servlet.FilterChain} interface. Used
|
||||
* for testing the web framework; also useful for testing custom
|
||||
* {@link javax.servlet.Filter} implementations.
|
||||
* Mock implementation of the {@link javax.servlet.FilterChain} interface.
|
||||
*
|
||||
* <p>A {@link MockFilterChain} can be configured with one or more filters and a
|
||||
* Servlet to invoke. The first time the chain is called, it invokes all filters
|
||||
@@ -120,10 +118,7 @@ public class MockFilterChain implements FilterChain {
|
||||
public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
|
||||
Assert.notNull(request, "Request must not be null");
|
||||
Assert.notNull(response, "Response must not be null");
|
||||
|
||||
if (this.request != null) {
|
||||
throw new IllegalStateException("This FilterChain has already been called!");
|
||||
}
|
||||
Assert.state(this.request == null, "This FilterChain has already been called!");
|
||||
|
||||
if (this.iterator == null) {
|
||||
this.iterator = this.filters.iterator();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -70,7 +70,7 @@ import org.springframework.util.StringUtils;
|
||||
* is {@link Locale#ENGLISH}. This value can be changed via {@link #addPreferredLocale}
|
||||
* or {@link #setPreferredLocales}.
|
||||
*
|
||||
* <p>As of Spring Framework 5.0, this set of mocks is designed on a Servlet 3.1 baseline.
|
||||
* <p>As of Spring Framework 5.0, this set of mocks is designed on a Servlet 4.0 baseline.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Rod Johnson
|
||||
|
||||
@@ -45,7 +45,7 @@ import org.springframework.web.util.WebUtils;
|
||||
/**
|
||||
* Mock implementation of the {@link javax.servlet.http.HttpServletResponse} interface.
|
||||
*
|
||||
* <p>As of Spring Framework 5.0, this set of mocks is designed on a Servlet 3.1 baseline.
|
||||
* <p>As of Spring Framework 5.0, this set of mocks is designed on a Servlet 4.0 baseline.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Rod Johnson
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -34,10 +34,7 @@ import org.springframework.util.Assert;
|
||||
/**
|
||||
* Mock implementation of the {@link javax.servlet.http.HttpSession} interface.
|
||||
*
|
||||
* <p>As of Spring 4.0, this set of mocks is designed on a Servlet 3.0 baseline.
|
||||
*
|
||||
* <p>Used for testing the web framework; also useful for testing application
|
||||
* controllers.
|
||||
* <p>As of Spring 5.0, this set of mocks is designed on a Servlet 4.0 baseline.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Rod Johnson
|
||||
@@ -72,7 +69,6 @@ public class MockHttpSession implements HttpSession {
|
||||
|
||||
/**
|
||||
* Create a new MockHttpSession with a default {@link MockServletContext}.
|
||||
*
|
||||
* @see MockServletContext
|
||||
*/
|
||||
public MockHttpSession() {
|
||||
@@ -81,7 +77,6 @@ public class MockHttpSession implements HttpSession {
|
||||
|
||||
/**
|
||||
* Create a new MockHttpSession.
|
||||
*
|
||||
* @param servletContext the ServletContext that the session runs in
|
||||
*/
|
||||
public MockHttpSession(ServletContext servletContext) {
|
||||
@@ -90,7 +85,6 @@ public class MockHttpSession implements HttpSession {
|
||||
|
||||
/**
|
||||
* Create a new MockHttpSession.
|
||||
*
|
||||
* @param servletContext the ServletContext that the session runs in
|
||||
* @param id a unique identifier for this session
|
||||
*/
|
||||
@@ -99,6 +93,7 @@ public class MockHttpSession implements HttpSession {
|
||||
this.id = (id != null ? id : Integer.toString(nextId++));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public long getCreationTime() {
|
||||
assertIsValid();
|
||||
@@ -111,8 +106,8 @@ public class MockHttpSession implements HttpSession {
|
||||
}
|
||||
|
||||
/**
|
||||
* As of Servlet 3.1 the id of a session can be changed.
|
||||
* @return the new session id.
|
||||
* As of Servlet 3.1, the id of a session can be changed.
|
||||
* @return the new session id
|
||||
* @since 4.0.3
|
||||
*/
|
||||
public String changeSessionId() {
|
||||
@@ -227,7 +222,6 @@ public class MockHttpSession implements HttpSession {
|
||||
|
||||
/**
|
||||
* Invalidates this session then unbinds any objects bound to it.
|
||||
*
|
||||
* @throws IllegalStateException if this method is called on an already invalidated session
|
||||
*/
|
||||
@Override
|
||||
@@ -244,13 +238,10 @@ public class MockHttpSession implements HttpSession {
|
||||
/**
|
||||
* Convenience method for asserting that this session has not been
|
||||
* {@linkplain #invalidate() invalidated}.
|
||||
*
|
||||
* @throws IllegalStateException if this session has been invalidated
|
||||
*/
|
||||
private void assertIsValid() {
|
||||
if (isInvalid()) {
|
||||
throw new IllegalStateException("The session has already been invalidated");
|
||||
}
|
||||
Assert.state(!isInvalid(), "The session has already been invalidated");
|
||||
}
|
||||
|
||||
public void setNew(boolean value) {
|
||||
@@ -266,7 +257,6 @@ public class MockHttpSession implements HttpSession {
|
||||
/**
|
||||
* Serialize the attributes of this session into an object that can be
|
||||
* turned into a byte array with standard Java serialization.
|
||||
*
|
||||
* @return a representation of this session's serialized state
|
||||
*/
|
||||
public Serializable serializeState() {
|
||||
@@ -293,7 +283,6 @@ public class MockHttpSession implements HttpSession {
|
||||
/**
|
||||
* Deserialize the attributes of this session from a state object created by
|
||||
* {@link #serializeState()}.
|
||||
*
|
||||
* @param state a representation of this session's serialized state
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -24,9 +24,7 @@ import javax.servlet.jsp.JspWriter;
|
||||
|
||||
/**
|
||||
* Mock implementation of the {@link javax.servlet.jsp.JspWriter} class.
|
||||
*
|
||||
* <p>Used for testing the web framework; only necessary for testing
|
||||
* applications when testing custom JSP tags.
|
||||
* Only necessary for testing applications when testing custom JSP tags.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.5
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -35,11 +35,10 @@ import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||
* Mock implementation of the
|
||||
* {@link org.springframework.web.multipart.MultipartHttpServletRequest} interface.
|
||||
*
|
||||
* <p>As of Spring 4.0, this set of mocks is designed on a Servlet 3.0 baseline.
|
||||
* <p>As of Spring 5.0, this set of mocks is designed on a Servlet 4.0 baseline.
|
||||
*
|
||||
* <p>Useful for testing application controllers that access multipart uploads.
|
||||
* The {@link MockMultipartFile} can be used to populate these mock requests
|
||||
* with files.
|
||||
* {@link MockMultipartFile} can be used to populate these mock requests with files.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Eric Crampton
|
||||
@@ -49,8 +48,7 @@ import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||
*/
|
||||
public class MockMultipartHttpServletRequest extends MockHttpServletRequest implements MultipartHttpServletRequest {
|
||||
|
||||
private final MultiValueMap<String, MultipartFile> multipartFiles =
|
||||
new LinkedMultiValueMap<>();
|
||||
private final MultiValueMap<String, MultipartFile> multipartFiles = new LinkedMultiValueMap<>();
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -40,9 +40,7 @@ import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Mock implementation of the {@link javax.servlet.jsp.PageContext} interface.
|
||||
*
|
||||
* <p>Used for testing the web framework; only necessary for testing
|
||||
* applications when testing custom JSP tags.
|
||||
* Only necessary for testing applications when testing custom JSP tags.
|
||||
*
|
||||
* <p>Note: Expects initialization via the constructor rather than via the
|
||||
* {@code PageContext.initialize} method. Does not support writing to a
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -29,9 +29,6 @@ import org.springframework.util.Assert;
|
||||
/**
|
||||
* Mock implementation of the {@link javax.servlet.RequestDispatcher} interface.
|
||||
*
|
||||
* <p>Used for testing the web framework; typically not necessary for
|
||||
* testing application controllers.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
* @author Sam Brannen
|
||||
@@ -50,7 +47,7 @@ public class MockRequestDispatcher implements RequestDispatcher {
|
||||
* particular path or given by a particular name
|
||||
*/
|
||||
public MockRequestDispatcher(String resource) {
|
||||
Assert.notNull(resource, "resource must not be null");
|
||||
Assert.notNull(resource, "Resource must not be null");
|
||||
this.resource = resource;
|
||||
}
|
||||
|
||||
@@ -59,9 +56,7 @@ public class MockRequestDispatcher implements RequestDispatcher {
|
||||
public void forward(ServletRequest request, ServletResponse response) {
|
||||
Assert.notNull(request, "Request must not be null");
|
||||
Assert.notNull(response, "Response must not be null");
|
||||
if (response.isCommitted()) {
|
||||
throw new IllegalStateException("Cannot perform forward - response is already committed");
|
||||
}
|
||||
Assert.state(!response.isCommitted(), "Cannot perform forward - response is already committed");
|
||||
getMockHttpServletResponse(response).setForwardedUrl(this.resource);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("MockRequestDispatcher: forwarding to [" + this.resource + "]");
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -28,9 +28,6 @@ import org.springframework.util.Assert;
|
||||
/**
|
||||
* Mock implementation of the {@link javax.servlet.ServletConfig} interface.
|
||||
*
|
||||
* <p>Used for testing the web framework; typically not necessary for
|
||||
* testing application controllers.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
* @since 1.0.2
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -55,37 +55,21 @@ import org.springframework.web.util.WebUtils;
|
||||
/**
|
||||
* Mock implementation of the {@link javax.servlet.ServletContext} interface.
|
||||
*
|
||||
* <p>As of Spring 4.0, this set of mocks is designed on a Servlet 3.0 baseline.
|
||||
* <p>As of Spring 5.0, this set of mocks is designed on a Servlet 4.0 baseline.
|
||||
*
|
||||
* <p>Compatible with Servlet 3.0 but can be configured to expose a specific version
|
||||
* through {@link #setMajorVersion}/{@link #setMinorVersion}; default is 3.0.
|
||||
* Note that Servlet 3.0 support is limited: servlet, filter and listener
|
||||
* <p>Compatible with Servlet 3.1 but can be configured to expose a specific version
|
||||
* through {@link #setMajorVersion}/{@link #setMinorVersion}; default is 3.1.
|
||||
* Note that Servlet 3.1 support is limited: servlet, filter and listener
|
||||
* registration methods are not supported; neither is JSP configuration.
|
||||
* We generally do not recommend to unit test your ServletContainerInitializers and
|
||||
* WebApplicationInitializers which is where those registration methods would be used.
|
||||
*
|
||||
* <p>Used for testing the Spring web framework; only rarely necessary for testing
|
||||
* application controllers. As long as application components don't explicitly
|
||||
* access the {@code ServletContext}, {@code ClassPathXmlApplicationContext} or
|
||||
* {@code FileSystemXmlApplicationContext} can be used to load the context files
|
||||
* for testing, even for {@code DispatcherServlet} context definitions.
|
||||
*
|
||||
* <p>For setting up a full {@code WebApplicationContext} in a test environment,
|
||||
* you can use {@code AnnotationConfigWebApplicationContext},
|
||||
* {@code XmlWebApplicationContext}, or {@code GenericWebApplicationContext},
|
||||
* passing in an appropriate {@code MockServletContext} instance. You might want
|
||||
* to configure your {@code MockServletContext} with a {@code FileSystemResourceLoader}
|
||||
* in that case to ensure that resource paths are interpreted as relative filesystem
|
||||
* locations.
|
||||
*
|
||||
* <p>A common setup is to point your JVM working directory to the root of your
|
||||
* web application directory, in combination with filesystem-based resource loading.
|
||||
* This allows to load the context files as used in the web application, with
|
||||
* relative paths getting interpreted correctly. Such a setup will work with both
|
||||
* {@code FileSystemXmlApplicationContext} (which will load straight from the
|
||||
* filesystem) and {@code XmlWebApplicationContext} with an underlying
|
||||
* {@code MockServletContext} (as long as the {@code MockServletContext} has been
|
||||
* configured with a {@code FileSystemResourceLoader}).
|
||||
* <p>For setting up a full {@code WebApplicationContext} in a test environment, you can
|
||||
* use {@code AnnotationConfigWebApplicationContext}, {@code XmlWebApplicationContext},
|
||||
* or {@code GenericWebApplicationContext}, passing in a corresponding
|
||||
* {@code MockServletContext} instance. Consider configuring your
|
||||
* {@code MockServletContext} with a {@code FileSystemResourceLoader} in order to
|
||||
* interpret resource paths as relative filesystem locations.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
@@ -95,18 +79,15 @@ import org.springframework.web.util.WebUtils;
|
||||
* @see org.springframework.web.context.support.AnnotationConfigWebApplicationContext
|
||||
* @see org.springframework.web.context.support.XmlWebApplicationContext
|
||||
* @see org.springframework.web.context.support.GenericWebApplicationContext
|
||||
* @see org.springframework.context.support.ClassPathXmlApplicationContext
|
||||
* @see org.springframework.context.support.FileSystemXmlApplicationContext
|
||||
*/
|
||||
public class MockServletContext implements ServletContext {
|
||||
|
||||
/** Default Servlet name used by Tomcat, Jetty, JBoss, and GlassFish: {@value}. */
|
||||
/** Default Servlet name used by Tomcat, Jetty, JBoss, and GlassFish: {@value} */
|
||||
private static final String COMMON_DEFAULT_SERVLET_NAME = "default";
|
||||
|
||||
private static final String TEMP_DIR_SYSTEM_PROPERTY = "java.io.tmpdir";
|
||||
|
||||
private static final Set<SessionTrackingMode> DEFAULT_SESSION_TRACKING_MODES =
|
||||
new LinkedHashSet<>(3);
|
||||
private static final Set<SessionTrackingMode> DEFAULT_SESSION_TRACKING_MODES = new LinkedHashSet<>(4);
|
||||
|
||||
static {
|
||||
DEFAULT_SESSION_TRACKING_MODES.add(SessionTrackingMode.COOKIE);
|
||||
@@ -127,11 +108,11 @@ public class MockServletContext implements ServletContext {
|
||||
|
||||
private int majorVersion = 3;
|
||||
|
||||
private int minorVersion = 0;
|
||||
private int minorVersion = 1;
|
||||
|
||||
private int effectiveMajorVersion = 3;
|
||||
|
||||
private int effectiveMinorVersion = 0;
|
||||
private int effectiveMinorVersion = 1;
|
||||
|
||||
private final Map<String, RequestDispatcher> namedRequestDispatchers = new HashMap<>();
|
||||
|
||||
@@ -149,6 +130,8 @@ public class MockServletContext implements ServletContext {
|
||||
|
||||
private final SessionCookieConfig sessionCookieConfig = new MockSessionCookieConfig();
|
||||
|
||||
private int sessionTimeout;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new {@code MockServletContext}, using no base path and a
|
||||
@@ -425,13 +408,13 @@ public class MockServletContext implements ServletContext {
|
||||
@Override
|
||||
@Deprecated
|
||||
public Enumeration<Servlet> getServlets() {
|
||||
return Collections.enumeration(Collections.<Servlet>emptySet());
|
||||
return Collections.enumeration(Collections.emptySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public Enumeration<String> getServletNames() {
|
||||
return Collections.enumeration(Collections.<String>emptySet());
|
||||
return Collections.enumeration(Collections.emptySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -570,6 +553,16 @@ public class MockServletContext implements ServletContext {
|
||||
return this.sessionCookieConfig;
|
||||
}
|
||||
|
||||
// @Override - but only against Servlet 4.0
|
||||
public void setSessionTimeout(int sessionTimeout) {
|
||||
this.sessionTimeout = sessionTimeout;
|
||||
}
|
||||
|
||||
// @Override - but only against Servlet 4.0
|
||||
public int getSessionTimeout() {
|
||||
return this.sessionTimeout;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Unsupported Servlet 3.0 registration methods
|
||||
@@ -580,6 +573,11 @@ public class MockServletContext implements ServletContext {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
// @Override - but only against Servlet 4.0
|
||||
public ServletRegistration.Dynamic addJspFile(String servletName, String jspFile) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServletRegistration.Dynamic addServlet(String servletName, String className) {
|
||||
throw new UnsupportedOperationException();
|
||||
|
||||
Reference in New Issue
Block a user