You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by mr...@apache.org on 2005/08/26 07:46:58 UTC

svn commit: r240168 [13/30] - in /struts/sandbox/trunk/ti: ./ core/src/java/org/apache/ti/ core/src/java/org/apache/ti/config/ core/src/java/org/apache/ti/config/mapper/ core/src/java/org/apache/ti/core/ core/src/java/org/apache/ti/core/factory/ core/s...

Added: struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/scoping/ScopedRequest.java.disabled
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/scoping/ScopedRequest.java.disabled?rev=240168&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/scoping/ScopedRequest.java.disabled (added)
+++ struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/scoping/ScopedRequest.java.disabled Thu Aug 25 22:46:03 2005
@@ -0,0 +1,294 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.pageflow.scoping;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Map;
+
+
+/**
+ * A wrapper around HttpServletRequest, associated with a given scope-key.  All calls to setAttribute,
+ * getAttribute, removeAttribute, etc. are scoped to this object, while most other functionality
+ * delegates to the wrapped HttpServletRequest.
+ * Instances of this class also keep track of their own request-URIs, which are independent of the
+ * wrapped request-URIs.
+ */
+public interface ScopedRequest
+        extends HttpServletRequest
+{
+    public String AUTOSCOPE_PREFIX = "_autoscope_";
+    
+    
+    public void setRequestURI( String uri );
+
+    /**
+     * Adds a scope to "listen" to.  This scope will see all request parameters from a ScopedRequest
+     * of the given scope.
+     */ 
+    public void addListenScope( Object scopeKey );
+    
+    public void doForward();
+
+    public String getForwardedURI();
+
+    /**
+     * @deprecated Use {@link ScopedResponse#didRedirect} instead.
+     */ 
+    public boolean didRedirect();
+    
+    /**
+     * Stores the current map of request attributes in the Session.
+     */
+    public void persistAttributes();
+
+    /**
+     * Restores the map of request attributes from a map saved in the Session.
+     */
+    public void restoreAttributes();
+    
+    public HttpServletRequest getOuterRequest();
+    
+    public Object getScopeKey();
+    
+    public void renameScope( Object newScopeKey );
+    
+    /**
+     * Makes this request listen to specially-prefixed request parameters.
+     */ 
+    public void setActiveRequest();
+    
+    public String getScopedName( String baseName );
+
+    public void registerOuterAttribute( String attrName );
+
+    public String getLocalParameter( String attrName );
+    public String getListenScopeParameter( String attrName );
+    public boolean hasListenScopes();
+    
+    /**
+     * Same as <code>getAttribute</code>, but allows outer request attributes to be hidden explicitly, even if the implementation
+     * of getAttribute shows them by default.
+     */ 
+    public Object getAttribute( String attrName, boolean allowOuterRequestAttributes );
+    
+    /**
+     * @exclude
+     */ 
+    public Map filterParameterMap( Map parameterMap );
+    
+    /**
+     * Simply stores the URI that was being forwarded to.
+     */
+    public void setForwardedURI( String uri );
+}
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.pageflow.scoping;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Map;
+
+
+/**
+ * A wrapper around HttpServletRequest, associated with a given scope-key.  All calls to setAttribute,
+ * getAttribute, removeAttribute, etc. are scoped to this object, while most other functionality
+ * delegates to the wrapped HttpServletRequest.
+ * Instances of this class also keep track of their own request-URIs, which are independent of the
+ * wrapped request-URIs.
+ */
+public interface ScopedRequest
+        extends HttpServletRequest
+{
+    public String AUTOSCOPE_PREFIX = "_autoscope_";
+    
+    
+    public void setRequestURI( String uri );
+
+    /**
+     * Adds a scope to "listen" to.  This scope will see all request parameters from a ScopedRequest
+     * of the given scope.
+     */ 
+    public void addListenScope( Object scopeKey );
+    
+    public void doForward();
+
+    public String getForwardedURI();
+
+    /**
+     * @deprecated Use {@link ScopedResponse#didRedirect} instead.
+     */ 
+    public boolean didRedirect();
+    
+    /**
+     * Stores the current map of request attributes in the Session.
+     */
+    public void persistAttributes();
+
+    /**
+     * Restores the map of request attributes from a map saved in the Session.
+     */
+    public void restoreAttributes();
+    
+    public HttpServletRequest getOuterRequest();
+    
+    public Object getScopeKey();
+    
+    public void renameScope( Object newScopeKey );
+    
+    /**
+     * Makes this request listen to specially-prefixed request parameters.
+     */ 
+    public void setActiveRequest();
+    
+    public String getScopedName( String baseName );
+
+    public void registerOuterAttribute( String attrName );
+
+    public String getLocalParameter( String attrName );
+    public String getListenScopeParameter( String attrName );
+    public boolean hasListenScopes();
+    
+    /**
+     * Same as <code>getAttribute</code>, but allows outer request attributes to be hidden explicitly, even if the implementation
+     * of getAttribute shows them by default.
+     */ 
+    public Object getAttribute( String attrName, boolean allowOuterRequestAttributes );
+    
+    /**
+     * @exclude
+     */ 
+    public Map filterParameterMap( Map parameterMap );
+    
+    /**
+     * Simply stores the URI that was being forwarded to.
+     */
+    public void setForwardedURI( String uri );
+}
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.pageflow.scoping;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Map;
+
+
+/**
+ * A wrapper around HttpServletRequest, associated with a given scope-key.  All calls to setAttribute,
+ * getAttribute, removeAttribute, etc. are scoped to this object, while most other functionality
+ * delegates to the wrapped HttpServletRequest.
+ * Instances of this class also keep track of their own request-URIs, which are independent of the
+ * wrapped request-URIs.
+ */
+public interface ScopedRequest
+        extends HttpServletRequest
+{
+    public String AUTOSCOPE_PREFIX = "_autoscope_";
+    
+    
+    public void setRequestURI( String uri );
+
+    /**
+     * Adds a scope to "listen" to.  This scope will see all request parameters from a ScopedRequest
+     * of the given scope.
+     */ 
+    public void addListenScope( Object scopeKey );
+    
+    public void doForward();
+
+    public String getForwardedURI();
+
+    /**
+     * @deprecated Use {@link ScopedResponse#didRedirect} instead.
+     */ 
+    public boolean didRedirect();
+    
+    /**
+     * Stores the current map of request attributes in the Session.
+     */
+    public void persistAttributes();
+
+    /**
+     * Restores the map of request attributes from a map saved in the Session.
+     */
+    public void restoreAttributes();
+    
+    public HttpServletRequest getOuterRequest();
+    
+    public Object getScopeKey();
+    
+    public void renameScope( Object newScopeKey );
+    
+    /**
+     * Makes this request listen to specially-prefixed request parameters.
+     */ 
+    public void setActiveRequest();
+    
+    public String getScopedName( String baseName );
+
+    public void registerOuterAttribute( String attrName );
+
+    public String getLocalParameter( String attrName );
+    public String getListenScopeParameter( String attrName );
+    public boolean hasListenScopes();
+    
+    /**
+     * Same as <code>getAttribute</code>, but allows outer request attributes to be hidden explicitly, even if the implementation
+     * of getAttribute shows them by default.
+     */ 
+    public Object getAttribute( String attrName, boolean allowOuterRequestAttributes );
+    
+    /**
+     * @exclude
+     */ 
+    public Map filterParameterMap( Map parameterMap );
+    
+    /**
+     * Simply stores the URI that was being forwarded to.
+     */
+    public void setForwardedURI( String uri );
+}

