cziegeler    01/10/23 05:04:14

  Modified:    src/org/apache/cocoon/generation Tag: cocoon_20_branch
                        StreamGenerator.java
               src/org/apache/cocoon/util Tag: cocoon_20_branch
                        PostInputStream.java
  Log:
  Patch for Bug 4124  StreamGenerator does not preserve XML encoding PI
  Submitted by: kingadziembowska [[EMAIL PROTECTED]]
  
  Revision  Changes    Path
  No                   revision
  
  
  No                   revision
  
  
  1.1.2.9   +99 -19    
xml-cocoon2/src/org/apache/cocoon/generation/StreamGenerator.java
  
  Index: StreamGenerator.java
  ===================================================================
  RCS file: 
/home/cvs/xml-cocoon2/src/org/apache/cocoon/generation/StreamGenerator.java,v
  retrieving revision 1.1.2.8
  retrieving revision 1.1.2.9
  diff -u -r1.1.2.8 -r1.1.2.9
  --- StreamGenerator.java      2001/10/11 08:56:12     1.1.2.8
  +++ StreamGenerator.java      2001/10/23 12:04:14     1.1.2.9
  @@ -13,8 +13,9 @@
   import org.apache.cocoon.ProcessingException;
   import org.apache.cocoon.ResourceNotFoundException;
   import org.apache.cocoon.components.parser.Parser;
  -import org.apache.cocoon.environment.Request;
  +import org.apache.avalon.excalibur.pool.Poolable;
   import org.apache.cocoon.environment.http.HttpEnvironment;
  +import javax.servlet.http.HttpServletRequest;
   import org.apache.cocoon.util.PostInputStream;
   import org.xml.sax.InputSource;
   import org.xml.sax.SAXException;
  @@ -43,9 +44,10 @@
    * number of bytes read is equal to the getContentLength() value.
    *
    * @author <a href="mailto:[EMAIL PROTECTED]";>Kinga Dziembowski</a>
  - * @version $Revision: 1.1.2.8 $ $Date: 2001/10/11 08:56:12 $
  + * @version $Revision: 1.1.2.9 $ $Date: 2001/10/23 12:04:14 $
    */
  -public class StreamGenerator extends ComposerGenerator {
  +public class StreamGenerator extends ComposerGenerator implements Poolable
  +{
       public static final String CLASS = StreamGenerator.class.getName();
   
       /** The parameter holding the name associated with the xml data  **/
  @@ -70,31 +72,27 @@
       /**
        * Generate XML data out of request InputStream.
        */
  -    public void generate() throws IOException, SAXException, ProcessingException {
  +    public void generate() throws IOException, SAXException, ProcessingException
  +    {
           Parser parser = null;
           String parameter = parameters.getParameter(StreamGenerator.FORM_NAME, null);
           int len = 0;
  -
  -        try {
  -            Request request = (Request)objectModel.get(Constants.REQUEST_OBJECT);
  -            if 
(request.getContentType().equals("application/x-www-form-urlencoded")) {
  +             String contentType = null;
  +        try
  +        {
  +            HttpServletRequest request = (HttpServletRequest) 
objectModel.get(HttpEnvironment.HTTP_REQUEST_OBJECT);
  +            contentType = request.getContentType();
  +            if (contentType.startsWith("application/x-www-form-urlencoded")) {
                   String sXml = request.getParameter(parameter);
                   inputSource = new InputSource(new StringReader(sXml));
  -            } else if (request.getContentType().equals("text/plain") ||
  -                    request.getContentType().equals("text/xml") ||
  -                    request.getContentType().equals("application/xml")) {
  +            } else if (contentType.startsWith("text/plain") ||
  +                    contentType.startsWith("text/xml") ||
  +                    contentType.startsWith("application/xml")) {
                   len = request.getContentLength();
   
                   if (len > 0) {
  -                    // we have hopefully an http request here
  -                    javax.servlet.http.HttpServletRequest httpRequest =
  -                         
(javax.servlet.http.HttpServletRequest)objectModel.get(HttpEnvironment.HTTP_REQUEST_OBJECT);
  -                    if (httpRequest != null) {
  -                        PostInputStream anStream = new 
PostInputStream(httpRequest.getInputStream(), len);
  +                        PostInputStream anStream = new 
PostInputStream(request.getInputStream(), len);
                           inputSource = new InputSource(anStream);
  -                    } else {
  -                        throw new IOException("No http request object found");
  -                    }
                   } else {
                       throw new IOException("getContentLen() == 0");
                   }
  @@ -105,6 +103,11 @@
               if (getLogger().isDebugEnabled()) {
                   getLogger().debug("processing stream ContentType= " + 
request.getContentType() + "ContentLen= " + len);
               }
  +            String charset =  getCharacterEncoding(request, contentType) ;
  +                     if( charset != null)
  +                     {
  +                             this.inputSource.setEncoding(charset);
  +            }
               parser = (Parser)this.manager.lookup(Parser.ROLE);
               parser.setContentHandler(super.contentHandler);
               parser.setLexicalHandler(super.lexicalHandler);
  @@ -124,4 +127,81 @@
               }
           }
       }
  +
  +    /**
  +     * Content type HTTP header can contains character encodinf info
  +     * for ex. Content-Type: text/xml; charset=UTF-8
  +     * If the servlet is following spec 2.3 and higher the servlet API can be used 
to retrieve character encoding part of
  +     * Content-Type header. Some containers can choose to not unpack charset info - 
the spec is not strong about it.
  +     * in any case this method can be used as a latest resource to retrieve the 
passed charset value.
  +     * <code>null</code> is returned.
  +     * It is very common mistake to send : Content-Type: text/xml; charset="UTF-8".
  +     * Some containers are not filtering this mistake and the processing results in 
exception..
  +    * The getCharacterEncoding() compensates for above mistake.
  +     *
  +     * @param contentType value associated with Content-Type HTTP header.
  +     */
  +     public String getCharacterEncoding(HttpServletRequest req, String contentType)
  +     {
  +             String charencoding = null;
  +             String charset = "charset=";
  +             if (contentType == null)
  +             {
  +                     return (null);
  +             }
  +             int idx = contentType.indexOf(charset);
  +             if (idx == -1)
  +             {
  +                     return (null);
  +             }
  +             try
  +             {
  +                     charencoding = req.getCharacterEncoding();
  +
  +                     if ( charencoding != null)
  +                     {
  +                             getLogger().debug("charset from container: " + 
charencoding);
  +                             charencoding = charencoding.trim();
  +                             if ((charencoding.length() > 2) && 
(charencoding.startsWith("\""))&& (charencoding.endsWith("\"")))
  +                             {
  +                                     charencoding = charencoding.substring(1, 
charencoding.length() - 1);
  +                             }
  +                             getLogger().debug("charset from container clean: " + 
charencoding);
  +                             return (charencoding);
  +                     }
  +                     else
  +                     {
  +
  +                             return extractCharset( contentType, idx );
  +                     }
  +             }
  +             catch(Throwable e)
  +             {
  +                     // We will be there if the container do not implement 
getCharacterEncoding() method
  +                      return extractCharset( contentType, idx );
  +             }
  +     }
  +
  +
  +     protected String extractCharset(String contentType, int idx)
  +     {
  +             String charencoding = null;
  +             String charset = "charset=";
  +
  +             getLogger().debug("charset from extractCharset");
  +             charencoding = contentType.substring(idx + charset.length());
  +             int idxEnd = charencoding.indexOf(";");
  +             if (idxEnd != -1)
  +             {
  +                     charencoding = charencoding.substring(0, idxEnd);
  +             }
  +             charencoding = charencoding.trim();
  +             if ((charencoding.length() > 2) && (charencoding.startsWith("\""))&& 
(charencoding.endsWith("\"")))
  +             {
  +                     charencoding = charencoding.substring(1, charencoding.length() 
- 1);
  +             }
  +             getLogger().debug("charset from extractCharset: " + charencoding);
  +             return (charencoding.trim());
  +
  +     }
   }
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.1.2.5   +13 -4     xml-cocoon2/src/org/apache/cocoon/util/PostInputStream.java
  
  Index: PostInputStream.java
  ===================================================================
  RCS file: /home/cvs/xml-cocoon2/src/org/apache/cocoon/util/PostInputStream.java,v
  retrieving revision 1.1.2.4
  retrieving revision 1.1.2.5
  diff -u -r1.1.2.4 -r1.1.2.5
  --- PostInputStream.java      2001/10/11 08:56:16     1.1.2.4
  +++ PostInputStream.java      2001/10/23 12:04:14     1.1.2.5
  @@ -14,7 +14,7 @@
    * It allows to control read operation, restricting the number of bytes read to the 
value returned by getContentLen() method.
    *
    * @author <a href="mailto:[EMAIL PROTECTED]";>Kinga Dziembowski</a>
  - * @version $Id: PostInputStream.java,v 1.1.2.4 2001/10/11 08:56:16 cziegeler Exp $
  + * @version $Id: PostInputStream.java,v 1.1.2.5 2001/10/23 12:04:14 cziegeler Exp $
    */
   
   public class PostInputStream extends InputStream {
  @@ -151,7 +151,8 @@
           if (m_bytesRead == m_contentLen) {
               return -1;
           }
  -        int num = m_inputStream.read(buffer, offset, len);
  +        int available = Math.min( available(), len );
  +             int num = m_inputStream.read( buffer, offset, available );
           if (num > 0) {
               m_bytesRead += num;
           }
  @@ -185,8 +186,16 @@
        * @exception  IOException  if an I/O error occurs.
        */
       public synchronized long skip(long n) throws IOException {
  -        checkOpen();
  -        return m_inputStream.skip(n);
  +             checkOpen();
  +             if ( m_bytesRead == m_contentLen )
  +             {
  +                     return ( 0 );
  +             }
  +             else
  +             {
  +                     return ( m_inputStream.skip( n ) );
  +             }
  +
       }
   
       /**
  
  
  

----------------------------------------------------------------------
In case of troubles, e-mail:     [EMAIL PROTECTED]
To unsubscribe, e-mail:          [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to