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 [14/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/internal/ParseUtils.java.disabled
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/scoping/internal/ParseUtils.java.disabled?rev=240168&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/scoping/internal/ParseUtils.java.disabled (added)
+++ struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/scoping/internal/ParseUtils.java.disabled Thu Aug 25 22:46:03 2005
@@ -0,0 +1,884 @@
+/*
+ * 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 java.util.Map;
+import java.util.StringTokenizer;
+import java.io.UnsupportedEncodingException;
+
+
+class ParseUtils
+{
+    //-------------------------------------------------------------------------------------------------
+    // helpers to parse the query string.  
+    
+    /**
+     * Parses an RFC1630 query string into an existing Map.
+     *
+     * @param str      Query string
+     * @param res      Map into which insert the values.
+     * @param encoding Encoding to be used for stored Strings
+     */
+    public static void parseQueryString( String str, Map res, String encoding )
+    {
+
+        // "Within the query string, the plus sign is reserved as
+        // shorthand notation for a space. Therefore, real plus signs must
+        // be encoded. This method was used to make query URIs easier to
+        // pass in systems which did not allow spaces." -- RFC 1630
+        int i = str.indexOf( '#' );
+        if ( i > 0 )
+        {
+            str = str.substring( 0, i );
+        }
+        StringTokenizer st = new StringTokenizer( str.replace( '+', ' ' ), "&" );
+
+        while ( st.hasMoreTokens() )
+        {
+            String qp = st.nextToken();
+            String[] pair = qp.split( "=" );  // was String[] pair = StringUtils.split(qp, '=');
+            //String s = unescape(pair[1], encoding);
+            res.put( unescape( pair[0], encoding ), unescape( pair[1], encoding ) );
+        }
+    }
+
+    /**
+     * URI-unescapes the specified string, except for +/<space>
+     * encoding.
+     *
+     * @param str      String to be unescaped
+     * @param encoding The name of a character encoding
+     * @return Unescaped string
+     */
+    private static String unescape( String str, String encoding )
+    {
+        //We cannot unescape '+' to space because '+' is allowed in the file name
+        //str = str.replace('+', ' ');
+        
+        //if the str does not contain "%", we don't need to do anything
+        if ( str.indexOf( '%' ) < 0 )
+        {
+            return str;
+        }
+
+        if ( encoding == null || encoding.length() == 0 )
+        {
+            encoding = WLS_DEFAULT_ENCODING;
+        }
+        
+        // Do not assume String only contains ascii.  str.length() <= str.getBytes().length
+        int out = 0;
+
+        byte[] strbytes = str.getBytes();
+        int len = strbytes.length;
+
+        boolean foundNonAscii = false;
+        for ( int in = 0; in < len; in++, out++ )
+        {
+            if ( strbytes[in] == '%' && ( in + 2 < len ) )
+            {
+                if ( Hex.isHexChar( strbytes[in + 1] ) &&
+                     Hex.isHexChar( strbytes[in + 2] ) )
+                {
+                    strbytes[out] =
+                    ( byte ) ( ( Hex.hexValueOf( strbytes[in + 1] ) << 4 ) +
+                               ( Hex.hexValueOf( strbytes[in + 2] ) << 0 ) );
+                    in += 2;
+                    continue;
+                }
+            }
+            // IE takes non-ASCII URLs. We use the default encoding
+            // if non-ASCII characters are contained in URLs.
+            if ( !foundNonAscii &&
+                 ( strbytes[in] <= 0x1f || strbytes[in] == 0x7f ) )
+            {
+                encoding = System.getProperty( "file.encoding" );
+                foundNonAscii = true;
+            }
+            strbytes[out] = strbytes[in];
+        }
+
+        return newString( strbytes, 0, out, encoding );  // was:  BytesToString.newString(...)
+    }
+
+    private static String newString( byte b[], int offset, int length, String enc )
+    {
+        if ( is8BitUnicodeSubset( enc ) )
+        {
+            return getString( b, offset, length );
+        }
+        try
+        {
+            return new String( b, offset, length, enc );
+        }
+        catch ( UnsupportedEncodingException uee )
+        {
+            return getString( b, offset, length );
+        }
+    }
+
+    private static boolean is8BitUnicodeSubset( String enc )
+    {
+        return enc == null || "ISO-8859-1".equalsIgnoreCase( enc ) ||
+               "ISO8859_1".equalsIgnoreCase( enc ) || "ASCII".equalsIgnoreCase( enc );
+    }
+
+    private static final String WLS_DEFAULT_ENCODING = "ISO-8859-1";
+
+    private static String getString( byte b[], int offset, int length )
+    {
+        try
+        {
+            return new String( b, offset, length, WLS_DEFAULT_ENCODING );
+        }
+        catch ( UnsupportedEncodingException uee )
+        {
+            // every JVM is supposed to support ISO-8859-1
+            throw new AssertionError( uee );
+        }
+    }
+
+    static class Hex
+    {
+
+        // this class exists only for its static methods
+        private Hex()
+        {
+        }
+
+        public static int hexValueOf( int c )
+        {
+            if ( c >= '0' && c <= '9' )
+            {
+                return c - '0';
+            }
+            if ( c >= 'a' && c <= 'f' )
+            {
+                return c - 'a' + 10;
+            }
+            if ( c >= 'A' && c <= 'F' )
+            {
+                return c - 'A' + 10;
+            }
+            return 0;
+        }
+
+
+        /**
+         * Test a character to see whether it is a possible hex char.
+         *
+         * @param c char (int actually) to test.
+         */
+        public static final boolean isHexChar( int c )
+        {
+            // trade space for speed !!!!
+            switch ( c )
+            {
+                case '0':
+                case '1':
+                case '2':
+                case '3':
+                case '4':
+                case '5':
+                case '6':
+                case '7':
+                case '8':
+                case '9':
+                case 'a':
+                case 'b':
+                case 'c':
+                case 'd':
+                case 'e':
+                case 'f':
+                case 'A':
+                case 'B':
+                case 'C':
+                case 'D':
+                case 'E':
+                case 'F':
+                    return true;
+                default:
+                    return false;
+            }
+        }
+
+    }
+}
+/*
+ * 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 java.util.Map;
+import java.util.StringTokenizer;
+import java.io.UnsupportedEncodingException;
+
+
+class ParseUtils
+{
+    //-------------------------------------------------------------------------------------------------
+    // helpers to parse the query string.  
+    
+    /**
+     * Parses an RFC1630 query string into an existing Map.
+     *
+     * @param str      Query string
+     * @param res      Map into which insert the values.
+     * @param encoding Encoding to be used for stored Strings
+     */
+    public static void parseQueryString( String str, Map res, String encoding )
+    {
+
+        // "Within the query string, the plus sign is reserved as
+        // shorthand notation for a space. Therefore, real plus signs must
+        // be encoded. This method was used to make query URIs easier to
+        // pass in systems which did not allow spaces." -- RFC 1630
+        int i = str.indexOf( '#' );
+        if ( i > 0 )
+        {
+            str = str.substring( 0, i );
+        }
+        StringTokenizer st = new StringTokenizer( str.replace( '+', ' ' ), "&" );
+
+        while ( st.hasMoreTokens() )
+        {
+            String qp = st.nextToken();
+            String[] pair = qp.split( "=" );  // was String[] pair = StringUtils.split(qp, '=');
+            //String s = unescape(pair[1], encoding);
+            res.put( unescape( pair[0], encoding ), unescape( pair[1], encoding ) );
+        }
+    }
+
+    /**
+     * URI-unescapes the specified string, except for +/<space>
+     * encoding.
+     *
+     * @param str      String to be unescaped
+     * @param encoding The name of a character encoding
+     * @return Unescaped string
+     */
+    private static String unescape( String str, String encoding )
+    {
+        //We cannot unescape '+' to space because '+' is allowed in the file name
+        //str = str.replace('+', ' ');
+        
+        //if the str does not contain "%", we don't need to do anything
+        if ( str.indexOf( '%' ) < 0 )
+        {
+            return str;
+        }
+
+        if ( encoding == null || encoding.length() == 0 )
+        {
+            encoding = WLS_DEFAULT_ENCODING;
+        }
+        
+        // Do not assume String only contains ascii.  str.length() <= str.getBytes().length
+        int out = 0;
+
+        byte[] strbytes = str.getBytes();
+        int len = strbytes.length;
+
+        boolean foundNonAscii = false;
+        for ( int in = 0; in < len; in++, out++ )
+        {
+            if ( strbytes[in] == '%' && ( in + 2 < len ) )
+            {
+                if ( Hex.isHexChar( strbytes[in + 1] ) &&
+                     Hex.isHexChar( strbytes[in + 2] ) )
+                {
+                    strbytes[out] =
+                    ( byte ) ( ( Hex.hexValueOf( strbytes[in + 1] ) << 4 ) +
+                               ( Hex.hexValueOf( strbytes[in + 2] ) << 0 ) );
+                    in += 2;
+                    continue;
+                }
+            }
+            // IE takes non-ASCII URLs. We use the default encoding
+            // if non-ASCII characters are contained in URLs.
+            if ( !foundNonAscii &&
+                 ( strbytes[in] <= 0x1f || strbytes[in] == 0x7f ) )
+            {
+                encoding = System.getProperty( "file.encoding" );
+                foundNonAscii = true;
+            }
+            strbytes[out] = strbytes[in];
+        }
+
+        return newString( strbytes, 0, out, encoding );  // was:  BytesToString.newString(...)
+    }
+
+    private static String newString( byte b[], int offset, int length, String enc )
+    {
+        if ( is8BitUnicodeSubset( enc ) )
+        {
+            return getString( b, offset, length );
+        }
+        try
+        {
+            return new String( b, offset, length, enc );
+        }
+        catch ( UnsupportedEncodingException uee )
+        {
+            return getString( b, offset, length );
+        }
+    }
+
+    private static boolean is8BitUnicodeSubset( String enc )
+    {
+        return enc == null || "ISO-8859-1".equalsIgnoreCase( enc ) ||
+               "ISO8859_1".equalsIgnoreCase( enc ) || "ASCII".equalsIgnoreCase( enc );
+    }
+
+    private static final String WLS_DEFAULT_ENCODING = "ISO-8859-1";
+
+    private static String getString( byte b[], int offset, int length )
+    {
+        try
+        {
+            return new String( b, offset, length, WLS_DEFAULT_ENCODING );
+        }
+        catch ( UnsupportedEncodingException uee )
+        {
+            // every JVM is supposed to support ISO-8859-1
+            throw new AssertionError( uee );
+        }
+    }
+
+    static class Hex
+    {
+
+        // this class exists only for its static methods
+        private Hex()
+        {
+        }
+
+        public static int hexValueOf( int c )
+        {
+            if ( c >= '0' && c <= '9' )
+            {
+                return c - '0';
+            }
+            if ( c >= 'a' && c <= 'f' )
+            {
+                return c - 'a' + 10;
+            }
+            if ( c >= 'A' && c <= 'F' )
+            {
+                return c - 'A' + 10;
+            }
+            return 0;
+        }
+
+
+        /**
+         * Test a character to see whether it is a possible hex char.
+         *
+         * @param c char (int actually) to test.
+         */
+        public static final boolean isHexChar( int c )
+        {
+            // trade space for speed !!!!
+            switch ( c )
+            {
+                case '0':
+                case '1':
+                case '2':
+                case '3':
+                case '4':
+                case '5':
+                case '6':
+                case '7':
+                case '8':
+                case '9':
+                case 'a':
+                case 'b':
+                case 'c':
+                case 'd':
+                case 'e':
+                case 'f':
+                case 'A':
+                case 'B':
+                case 'C':
+                case 'D':
+                case 'E':
+                case 'F':
+                    return true;
+                default:
+                    return false;
+            }
+        }
+
+    }
+}
+/*
+ * 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 java.util.Map;
+import java.util.StringTokenizer;
+import java.io.UnsupportedEncodingException;
+
+
+class ParseUtils
+{
+    //-------------------------------------------------------------------------------------------------
+    // helpers to parse the query string.  
+    
+    /**
+     * Parses an RFC1630 query string into an existing Map.
+     *
+     * @param str      Query string
+     * @param res      Map into which insert the values.
+     * @param encoding Encoding to be used for stored Strings
+     */
+    public static void parseQueryString( String str, Map res, String encoding )
+    {
+
+        // "Within the query string, the plus sign is reserved as
+        // shorthand notation for a space. Therefore, real plus signs must
+        // be encoded. This method was used to make query URIs easier to
+        // pass in systems which did not allow spaces." -- RFC 1630
+        int i = str.indexOf( '#' );
+        if ( i > 0 )
+        {
+            str = str.substring( 0, i );
+        }
+        StringTokenizer st = new StringTokenizer( str.replace( '+', ' ' ), "&" );
+
+        while ( st.hasMoreTokens() )
+        {
+            String qp = st.nextToken();
+            String[] pair = qp.split( "=" );  // was String[] pair = StringUtils.split(qp, '=');
+            //String s = unescape(pair[1], encoding);
+            res.put( unescape( pair[0], encoding ), unescape( pair[1], encoding ) );
+        }
+    }
+
+    /**
+     * URI-unescapes the specified string, except for +/<space>
+     * encoding.
+     *
+     * @param str      String to be unescaped
+     * @param encoding The name of a character encoding
+     * @return Unescaped string
+     */
+    private static String unescape( String str, String encoding )
+    {
+        //We cannot unescape '+' to space because '+' is allowed in the file name
+        //str = str.replace('+', ' ');
+        
+        //if the str does not contain "%", we don't need to do anything
+        if ( str.indexOf( '%' ) < 0 )
+        {
+            return str;
+        }
+
+        if ( encoding == null || encoding.length() == 0 )
+        {
+            encoding = WLS_DEFAULT_ENCODING;
+        }
+        
+        // Do not assume String only contains ascii.  str.length() <= str.getBytes().length
+        int out = 0;
+
+        byte[] strbytes = str.getBytes();
+        int len = strbytes.length;
+
+        boolean foundNonAscii = false;
+        for ( int in = 0; in < len; in++, out++ )
+        {
+            if ( strbytes[in] == '%' && ( in + 2 < len ) )
+            {
+                if ( Hex.isHexChar( strbytes[in + 1] ) &&
+                     Hex.isHexChar( strbytes[in + 2] ) )
+                {
+                    strbytes[out] =
+                    ( byte ) ( ( Hex.hexValueOf( strbytes[in + 1] ) << 4 ) +
+                               ( Hex.hexValueOf( strbytes[in + 2] ) << 0 ) );
+                    in += 2;
+                    continue;
+                }
+            }
+            // IE takes non-ASCII URLs. We use the default encoding
+            // if non-ASCII characters are contained in URLs.
+            if ( !foundNonAscii &&
+                 ( strbytes[in] <= 0x1f || strbytes[in] == 0x7f ) )
+            {
+                encoding = System.getProperty( "file.encoding" );
+                foundNonAscii = true;
+            }
+            strbytes[out] = strbytes[in];
+        }
+
+        return newString( strbytes, 0, out, encoding );  // was:  BytesToString.newString(...)
+    }
+
+    private static String newString( byte b[], int offset, int length, String enc )
+    {
+        if ( is8BitUnicodeSubset( enc ) )
+        {
+            return getString( b, offset, length );
+        }
+        try
+        {
+            return new String( b, offset, length, enc );
+        }
+        catch ( UnsupportedEncodingException uee )
+        {
+            return getString( b, offset, length );
+        }
+    }
+
+    private static boolean is8BitUnicodeSubset( String enc )
+    {
+        return enc == null || "ISO-8859-1".equalsIgnoreCase( enc ) ||
+               "ISO8859_1".equalsIgnoreCase( enc ) || "ASCII".equalsIgnoreCase( enc );
+    }
+
+    private static final String WLS_DEFAULT_ENCODING = "ISO-8859-1";
+
+    private static String getString( byte b[], int offset, int length )
+    {
+        try
+        {
+            return new String( b, offset, length, WLS_DEFAULT_ENCODING );
+        }
+        catch ( UnsupportedEncodingException uee )
+        {
+            // every JVM is supposed to support ISO-8859-1
+            throw new AssertionError( uee );
+        }
+    }
+
+    static class Hex
+    {
+
+        // this class exists only for its static methods
+        private Hex()
+        {
+        }
+
+        public static int hexValueOf( int c )
+        {
+            if ( c >= '0' && c <= '9' )
+            {
+                return c - '0';
+            }
+            if ( c >= 'a' && c <= 'f' )
+            {
+                return c - 'a' + 10;
+            }
+            if ( c >= 'A' && c <= 'F' )
+            {
+                return c - 'A' + 10;
+            }
+            return 0;
+        }
+
+
+        /**
+         * Test a character to see whether it is a possible hex char.
+         *
+         * @param c char (int actually) to test.
+         */
+        public static final boolean isHexChar( int c )
+        {
+            // trade space for speed !!!!
+            switch ( c )
+            {
+                case '0':
+                case '1':
+                case '2':
+                case '3':
+                case '4':
+                case '5':
+                case '6':
+                case '7':
+                case '8':
+                case '9':
+                case 'a':
+                case 'b':
+                case 'c':
+                case 'd':
+                case 'e':
+                case 'f':
+                case 'A':
+                case 'B':
+                case 'C':
+                case 'D':
+                case 'E':
+                case 'F':
+                    return true;
+                default:
+                    return false;
+            }
+        }
+
+    }
+}
+/*
+ * 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 java.util.Map;
+import java.util.StringTokenizer;
+import java.io.UnsupportedEncodingException;
+
+
+class ParseUtils
+{
+    //-------------------------------------------------------------------------------------------------
+    // helpers to parse the query string.  
+    
+    /**
+     * Parses an RFC1630 query string into an existing Map.
+     *
+     * @param str      Query string
+     * @param res      Map into which insert the values.
+     * @param encoding Encoding to be used for stored Strings
+     */
+    public static void parseQueryString( String str, Map res, String encoding )
+    {
+
+        // "Within the query string, the plus sign is reserved as
+        // shorthand notation for a space. Therefore, real plus signs must
+        // be encoded. This method was used to make query URIs easier to
+        // pass in systems which did not allow spaces." -- RFC 1630
+        int i = str.indexOf( '#' );
+        if ( i > 0 )
+        {
+            str = str.substring( 0, i );
+        }
+        StringTokenizer st = new StringTokenizer( str.replace( '+', ' ' ), "&" );
+
+        while ( st.hasMoreTokens() )
+        {
+            String qp = st.nextToken();
+            String[] pair = qp.split( "=" );  // was String[] pair = StringUtils.split(qp, '=');
+            //String s = unescape(pair[1], encoding);
+            res.put( unescape( pair[0], encoding ), unescape( pair[1], encoding ) );
+        }
+    }
+
+    /**
+     * URI-unescapes the specified string, except for +/<space>
+     * encoding.
+     *
+     * @param str      String to be unescaped
+     * @param encoding The name of a character encoding
+     * @return Unescaped string
+     */
+    private static String unescape( String str, String encoding )
+    {
+        //We cannot unescape '+' to space because '+' is allowed in the file name
+        //str = str.replace('+', ' ');
+        
+        //if the str does not contain "%", we don't need to do anything
+        if ( str.indexOf( '%' ) < 0 )
+        {
+            return str;
+        }
+
+        if ( encoding == null || encoding.length() == 0 )
+        {
+            encoding = WLS_DEFAULT_ENCODING;
+        }
+        
+        // Do not assume String only contains ascii.  str.length() <= str.getBytes().length
+        int out = 0;
+
+        byte[] strbytes = str.getBytes();
+        int len = strbytes.length;
+
+        boolean foundNonAscii = false;
+        for ( int in = 0; in < len; in++, out++ )
+        {
+            if ( strbytes[in] == '%' && ( in + 2 < len ) )
+            {
+                if ( Hex.isHexChar( strbytes[in + 1] ) &&
+                     Hex.isHexChar( strbytes[in + 2] ) )
+                {
+                    strbytes[out] =
+                    ( byte ) ( ( Hex.hexValueOf( strbytes[in + 1] ) << 4 ) +
+                               ( Hex.hexValueOf( strbytes[in + 2] ) << 0 ) );
+                    in += 2;
+                    continue;
+                }
+            }
+            // IE takes non-ASCII URLs. We use the default encoding
+            // if non-ASCII characters are contained in URLs.
+            if ( !foundNonAscii &&
+                 ( strbytes[in] <= 0x1f || strbytes[in] == 0x7f ) )
+            {
+                encoding = System.getProperty( "file.encoding" );
+                foundNonAscii = true;
+            }
+            strbytes[out] = strbytes[in];
+        }
+
+        return newString( strbytes, 0, out, encoding );  // was:  BytesToString.newString(...)
+    }
+
+    private static String newString( byte b[], int offset, int length, String enc )
+    {
+        if ( is8BitUnicodeSubset( enc ) )
+        {
+            return getString( b, offset, length );
+        }
+        try
+        {
+            return new String( b, offset, length, enc );
+        }
+        catch ( UnsupportedEncodingException uee )
+        {
+            return getString( b, offset, length );
+        }
+    }
+
+    private static boolean is8BitUnicodeSubset( String enc )
+    {
+        return enc == null || "ISO-8859-1".equalsIgnoreCase( enc ) ||
+               "ISO8859_1".equalsIgnoreCase( enc ) || "ASCII".equalsIgnoreCase( enc );
+    }
+
+    private static final String WLS_DEFAULT_ENCODING = "ISO-8859-1";
+
+    private static String getString( byte b[], int offset, int length )
+    {
+        try
+        {
+            return new String( b, offset, length, WLS_DEFAULT_ENCODING );
+        }
+        catch ( UnsupportedEncodingException uee )
+        {
+            // every JVM is supposed to support ISO-8859-1
+            throw new AssertionError( uee );
+        }
+    }
+
+    static class Hex
+    {
+
+        // this class exists only for its static methods
+        private Hex()
+        {
+        }
+
+        public static int hexValueOf( int c )
+        {
+            if ( c >= '0' && c <= '9' )
+            {
+                return c - '0';
+            }
+            if ( c >= 'a' && c <= 'f' )
+            {
+                return c - 'a' + 10;
+            }
+            if ( c >= 'A' && c <= 'F' )
+            {
+                return c - 'A' + 10;
+            }
+            return 0;
+        }
+
+
+        /**
+         * Test a character to see whether it is a possible hex char.
+         *
+         * @param c char (int actually) to test.
+         */
+        public static final boolean isHexChar( int c )
+        {
+            // trade space for speed !!!!
+            switch ( c )
+            {
+                case '0':
+                case '1':
+                case '2':
+                case '3':
+                case '4':
+                case '5':
+                case '6':
+                case '7':
+                case '8':
+                case '9':
+                case 'a':
+                case 'b':
+                case 'c':
+                case 'd':
+                case 'e':
+                case 'f':
+                case 'A':
+                case 'B':
+                case 'C':
+                case 'D':
+                case 'E':
+                case 'F':
+                    return true;
+                default:
+                    return false;
+            }
+        }
+
+    }
+}