Added: struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/scoping/ScopedResponse.java.disabled
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/scoping/ScopedResponse.java.disabled?rev=240168&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/scoping/ScopedResponse.java.disabled (added)
+++ struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/scoping/ScopedResponse.java.disabled Thu Aug 25 22:46:03 2005
@@ -0,0 +1,333 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.pageflow.scoping;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.Cookie;
+import java.util.List;
+import java.util.Map;
+import java.io.IOException;
+
+
+/**
+ * A wrapper around HttpServletResponse, associated with a given scope-key.  Delegates to the wrapped
+ * response object for some functionality, but prevents output or error codes or forwards from actually
+ * happening.
+ */
+public interface ScopedResponse
+        extends HttpServletResponse
+{
+    /**
+     * Get a cookie that was added to the response.
+     */ 
+    public Cookie getCookie( String cookieName );
+    
+    /**
+     * Get all Cookies that were added to the response.
+     */ 
+    public Cookie[] getCookies();
+    
+    /**
+     * Get all headers.
+     *
+     * @return a Map of header-name (String) -> headers (List).
+     */
+    public Map getHeaders();
+    
+    /**
+     * Get all headers with the given name.
+     * 
+     * @return a List of headers (String, Integer, Date), or <code>null</code> if none are found.
+     */ 
+    public List getHeaders( String name );
+    
+    /**
+     * Get the first header with the given name.
+     * @return an Object (String, Integer, Date) that is the first header with the given name,
+     *         or <code>null</code> if none is found.
+     */ 
+    public Object getFirstHeader( String name );
+    
+    public HttpServletResponse getOuterResponse();
+    
+    /**
+     * Tell whether the response is in error.
+     * 
+     * @return <code>true</code> if {@link #sendError(int,String)} or {@link #sendError(int)} was called.
+     */ 
+    public boolean isError();
+
+    /**
+     * Get the status code on the response.
+     * 
+     * @return the status code, set by {@link #setStatus(int)}, {@link #sendError(int,String)}, or
+     *         {@link #sendError(int)}; -1 if no status was set explicitly.
+     */ 
+    public int getStatusCode();
+
+    /**
+     * Get the status message on the response.
+     * 
+     * @return the status code, set by {@link #sendError(int,String)}, or <code>null</code> if none was set.
+     */ 
+    public String getStatusMessage();
+    
+    /**
+     * Tell whether a browser redirect was sent.
+     * 
+     * @return <code>true</code> if {@link #sendRedirect} was called.
+     */ 
+    public boolean didRedirect();
+    
+    /**
+     * Get the redirect URI.
+     * 
+     * @return the URI passed to {@link #sendRedirect}, or <code>null</code> if there was no redirect.
+     */ 
+    public String getRedirectURI();
+    
+    /**
+     * Actually send the redirect that was suggested by {@link #sendRedirect}.
+     * 
+     * @throws IllegalStateException if {@link #sendRedirect} was not called.
+     * @throws IOException if {@link HttpServletResponse#sendRedirect} causes an IOException.
+     */ 
+    public void applyRedirect() throws IOException;
+}
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.pageflow.scoping;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.Cookie;
+import java.util.List;
+import java.util.Map;
+import java.io.IOException;
+
+
+/**
+ * A wrapper around HttpServletResponse, associated with a given scope-key.  Delegates to the wrapped
+ * response object for some functionality, but prevents output or error codes or forwards from actually
+ * happening.
+ */
+public interface ScopedResponse
+        extends HttpServletResponse
+{
+    /**
+     * Get a cookie that was added to the response.
+     */ 
+    public Cookie getCookie( String cookieName );
+    
+    /**
+     * Get all Cookies that were added to the response.
+     */ 
+    public Cookie[] getCookies();
+    
+    /**
+     * Get all headers.
+     *
+     * @return a Map of header-name (String) -> headers (List).
+     */
+    public Map getHeaders();
+    
+    /**
+     * Get all headers with the given name.
+     * 
+     * @return a List of headers (String, Integer, Date), or <code>null</code> if none are found.
+     */ 
+    public List getHeaders( String name );
+    
+    /**
+     * Get the first header with the given name.
+     * @return an Object (String, Integer, Date) that is the first header with the given name,
+     *         or <code>null</code> if none is found.
+     */ 
+    public Object getFirstHeader( String name );
+    
+    public HttpServletResponse getOuterResponse();
+    
+    /**
+     * Tell whether the response is in error.
+     * 
+     * @return <code>true</code> if {@link #sendError(int,String)} or {@link #sendError(int)} was called.
+     */ 
+    public boolean isError();
+
+    /**
+     * Get the status code on the response.
+     * 
+     * @return the status code, set by {@link #setStatus(int)}, {@link #sendError(int,String)}, or
+     *         {@link #sendError(int)}; -1 if no status was set explicitly.
+     */ 
+    public int getStatusCode();
+
+    /**
+     * Get the status message on the response.
+     * 
+     * @return the status code, set by {@link #sendError(int,String)}, or <code>null</code> if none was set.
+     */ 
+    public String getStatusMessage();
+    
+    /**
+     * Tell whether a browser redirect was sent.
+     * 
+     * @return <code>true</code> if {@link #sendRedirect} was called.
+     */ 
+    public boolean didRedirect();
+    
+    /**
+     * Get the redirect URI.
+     * 
+     * @return the URI passed to {@link #sendRedirect}, or <code>null</code> if there was no redirect.
+     */ 
+    public String getRedirectURI();
+    
+    /**
+     * Actually send the redirect that was suggested by {@link #sendRedirect}.
+     * 
+     * @throws IllegalStateException if {@link #sendRedirect} was not called.
+     * @throws IOException if {@link HttpServletResponse#sendRedirect} causes an IOException.
+     */ 
+    public void applyRedirect() throws IOException;
+}
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.pageflow.scoping;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.Cookie;
+import java.util.List;
+import java.util.Map;
+import java.io.IOException;
+
+
+/**
+ * A wrapper around HttpServletResponse, associated with a given scope-key.  Delegates to the wrapped
+ * response object for some functionality, but prevents output or error codes or forwards from actually
+ * happening.
+ */
+public interface ScopedResponse
+        extends HttpServletResponse
+{
+    /**
+     * Get a cookie that was added to the response.
+     */ 
+    public Cookie getCookie( String cookieName );
+    
+    /**
+     * Get all Cookies that were added to the response.
+     */ 
+    public Cookie[] getCookies();
+    
+    /**
+     * Get all headers.
+     *
+     * @return a Map of header-name (String) -> headers (List).
+     */
+    public Map getHeaders();
+    
+    /**
+     * Get all headers with the given name.
+     * 
+     * @return a List of headers (String, Integer, Date), or <code>null</code> if none are found.
+     */ 
+    public List getHeaders( String name );
+    
+    /**
+     * Get the first header with the given name.
+     * @return an Object (String, Integer, Date) that is the first header with the given name,
+     *         or <code>null</code> if none is found.
+     */ 
+    public Object getFirstHeader( String name );
+    
+    public HttpServletResponse getOuterResponse();
+    
+    /**
+     * Tell whether the response is in error.
+     * 
+     * @return <code>true</code> if {@link #sendError(int,String)} or {@link #sendError(int)} was called.
+     */ 
+    public boolean isError();
+
+    /**
+     * Get the status code on the response.
+     * 
+     * @return the status code, set by {@link #setStatus(int)}, {@link #sendError(int,String)}, or
+     *         {@link #sendError(int)}; -1 if no status was set explicitly.
+     */ 
+    public int getStatusCode();
+
+    /**
+     * Get the status message on the response.
+     * 
+     * @return the status code, set by {@link #sendError(int,String)}, or <code>null</code> if none was set.
+     */ 
+    public String getStatusMessage();
+    
+    /**
+     * Tell whether a browser redirect was sent.
+     * 
+     * @return <code>true</code> if {@link #sendRedirect} was called.
+     */ 
+    public boolean didRedirect();
+    
+    /**
+     * Get the redirect URI.
+     * 
+     * @return the URI passed to {@link #sendRedirect}, or <code>null</code> if there was no redirect.
+     */ 
+    public String getRedirectURI();
+    
+    /**
+     * Actually send the redirect that was suggested by {@link #sendRedirect}.
+     * 
+     * @throws IllegalStateException if {@link #sendRedirect} was not called.
+     * @throws IOException if {@link HttpServletResponse#sendRedirect} causes an IOException.
+     */ 
+    public void applyRedirect() throws IOException;
+}

