You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shiro.apache.org by lh...@apache.org on 2010/05/17 22:33:13 UTC

svn commit: r945349 [2/2] - in /incubator/shiro/trunk: core/src/main/java/org/apache/shiro/authz/ core/src/main/java/org/apache/shiro/mgt/ core/src/main/java/org/apache/shiro/session/ core/src/main/java/org/apache/shiro/session/mgt/ core/src/main/java/...

Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/WebUtils.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/WebUtils.java?rev=945349&r1=945348&r2=945349&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/WebUtils.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/WebUtils.java Mon May 17 20:33:12 2010
@@ -432,13 +432,7 @@ public class WebUtils {
      * It is the case in certain enterprise environments where a web-enabled SecurityManager (and its internal mechanisms)
      * is the primary SecurityManager but also serves as a 'central' coordinator for security operations in a cluster.
      * In these environments, it is possible for a web-enabled SecurityManager to receive remote method invocations that
-     * are not HTTP based.
-     * <p/>
-     * In these environments, we need to acquire a thread-bound ServletRequest if it exists, but
-     * not throw an exception if one is not found (with the assumption that the incoming call is not a web request but
-     * instead a remote method invocation).  This method exists to support these environments, whereas the
-     * {@link #getRequiredServletRequest() getRequiredServletRequest()} method always assumes a
-     * servlet-only environment.
+     * are not HTTP based.  In such an environment this method would return {@code null}.
      * <p/>
      * <b>THIS IS NOT PART OF APACHE SHIRO'S PUBLIC API.</b>  It exists for Shiro implementation requirements only.
      *
@@ -446,30 +440,13 @@ public class WebUtils {
      * @since 1.0
      */
     public static ServletRequest getServletRequest() {
-        return (ServletRequest) ThreadContext.get(SERVLET_REQUEST_KEY);
-    }
-
-    /**
-     * Convenience method that simplifies retrieval of a required thread-bound ServletRequest.  If there is no
-     * ServletRequest bound to the thread when this method is called, an <code>IllegalStateException</code> is
-     * thrown.
-     * <p/>
-     * This method is basically a convenient wrapper for the following:
-     * <p/>
-     * <code>(ServletRequest){@link ThreadContext#get ThreadContext.get}( SERVLET_REQUEST_KEY );</code>
-     * <p/>
-     * But throws an <code>IllegalStateException</code> if the value is not bound to the <code>ThreadContext</code>.
-     * <p/>
-     * This method only returns the bound value if it exists - it does not remove it
-     * from the thread.  To remove it, one must call {@link #unbindServletRequest() unbindServletRequest} instead.
-     *
-     * @return the ServletRequest bound to the thread.  Never returns null.
-     * @throws IllegalStateException if no servlet request is bound in the {@link org.apache.shiro.util.ThreadContext ThreadContext}.
-     */
-    public static ServletRequest getRequiredServletRequest() throws IllegalStateException {
-        ServletRequest request = getServletRequest();
+        ServletRequest request = (ServletRequest) ThreadContext.get(SERVLET_REQUEST_KEY);
         if (request == null) {
-            throw new IllegalStateException("No ServletRequest found in ThreadContext. " + NOT_BOUND_ERROR_MESSAGE);
+            Subject subject = ThreadContext.getSubject();
+            if (subject instanceof WebSubject) {
+                WebSubject webSubject = (WebSubject) subject;
+                request = webSubject.getServletRequest();
+            }
         }
         return request;
     }
@@ -495,36 +472,12 @@ public class WebUtils {
     }
 
     /**
-     * Convenience method that simplifies removal of a thread-local ServletRequest from the thread.
-     * <p/>
-     * The implementation just helps reduce casting and remembering of the ThreadContext key name, i.e it is
-     * merely a conveient wrapper for the following:
-     * <p/>
-     * <code>return (ServletRequest)ThreadContext.remove( SERVLET_REQUEST_KEY );</code>
-     * <p/>
-     * If you wish to just retrieve the object from the thread without removing it (so it can be retrieved later during
-     * thread execution), you should use the {@link #getRequiredServletRequest() getRequiredServletRequest()} method
-     * for that purpose.
-     *
-     * @return the Session object previously bound to the thread, or <tt>null</tt> if there was none bound.
-     */
-    public static ServletRequest unbindServletRequest() {
-        return (ServletRequest) ThreadContext.remove(SERVLET_REQUEST_KEY);
-    }
-
-    /**
      * Returns the current thread-bound {@code ServletResponse} or {@code null} if there is not one bound.
      * <p/>
      * It is the case in certain enterprise environments where a web-enabled SecurityManager (and its internal mechanisms)
      * is the primary SecurityManager but also serves as a 'central' coordinator for security operations in a cluster.
      * In these environments, it is possible for a web-enabled SecurityManager to receive remote method invocations that
-     * are not HTTP based.
-     * <p/>
-     * In these environments, we need to acquire a thread-bound ServletResponse if it exists, but
-     * not throw an exception if one is not found (with the assumption that the incoming call is not a web request but
-     * instead a remote method invocation).  This method exists to support these environments, whereas the
-     * {@link #getRequiredServletResponse() getRequiredServletResponse()} method always assumes a
-     * servlet-only environment.
+     * are not HTTP based.  In such an environment this method would return {@code null}.
      * <p/>
      * <b>THIS IS NOT PART OF APACHE SHIRO'S PUBLIC API.</b>  It exists for Shiro implementation requirements only.
      *
@@ -532,30 +485,13 @@ public class WebUtils {
      * @since 1.0
      */
     public static ServletResponse getServletResponse() {
-        return (ServletResponse) ThreadContext.get(SERVLET_RESPONSE_KEY);
-    }
-
-    /**
-     * Convenience method that simplifies retrieval of a required thread-bound ServletResponse.  If there is no
-     * ServletResponse bound to the thread when this method is called, an <code>IllegalStateException</code> is
-     * thrown.
-     * <p/>
-     * This method is basically a convenient wrapper for the following:
-     * <p/>
-     * <code>return (ServletResponse){@link ThreadContext#get ThreadContext.get}( SERVLET_RESPONSE_KEY );</code>
-     * <p/>
-     * But throws an <code>IllegalStateException</code> if the value is not bound to the <code>ThreadContext</code>.
-     * <p/>
-     * This method only returns the bound value if it exists - it does not remove it
-     * from the thread.  To remove it, one must call {@link #unbindServletResponse() unbindServletResponse} instead.
-     *
-     * @return the ServletResponse bound to the thread.  Never returns null.
-     * @throws IllegalStateException if no <code>ServletResponse> is bound in the {@link ThreadContext ThreadContext}
-     */
-    public static ServletResponse getRequiredServletResponse() throws IllegalStateException {
         ServletResponse response = (ServletResponse) ThreadContext.get(SERVLET_RESPONSE_KEY);
         if (response == null) {
-            throw new IllegalStateException("No ServletResponse found in ThreadContext. " + NOT_BOUND_ERROR_MESSAGE);
+            Subject subject = ThreadContext.getSubject();
+            if (subject instanceof WebSubject) {
+                WebSubject webSubject = (WebSubject) subject;
+                response = webSubject.getServletResponse();
+            }
         }
         return response;
     }
@@ -581,24 +517,6 @@ public class WebUtils {
     }
 
     /**
-     * Convenience method that simplifies removal of a thread-local ServletResponse from the thread.
-     * <p/>
-     * The implementation just helps reduce casting and remembering of the ThreadContext key name, i.e it is
-     * merely a conveient wrapper for the following:
-     * <p/>
-     * <code>return (ServletResponse)ThreadContext.remove( SERVLET_RESPONSE_KEY );</code>
-     * <p/>
-     * If you wish to just retrieve the object from the thread without removing it (so it can be retrieved later during
-     * thread execution), you should use the {@link #getRequiredServletResponse() getRequiredServletResponse()} method
-     * for that purpose.
-     *
-     * @return the Session object previously bound to the thread, or <tt>null</tt> if there was none bound.
-     */
-    public static ServletResponse unbindServletResponse() {
-        return (ServletResponse) ThreadContext.remove(SERVLET_RESPONSE_KEY);
-    }
-
-    /**
      * Redirects the current request to a new URL based on the given parameters.
      *
      * @param request          the servlet request.

Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/AbstractShiroFilter.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/AbstractShiroFilter.java?rev=945349&r1=945348&r2=945349&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/AbstractShiroFilter.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/AbstractShiroFilter.java Mon May 17 20:33:12 2010
@@ -20,15 +20,12 @@ package org.apache.shiro.web.servlet;
 
 import org.apache.shiro.SecurityUtils;
 import org.apache.shiro.session.Session;
+import org.apache.shiro.subject.ExecutionException;
 import org.apache.shiro.subject.Subject;
-import org.apache.shiro.util.ThreadContext;
-import org.apache.shiro.util.ThreadState;
 import org.apache.shiro.web.DefaultWebSecurityManager;
 import org.apache.shiro.web.WebSecurityManager;
-import org.apache.shiro.web.WebUtils;
 import org.apache.shiro.web.filter.mgt.FilterChainResolver;
 import org.apache.shiro.web.subject.WebSubject;
-import org.apache.shiro.web.subject.support.WebSubjectThreadState;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -39,6 +36,7 @@ import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
+import java.util.concurrent.Callable;
 
 /**
  * Abstract base class that provides all standard Shiro request filtering behavior and expects
@@ -192,48 +190,16 @@ public abstract class AbstractShiroFilte
     }
 
     /**
-     * Binds the current request/response pair and additional information to a thread-local to be made available to Shiro
-     * during the course of the request/response process.  This implementation binds the request/response pair and
-     * any associated Subject (and its relevant thread-based data) via a {@link org.apache.shiro.web.subject.support.WebSubjectThreadState}.  That
-     * threadState is returned so it can be used during thread cleanup at the end of the request.
-     * <p/>
-     * To guarantee properly cleaned threads in a thread-pooled Servlet Container environment, the corresponding
-     * {@link #unbind} method must be called in a {@code finally} block to ensure that the thread remains clean even
-     * in the event of an exception thrown while processing the request.  This class's
-     * {@link #doFilterInternal(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)}
-     * method implementation does indeed function this way.
+     * Creates a {@link WebSubject} instance to associate with the incoming request/response pair which will be used
+     * throughout the request/response execution.
      *
-     * @param request  the incoming ServletRequest
-     * @param response the outgoing ServletResponse
-     * @return ThreadStateManager the thread state used to bind necessary state for the request execution.
+     * @param request  the incoming {@code ServletRequest}
+     * @param response the outgoing {@code ServletResponse}
+     * @return the {@code WebSubject} instance to associate with the request/response execution
      * @since 1.0
      */
-    protected ThreadState bind(ServletRequest request, ServletResponse response) {
-        ThreadContext.bind(getSecurityManager());
-        WebUtils.bind(request);
-        WebUtils.bind(response);
-        WebSubject subject = new WebSubject.Builder(getSecurityManager(), request, response).buildWebSubject();
-        ThreadState threadState = new WebSubjectThreadState(subject);
-        threadState.bind();
-        return threadState;
-    }
-
-    /**
-     * Unbinds (removes out of scope) the current {@code ServletRequest} and {@link ServletResponse}.
-     * <p/>
-     * This method implementation merely clears <em>all</em> thread state by calling
-     * {@link org.apache.shiro.subject.support.SubjectThreadState#clear()} to guarantee
-     * that <em>everything</em> that might have been bound to the thread by Shiro has been removed to ensure the
-     * underlying Thread may be safely re-used in a thread-pooled Servlet Container environment.
-     *
-     * @param threadState the web thread state created when the request and response first were initiated.
-     * @since 1.0
-     */
-    @SuppressWarnings({"UnusedDeclaration"})
-    protected void unbind(ThreadState threadState) {
-        if ( threadState != null ) {
-            threadState.clear();
-        }
+    protected WebSubject createSubject(ServletRequest request, ServletResponse response) {
+        return new WebSubject.Builder(getSecurityManager(), request, response).buildWebSubject();
     }
 
     /**
@@ -274,41 +240,58 @@ public abstract class AbstractShiroFilte
      * the incoming {@code ServletRequest} for use during Shiro's processing</li>
      * <li>{@link #prepareServletResponse(ServletRequest, ServletResponse, FilterChain) Prepares}
      * the outgoing {@code ServletResponse} for use during Shiro's processing</li>
-     * <li>{@link #bind(ServletRequest,ServletResponse) Binds} the request/response pair
-     * and associated data to the currently executing thread for use during processing</li>
-     * <li>{@link #updateSessionLastAccessTime(javax.servlet.ServletRequest, javax.servlet.ServletResponse) Updates}
-     * any associated session's {@link org.apache.shiro.session.Session#getLastAccessTime() lastAccessTime} to ensure
-     * session timeouts are honored</li>
-     * <li>{@link #executeChain(ServletRequest,ServletResponse,FilterChain) Executes}
-     * the appropriate {@code FilterChain}</li>
-     * <li>{@link #unbind(org.apache.shiro.util.ThreadState) Unbinds} the request/response
-     * pair and any other associated data from the thread.
-     * </ul>
+     * <li> {@link #createSubject(javax.servlet.ServletRequest, javax.servlet.ServletResponse) Creates} a
+     * {@link Subject} instance based on the specified request/response pair.</li>
+     * <li>Finally {@link Subject#execute(Runnable) executes} the
+     * {@link #updateSessionLastAccessTime(javax.servlet.ServletRequest, javax.servlet.ServletResponse)} and
+     * {@link #executeChain(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)}
+     * methods</li>
+     * </ol>
      * <p/>
-     * The {@link #unbind(org.apache.shiro.util.ThreadState) unbind} method is called in a
-     * {@code finally} block to guarantee the thread may be cleanly re-used in a thread-pooled Servlet Container
-     * environment.
+     * The {@code Subject.}{@link Subject#execute(Runnable) execute(Runnable)} call in step #4 is used as an
+     * implementation technique to guarantee proper thread binding and restoration is completed successfully.
      *
      * @param servletRequest  the incoming {@code ServletRequest}
      * @param servletResponse the outgoing {@code ServletResponse}
      * @param chain           the container-provided {@code FilterChain} to execute
-     * @throws javax.servlet.ServletException if an error occurs
      * @throws IOException                    if an IO error occurs
+     * @throws javax.servlet.ServletException if an Throwable other than an IOException
      */
-    protected void doFilterInternal(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
+    protected void doFilterInternal(ServletRequest servletRequest, ServletResponse servletResponse, final FilterChain chain)
             throws ServletException, IOException {
 
-        ServletRequest request = prepareServletRequest(servletRequest, servletResponse, chain);
-        ServletResponse response = prepareServletResponse(request, servletResponse, chain);
+        Throwable t = null;
+        
+        try {
+            final ServletRequest request = prepareServletRequest(servletRequest, servletResponse, chain);
+            final ServletResponse response = prepareServletResponse(request, servletResponse, chain);
 
-        ThreadState threadState = null;
+            final Subject subject = createSubject(request, response);
 
-        try {
-            threadState = bind(request, response);
-            updateSessionLastAccessTime(request, response);
-            executeChain(request, response, chain);
-        } finally {
-            unbind(threadState);
+            //noinspection unchecked
+            subject.execute(new Callable() {
+                public Object call() throws Exception {
+                    updateSessionLastAccessTime(request, response);
+                    executeChain(request, response, chain);
+                    return null;
+                }
+            });
+        } catch (ExecutionException ex) {
+            t = ex.getCause();
+        } catch (Throwable throwable) {
+            t = throwable;
+        }
+
+        if (t != null) {
+            if (t instanceof ServletException) {
+                throw (ServletException) t;
+            }
+            if (t instanceof IOException) {
+                throw (IOException) t;
+            }
+            //otherwise it's not one of the two exceptions expected by the filter method signature - wrap it in one:
+            String msg = "Filtered request failed.";
+            throw new ServletException(msg, t);
         }
     }
 

Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/ShiroHttpSession.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/ShiroHttpSession.java?rev=945349&r1=945348&r2=945349&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/ShiroHttpSession.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/servlet/ShiroHttpSession.java Mon May 17 20:33:12 2010
@@ -20,7 +20,7 @@ package org.apache.shiro.web.servlet;
 
 import org.apache.shiro.session.InvalidSessionException;
 import org.apache.shiro.session.Session;
-import org.apache.shiro.web.session.WebSession;
+import org.apache.shiro.web.session.HttpServletSession;
 
 import javax.servlet.ServletContext;
 import javax.servlet.http.HttpServletRequest;
@@ -71,8 +71,8 @@ public class ShiroHttpSession implements
     protected Session session = null; //'real' Shiro Session
 
     public ShiroHttpSession(Session session, HttpServletRequest currentRequest, ServletContext servletContext) {
-        if (session instanceof WebSession) {
-            String msg = "Session constructor argument cannot be an instance of WebSession.  This is enforced to " +
+        if (session instanceof HttpServletSession) {
+            String msg = "Session constructor argument cannot be an instance of HttpServletSession.  This is enforced to " +
                     "prevent circular dependencies and infinite loops.";
             throw new IllegalArgumentException(msg);
         }

Added: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/DefaultWebSessionContext.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/DefaultWebSessionContext.java?rev=945349&view=auto
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/DefaultWebSessionContext.java (added)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/DefaultWebSessionContext.java Mon May 17 20:33:12 2010
@@ -0,0 +1,68 @@
+/*
+ * 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.shiro.web.session;
+
+import org.apache.shiro.session.mgt.DefaultSessionContext;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import java.util.Map;
+
+/**
+ * Default implementation of the {@link WebSessionContext} interface which provides getters and setters that
+ * wrap interaction with the underlying backing context map.
+ *
+ * @author Les Hazlewood
+ * @since 1.0
+ */
+public class DefaultWebSessionContext extends DefaultSessionContext implements WebSessionContext {
+
+    private static final long serialVersionUID = -3974604687792523072L;
+
+    private static final String SERVLET_REQUEST = DefaultWebSessionContext.class.getName() + ".SERVLET_REQUEST";
+    private static final String SERVLET_RESPONSE = DefaultWebSessionContext.class.getName() + ".SERVLET_RESPONSE";
+
+    public DefaultWebSessionContext() {
+        super();
+    }
+
+    public DefaultWebSessionContext(Map<String, Object> map) {
+        super(map);
+    }
+
+    public void setServletRequest(ServletRequest request) {
+        if (request != null) {
+            put(SERVLET_REQUEST, request);
+        }
+    }
+
+    public ServletRequest getServletRequest() {
+        return getTypedValue(SERVLET_REQUEST, ServletRequest.class);
+    }
+
+    public void setServletResponse(ServletResponse response) {
+        if (response != null) {
+            put(SERVLET_RESPONSE, response);
+        }
+    }
+
+    public ServletResponse getServletResponse() {
+        return getTypedValue(SERVLET_RESPONSE, ServletResponse.class);
+    }
+}

Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/DefaultWebSessionManager.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/DefaultWebSessionManager.java?rev=945349&r1=945348&r2=945349&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/DefaultWebSessionManager.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/DefaultWebSessionManager.java Mon May 17 20:33:12 2010
@@ -19,6 +19,7 @@
 package org.apache.shiro.web.session;
 
 import org.apache.shiro.session.Session;
+import org.apache.shiro.session.SessionException;
 import org.apache.shiro.session.mgt.DefaultSessionManager;
 import org.apache.shiro.web.WebUtils;
 import org.apache.shiro.web.servlet.Cookie;
@@ -170,6 +171,15 @@ public class DefaultWebSessionManager ex
         request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_IS_NEW, Boolean.TRUE);
     }
 
+    public Session getSession(ServletRequest request, ServletResponse response) throws SessionException {
+        Serializable id = getReferencedSessionId(request, response);
+        Session session = null;
+        if ( id != null ) {
+            session = getSession(id);
+        }
+        return session;
+    }
+
     public Serializable getSessionId(ServletRequest request, ServletResponse response) {
         return getReferencedSessionId(request, response);
     }

Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/DelegatingWebSessionManager.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/DelegatingWebSessionManager.java?rev=945349&r1=945348&r2=945349&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/DelegatingWebSessionManager.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/DelegatingWebSessionManager.java Mon May 17 20:33:12 2010
@@ -23,6 +23,7 @@ import org.apache.shiro.session.InvalidS
 import org.apache.shiro.session.Session;
 import org.apache.shiro.session.SessionException;
 import org.apache.shiro.session.mgt.DelegatingSession;
+import org.apache.shiro.session.mgt.SessionContext;
 import org.apache.shiro.session.mgt.SessionManager;
 import org.apache.shiro.util.ThreadContext;
 import org.slf4j.Logger;
@@ -31,7 +32,6 @@ import org.slf4j.LoggerFactory;
 import java.io.Serializable;
 import java.util.Collection;
 import java.util.Date;
-import java.util.Map;
 
 /**
  * WARNING: THIS IS A WORK IN PROGRESS AND IS NOT RECOMMENDED FOR USE!
@@ -94,10 +94,10 @@ public class DelegatingWebSessionManager
     }
 
     @Override
-    protected Session doCreateSession(Map initData) {
+    protected Session doCreateSession(SessionContext initData) {
         assertDelegateExists();
-        Serializable sessionId = this.delegateSessionManager.start(initData);
-        return new DelegatingSession(this, sessionId);
+        Session session = this.delegateSessionManager.start(initData);
+        return new DelegatingSession(this, session.getId());
     }
 
     @Override
@@ -167,16 +167,8 @@ public class DelegatingWebSessionManager
             }
         }
 
-        public Serializable start(final String host) throws AuthorizationException {
-            return (Serializable) execute(new SessionManagerCallback() {
-                public Object doWithSessionManager(SessionManager sm) throws SessionException {
-                    return sm.start(host);
-                }
-            });
-        }
-
-        public Serializable start(final Map initData) throws AuthorizationException {
-            return (Serializable) execute(new SessionManagerCallback() {
+        public Session start(final SessionContext initData) throws AuthorizationException {
+            return (Session) execute(new SessionManagerCallback() {
                 public Object doWithSessionManager(SessionManager sm) throws SessionException {
                     return sm.start(initData);
                 }

Copied: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/HttpServletSession.java (from r944702, incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/WebSession.java)
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/HttpServletSession.java?p2=incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/HttpServletSession.java&p1=incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/WebSession.java&r1=944702&r2=945349&rev=945349&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/WebSession.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/HttpServletSession.java Mon May 17 20:33:12 2010
@@ -30,23 +30,23 @@ import java.util.Collection;
 import java.util.Date;
 import java.util.Enumeration;
 
-
 /**
- * TODO class JavaDoc
+ * {@link Session Session} implementation that is backed entirely by a standard servlet container
+ * {@link HttpSession HttpSession} instance.  It does not interact with any of Shiro's session-related components
+ * {@code SessionManager}, {@code SecurityManager}, etc, and instead satisfies all method implementations by interacting
+ * with a servlet container provided {@link HttpSession HttpSession} instance.
  *
  * @author Les Hazlewood
- * @since 0.9
+ * @since 1.0
  */
-public class WebSession implements Session {
-
-    //TODO - complete JavaDoc
+public class HttpServletSession implements Session {
 
-    private static final String HOST_SESSION_KEY = WebSession.class.getName() + ".HOST_SESSION_KEY";
-    private static final String TOUCH_OBJECT_SESSION_KEY = WebSession.class.getName() + ".TOUCH_OBJECT_SESSION_KEY";
+    private static final String HOST_SESSION_KEY = HttpServletSession.class.getName() + ".HOST_SESSION_KEY";
+    private static final String TOUCH_OBJECT_SESSION_KEY = HttpServletSession.class.getName() + ".TOUCH_OBJECT_SESSION_KEY";
 
     private HttpSession httpSession = null;
 
-    public WebSession(HttpSession httpSession, String host) {
+    public HttpServletSession(HttpSession httpSession, String host) {
         if (httpSession == null) {
             String msg = "HttpSession constructor argument cannot be null.";
             throw new IllegalArgumentException(msg);

Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/ServletContainerSessionManager.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/ServletContainerSessionManager.java?rev=945349&r1=945348&r2=945349&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/ServletContainerSessionManager.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/ServletContainerSessionManager.java Mon May 17 20:33:12 2010
@@ -22,15 +22,13 @@ import org.apache.shiro.authz.Authorizat
 import org.apache.shiro.session.InvalidSessionException;
 import org.apache.shiro.session.Session;
 import org.apache.shiro.session.mgt.AbstractSessionManager;
-import org.apache.shiro.session.mgt.SessionFactory;
-import org.apache.shiro.web.WebUtils;
+import org.apache.shiro.session.mgt.SessionContext;
 
 import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpSession;
 import java.io.Serializable;
-import java.util.Map;
 
 
 /**
@@ -62,15 +60,43 @@ public class ServletContainerSessionMana
     public ServletContainerSessionManager() {
     }
 
+    @Override
+    public Session start(SessionContext initData) throws AuthorizationException {
+        return createSession(initData);
+    }
+
+    /**
+     * This method exists only to satisfy the parent's abstract method signature.  It should never be called since
+     * there is no way to obtain a Session instance from a Servlet Container by id (in a system independent
+     * manner).
+     * <p/>
+     * This method will always throw an exception if called since the
+     * {@link #getSession(javax.servlet.ServletRequest, javax.servlet.ServletResponse)} method should be used in all
+     * cases instead.
+     *
+     * @param sessionId
+     * @return
+     * @throws InvalidSessionException
+     */
     protected Session doGetSession(Serializable sessionId) throws InvalidSessionException {
         //Ignore session id since there is no way to acquire a session based on an id in a servlet container
         //(that is implementation agnostic)
-        ServletRequest request = WebUtils.getRequiredServletRequest();
-        ServletResponse response = WebUtils.getRequiredServletResponse();
-        return getSession(request, response);
+        String msg = "Cannot retrieve sessions by ID when Sessions are managed by the Servlet Container.  This " +
+                "feature is available for Shiro 'native' session SessionManager implementations only.";
+        throw new IllegalStateException(msg);
+        /*ServletRequest request = WebUtils.getServletRequest();
+        ServletResponse response = WebUtils.getServletResponse();
+        if (request == null) {
+            String msg = "Thread-bound ServletRequest cannot be null in ServletContainer-managed Session environments.";
+            throw new IllegalStateException(msg);
+        }
+        return getSession(request, response);*/
     }
 
-    protected Session getSession(ServletRequest request, ServletResponse response) throws AuthorizationException {
+    /**
+     * @since 1.0
+     */
+    public Session getSession(ServletRequest request, ServletResponse response) {
         Session session = null;
         HttpSession httpSession = ((HttpServletRequest) request).getSession(false);
         if (httpSession != null) {
@@ -79,32 +105,51 @@ public class ServletContainerSessionMana
         return session;
     }
 
+    /**
+     * @since 1.0
+     */
     public Serializable getSessionId(ServletRequest request, ServletResponse response) {
         HttpSession httpSession = ((HttpServletRequest) request).getSession(false);
         return httpSession != null ? httpSession.getId() : null;
     }
 
-    protected Session createSession(Map initData) throws AuthorizationException {
+    /**
+     * @since 1.0
+     */
+    protected Session createSession(SessionContext sessionContext) throws AuthorizationException {
+        if (!(sessionContext instanceof WebSessionContext)) {
+            String msg = "SessionContext must be a " + WebSessionContext.class.getName() + " instance.";
+            throw new IllegalArgumentException(msg);
+        }
+
+        WebSessionContext wsc = (WebSessionContext) sessionContext;
+
+        ServletRequest request = wsc.getServletRequest();
+        if (request == null) {
+            String msg = "WebSessionContext must contain a ServletRequest.";
+            throw new IllegalStateException(msg);
+        }
+        ServletResponse response = wsc.getServletResponse();
+        if (response == null) {
+            String msg = "WebSessionContext must contain a ServletResponse.";
+            throw new IllegalStateException(msg);
+        }
 
-        ServletRequest request = WebUtils.getRequiredServletRequest();
         HttpSession httpSession = ((HttpServletRequest) request).getSession();
 
         //ensure that the httpSession timeout reflects what is configured:
         long timeoutMillis = getGlobalSessionTimeout();
         httpSession.setMaxInactiveInterval((int) (timeoutMillis / MILLIS_PER_SECOND));
 
-        String originatingHost;
-        if (initData != null && initData.containsKey(SessionFactory.HOST_KEY)) {
-            originatingHost = (String) initData.get(SessionFactory.HOST_KEY);
-        } else {
+        String originatingHost = wsc.getHost();
+        if (originatingHost == null) {
             originatingHost = request.getRemoteHost();
         }
-
         return createSession(httpSession, originatingHost);
     }
 
     protected Session createSession(HttpSession httpSession, String host) {
-        return new WebSession(httpSession, host);
+        return new HttpServletSession(httpSession, host);
     }
 
 }

Added: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/WebSessionContext.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/WebSessionContext.java?rev=945349&view=auto
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/WebSessionContext.java (added)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/WebSessionContext.java Mon May 17 20:33:12 2010
@@ -0,0 +1,69 @@
+/*
+ * 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.shiro.web.session;
+
+import org.apache.shiro.session.mgt.SessionContext;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+
+/**
+ * A {@code WebSubjectContext} is a {@link SessionContext} that additionally provides for type-safe
+ * methods to set and retrieve a {@link ServletRequest} and {@link ServletResponse}, as the request/response pair will
+ * often need to be referenced during construction of web-initiated {@code Session} instances.
+ *
+ * @author Les Hazlewood
+ * @since 1.0
+ */
+public interface WebSessionContext extends SessionContext {
+
+    /**
+     * Returns the {@code ServletRequest} received by the servlet container triggering the creation of the
+     * {@code Session} instance.
+     *
+     * @return the {@code ServletRequest} received by the servlet container triggering the creation of the
+     *         {@code Session} instance.
+     */
+    ServletRequest getServletRequest();
+
+    /**
+     * Sets the {@code ServletRequest} received by the servlet container triggering the creation of the
+     * {@code Session} instance.
+     *
+     * @param request the {@code ServletRequest} received by the servlet container triggering the creation of the
+     *                {@code Session} instance.
+     */
+    void setServletRequest(ServletRequest request);
+
+    /**
+     * The paired {@code ServletResponse} corresponding to the associated {@link #getServletRequest servletRequest}.
+     *
+     * @return the paired {@code ServletResponse} corresponding to the associated
+     *         {@link #getServletRequest servletRequest}.
+     */
+    ServletResponse getServletResponse();
+
+    /**
+     * Sets the paired {@code ServletResponse} corresponding to the associated {@link #getServletRequest servletRequest}.
+     *
+     * @param response The paired {@code ServletResponse} corresponding to the associated
+     *                 {@link #getServletRequest servletRequest}.
+     */
+    void setServletResponse(ServletResponse response);
+}

Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/WebSessionManager.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/WebSessionManager.java?rev=945349&r1=945348&r2=945349&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/WebSessionManager.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/session/WebSessionManager.java Mon May 17 20:33:12 2010
@@ -18,6 +18,8 @@
  */
 package org.apache.shiro.web.session;
 
+import org.apache.shiro.session.Session;
+import org.apache.shiro.session.SessionException;
 import org.apache.shiro.session.mgt.SessionManager;
 
 import javax.servlet.ServletRequest;
@@ -45,4 +47,17 @@ public interface WebSessionManager exten
      * @since 1.0
      */
     Serializable getSessionId(ServletRequest request, ServletResponse response);
+
+    /**
+     * Returns the session associated with the specified request pair or {@code null} if there is no session
+     * associated with the request.
+     *
+     * @param request  the incoming {@code ServletRequest}
+     * @param response the outgoing {@code ServletResponse}
+     * @return the current session associated with the specified request pair, or {@code null} if there is no
+     *         session associated with the request.
+     * @throws SessionException if there is a problem acquiring the Session associated with the request/response pair
+     * @since 1.0
+     */
+    Session getSession(ServletRequest request, ServletResponse response) throws SessionException;
 }

Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/WebSubject.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/WebSubject.java?rev=945349&r1=945348&r2=945349&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/WebSubject.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/WebSubject.java Mon May 17 20:33:12 2010
@@ -22,7 +22,6 @@ import org.apache.shiro.SecurityUtils;
 import org.apache.shiro.mgt.SecurityManager;
 import org.apache.shiro.subject.Subject;
 import org.apache.shiro.subject.SubjectContext;
-import org.apache.shiro.web.WebUtils;
 import org.apache.shiro.web.subject.support.DefaultWebSubjectContext;
 
 import javax.servlet.ServletRequest;
@@ -52,16 +51,6 @@ public interface WebSubject extends Subj
 
     public static class Builder extends Subject.Builder {
 
-        public Builder() {
-            this(SecurityUtils.getSecurityManager(),
-                    WebUtils.getRequiredServletRequest(),
-                    WebUtils.getRequiredServletResponse());
-        }
-
-        public Builder(SecurityManager securityManager) {
-            this(securityManager, WebUtils.getRequiredServletRequest(), WebUtils.getRequiredServletResponse());
-        }
-
         public Builder(ServletRequest request, ServletResponse response) {
             this(SecurityUtils.getSecurityManager(), request, response);
         }

Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/support/DefaultWebSubjectContext.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/support/DefaultWebSubjectContext.java?rev=945349&r1=945348&r2=945349&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/support/DefaultWebSubjectContext.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/support/DefaultWebSubjectContext.java Mon May 17 20:33:12 2010
@@ -36,8 +36,9 @@ import javax.servlet.ServletResponse;
  */
 public class DefaultWebSubjectContext extends DefaultSubjectContext implements WebSubjectContext {
 
-    private static final String SERVLET_REQUEST = DefaultWebSubjectContext.class.getName() + ".SERVLET_REQUEST";
+    private static final long serialVersionUID = 8188555355305827739L;
 
+    private static final String SERVLET_REQUEST = DefaultWebSubjectContext.class.getName() + ".SERVLET_REQUEST";
     private static final String SERVLET_RESPONSE = DefaultWebSubjectContext.class.getName() + ".SERVLET_RESPONSE";
 
     public DefaultWebSubjectContext() {

Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/support/WebDelegatingSubject.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/support/WebDelegatingSubject.java?rev=945349&r1=945348&r2=945349&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/support/WebDelegatingSubject.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/support/WebDelegatingSubject.java Mon May 17 20:33:12 2010
@@ -20,8 +20,12 @@ package org.apache.shiro.web.subject.sup
 
 import org.apache.shiro.mgt.SecurityManager;
 import org.apache.shiro.session.Session;
+import org.apache.shiro.session.mgt.SessionContext;
 import org.apache.shiro.subject.PrincipalCollection;
 import org.apache.shiro.subject.support.DelegatingSubject;
+import org.apache.shiro.util.StringUtils;
+import org.apache.shiro.web.session.DefaultWebSessionContext;
+import org.apache.shiro.web.session.WebSessionContext;
 import org.apache.shiro.web.subject.WebSubject;
 
 import javax.servlet.ServletRequest;
@@ -33,6 +37,8 @@ import java.util.concurrent.Callable;
  */
 public class WebDelegatingSubject extends DelegatingSubject implements WebSubject {
 
+    private static final long serialVersionUID = -1655724323350159250L;
+
     private final ServletRequest servletRequest;
     private final ServletResponse servletResponse;
 
@@ -54,6 +60,18 @@ public class WebDelegatingSubject extend
     }
 
     @Override
+    protected SessionContext createSessionContext() {
+        WebSessionContext wsc = new DefaultWebSessionContext();
+        String host = getHost();
+        if (StringUtils.hasText(host)) {
+            wsc.setHost(host);
+        }
+        wsc.setServletRequest(this.servletRequest);
+        wsc.setServletResponse(this.servletResponse);
+        return wsc;
+    }
+
+    @Override
     public <V> Callable<V> associateWith(Callable<V> callable) {
         return new WebSubjectCallable<V>(this, callable);
     }

Modified: incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/support/WebSubjectThreadState.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/support/WebSubjectThreadState.java?rev=945349&r1=945348&r2=945349&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/support/WebSubjectThreadState.java (original)
+++ incubator/shiro/trunk/web/src/main/java/org/apache/shiro/web/subject/support/WebSubjectThreadState.java Mon May 17 20:33:12 2010
@@ -26,6 +26,11 @@ import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
 
 /**
+ * Web-specific {@code SubjectThreadState} implementation that, in addition to the parent class's bind/unbind
+ * behavior, also ensures that a {@link ServletRequest ServletRequest} and {@link ServletResponse ServletResponse}
+ * pair are also bound/unbound as necessary.
+ *
+ * @author Les Hazlewood
  * @since 1.0
  */
 public class WebSubjectThreadState extends SubjectThreadState {
@@ -33,6 +38,15 @@ public class WebSubjectThreadState exten
     private final ServletRequest request;
     private final ServletResponse response;
 
+    /**
+     * Creates a new {@code WebSubjectThreadState} instance, retaining the {@link WebSubject} argument's
+     * {@link org.apache.shiro.web.subject.WebSubject#getServletRequest() servletRequest} and
+     * {@link org.apache.shiro.web.subject.WebSubject#getServletResponse() servletResponse} in addition to any
+     * state retained by the parent class's constructor.
+     *
+     * @param subject the {@link WebSubject} to bind as well as from which to acquire the
+     *                {@code ServletRequest} and {@code ServletResponse} pair.
+     */
     public WebSubjectThreadState(WebSubject subject) {
         super(subject);
 
@@ -49,6 +63,12 @@ public class WebSubjectThreadState exten
         this.response = response;
     }
 
+    /**
+     * Calls {@code super.bind()} and then additionally binds the internal {@code ServletRequest} and
+     * {@code ServletResponse} pair via
+     * {@code WebUtils.}{@link WebUtils#bind(javax.servlet.ServletRequest) bind(ServletRequest)} and
+     * {@code WebUtils.}{@link WebUtils#bind(javax.servlet.ServletResponse) bind(ServletResponse)}, respectively.
+     */
     @Override
     public void bind() {
         super.bind();

Modified: incubator/shiro/trunk/web/src/test/java/org/apache/shiro/web/DelegatingWebSecurityManagerTest.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/test/java/org/apache/shiro/web/DelegatingWebSecurityManagerTest.java?rev=945349&r1=945348&r2=945349&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/test/java/org/apache/shiro/web/DelegatingWebSecurityManagerTest.java (original)
+++ incubator/shiro/trunk/web/src/test/java/org/apache/shiro/web/DelegatingWebSecurityManagerTest.java Mon May 17 20:33:12 2010
@@ -22,6 +22,8 @@ import org.apache.shiro.mgt.SecurityMana
 import org.apache.shiro.session.ExpiredSessionException;
 import org.apache.shiro.session.Session;
 import org.apache.shiro.session.mgt.AbstractSessionManager;
+import org.apache.shiro.session.mgt.DelegatingSession;
+import org.apache.shiro.session.mgt.SessionContext;
 import org.apache.shiro.subject.Subject;
 import org.easymock.EasyMock;
 import org.junit.After;
@@ -33,7 +35,6 @@ import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.io.Serializable;
-import java.util.Map;
 import java.util.UUID;
 
 import static org.easymock.EasyMock.*;
@@ -78,7 +79,7 @@ public class DelegatingWebSecurityManage
         String host = "192.168.1.1";
 
         Serializable sessionId = UUID.randomUUID().toString();
-        expect(delegate.start(EasyMock.<Map>anyObject())).andReturn(sessionId);
+        expect(delegate.start(EasyMock.<SessionContext>anyObject())).andReturn(new DelegatingSession(sm, sessionId));
         expect(delegate.getHost(sessionId)).andReturn(host);
         expect(delegate.getTimeout(sessionId)).andReturn(AbstractSessionManager.DEFAULT_GLOBAL_SESSION_TIMEOUT);
         delegate.setTimeout(sessionId, 125L);

Modified: incubator/shiro/trunk/web/src/test/java/org/apache/shiro/web/filter/mgt/SimpleNamedFilterListTest.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/web/src/test/java/org/apache/shiro/web/filter/mgt/SimpleNamedFilterListTest.java?rev=945349&r1=945348&r2=945349&view=diff
==============================================================================
--- incubator/shiro/trunk/web/src/test/java/org/apache/shiro/web/filter/mgt/SimpleNamedFilterListTest.java (original)
+++ incubator/shiro/trunk/web/src/test/java/org/apache/shiro/web/filter/mgt/SimpleNamedFilterListTest.java Mon May 17 20:33:12 2010
@@ -24,16 +24,14 @@ import org.apache.shiro.web.filter.authz
 import org.apache.shiro.web.filter.authz.PortFilter;
 import org.apache.shiro.web.filter.authz.RolesAuthorizationFilter;
 import org.apache.shiro.web.filter.authz.SslFilter;
-import static org.easymock.EasyMock.*;
-import static org.junit.Assert.*;
 import org.junit.Test;
 
 import javax.servlet.Filter;
 import javax.servlet.FilterChain;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
+import java.util.*;
+
+import static org.easymock.EasyMock.createNiceMock;
+import static org.junit.Assert.*;
 
 /**
  * Test case for the {@link SimpleNamedFilterList} implementation.
@@ -57,8 +55,7 @@ public class SimpleNamedFilterListTest {
 
     @Test
     public void testNewInstanceBackingList() {
-        //noinspection unchecked
-        new SimpleNamedFilterList("test", new ArrayList());
+        new SimpleNamedFilterList("test", new ArrayList<Filter>());
     }
 
     @Test(expected = NullPointerException.class)
@@ -87,7 +84,7 @@ public class SimpleNamedFilterListTest {
         list.add(0, singleFilter);
         assertEquals(2, list.size());
         assertTrue(list.get(0) instanceof SslFilter);
-        assertEquals(list.toArray(), new Object[]{singleFilter, filter});
+        assertTrue(Arrays.equals(list.toArray(), new Object[]{singleFilter, filter}));
 
         list.addAll(multipleFilters);
         assertEquals(4, list.size());