Added: struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/scoping/internal/ScopedAttributeContainer.java.disabled
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/scoping/internal/ScopedAttributeContainer.java.disabled?rev=240168&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/scoping/internal/ScopedAttributeContainer.java.disabled (added)
+++ struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/scoping/internal/ScopedAttributeContainer.java.disabled Thu Aug 25 22:46:03 2005
@@ -0,0 +1,284 @@
+/*
+ * 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.pageflow.scoping.ScopedUtils;
+
+
+/**
+ * Base class for wrapper objects that keep their own scoped attributes, ignoring the attributes
+ * of the wrapped objects.
+ */
+public class ScopedAttributeContainer extends AttributeContainer
+{
+    private Object _scopeKey;
+
+    public ScopedAttributeContainer( Object scopeKey )
+    {
+        _scopeKey = scopeKey;
+    }
+
+    public final String getScopedName( String baseName )
+    {
+        return ScopedUtils.getScopedName( baseName, _scopeKey );
+    }
+
+    public boolean isInScope( String keyName )
+    {
+        return isInScope( keyName, _scopeKey );
+    }
+
+    public static boolean isInScope( String keyName, Object scopeKey )
+    {
+        return keyName.startsWith( scopeKey.toString() );
+    }
+
+    public String removeScope( String keyName )
+    {
+        return removeScope( keyName, _scopeKey );
+    }
+    
+    public static String removeScope( String keyName, Object scopeKey )
+    {
+        assert keyName.startsWith( scopeKey.toString() ) : keyName;
+        return keyName.substring( scopeKey.toString().length() );
+    }
+    
+    public final Object getScopeKey()
+    {
+        return _scopeKey;
+    }
+
+    public void renameScope( Object newScopeKey )
+    {
+        _scopeKey = newScopeKey;
+    }
+}
+/*
+ * 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.pageflow.scoping.ScopedUtils;
+
+
+/**
+ * Base class for wrapper objects that keep their own scoped attributes, ignoring the attributes
+ * of the wrapped objects.
+ */
+public class ScopedAttributeContainer extends AttributeContainer
+{
+    private Object _scopeKey;
+
+    public ScopedAttributeContainer( Object scopeKey )
+    {
+        _scopeKey = scopeKey;
+    }
+
+    public final String getScopedName( String baseName )
+    {
+        return ScopedUtils.getScopedName( baseName, _scopeKey );
+    }
+
+    public boolean isInScope( String keyName )
+    {
+        return isInScope( keyName, _scopeKey );
+    }
+
+    public static boolean isInScope( String keyName, Object scopeKey )
+    {
+        return keyName.startsWith( scopeKey.toString() );
+    }
+
+    public String removeScope( String keyName )
+    {
+        return removeScope( keyName, _scopeKey );
+    }
+    
+    public static String removeScope( String keyName, Object scopeKey )
+    {
+        assert keyName.startsWith( scopeKey.toString() ) : keyName;
+        return keyName.substring( scopeKey.toString().length() );
+    }
+    
+    public final Object getScopeKey()
+    {
+        return _scopeKey;
+    }
+
+    public void renameScope( Object newScopeKey )
+    {
+        _scopeKey = newScopeKey;
+    }
+}
+/*
+ * 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.pageflow.scoping.ScopedUtils;
+
+
+/**
+ * Base class for wrapper objects that keep their own scoped attributes, ignoring the attributes
+ * of the wrapped objects.
+ */
+public class ScopedAttributeContainer extends AttributeContainer
+{
+    private Object _scopeKey;
+
+    public ScopedAttributeContainer( Object scopeKey )
+    {
+        _scopeKey = scopeKey;
+    }
+
+    public final String getScopedName( String baseName )
+    {
+        return ScopedUtils.getScopedName( baseName, _scopeKey );
+    }
+
+    public boolean isInScope( String keyName )
+    {
+        return isInScope( keyName, _scopeKey );
+    }
+
+    public static boolean isInScope( String keyName, Object scopeKey )
+    {
+        return keyName.startsWith( scopeKey.toString() );
+    }
+
+    public String removeScope( String keyName )
+    {
+        return removeScope( keyName, _scopeKey );
+    }
+    
+    public static String removeScope( String keyName, Object scopeKey )
+    {
+        assert keyName.startsWith( scopeKey.toString() ) : keyName;
+        return keyName.substring( scopeKey.toString().length() );
+    }
+    
+    public final Object getScopeKey()
+    {
+        return _scopeKey;
+    }
+
+    public void renameScope( Object newScopeKey )
+    {
+        _scopeKey = newScopeKey;
+    }
+}
+/*
+ * 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.pageflow.scoping.ScopedUtils;
+
+
+/**
+ * Base class for wrapper objects that keep their own scoped attributes, ignoring the attributes
+ * of the wrapped objects.
+ */
+public class ScopedAttributeContainer extends AttributeContainer
+{
+    private Object _scopeKey;
+
+    public ScopedAttributeContainer( Object scopeKey )
+    {
+        _scopeKey = scopeKey;
+    }
+
+    public final String getScopedName( String baseName )
+    {
+        return ScopedUtils.getScopedName( baseName, _scopeKey );
+    }
+
+    public boolean isInScope( String keyName )
+    {
+        return isInScope( keyName, _scopeKey );
+    }
+
+    public static boolean isInScope( String keyName, Object scopeKey )
+    {
+        return keyName.startsWith( scopeKey.toString() );
+    }
+
+    public String removeScope( String keyName )
+    {
+        return removeScope( keyName, _scopeKey );
+    }
+    
+    public static String removeScope( String keyName, Object scopeKey )
+    {
+        assert keyName.startsWith( scopeKey.toString() ) : keyName;
+        return keyName.substring( scopeKey.toString().length() );
+    }
+    
+    public final Object getScopeKey()
+    {
+        return _scopeKey;
+    }
+
+    public void renameScope( Object newScopeKey )
+    {
+        _scopeKey = newScopeKey;
+    }
+}