Added: struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/scoping/ScopedUtils.java.disabled
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/scoping/ScopedUtils.java.disabled?rev=240168&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/scoping/ScopedUtils.java.disabled (added)
+++ struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/scoping/ScopedUtils.java.disabled Thu Aug 25 22:46:03 2005
@@ -0,0 +1,1230 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.pageflow.scoping;
+
+import org.apache.ti.pageflow.scoping.internal.ScopedRequestImpl;
+import org.apache.ti.pageflow.scoping.internal.ScopedResponseImpl;
+import org.apache.ti.pageflow.internal.InternalUtils;
+import org.apache.ti.util.logging.Logger;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletRequestWrapper;
+import javax.servlet.ServletResponse;
+import javax.servlet.ServletResponseWrapper;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+
+/**
+ * Utilities for creating scoped wrapper versions of HttpRequest, HttpResponse, ServletContext.  These
+ * wrappers are the basis for a scoped servlet environment, which can be used to scope the Struts
+ * framework.
+ */
+public class ScopedUtils
+{
+    static final String ATTR_PREFIX = "_netui:";
+    private static final String OVERRIDE_REQUEST_ATTR = ATTR_PREFIX + "overrideRequest";
+    private static final String OVERRIDE_RESPONSE_ATTR = ATTR_PREFIX + "overrideResponse";
+    
+    private static final Logger logger = Logger.getInstance( ScopedUtils.class );
+    
+    
+    /**
+     * Get the cached ScopedRequest wrapper.  If none exists, creates one and caches it.
+     * @deprecated Use {@link #getScopedRequest(HttpServletRequest, String, ServletContext, Object, boolean)}.
+     *
+     * @param realRequest the "real" (outer) HttpServletRequest, which will be wrapped.
+     * @param overrideURI the request-URI for the wrapped object.  This is a <i>webapp-relative</i> URI,
+     *                    i.e., it does not include the context path.
+     * @param servletContext the current ServletContext.
+     * @param scopeKey the scope-key associated with the new (or looked-up) scoped request.
+     * @return the cached (or newly-created) ScopedRequest.
+     */
+    public static ScopedRequest getScopedRequest( HttpServletRequest realRequest, String overrideURI,
+                                                  ServletContext servletContext, Object scopeKey )
+    {
+        return getScopedRequest( realRequest, overrideURI, servletContext, scopeKey, false );
+    }
+    
+    /**
+     * Get the cached ScopedRequest wrapper.  If none exists, creates one and caches it.
+     *
+     * @param realRequest the "real" (outer) HttpServletRequest, which will be wrapped.
+     * @param overrideURI the request-URI for the wrapped object.  This is a <i>webapp-relative</i> URI,
+     *                    i.e., it does not include the context path.
+     * @param servletContext the current ServletContext.
+     * @param scopeKey the scope-key associated with the new (or looked-up) scoped request.
+     * @param seeOuterRequestAttributes if <code>true</code>, a request attribute will be "seen" in the outer request,
+     *            if it is not found within the scoped request; if <code>false</code>, attributes are only seen when
+     *            they are present in the scoped request.
+     * @return the cached (or newly-created) ScopedRequest.
+     */
+    public static ScopedRequest getScopedRequest( HttpServletRequest realRequest, String overrideURI,
+                                                  ServletContext servletContext, Object scopeKey,
+                                                  boolean seeOuterRequestAttributes )
+    {
+        assert ! ( realRequest instanceof ScopedRequest );
+        
+        String requestAttr = getScopedName( OVERRIDE_REQUEST_ATTR, scopeKey );
+        ScopedRequest scopedRequest = ( ScopedRequest ) realRequest.getAttribute( requestAttr );
+        
+        //
+        // If it doesn't exist, create it and cache it.
+        //
+        if ( scopedRequest == null )
+        {
+            //
+            // The override URI must start with a slash -- it's webapp-relative.
+            //
+            if ( overrideURI != null && ! overrideURI.startsWith( "/" ) ) overrideURI = '/' + overrideURI;
+            
+            scopedRequest = 
+                new ScopedRequestImpl( realRequest, overrideURI, scopeKey, servletContext, seeOuterRequestAttributes );
+            realRequest.setAttribute( requestAttr, scopedRequest );            
+        }
+        
+        return scopedRequest;
+    }
+
+    /**
+     * Get the cached wrapper servlet response.  If none exists, creates one and caches it.
+     *
+     * @param realResponse the "real" (outer) ServletResponse, which will be wrapped.
+     * @param scopedRequest the ScopedRequest returned from {@link #getScopedRequest}.
+     * @return the cached (or newly-created) ScopedResponse.
+     */
+    public static ScopedResponse getScopedResponse( HttpServletResponse realResponse,
+                                                    ScopedRequest scopedRequest )
+    {
+        assert ! ( realResponse instanceof ScopedResponse );
+        
+        String responseAttr = getScopedName( OVERRIDE_RESPONSE_ATTR,
+                                                                      scopedRequest.getScopeKey() );
+        HttpServletRequest outerRequest = scopedRequest.getOuterRequest();
+        ScopedResponse scopedResponse = ( ScopedResponse ) outerRequest.getAttribute( responseAttr );
+        
+        //
+        // If it doesn't exist, create it and cache it.
+        //
+        if ( scopedResponse == null )
+        {
+            scopedResponse = new ScopedResponseImpl( realResponse );
+            outerRequest.setAttribute( responseAttr, scopedResponse );
+        }
+        
+        return scopedResponse;
+    }
+
+    /**
+     * Find all scoped objects ({@link ScopedRequest}, {@link ScopedResponse})
+     * which have a certain scope-key, replaces this scope-key with the new one, and re-caches the objects
+     * the new scope-key.
+     * @param oldScopeKey
+     * @param newScopeKey
+     * @param request the real (outer) request, where the scoped objects are cached.
+     */ 
+    public static void renameScope( Object oldScopeKey, Object newScopeKey, HttpServletRequest request )
+    {
+        assert ! ( request instanceof ScopedRequest );
+        
+        String requestAttr = getScopedName( OVERRIDE_REQUEST_ATTR, oldScopeKey );
+        String responseAttr = getScopedName( OVERRIDE_RESPONSE_ATTR, oldScopeKey );
+        ScopedRequest scopedRequest = ( ScopedRequest ) request.getAttribute( requestAttr );
+        ScopedResponse scopedResponse = ( ScopedResponse ) request.getAttribute( responseAttr );
+        
+        if ( scopedRequest != null )
+        {
+            scopedRequest.renameScope( newScopeKey );
+            request.removeAttribute( requestAttr );
+            requestAttr = getScopedName( OVERRIDE_REQUEST_ATTR, newScopeKey );
+            request.setAttribute( requestAttr, scopedRequest );
+        }
+        else
+        {
+            ScopedRequestImpl.renameSessionScope( oldScopeKey, newScopeKey, request );
+        }
+
+        if ( scopedResponse != null )
+        {
+            request.removeAttribute( responseAttr );
+            responseAttr = getScopedName( OVERRIDE_RESPONSE_ATTR, newScopeKey );
+            request.setAttribute( responseAttr, scopedResponse );
+        }
+    }    
+    
+    /**
+     * Get a scoped version of a given name.
+     * 
+     * @param baseName the name to be scoped.
+     * @param scopeKey the context key for scoping the name.
+     * @return a scoped version of the given name.
+     */ 
+    public static String getScopedName( String baseName, Object scopeKey )
+    {
+        return scopeKey + baseName;
+    }    
+    
+    /**
+     * Tell whether this is a scoped request.
+     * 
+     * @param request the ServletRequest to test.
+     * @return <code>true</code> if the given ServletRequest is a ScopedRequest.
+     */ 
+    /*
+    public static boolean isScoped( ServletRequest request )
+    {
+ 
+    }
+    */
+        
+    /**
+     * Get the outer (unwrapped) request.
+     * 
+     * @param request the request to unwrap.
+     * @return the outer request, if the given request is a ScopedRequest (or wraps a ScopedRequest);
+     *         otherwise, the given request itself.
+     */ 
+    public static HttpServletRequest getOuterRequest( HttpServletRequest request )
+    {
+        ScopedRequest scopedRequest = unwrapRequest( request );
+        return scopedRequest != null ? scopedRequest.getOuterRequest() : request;
+    }
+    
+    /**
+     * Get the outer (unwrapped) request.
+     * 
+     * @param request the request to unwrap.
+     * @return the outer request, if the given request is a ScopedRequest (or wraps a ScopedRequest);
+     *         otherwise, the given request itself.
+     */ 
+    public static ServletRequest getOuterServletRequest( ServletRequest request )
+    {
+        ScopedRequest scopedRequest = unwrapRequest( request );
+        return scopedRequest != null ? scopedRequest.getOuterRequest() : request;
+    }
+    
+    /**
+     * Unwraps the contained ScopedRequest from the given ServletRequest, which may be a
+     * ServletRequestWrapper.
+     * 
+     * @param request the ScopedRequest, or a wrapper (ServletRequestWrapper) around it.
+     * @return the unwrapped ScopedRequest.
+     * 
+     * @exclude
+     */ 
+    public static ScopedRequest unwrapRequest( ServletRequest request )
+    {
+        while ( request instanceof ServletRequestWrapper )
+        {
+            if ( request instanceof ScopedRequest )
+            {
+                return ( ScopedRequest ) request;
+            }
+            else
+            {
+                request = ( ( ServletRequestWrapper ) request ).getRequest();
+            }
+        }
+        
+        return null;
+    }  
+    
+    /**
+     * Unwraps the contained ScopedResponseImpl from the given ServletResponse, which may be a
+     * ServletResponseWrapper.
+     * 
+     * @param response the ScopedResponse, or a wrapper (ServletResponseWrapper) around it.
+     * @return the unwrapped ScopedResponseImpl.
+     * 
+     * @exclude
+     */ 
+    public static ScopedResponse unwrapResponse( ServletResponse response )
+    {
+        while ( response instanceof ServletResponseWrapper )
+         {
+             if ( response instanceof ScopedResponse )
+             {
+                 return ( ScopedResponse ) response;
+             }
+             else
+             {
+                 response = ( ( ServletResponseWrapper ) response ).getResponse();
+             }
+         }
+        
+         return null;
+     }
+
+    /**
+     * If the request is a ScopedRequest, this returns an attribute whose name is scoped to that request's scope-ID;
+     * otherwise, it is a straight passthrough to {@link HttpSession#getAttribute}.
+     * 
+     * @exclude
+     */ 
+    public static Object getScopedSessionAttr( String attrName, HttpServletRequest request )
+    {
+        HttpSession session = request.getSession( false );
+        
+        if ( session != null )
+        {
+            return session.getAttribute( InternalUtils.getScopedAttrName( attrName, request ) );
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+    /**
+     * If the request is a ScopedRequest, this sets an attribute whose name is scoped to that request's scope-ID;
+     * otherwise, it is a straight passthrough to {@link HttpSession#setAttribute}.
+     * 
+     * @exclude
+     */ 
+    public static void setScopedSessionAttr( String attrName, Object val, HttpServletRequest request )
+    {
+        request.getSession().setAttribute( InternalUtils.getScopedAttrName( attrName, request ), val );
+    }
+
+    /**
+     * If the request is a ScopedRequest, this removes an attribute whose name is scoped to that request's scope-ID;
+     * otherwise, it is a straight passthrough to {@link HttpSession#removeAttribute}.
+     * 
+     * @exclude
+     */ 
+    public static void removeScopedSessionAttr( String attrName, HttpServletRequest request )
+    {
+        HttpSession session = request.getSession( false );
+        
+        if ( session != null )
+        {
+            session.removeAttribute( InternalUtils.getScopedAttrName( attrName, request ) );
+        }
+    }
+    
+    /**
+     * Get an attribute from the given request, and if it is a {@link ScopedRequest}, ensure that the attribute
+     * is <strong>not</strong> "showing through" from the outer request, even if the ScopedRequest allows that by
+     * default.
+     * 
+     * @exclude
+     */ 
+    public static Object getScopedRequestAttribute( String attrName, ServletRequest request )
+    {
+        if ( request instanceof ScopedRequest )
+        {
+            return ( ( ScopedRequest ) request ).getAttribute( attrName, false );
+        }
+        
+        return request.getAttribute( attrName );
+    }
+    
+    /**
+     * Get the request URI, relative to the webapp root.
+     *
+     * @param request the current HttpServletRequest.
+     */
+    public static final String getRelativeURI( HttpServletRequest request )
+    {
+        return request.getServletPath();
+    }
+
+    /**
+     * Get a URI relative to the webapp root.
+     *
+     * @param request the current HttpServletRequest.
+     * @param uri the URI which should be made relative.
+     */
+    public static final String getRelativeURI( HttpServletRequest request, String uri )
+    {
+        return getRelativeURI( request.getContextPath(), uri );
+    }
+    
+    /**
+     * Get a URI relative to a given webapp root.
+     *
+     * @param contextPath the webapp context path, e.g., "/myWebapp"
+     * @param uri the URI which should be made relative.
+     */
+    public static final String getRelativeURI( String contextPath, String uri )
+    {
+        String requestUrl = uri;
+        int overlap = requestUrl.indexOf( contextPath + '/' );
+        assert overlap != -1 : "contextPath: " + contextPath + ", uri: " + uri;
+        return requestUrl.substring( overlap + contextPath.length() );
+    }
+
+    /**
+     * Resolve "." and ".." in a URI.
+     * @exclude
+     */ 
+    public static String normalizeURI( String uri )
+    {
+        //
+        // If it's a relative URI, normalize it.  Note that we don't want to create a URI
+        // (very expensive) unless we think we'll need to.  "./" catches "../" and "./".
+        //
+        if ( uri.indexOf( "./" ) != -1 )
+        {
+            try
+            {
+                uri = new URI( uri ).normalize().toString();
+            }
+            catch ( URISyntaxException e )
+            {
+                logger.error( "Could not parse relative URI " + uri );
+            }
+        }
+        
+        return uri;
+    }
+    
+    
+    /**
+     * @exclude
+     */ 
+    public static String decodeURI( HttpServletRequest request )
+    {
+        return request.getContextPath() + request.getServletPath();     // TODO: always decoded?
+    }
+}
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.pageflow.scoping;
+
+import org.apache.ti.pageflow.scoping.internal.ScopedRequestImpl;
+import org.apache.ti.pageflow.scoping.internal.ScopedResponseImpl;
+import org.apache.ti.pageflow.internal.InternalUtils;
+import org.apache.ti.util.logging.Logger;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletRequestWrapper;
+import javax.servlet.ServletResponse;
+import javax.servlet.ServletResponseWrapper;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+
+/**
+ * Utilities for creating scoped wrapper versions of HttpRequest, HttpResponse, ServletContext.  These
+ * wrappers are the basis for a scoped servlet environment, which can be used to scope the Struts
+ * framework.
+ */
+public class ScopedUtils
+{
+    static final String ATTR_PREFIX = "_netui:";
+    private static final String OVERRIDE_REQUEST_ATTR = ATTR_PREFIX + "overrideRequest";
+    private static final String OVERRIDE_RESPONSE_ATTR = ATTR_PREFIX + "overrideResponse";
+    
+    private static final Logger logger = Logger.getInstance( ScopedUtils.class );
+    
+    
+    /**
+     * Get the cached ScopedRequest wrapper.  If none exists, creates one and caches it.
+     * @deprecated Use {@link #getScopedRequest(HttpServletRequest, String, ServletContext, Object, boolean)}.
+     *
+     * @param realRequest the "real" (outer) HttpServletRequest, which will be wrapped.
+     * @param overrideURI the request-URI for the wrapped object.  This is a <i>webapp-relative</i> URI,
+     *                    i.e., it does not include the context path.
+     * @param servletContext the current ServletContext.
+     * @param scopeKey the scope-key associated with the new (or looked-up) scoped request.
+     * @return the cached (or newly-created) ScopedRequest.
+     */
+    public static ScopedRequest getScopedRequest( HttpServletRequest realRequest, String overrideURI,
+                                                  ServletContext servletContext, Object scopeKey )
+    {
+        return getScopedRequest( realRequest, overrideURI, servletContext, scopeKey, false );
+    }
+    
+    /**
+     * Get the cached ScopedRequest wrapper.  If none exists, creates one and caches it.
+     *
+     * @param realRequest the "real" (outer) HttpServletRequest, which will be wrapped.
+     * @param overrideURI the request-URI for the wrapped object.  This is a <i>webapp-relative</i> URI,
+     *                    i.e., it does not include the context path.
+     * @param servletContext the current ServletContext.
+     * @param scopeKey the scope-key associated with the new (or looked-up) scoped request.
+     * @param seeOuterRequestAttributes if <code>true</code>, a request attribute will be "seen" in the outer request,
+     *            if it is not found within the scoped request; if <code>false</code>, attributes are only seen when
+     *            they are present in the scoped request.
+     * @return the cached (or newly-created) ScopedRequest.
+     */
+    public static ScopedRequest getScopedRequest( HttpServletRequest realRequest, String overrideURI,
+                                                  ServletContext servletContext, Object scopeKey,
+                                                  boolean seeOuterRequestAttributes )
+    {
+        assert ! ( realRequest instanceof ScopedRequest );
+        
+        String requestAttr = getScopedName( OVERRIDE_REQUEST_ATTR, scopeKey );
+        ScopedRequest scopedRequest = ( ScopedRequest ) realRequest.getAttribute( requestAttr );
+        
+        //
+        // If it doesn't exist, create it and cache it.
+        //
+        if ( scopedRequest == null )
+        {
+            //
+            // The override URI must start with a slash -- it's webapp-relative.
+            //
+            if ( overrideURI != null && ! overrideURI.startsWith( "/" ) ) overrideURI = '/' + overrideURI;
+            
+            scopedRequest = 
+                new ScopedRequestImpl( realRequest, overrideURI, scopeKey, servletContext, seeOuterRequestAttributes );
+            realRequest.setAttribute( requestAttr, scopedRequest );            
+        }
+        
+        return scopedRequest;
+    }
+
+    /**
+     * Get the cached wrapper servlet response.  If none exists, creates one and caches it.
+     *
+     * @param realResponse the "real" (outer) ServletResponse, which will be wrapped.
+     * @param scopedRequest the ScopedRequest returned from {@link #getScopedRequest}.
+     * @return the cached (or newly-created) ScopedResponse.
+     */
+    public static ScopedResponse getScopedResponse( HttpServletResponse realResponse,
+                                                    ScopedRequest scopedRequest )
+    {
+        assert ! ( realResponse instanceof ScopedResponse );
+        
+        String responseAttr = getScopedName( OVERRIDE_RESPONSE_ATTR,
+                                                                      scopedRequest.getScopeKey() );
+        HttpServletRequest outerRequest = scopedRequest.getOuterRequest();
+        ScopedResponse scopedResponse = ( ScopedResponse ) outerRequest.getAttribute( responseAttr );
+        
+        //
+        // If it doesn't exist, create it and cache it.
+        //
+        if ( scopedResponse == null )
+        {
+            scopedResponse = new ScopedResponseImpl( realResponse );
+            outerRequest.setAttribute( responseAttr, scopedResponse );
+        }
+        
+        return scopedResponse;
+    }
+
+    /**
+     * Find all scoped objects ({@link ScopedRequest}, {@link ScopedResponse})
+     * which have a certain scope-key, replaces this scope-key with the new one, and re-caches the objects
+     * the new scope-key.
+     * @param oldScopeKey
+     * @param newScopeKey
+     * @param request the real (outer) request, where the scoped objects are cached.
+     */ 
+    public static void renameScope( Object oldScopeKey, Object newScopeKey, HttpServletRequest request )
+    {
+        assert ! ( request instanceof ScopedRequest );
+        
+        String requestAttr = getScopedName( OVERRIDE_REQUEST_ATTR, oldScopeKey );
+        String responseAttr = getScopedName( OVERRIDE_RESPONSE_ATTR, oldScopeKey );
+        ScopedRequest scopedRequest = ( ScopedRequest ) request.getAttribute( requestAttr );
+        ScopedResponse scopedResponse = ( ScopedResponse ) request.getAttribute( responseAttr );
+        
+        if ( scopedRequest != null )
+        {
+            scopedRequest.renameScope( newScopeKey );
+            request.removeAttribute( requestAttr );
+            requestAttr = getScopedName( OVERRIDE_REQUEST_ATTR, newScopeKey );
+            request.setAttribute( requestAttr, scopedRequest );
+        }
+        else
+        {
+            ScopedRequestImpl.renameSessionScope( oldScopeKey, newScopeKey, request );
+        }
+
+        if ( scopedResponse != null )
+        {
+            request.removeAttribute( responseAttr );
+            responseAttr = getScopedName( OVERRIDE_RESPONSE_ATTR, newScopeKey );
+            request.setAttribute( responseAttr, scopedResponse );
+        }
+    }    
+    
+    /**
+     * Get a scoped version of a given name.
+     * 
+     * @param baseName the name to be scoped.
+     * @param scopeKey the context key for scoping the name.
+     * @return a scoped version of the given name.
+     */ 
+    public static String getScopedName( String baseName, Object scopeKey )
+    {
+        return scopeKey + baseName;
+    }    
+    
+    /**
+     * Tell whether this is a scoped request.
+     * 
+     * @param request the ServletRequest to test.
+     * @return <code>true</code> if the given ServletRequest is a ScopedRequest.
+     */ 
+    /*
+    public static boolean isScoped( ServletRequest request )
+    {
+ 
+    }
+    */
+        
+    /**
+     * Get the outer (unwrapped) request.
+     * 
+     * @param request the request to unwrap.
+     * @return the outer request, if the given request is a ScopedRequest (or wraps a ScopedRequest);
+     *         otherwise, the given request itself.
+     */ 
+    public static HttpServletRequest getOuterRequest( HttpServletRequest request )
+    {
+        ScopedRequest scopedRequest = unwrapRequest( request );
+        return scopedRequest != null ? scopedRequest.getOuterRequest() : request;
+    }
+    
+    /**
+     * Get the outer (unwrapped) request.
+     * 
+     * @param request the request to unwrap.
+     * @return the outer request, if the given request is a ScopedRequest (or wraps a ScopedRequest);
+     *         otherwise, the given request itself.
+     */ 
+    public static ServletRequest getOuterServletRequest( ServletRequest request )
+    {
+        ScopedRequest scopedRequest = unwrapRequest( request );
+        return scopedRequest != null ? scopedRequest.getOuterRequest() : request;
+    }
+    
+    /**
+     * Unwraps the contained ScopedRequest from the given ServletRequest, which may be a
+     * ServletRequestWrapper.
+     * 
+     * @param request the ScopedRequest, or a wrapper (ServletRequestWrapper) around it.
+     * @return the unwrapped ScopedRequest.
+     * 
+     * @exclude
+     */ 
+    public static ScopedRequest unwrapRequest( ServletRequest request )
+    {
+        while ( request instanceof ServletRequestWrapper )
+        {
+            if ( request instanceof ScopedRequest )
+            {
+                return ( ScopedRequest ) request;
+            }
+            else
+            {
+                request = ( ( ServletRequestWrapper ) request ).getRequest();
+            }
+        }
+        
+        return null;
+    }  
+    
+    /**
+     * Unwraps the contained ScopedResponseImpl from the given ServletResponse, which may be a
+     * ServletResponseWrapper.
+     * 
+     * @param response the ScopedResponse, or a wrapper (ServletResponseWrapper) around it.
+     * @return the unwrapped ScopedResponseImpl.
+     * 
+     * @exclude
+     */ 
+    public static ScopedResponse unwrapResponse( ServletResponse response )
+    {
+        while ( response instanceof ServletResponseWrapper )
+         {
+             if ( response instanceof ScopedResponse )
+             {
+                 return ( ScopedResponse ) response;
+             }
+             else
+             {
+                 response = ( ( ServletResponseWrapper ) response ).getResponse();
+             }
+         }
+        
+         return null;
+     }
+
+    /**
+     * If the request is a ScopedRequest, this returns an attribute whose name is scoped to that request's scope-ID;
+     * otherwise, it is a straight passthrough to {@link HttpSession#getAttribute}.
+     * 
+     * @exclude
+     */ 
+    public static Object getScopedSessionAttr( String attrName, HttpServletRequest request )
+    {
+        HttpSession session = request.getSession( false );
+        
+        if ( session != null )
+        {
+            return session.getAttribute( InternalUtils.getScopedAttrName( attrName, request ) );
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+    /**
+     * If the request is a ScopedRequest, this sets an attribute whose name is scoped to that request's scope-ID;
+     * otherwise, it is a straight passthrough to {@link HttpSession#setAttribute}.
+     * 
+     * @exclude
+     */ 
+    public static void setScopedSessionAttr( String attrName, Object val, HttpServletRequest request )
+    {
+        request.getSession().setAttribute( InternalUtils.getScopedAttrName( attrName, request ), val );
+    }
+
+    /**
+     * If the request is a ScopedRequest, this removes an attribute whose name is scoped to that request's scope-ID;
+     * otherwise, it is a straight passthrough to {@link HttpSession#removeAttribute}.
+     * 
+     * @exclude
+     */ 
+    public static void removeScopedSessionAttr( String attrName, HttpServletRequest request )
+    {
+        HttpSession session = request.getSession( false );
+        
+        if ( session != null )
+        {
+            session.removeAttribute( InternalUtils.getScopedAttrName( attrName, request ) );
+        }
+    }
+    
+    /**
+     * Get an attribute from the given request, and if it is a {@link ScopedRequest}, ensure that the attribute
+     * is <strong>not</strong> "showing through" from the outer request, even if the ScopedRequest allows that by
+     * default.
+     * 
+     * @exclude
+     */ 
+    public static Object getScopedRequestAttribute( String attrName, ServletRequest request )
+    {
+        if ( request instanceof ScopedRequest )
+        {
+            return ( ( ScopedRequest ) request ).getAttribute( attrName, false );
+        }
+        
+        return request.getAttribute( attrName );
+    }
+    
+    /**
+     * Get the request URI, relative to the webapp root.
+     *
+     * @param request the current HttpServletRequest.
+     */
+    public static final String getRelativeURI( HttpServletRequest request )
+    {
+        return request.getServletPath();
+    }
+
+    /**
+     * Get a URI relative to the webapp root.
+     *
+     * @param request the current HttpServletRequest.
+     * @param uri the URI which should be made relative.
+     */
+    public static final String getRelativeURI( HttpServletRequest request, String uri )
+    {
+        return getRelativeURI( request.getContextPath(), uri );
+    }
+    
+    /**
+     * Get a URI relative to a given webapp root.
+     *
+     * @param contextPath the webapp context path, e.g., "/myWebapp"
+     * @param uri the URI which should be made relative.
+     */
+    public static final String getRelativeURI( String contextPath, String uri )
+    {
+        String requestUrl = uri;
+        int overlap = requestUrl.indexOf( contextPath + '/' );
+        assert overlap != -1 : "contextPath: " + contextPath + ", uri: " + uri;
+        return requestUrl.substring( overlap + contextPath.length() );
+    }
+
+    /**
+     * Resolve "." and ".." in a URI.
+     * @exclude
+     */ 
+    public static String normalizeURI( String uri )
+    {
+        //
+        // If it's a relative URI, normalize it.  Note that we don't want to create a URI
+        // (very expensive) unless we think we'll need to.  "./" catches "../" and "./".
+        //
+        if ( uri.indexOf( "./" ) != -1 )
+        {
+            try
+            {
+                uri = new URI( uri ).normalize().toString();
+            }
+            catch ( URISyntaxException e )
+            {
+                logger.error( "Could not parse relative URI " + uri );
+            }
+        }
+        
+        return uri;
+    }
+    
+    
+    /**
+     * @exclude
+     */ 
+    public static String decodeURI( HttpServletRequest request )
+    {
+        return request.getContextPath() + request.getServletPath();     // TODO: always decoded?
+    }
+}
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.pageflow.scoping;
+
+import org.apache.ti.pageflow.scoping.internal.ScopedRequestImpl;
+import org.apache.ti.pageflow.scoping.internal.ScopedResponseImpl;
+import org.apache.ti.pageflow.internal.InternalUtils;
+import org.apache.ti.util.logging.Logger;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletRequestWrapper;
+import javax.servlet.ServletResponse;
+import javax.servlet.ServletResponseWrapper;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+
+/**
+ * Utilities for creating scoped wrapper versions of HttpRequest, HttpResponse, ServletContext.  These
+ * wrappers are the basis for a scoped servlet environment, which can be used to scope the Struts
+ * framework.
+ */
+public class ScopedUtils
+{
+    static final String ATTR_PREFIX = "_netui:";
+    private static final String OVERRIDE_REQUEST_ATTR = ATTR_PREFIX + "overrideRequest";
+    private static final String OVERRIDE_RESPONSE_ATTR = ATTR_PREFIX + "overrideResponse";
+    
+    private static final Logger logger = Logger.getInstance( ScopedUtils.class );
+    
+    
+    /**
+     * Get the cached ScopedRequest wrapper.  If none exists, creates one and caches it.
+     * @deprecated Use {@link #getScopedRequest(HttpServletRequest, String, ServletContext, Object, boolean)}.
+     *
+     * @param realRequest the "real" (outer) HttpServletRequest, which will be wrapped.
+     * @param overrideURI the request-URI for the wrapped object.  This is a <i>webapp-relative</i> URI,
+     *                    i.e., it does not include the context path.
+     * @param servletContext the current ServletContext.
+     * @param scopeKey the scope-key associated with the new (or looked-up) scoped request.
+     * @return the cached (or newly-created) ScopedRequest.
+     */
+    public static ScopedRequest getScopedRequest( HttpServletRequest realRequest, String overrideURI,
+                                                  ServletContext servletContext, Object scopeKey )
+    {
+        return getScopedRequest( realRequest, overrideURI, servletContext, scopeKey, false );
+    }
+    
+    /**
+     * Get the cached ScopedRequest wrapper.  If none exists, creates one and caches it.
+     *
+     * @param realRequest the "real" (outer) HttpServletRequest, which will be wrapped.
+     * @param overrideURI the request-URI for the wrapped object.  This is a <i>webapp-relative</i> URI,
+     *                    i.e., it does not include the context path.
+     * @param servletContext the current ServletContext.
+     * @param scopeKey the scope-key associated with the new (or looked-up) scoped request.
+     * @param seeOuterRequestAttributes if <code>true</code>, a request attribute will be "seen" in the outer request,
+     *            if it is not found within the scoped request; if <code>false</code>, attributes are only seen when
+     *            they are present in the scoped request.
+     * @return the cached (or newly-created) ScopedRequest.
+     */
+    public static ScopedRequest getScopedRequest( HttpServletRequest realRequest, String overrideURI,
+                                                  ServletContext servletContext, Object scopeKey,
+                                                  boolean seeOuterRequestAttributes )
+    {
+        assert ! ( realRequest instanceof ScopedRequest );
+        
+        String requestAttr = getScopedName( OVERRIDE_REQUEST_ATTR, scopeKey );
+        ScopedRequest scopedRequest = ( ScopedRequest ) realRequest.getAttribute( requestAttr );
+        
+        //
+        // If it doesn't exist, create it and cache it.
+        //
+        if ( scopedRequest == null )
+        {
+            //
+            // The override URI must start with a slash -- it's webapp-relative.
+            //
+            if ( overrideURI != null && ! overrideURI.startsWith( "/" ) ) overrideURI = '/' + overrideURI;
+            
+            scopedRequest = 
+                new ScopedRequestImpl( realRequest, overrideURI, scopeKey, servletContext, seeOuterRequestAttributes );
+            realRequest.setAttribute( requestAttr, scopedRequest );            
+        }
+        
+        return scopedRequest;
+    }
+
+    /**
+     * Get the cached wrapper servlet response.  If none exists, creates one and caches it.
+     *
+     * @param realResponse the "real" (outer) ServletResponse, which will be wrapped.
+     * @param scopedRequest the ScopedRequest returned from {@link #getScopedRequest}.
+     * @return the cached (or newly-created) ScopedResponse.
+     */
+    public static ScopedResponse getScopedResponse( HttpServletResponse realResponse,
+                                                    ScopedRequest scopedRequest )
+    {
+        assert ! ( realResponse instanceof ScopedResponse );
+        
+        String responseAttr = getScopedName( OVERRIDE_RESPONSE_ATTR,
+                                                                      scopedRequest.getScopeKey() );
+        HttpServletRequest outerRequest = scopedRequest.getOuterRequest();
+        ScopedResponse scopedResponse = ( ScopedResponse ) outerRequest.getAttribute( responseAttr );
+        
+        //
+        // If it doesn't exist, create it and cache it.
+        //
+        if ( scopedResponse == null )
+        {
+            scopedResponse = new ScopedResponseImpl( realResponse );
+            outerRequest.setAttribute( responseAttr, scopedResponse );
+        }
+        
+        return scopedResponse;
+    }
+
+    /**
+     * Find all scoped objects ({@link ScopedRequest}, {@link ScopedResponse})
+     * which have a certain scope-key, replaces this scope-key with the new one, and re-caches the objects
+     * the new scope-key.
+     * @param oldScopeKey
+     * @param newScopeKey
+     * @param request the real (outer) request, where the scoped objects are cached.
+     */ 
+    public static void renameScope( Object oldScopeKey, Object newScopeKey, HttpServletRequest request )
+    {
+        assert ! ( request instanceof ScopedRequest );
+        
+        String requestAttr = getScopedName( OVERRIDE_REQUEST_ATTR, oldScopeKey );
+        String responseAttr = getScopedName( OVERRIDE_RESPONSE_ATTR, oldScopeKey );
+        ScopedRequest scopedRequest = ( ScopedRequest ) request.getAttribute( requestAttr );
+        ScopedResponse scopedResponse = ( ScopedResponse ) request.getAttribute( responseAttr );
+        
+        if ( scopedRequest != null )
+        {
+            scopedRequest.renameScope( newScopeKey );
+            request.removeAttribute( requestAttr );
+            requestAttr = getScopedName( OVERRIDE_REQUEST_ATTR, newScopeKey );
+            request.setAttribute( requestAttr, scopedRequest );
+        }
+        else
+        {
+            ScopedRequestImpl.renameSessionScope( oldScopeKey, newScopeKey, request );
+        }
+
+        if ( scopedResponse != null )
+        {
+            request.removeAttribute( responseAttr );
+            responseAttr = getScopedName( OVERRIDE_RESPONSE_ATTR, newScopeKey );
+            request.setAttribute( responseAttr, scopedResponse );
+        }
+    }    
+    
+    /**
+     * Get a scoped version of a given name.
+     * 
+     * @param baseName the name to be scoped.
+     * @param scopeKey the context key for scoping the name.
+     * @return a scoped version of the given name.
+     */ 
+    public static String getScopedName( String baseName, Object scopeKey )
+    {
+        return scopeKey + baseName;
+    }    
+    
+    /**
+     * Tell whether this is a scoped request.
+     * 
+     * @param request the ServletRequest to test.
+     * @return <code>true</code> if the given ServletRequest is a ScopedRequest.
+     */ 
+    /*
+    public static boolean isScoped( ServletRequest request )
+    {
+ 
+    }
+    */
+        
+    /**
+     * Get the outer (unwrapped) request.
+     * 
+     * @param request the request to unwrap.
+     * @return the outer request, if the given request is a ScopedRequest (or wraps a ScopedRequest);
+     *         otherwise, the given request itself.
+     */ 
+    public static HttpServletRequest getOuterRequest( HttpServletRequest request )
+    {
+        ScopedRequest scopedRequest = unwrapRequest( request );
+        return scopedRequest != null ? scopedRequest.getOuterRequest() : request;
+    }
+    
+    /**
+     * Get the outer (unwrapped) request.
+     * 
+     * @param request the request to unwrap.
+     * @return the outer request, if the given request is a ScopedRequest (or wraps a ScopedRequest);
+     *         otherwise, the given request itself.
+     */ 
+    public static ServletRequest getOuterServletRequest( ServletRequest request )
+    {
+        ScopedRequest scopedRequest = unwrapRequest( request );
+        return scopedRequest != null ? scopedRequest.getOuterRequest() : request;
+    }
+    
+    /**
+     * Unwraps the contained ScopedRequest from the given ServletRequest, which may be a
+     * ServletRequestWrapper.
+     * 
+     * @param request the ScopedRequest, or a wrapper (ServletRequestWrapper) around it.
+     * @return the unwrapped ScopedRequest.
+     * 
+     * @exclude
+     */ 
+    public static ScopedRequest unwrapRequest( ServletRequest request )
+    {
+        while ( request instanceof ServletRequestWrapper )
+        {
+            if ( request instanceof ScopedRequest )
+            {
+                return ( ScopedRequest ) request;
+            }
+            else
+            {
+                request = ( ( ServletRequestWrapper ) request ).getRequest();
+            }
+        }
+        
+        return null;
+    }  
+    
+    /**
+     * Unwraps the contained ScopedResponseImpl from the given ServletResponse, which may be a
+     * ServletResponseWrapper.
+     * 
+     * @param response the ScopedResponse, or a wrapper (ServletResponseWrapper) around it.
+     * @return the unwrapped ScopedResponseImpl.
+     * 
+     * @exclude
+     */ 
+    public static ScopedResponse unwrapResponse( ServletResponse response )
+    {
+        while ( response instanceof ServletResponseWrapper )
+         {
+             if ( response instanceof ScopedResponse )
+             {
+                 return ( ScopedResponse ) response;
+             }
+             else
+             {
+                 response = ( ( ServletResponseWrapper ) response ).getResponse();
+             }
+         }
+        
+         return null;
+     }
+
+    /**
+     * If the request is a ScopedRequest, this returns an attribute whose name is scoped to that request's scope-ID;
+     * otherwise, it is a straight passthrough to {@link HttpSession#getAttribute}.
+     * 
+     * @exclude
+     */ 
+    public static Object getScopedSessionAttr( String attrName, HttpServletRequest request )
+    {
+        HttpSession session = request.getSession( false );
+        
+        if ( session != null )
+        {
+            return session.getAttribute( InternalUtils.getScopedAttrName( attrName, request ) );
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+    /**
+     * If the request is a ScopedRequest, this sets an attribute whose name is scoped to that request's scope-ID;
+     * otherwise, it is a straight passthrough to {@link HttpSession#setAttribute}.
+     * 
+     * @exclude
+     */ 
+    public static void setScopedSessionAttr( String attrName, Object val, HttpServletRequest request )
+    {
+        request.getSession().setAttribute( InternalUtils.getScopedAttrName( attrName, request ), val );
+    }
+
+    /**
+     * If the request is a ScopedRequest, this removes an attribute whose name is scoped to that request's scope-ID;
+     * otherwise, it is a straight passthrough to {@link HttpSession#removeAttribute}.
+     * 
+     * @exclude
+     */ 
+    public static void removeScopedSessionAttr( String attrName, HttpServletRequest request )
+    {
+        HttpSession session = request.getSession( false );
+        
+        if ( session != null )
+        {
+            session.removeAttribute( InternalUtils.getScopedAttrName( attrName, request ) );
+        }
+    }
+    
+    /**
+     * Get an attribute from the given request, and if it is a {@link ScopedRequest}, ensure that the attribute
+     * is <strong>not</strong> "showing through" from the outer request, even if the ScopedRequest allows that by
+     * default.
+     * 
+     * @exclude
+     */ 
+    public static Object getScopedRequestAttribute( String attrName, ServletRequest request )
+    {
+        if ( request instanceof ScopedRequest )
+        {
+            return ( ( ScopedRequest ) request ).getAttribute( attrName, false );
+        }
+        
+        return request.getAttribute( attrName );
+    }
+    
+    /**
+     * Get the request URI, relative to the webapp root.
+     *
+     * @param request the current HttpServletRequest.
+     */
+    public static final String getRelativeURI( HttpServletRequest request )
+    {
+        return request.getServletPath();
+    }
+
+    /**
+     * Get a URI relative to the webapp root.
+     *
+     * @param request the current HttpServletRequest.
+     * @param uri the URI which should be made relative.
+     */
+    public static final String getRelativeURI( HttpServletRequest request, String uri )
+    {
+        return getRelativeURI( request.getContextPath(), uri );
+    }
+    
+    /**
+     * Get a URI relative to a given webapp root.
+     *
+     * @param contextPath the webapp context path, e.g., "/myWebapp"
+     * @param uri the URI which should be made relative.
+     */
+    public static final String getRelativeURI( String contextPath, String uri )
+    {
+        String requestUrl = uri;
+        int overlap = requestUrl.indexOf( contextPath + '/' );
+        assert overlap != -1 : "contextPath: " + contextPath + ", uri: " + uri;
+        return requestUrl.substring( overlap + contextPath.length() );
+    }
+
+    /**
+     * Resolve "." and ".." in a URI.
+     * @exclude
+     */ 
+    public static String normalizeURI( String uri )
+    {
+        //
+        // If it's a relative URI, normalize it.  Note that we don't want to create a URI
+        // (very expensive) unless we think we'll need to.  "./" catches "../" and "./".
+        //
+        if ( uri.indexOf( "./" ) != -1 )
+        {
+            try
+            {
+                uri = new URI( uri ).normalize().toString();
+            }
+            catch ( URISyntaxException e )
+            {
+                logger.error( "Could not parse relative URI " + uri );
+            }
+        }
+        
+        return uri;
+    }
+    
+    
+    /**
+     * @exclude
+     */ 
+    public static String decodeURI( HttpServletRequest request )
+    {
+        return request.getContextPath() + request.getServletPath();     // TODO: always decoded?
+    }
+}

Added: struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/scoping/internal/AttributeContainer.java.disabled
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/scoping/internal/AttributeContainer.java.disabled?rev=240168&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/scoping/internal/AttributeContainer.java.disabled (added)
+++ struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/scoping/internal/AttributeContainer.java.disabled Thu Aug 25 22:46:03 2005
@@ -0,0 +1,472 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.pageflow.scoping.internal;
+
+import org.apache.ti.util.logging.Logger;
+
+import java.util.HashMap;
+import java.util.Enumeration;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Iterator;
+import java.io.Serializable;
+
+
+public class AttributeContainer
+{
+    private static final Logger logger = Logger.getInstance( AttributeContainer.class );
+    
+    private Map _attrs;
+
+    public Object getAttribute( String attrName )
+    {
+        return ( _attrs != null ? _attrs.get( attrName ) : null );
+    }
+
+    public void setAttribute( String attrName, Object o )
+    {
+        if ( _attrs == null )
+        {
+            _attrs = new HashMap();
+        }
+
+        _attrs.put( attrName, o );
+    }
+
+    public Enumeration getAttributeNames()
+    {
+        if ( _attrs == null )
+        {
+            _attrs = new HashMap();
+        }
+
+        return Collections.enumeration( _attrs.keySet() );
+    }
+
+    public String[] getAttributeNamesArray()
+    {
+        if ( _attrs == null )
+        {
+            return new String[0];
+        }
+
+        return ( String[] ) _attrs.keySet().toArray( new String[0] );
+    }
+
+    public void removeAttribute( String attrName )
+    {
+        if ( _attrs != null )
+        {
+            _attrs.remove( attrName );
+        }
+    }
+
+    public void removeAllAttributes()
+    {
+        _attrs = null;
+    }
+
+    protected final Map getSerializableAttrs()
+    {
+        Map ret = new HashMap();
+
+        for ( Iterator i = _attrs.entrySet().iterator(); i.hasNext(); )
+        {
+            Map.Entry entry = ( Map.Entry ) i.next();
+
+            if ( entry.getValue() instanceof Serializable )
+            {
+                ret.put( entry.getKey(), entry.getValue() );
+            }
+            else
+            {
+                if ( logger.isInfoEnabled() )
+                {
+                    logger.info( "Dropping non-serializable request attribute " + entry.getKey()
+                                  + " (" + entry.getValue() + ")." );
+                }
+            }
+        }
+
+        return ret;
+    }
+    
+    protected final Map getAttrMap()
+    {
+        return _attrs;
+    }
+
+    protected final void setAttrMap( Map attrs )
+    {
+        _attrs = attrs;
+    }
+}
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.pageflow.scoping.internal;
+
+import org.apache.ti.util.logging.Logger;
+
+import java.util.HashMap;
+import java.util.Enumeration;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Iterator;
+import java.io.Serializable;
+
+
+public class AttributeContainer
+{
+    private static final Logger logger = Logger.getInstance( AttributeContainer.class );
+    
+    private Map _attrs;
+
+    public Object getAttribute( String attrName )
+    {
+        return ( _attrs != null ? _attrs.get( attrName ) : null );
+    }
+
+    public void setAttribute( String attrName, Object o )
+    {
+        if ( _attrs == null )
+        {
+            _attrs = new HashMap();
+        }
+
+        _attrs.put( attrName, o );
+    }
+
+    public Enumeration getAttributeNames()
+    {
+        if ( _attrs == null )
+        {
+            _attrs = new HashMap();
+        }
+
+        return Collections.enumeration( _attrs.keySet() );
+    }
+
+    public String[] getAttributeNamesArray()
+    {
+        if ( _attrs == null )
+        {
+            return new String[0];
+        }
+
+        return ( String[] ) _attrs.keySet().toArray( new String[0] );
+    }
+
+    public void removeAttribute( String attrName )
+    {
+        if ( _attrs != null )
+        {
+            _attrs.remove( attrName );
+        }
+    }
+
+    public void removeAllAttributes()
+    {
+        _attrs = null;
+    }
+
+    protected final Map getSerializableAttrs()
+    {
+        Map ret = new HashMap();
+
+        for ( Iterator i = _attrs.entrySet().iterator(); i.hasNext(); )
+        {
+            Map.Entry entry = ( Map.Entry ) i.next();
+
+            if ( entry.getValue() instanceof Serializable )
+            {
+                ret.put( entry.getKey(), entry.getValue() );
+            }
+            else
+            {
+                if ( logger.isInfoEnabled() )
+                {
+                    logger.info( "Dropping non-serializable request attribute " + entry.getKey()
+                                  + " (" + entry.getValue() + ")." );
+                }
+            }
+        }
+
+        return ret;
+    }
+    
+    protected final Map getAttrMap()
+    {
+        return _attrs;
+    }
+
+    protected final void setAttrMap( Map attrs )
+    {
+        _attrs = attrs;
+    }
+}
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.pageflow.scoping.internal;
+
+import org.apache.ti.util.logging.Logger;
+
+import java.util.HashMap;
+import java.util.Enumeration;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Iterator;
+import java.io.Serializable;
+
+
+public class AttributeContainer
+{
+    private static final Logger logger = Logger.getInstance( AttributeContainer.class );
+    
+    private Map _attrs;
+
+    public Object getAttribute( String attrName )
+    {
+        return ( _attrs != null ? _attrs.get( attrName ) : null );
+    }
+
+    public void setAttribute( String attrName, Object o )
+    {
+        if ( _attrs == null )
+        {
+            _attrs = new HashMap();
+        }
+
+        _attrs.put( attrName, o );
+    }
+
+    public Enumeration getAttributeNames()
+    {
+        if ( _attrs == null )
+        {
+            _attrs = new HashMap();
+        }
+
+        return Collections.enumeration( _attrs.keySet() );
+    }
+
+    public String[] getAttributeNamesArray()
+    {
+        if ( _attrs == null )
+        {
+            return new String[0];
+        }
+
+        return ( String[] ) _attrs.keySet().toArray( new String[0] );
+    }
+
+    public void removeAttribute( String attrName )
+    {
+        if ( _attrs != null )
+        {
+            _attrs.remove( attrName );
+        }
+    }
+
+    public void removeAllAttributes()
+    {
+        _attrs = null;
+    }
+
+    protected final Map getSerializableAttrs()
+    {
+        Map ret = new HashMap();
+
+        for ( Iterator i = _attrs.entrySet().iterator(); i.hasNext(); )
+        {
+            Map.Entry entry = ( Map.Entry ) i.next();
+
+            if ( entry.getValue() instanceof Serializable )
+            {
+                ret.put( entry.getKey(), entry.getValue() );
+            }
+            else
+            {
+                if ( logger.isInfoEnabled() )
+                {
+                    logger.info( "Dropping non-serializable request attribute " + entry.getKey()
+                                  + " (" + entry.getValue() + ")." );
+                }
+            }
+        }
+
+        return ret;
+    }
+    
+    protected final Map getAttrMap()
+    {
+        return _attrs;
+    }
+
+    protected final void setAttrMap( Map attrs )
+    {
+        _attrs = attrs;
+    }
+}
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed 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.
+ *
+ * $Header:$
+ */
+package org.apache.ti.pageflow.scoping.internal;
+
+import org.apache.ti.util.logging.Logger;
+
+import java.util.HashMap;
+import java.util.Enumeration;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Iterator;
+import java.io.Serializable;
+
+
+public class AttributeContainer
+{
+    private static final Logger logger = Logger.getInstance( AttributeContainer.class );
+    
+    private Map _attrs;
+
+    public Object getAttribute( String attrName )
+    {
+        return ( _attrs != null ? _attrs.get( attrName ) : null );
+    }
+
+    public void setAttribute( String attrName, Object o )
+    {
+        if ( _attrs == null )
+        {
+            _attrs = new HashMap();
+        }
+
+        _attrs.put( attrName, o );
+    }
+
+    public Enumeration getAttributeNames()
+    {
+        if ( _attrs == null )
+        {
+            _attrs = new HashMap();
+        }
+
+        return Collections.enumeration( _attrs.keySet() );
+    }
+
+    public String[] getAttributeNamesArray()
+    {
+        if ( _attrs == null )
+        {
+            return new String[0];
+        }
+
+        return ( String[] ) _attrs.keySet().toArray( new String[0] );
+    }
+
+    public void removeAttribute( String attrName )
+    {
+        if ( _attrs != null )
+        {
+            _attrs.remove( attrName );
+        }
+    }
+
+    public void removeAllAttributes()
+    {
+        _attrs = null;
+    }
+
+    protected final Map getSerializableAttrs()
+    {
+        Map ret = new HashMap();
+
+        for ( Iterator i = _attrs.entrySet().iterator(); i.hasNext(); )
+        {
+            Map.Entry entry = ( Map.Entry ) i.next();
+
+            if ( entry.getValue() instanceof Serializable )
+            {
+                ret.put( entry.getKey(), entry.getValue() );
+            }
+            else
+            {
+                if ( logger.isInfoEnabled() )
+                {
+                    logger.info( "Dropping non-serializable request attribute " + entry.getKey()
+                                  + " (" + entry.getValue() + ")." );
+                }
+            }
+        }
+
+        return ret;
+    }
+    
+    protected final Map getAttrMap()
+    {
+        return _attrs;
+    }
+
+    protected final void setAttrMap( Map attrs )
+    {
+        _attrs = attrs;
+    }
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org