Added: struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/scoping/internal/ScopedRequestDispatcher.java.disabled
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/scoping/internal/ScopedRequestDispatcher.java.disabled?rev=240168&view=auto
==============================================================================
--- struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/scoping/internal/ScopedRequestDispatcher.java.disabled (added)
+++ struts/sandbox/trunk/ti/core/src/java/org/apache/ti/pageflow/scoping/internal/ScopedRequestDispatcher.java.disabled Thu Aug 25 22:46:03 2005
@@ -0,0 +1,512 @@
+/*
+ * 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 javax.servlet.RequestDispatcher;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+import org.apache.ti.pageflow.scoping.ScopedUtils;
+import org.apache.ti.util.logging.Logger;
+
+
+/**
+ * A request dispatcher that doesn't actually forward (but keeps track of the attempted
+ * forward), and which does some extra work to do server includes into our ScopedRequest
+ * and ScopedResponse.
+ *
+ * @see ScopedRequestImpl
+ * @see ScopedResponseImpl
+ */
+public class ScopedRequestDispatcher
+        implements RequestDispatcher
+{
+    private String _uri;
+
+    private static final String REQUEST_URI_INCLUDE = "javax.servlet.include.request_uri";
+
+    private static final Logger logger = Logger.getInstance( ScopedRequestDispatcher.class );
+    
+    
+    /**
+     * Constructor.
+     * 
+     * @param uri the URI to which we'll "forward" or include.
+     */ 
+    public ScopedRequestDispatcher( String uri )
+    {
+        _uri = uri;
+    }
+
+    /**
+     * Does not actually cause a server forward of the request, but informs the ScopedRequest
+     * object that a forward was attempted for a particular URI.
+     * 
+     * @param request the ScopedRequest, or a wrapper (ServletRequestWrapper) around it.
+     * @param response the ScopedResponse, or a wrapper (ServletResponseWrapper) around it.
+     */ 
+    public void forward( ServletRequest request, ServletResponse response )
+            throws ServletException, IOException
+    {
+        ScopedRequestImpl scopedRequest = ( ScopedRequestImpl ) ScopedUtils.unwrapRequest( request );
+        assert scopedRequest != null : request.getClass().getName();
+        scopedRequest.setForwardedURI( _uri );
+        scopedRequest.doForward();
+    }
+
+    /**
+     * Does a server include of the stored URI into the given ScopedRequest and ScopedResponse.
+     * 
+     * @param request the ScopedRequest, or a wrapper (ServletRequestWrapper) around it.
+     * @param response the ScopedResponse, or a wrapper (ServletResponseWrapper) around it.
+     */ 
+    public void include( ServletRequest request, ServletResponse response )
+            throws ServletException, IOException
+    {
+        assert request instanceof HttpServletRequest : request.getClass().getName();
+        HttpServletRequest httpRequest = ( HttpServletRequest ) request;
+        
+        //
+        // First, unwrap the request and response, looking for our ScopedRequest and ScopedResponse.
+        //
+        HttpServletRequest outerRequest = ScopedUtils.getOuterRequest( httpRequest );
+        
+        //
+        // Need to set the "javax.servlet.include.request_uri" attribute on the outer request
+        // before forwarding with a request dispatcher.  This attribute is used to keep track of
+        // the included URI.
+        //
+        outerRequest.setAttribute( REQUEST_URI_INCLUDE, httpRequest.getRequestURI());
+        
+        if ( logger.isDebugEnabled() )
+        {
+            logger.debug( "Delegating to RequestDispatcher for URI " + _uri );
+        }
+        
+        try
+        {
+            RequestDispatcher realDispatcher = outerRequest.getRequestDispatcher( _uri );
+            
+            if ( realDispatcher == null )
+            {
+                assert response instanceof HttpServletResponse : response.getClass().getName();
+                ( ( HttpServletResponse ) response ).setStatus( HttpServletResponse.SC_NOT_FOUND );                
+                logger.error( "Could not get RequestDispatcher for URI " + _uri );
+            }
+            else
+            {
+                realDispatcher.include( request, response );
+            }
+        }
+        catch ( ServletException e )
+        {
+            logger.error( "Exception during RequestDispatcher.include().", e.getRootCause() );
+            
+            throw e;
+        }
+    }
+}
+/*
+ * 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 javax.servlet.RequestDispatcher;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+import org.apache.ti.pageflow.scoping.ScopedUtils;
+import org.apache.ti.util.logging.Logger;
+
+
+/**
+ * A request dispatcher that doesn't actually forward (but keeps track of the attempted
+ * forward), and which does some extra work to do server includes into our ScopedRequest
+ * and ScopedResponse.
+ *
+ * @see ScopedRequestImpl
+ * @see ScopedResponseImpl
+ */
+public class ScopedRequestDispatcher
+        implements RequestDispatcher
+{
+    private String _uri;
+
+    private static final String REQUEST_URI_INCLUDE = "javax.servlet.include.request_uri";
+
+    private static final Logger logger = Logger.getInstance( ScopedRequestDispatcher.class );
+    
+    
+    /**
+     * Constructor.
+     * 
+     * @param uri the URI to which we'll "forward" or include.
+     */ 
+    public ScopedRequestDispatcher( String uri )
+    {
+        _uri = uri;
+    }
+
+    /**
+     * Does not actually cause a server forward of the request, but informs the ScopedRequest
+     * object that a forward was attempted for a particular URI.
+     * 
+     * @param request the ScopedRequest, or a wrapper (ServletRequestWrapper) around it.
+     * @param response the ScopedResponse, or a wrapper (ServletResponseWrapper) around it.
+     */ 
+    public void forward( ServletRequest request, ServletResponse response )
+            throws ServletException, IOException
+    {
+        ScopedRequestImpl scopedRequest = ( ScopedRequestImpl ) ScopedUtils.unwrapRequest( request );
+        assert scopedRequest != null : request.getClass().getName();
+        scopedRequest.setForwardedURI( _uri );
+        scopedRequest.doForward();
+    }
+
+    /**
+     * Does a server include of the stored URI into the given ScopedRequest and ScopedResponse.
+     * 
+     * @param request the ScopedRequest, or a wrapper (ServletRequestWrapper) around it.
+     * @param response the ScopedResponse, or a wrapper (ServletResponseWrapper) around it.
+     */ 
+    public void include( ServletRequest request, ServletResponse response )
+            throws ServletException, IOException
+    {
+        assert request instanceof HttpServletRequest : request.getClass().getName();
+        HttpServletRequest httpRequest = ( HttpServletRequest ) request;
+        
+        //
+        // First, unwrap the request and response, looking for our ScopedRequest and ScopedResponse.
+        //
+        HttpServletRequest outerRequest = ScopedUtils.getOuterRequest( httpRequest );
+        
+        //
+        // Need to set the "javax.servlet.include.request_uri" attribute on the outer request
+        // before forwarding with a request dispatcher.  This attribute is used to keep track of
+        // the included URI.
+        //
+        outerRequest.setAttribute( REQUEST_URI_INCLUDE, httpRequest.getRequestURI());
+        
+        if ( logger.isDebugEnabled() )
+        {
+            logger.debug( "Delegating to RequestDispatcher for URI " + _uri );
+        }
+        
+        try
+        {
+            RequestDispatcher realDispatcher = outerRequest.getRequestDispatcher( _uri );
+            
+            if ( realDispatcher == null )
+            {
+                assert response instanceof HttpServletResponse : response.getClass().getName();
+                ( ( HttpServletResponse ) response ).setStatus( HttpServletResponse.SC_NOT_FOUND );                
+                logger.error( "Could not get RequestDispatcher for URI " + _uri );
+            }
+            else
+            {
+                realDispatcher.include( request, response );
+            }
+        }
+        catch ( ServletException e )
+        {
+            logger.error( "Exception during RequestDispatcher.include().", e.getRootCause() );
+            
+            throw e;
+        }
+    }
+}
+/*
+ * 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 javax.servlet.RequestDispatcher;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+import org.apache.ti.pageflow.scoping.ScopedUtils;
+import org.apache.ti.util.logging.Logger;
+
+
+/**
+ * A request dispatcher that doesn't actually forward (but keeps track of the attempted
+ * forward), and which does some extra work to do server includes into our ScopedRequest
+ * and ScopedResponse.
+ *
+ * @see ScopedRequestImpl
+ * @see ScopedResponseImpl
+ */
+public class ScopedRequestDispatcher
+        implements RequestDispatcher
+{
+    private String _uri;
+
+    private static final String REQUEST_URI_INCLUDE = "javax.servlet.include.request_uri";
+
+    private static final Logger logger = Logger.getInstance( ScopedRequestDispatcher.class );
+    
+    
+    /**
+     * Constructor.
+     * 
+     * @param uri the URI to which we'll "forward" or include.
+     */ 
+    public ScopedRequestDispatcher( String uri )
+    {
+        _uri = uri;
+    }
+
+    /**
+     * Does not actually cause a server forward of the request, but informs the ScopedRequest
+     * object that a forward was attempted for a particular URI.
+     * 
+     * @param request the ScopedRequest, or a wrapper (ServletRequestWrapper) around it.
+     * @param response the ScopedResponse, or a wrapper (ServletResponseWrapper) around it.
+     */ 
+    public void forward( ServletRequest request, ServletResponse response )
+            throws ServletException, IOException
+    {
+        ScopedRequestImpl scopedRequest = ( ScopedRequestImpl ) ScopedUtils.unwrapRequest( request );
+        assert scopedRequest != null : request.getClass().getName();
+        scopedRequest.setForwardedURI( _uri );
+        scopedRequest.doForward();
+    }
+
+    /**
+     * Does a server include of the stored URI into the given ScopedRequest and ScopedResponse.
+     * 
+     * @param request the ScopedRequest, or a wrapper (ServletRequestWrapper) around it.
+     * @param response the ScopedResponse, or a wrapper (ServletResponseWrapper) around it.
+     */ 
+    public void include( ServletRequest request, ServletResponse response )
+            throws ServletException, IOException
+    {
+        assert request instanceof HttpServletRequest : request.getClass().getName();
+        HttpServletRequest httpRequest = ( HttpServletRequest ) request;
+        
+        //
+        // First, unwrap the request and response, looking for our ScopedRequest and ScopedResponse.
+        //
+        HttpServletRequest outerRequest = ScopedUtils.getOuterRequest( httpRequest );
+        
+        //
+        // Need to set the "javax.servlet.include.request_uri" attribute on the outer request
+        // before forwarding with a request dispatcher.  This attribute is used to keep track of
+        // the included URI.
+        //
+        outerRequest.setAttribute( REQUEST_URI_INCLUDE, httpRequest.getRequestURI());
+        
+        if ( logger.isDebugEnabled() )
+        {
+            logger.debug( "Delegating to RequestDispatcher for URI " + _uri );
+        }
+        
+        try
+        {
+            RequestDispatcher realDispatcher = outerRequest.getRequestDispatcher( _uri );
+            
+            if ( realDispatcher == null )
+            {
+                assert response instanceof HttpServletResponse : response.getClass().getName();
+                ( ( HttpServletResponse ) response ).setStatus( HttpServletResponse.SC_NOT_FOUND );                
+                logger.error( "Could not get RequestDispatcher for URI " + _uri );
+            }
+            else
+            {
+                realDispatcher.include( request, response );
+            }
+        }
+        catch ( ServletException e )
+        {
+            logger.error( "Exception during RequestDispatcher.include().", e.getRootCause() );
+            
+            throw e;
+        }
+    }
+}
+/*
+ * 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 javax.servlet.RequestDispatcher;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+import org.apache.ti.pageflow.scoping.ScopedUtils;
+import org.apache.ti.util.logging.Logger;
+
+
+/**
+ * A request dispatcher that doesn't actually forward (but keeps track of the attempted
+ * forward), and which does some extra work to do server includes into our ScopedRequest
+ * and ScopedResponse.
+ *
+ * @see ScopedRequestImpl
+ * @see ScopedResponseImpl
+ */
+public class ScopedRequestDispatcher
+        implements RequestDispatcher
+{
+    private String _uri;
+
+    private static final String REQUEST_URI_INCLUDE = "javax.servlet.include.request_uri";
+
+    private static final Logger logger = Logger.getInstance( ScopedRequestDispatcher.class );
+    
+    
+    /**
+     * Constructor.
+     * 
+     * @param uri the URI to which we'll "forward" or include.
+     */ 
+    public ScopedRequestDispatcher( String uri )
+    {
+        _uri = uri;
+    }
+
+    /**
+     * Does not actually cause a server forward of the request, but informs the ScopedRequest
+     * object that a forward was attempted for a particular URI.
+     * 
+     * @param request the ScopedRequest, or a wrapper (ServletRequestWrapper) around it.
+     * @param response the ScopedResponse, or a wrapper (ServletResponseWrapper) around it.
+     */ 
+    public void forward( ServletRequest request, ServletResponse response )
+            throws ServletException, IOException
+    {
+        ScopedRequestImpl scopedRequest = ( ScopedRequestImpl ) ScopedUtils.unwrapRequest( request );
+        assert scopedRequest != null : request.getClass().getName();
+        scopedRequest.setForwardedURI( _uri );
+        scopedRequest.doForward();
+    }
+
+    /**
+     * Does a server include of the stored URI into the given ScopedRequest and ScopedResponse.
+     * 
+     * @param request the ScopedRequest, or a wrapper (ServletRequestWrapper) around it.
+     * @param response the ScopedResponse, or a wrapper (ServletResponseWrapper) around it.
+     */ 
+    public void include( ServletRequest request, ServletResponse response )
+            throws ServletException, IOException
+    {
+        assert request instanceof HttpServletRequest : request.getClass().getName();
+        HttpServletRequest httpRequest = ( HttpServletRequest ) request;
+        
+        //
+        // First, unwrap the request and response, looking for our ScopedRequest and ScopedResponse.
+        //
+        HttpServletRequest outerRequest = ScopedUtils.getOuterRequest( httpRequest );
+        
+        //
+        // Need to set the "javax.servlet.include.request_uri" attribute on the outer request
+        // before forwarding with a request dispatcher.  This attribute is used to keep track of
+        // the included URI.
+        //
+        outerRequest.setAttribute( REQUEST_URI_INCLUDE, httpRequest.getRequestURI());
+        
+        if ( logger.isDebugEnabled() )
+        {
+            logger.debug( "Delegating to RequestDispatcher for URI " + _uri );
+        }
+        
+        try
+        {
+            RequestDispatcher realDispatcher = outerRequest.getRequestDispatcher( _uri );
+            
+            if ( realDispatcher == null )
+            {
+                assert response instanceof HttpServletResponse : response.getClass().getName();
+                ( ( HttpServletResponse ) response ).setStatus( HttpServletResponse.SC_NOT_FOUND );                
+                logger.error( "Could not get RequestDispatcher for URI " + _uri );
+            }
+            else
+            {
+                realDispatcher.include( request, response );
+            }
+        }
+        catch ( ServletException e )
+        {
+            logger.error( "Exception during RequestDispatcher.include().", e.getRootCause() );
+            
+            throw e;
+        }
+    }
+}



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