You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by re...@apache.org on 2009/03/15 14:15:26 UTC

svn commit: r754661 - in /cocoon/trunk/subprojects/cocoon-servlet-service/cocoon-servlet-service-impl/src: changes/ main/java/org/apache/cocoon/servletservice/ main/java/org/apache/cocoon/servletservice/url/ main/java/org/apache/cocoon/servletservice/u...

Author: reinhard
Date: Sun Mar 15 13:15:24 2009
New Revision: 754661

URL: http://svn.apache.org/viewvc?rev=754661&view=rev
Log:
ServletUrlConnection correctly implements #getHeaderFields() instead of relying on the NOP implementation of HttpURLConnection.

Modified:
    cocoon/trunk/subprojects/cocoon-servlet-service/cocoon-servlet-service-impl/src/changes/changes.xml
    cocoon/trunk/subprojects/cocoon-servlet-service/cocoon-servlet-service-impl/src/main/java/org/apache/cocoon/servletservice/AbstractServletConnection.java
    cocoon/trunk/subprojects/cocoon-servlet-service/cocoon-servlet-service-impl/src/main/java/org/apache/cocoon/servletservice/ServletConnection.java
    cocoon/trunk/subprojects/cocoon-servlet-service/cocoon-servlet-service-impl/src/main/java/org/apache/cocoon/servletservice/url/ServletURLConnection.java
    cocoon/trunk/subprojects/cocoon-servlet-service/cocoon-servlet-service-impl/src/main/java/org/apache/cocoon/servletservice/util/ServletServiceResponse.java

Modified: cocoon/trunk/subprojects/cocoon-servlet-service/cocoon-servlet-service-impl/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/cocoon/trunk/subprojects/cocoon-servlet-service/cocoon-servlet-service-impl/src/changes/changes.xml?rev=754661&r1=754660&r2=754661&view=diff
==============================================================================
--- cocoon/trunk/subprojects/cocoon-servlet-service/cocoon-servlet-service-impl/src/changes/changes.xml (original)
+++ cocoon/trunk/subprojects/cocoon-servlet-service/cocoon-servlet-service-impl/src/changes/changes.xml Sun Mar 15 13:15:24 2009
@@ -25,6 +25,9 @@
 <document>
   <body>
     <release version="1.2.0-SNAPSHOT" date="2008-??-??" description="unreleased">
+      <action dev="reinhard" type="add">
+        ServletUrlConnection correctly implements #getHeaderFields() instead of relying on the NOP implementation of HttpURLConnection.
+      </action>
       <action dev="gkossakowski" type="fix">
         Fixed NPE thrown by HttpServletResponseBufferingWrapper and ServletServiceResponse after resetBuffer() method was called.
       </action>

Modified: cocoon/trunk/subprojects/cocoon-servlet-service/cocoon-servlet-service-impl/src/main/java/org/apache/cocoon/servletservice/AbstractServletConnection.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/subprojects/cocoon-servlet-service/cocoon-servlet-service-impl/src/main/java/org/apache/cocoon/servletservice/AbstractServletConnection.java?rev=754661&r1=754660&r2=754661&view=diff
==============================================================================
--- cocoon/trunk/subprojects/cocoon-servlet-service/cocoon-servlet-service-impl/src/main/java/org/apache/cocoon/servletservice/AbstractServletConnection.java (original)
+++ cocoon/trunk/subprojects/cocoon-servlet-service/cocoon-servlet-service-impl/src/main/java/org/apache/cocoon/servletservice/AbstractServletConnection.java Sun Mar 15 13:15:24 2009
@@ -22,6 +22,7 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.net.URI;
+import java.util.Map;
 
 import javax.servlet.ServletContext;
 import javax.servlet.ServletException;
@@ -113,23 +114,14 @@
     }
 
     public long getLastModified() {
-        if (!this.connected) {
-            try {
-                this.connect();
-            } catch (Exception e) {
-                this.logger.warn("Exception while reading the getLastModified data.");
-                return 0;
-            }
-        }
-        long headerFieldDate = this.getHeaderFieldDate("Last-Modified", 0);
-        return headerFieldDate;
+        return this.getDateHeader("Last-Modified", 0);
     }
 
     public String getContentType() {
-        return this.getHeaderField("Content-Type");
+        return this.getHeader("Content-Type");
     }
 
-    public long getHeaderFieldDate(String name, long defaultValue) {
+    public long getDateHeader(String name, long defaultValue) {
         try {
             return this.response.getDateHeader(name);
         } catch (Exception e) {
@@ -139,7 +131,7 @@
         return defaultValue;
     }
 
-    public String getHeaderField(String name) {
+    public String getHeader(String name) {
         try {
             this.connect();
         } catch (Exception e) {
@@ -150,13 +142,32 @@
         return this.response.getHeader(name);
     }
 
+    public long getHeaderFieldDate(String name, long defaultValue) {
+        try {
+            return this.response.getDateHeader(name);
+        } catch (Exception e) {
+            this.logger.warn("Exception while reading the response header '" + name + "'.");
+        }
+
+        return defaultValue;
+    }
+
+    public Map getHeaders() {
+        try {
+            this.connect();
+        } catch (Exception e) {
+            this.logger.warn("Exception while reading the response headers.");
+            return null;
+        }
+
+        return this.response.getHeaders();
+    }
+
     public int getResponseCode() throws IOException {
-        if (!this.connected) {
-            try {
-                this.connect();
-            } catch (ServletException e) {
-                throw new IOException("Could not get response status code");
-            }
+        try {
+            this.connect();
+        } catch (ServletException e) {
+            throw new IOException("Could not get response status code");
         }
 
         return this.response.getStatus();
@@ -189,10 +200,10 @@
      */
     protected static class NoServletContextAvailableException extends RuntimeException {
 
+        private static final long serialVersionUID = 1L;
+
         public NoServletContextAvailableException(String message) {
             super(message);
         }
-
     }
-
 }

Modified: cocoon/trunk/subprojects/cocoon-servlet-service/cocoon-servlet-service-impl/src/main/java/org/apache/cocoon/servletservice/ServletConnection.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/subprojects/cocoon-servlet-service/cocoon-servlet-service-impl/src/main/java/org/apache/cocoon/servletservice/ServletConnection.java?rev=754661&r1=754660&r2=754661&view=diff
==============================================================================
--- cocoon/trunk/subprojects/cocoon-servlet-service/cocoon-servlet-service-impl/src/main/java/org/apache/cocoon/servletservice/ServletConnection.java (original)
+++ cocoon/trunk/subprojects/cocoon-servlet-service/cocoon-servlet-service-impl/src/main/java/org/apache/cocoon/servletservice/ServletConnection.java Sun Mar 15 13:15:24 2009
@@ -1,19 +1,19 @@
 /*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements.  See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License.  You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 package org.apache.cocoon.servletservice;
 
 import java.io.IOException;
@@ -21,39 +21,37 @@
 import java.io.OutputStream;
 import java.net.URI;
 import java.net.URLConnection;
+import java.util.Map;
 
 import javax.servlet.ServletException;
 
 /**
  * <p>
- * Contract to connect to a servlet service. The implementing classes differ from
- * how they look up the servlet service.
+ * Contract to connect to a servlet service. The implementing classes differ from how they look up
+ * the servlet service.
  * </p>
  * <p>
  * This class was designed similar to {@link URLConnection}.
  * </p>
- *
+ * 
  * @version $Id$
  * @since 1.0.0
  */
 public interface ServletConnection {
 
-
     // ~~~~~~~~~~~~~~~~~~~~~~~~ Pre-connect methods ~~~~~~~~~~~~~~~~~~
 
     /**
-     * Set the last modification date if you want to make use of caching. This
-     * method has to be called before any of the other methods of this interface
-     * is invoked.
-     *
-     * @param ifmodifiedsince
-     *            The timestamp of the last known resource.
+     * Set the last modification date if you want to make use of caching. This method has to be
+     * called before any of the other methods of this interface is invoked.
+     * 
+     * @param ifmodifiedsince The timestamp of the last known resource.
      */
     void setIfModifiedSince(long ifmodifiedsince);
 
     /**
      * Get an output stream that writes as POST to this connection.
-     *
+     * 
      * @return An output stream that writes as POST to this connection.
      */
     OutputStream getOutputStream();
@@ -61,13 +59,11 @@
     // ~~~~~~~~~~~~~~~~~~~~~~~~ connect method ~~~~~~~~~~~~~~~~~~
 
     /**
-     * Connect to the servlet service. Establishing a connection means that the
-     * service is executed and the response is available.
-     *
-     * @throws IOException
-     *             The connection to the servlet service can't be established.
-     * @throws ServletException
-     *             Any other problem when connecting to a servlet service.
+     * Connect to the servlet service. Establishing a connection means that the service is executed
+     * and the response is available.
+     * 
+     * @throws IOException The connection to the servlet service can't be established.
+     * @throws ServletException Any other problem when connecting to a servlet service.
      */
     void connect() throws IOException, ServletException;
 
@@ -75,17 +71,15 @@
 
     /**
      * Read the input stream from the servlet service response.
-     *
+     * 
      * @return An input stream on the servlet service response.
-     * @throws IOException
-     *             The connection to the servlet service can't be established.
-     * @throws ServletException
-     *             Any other problem when connecting to a servlet service.
+     * @throws IOException The connection to the servlet service can't be established.
+     * @throws ServletException Any other problem when connecting to a servlet service.
      */
     InputStream getInputStream() throws IOException, ServletException;
 
     /**
-     *
+     * 
      * @return The HTTP status code returned by the servlet service.
      * @throws IOException
      */
@@ -93,14 +87,14 @@
 
     /**
      * Get the last modification date of the servlet service.
-     *
+     * 
      * @return The last modification date of the servlet service.
      */
     long getLastModified();
 
     /**
      * Get the mime-type of the servlet-service.
-     *
+     * 
      * @return The mime-type of the servlet-service.
      */
     String getContentType();
@@ -109,10 +103,23 @@
 
     /**
      * Get a URI representing this servlet connection.
-     *
+     * 
      * @return a URI representing this servlet connection.
      */
     URI getURI();
 
+    /**
+     * Get a response header with the given name.
+     * 
+     * @param name The name of the header parameter
+     * @return The value of the header parameter
+     */
+    String getHeader(String name);
 
+    /**
+     * Get all response header fields.
+     * 
+     * @return A {@link Map} that contains all response headers.
+     */
+    Map<String, String> getHeaders();
 }

Modified: cocoon/trunk/subprojects/cocoon-servlet-service/cocoon-servlet-service-impl/src/main/java/org/apache/cocoon/servletservice/url/ServletURLConnection.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/subprojects/cocoon-servlet-service/cocoon-servlet-service-impl/src/main/java/org/apache/cocoon/servletservice/url/ServletURLConnection.java?rev=754661&r1=754660&r2=754661&view=diff
==============================================================================
--- cocoon/trunk/subprojects/cocoon-servlet-service/cocoon-servlet-service-impl/src/main/java/org/apache/cocoon/servletservice/url/ServletURLConnection.java (original)
+++ cocoon/trunk/subprojects/cocoon-servlet-service/cocoon-servlet-service-impl/src/main/java/org/apache/cocoon/servletservice/url/ServletURLConnection.java Sun Mar 15 13:15:24 2009
@@ -25,6 +25,12 @@
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
 
 import javax.servlet.ServletException;
 
@@ -88,6 +94,12 @@
         this.servletConnection.setIfModifiedSince(0);
     }
 
+    /**
+     * {@inheritDoc}
+     * 
+     * @see java.net.URLConnection#connect()
+     */
+    @Override
     public void connect() throws IOException {
         try {
             if (this.connected) {
@@ -104,6 +116,12 @@
         }
     }
 
+    /**
+     * {@inheritDoc}
+     * 
+     * @see java.net.HttpURLConnection#getErrorStream()
+     */
+    @Override
     public InputStream getErrorStream() {
         if (!this.connected) {
             return null;
@@ -118,6 +136,12 @@
         return null;
     }
 
+    /**
+     * {@inheritDoc}
+     * 
+     * @see java.net.URLConnection#getInputStream()
+     */
+    @Override
     public InputStream getInputStream() throws IOException {
         try {
             this.connect();
@@ -130,6 +154,12 @@
         }
     }
 
+    /**
+     * {@inheritDoc}
+     * 
+     * @see java.net.URLConnection#getLastModified()
+     */
+    @Override
     public long getLastModified() {
         try {
             this.connect();
@@ -140,10 +170,32 @@
         return this.servletConnection.getLastModified();
     }
 
+    /**
+     * {@inheritDoc}
+     * 
+     * @see java.net.URLConnection#getOutputStream()
+     */
+    @Override
     public OutputStream getOutputStream() throws IOException {
         return this.servletConnection.getOutputStream();
     }
 
+    /**
+     * {@inheritDoc}
+     * 
+     * @see java.net.URLConnection#getContentType()
+     */
+    @Override
+    public String getContentType() {
+        return this.servletConnection.getContentType();
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see java.net.HttpURLConnection#getResponseCode()
+     */
+    @Override
     public int getResponseCode() {
         try {
             this.connect();
@@ -154,11 +206,42 @@
         }
     }
 
+    /**
+     * {@inheritDoc}
+     * 
+     * @see java.net.HttpURLConnection#disconnect()
+     */
+    @Override
     public void disconnect() {
         throw new UnsupportedOperationException("Not implemented yet");
     }
 
+    /**
+     * {@inheritDoc}
+     * 
+     * @see java.net.HttpURLConnection#usingProxy()
+     */
+    @Override
     public boolean usingProxy() {
         throw new UnsupportedOperationException("Not implemented yet");
     }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see java.net.URLConnection#getHeaderFields()
+     */
+    @Override
+    public Map<String, List<String>> getHeaderFields() {
+        Map<String, List<String>> result = new HashMap<String, List<String>>();
+
+        Map<String, String> headers = this.servletConnection.getHeaders();
+        for (Entry<String, String> eachHeader : headers.entrySet()) {
+            List<String> values = new ArrayList<String>();
+            values.add(eachHeader.getValue());
+            result.put(eachHeader.getKey(), Collections.unmodifiableList(values));
+        }
+
+        return Collections.unmodifiableMap(result);
+    }
 }
\ No newline at end of file

Modified: cocoon/trunk/subprojects/cocoon-servlet-service/cocoon-servlet-service-impl/src/main/java/org/apache/cocoon/servletservice/util/ServletServiceResponse.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/subprojects/cocoon-servlet-service/cocoon-servlet-service-impl/src/main/java/org/apache/cocoon/servletservice/util/ServletServiceResponse.java?rev=754661&r1=754660&r2=754661&view=diff
==============================================================================
--- cocoon/trunk/subprojects/cocoon-servlet-service/cocoon-servlet-service-impl/src/main/java/org/apache/cocoon/servletservice/util/ServletServiceResponse.java (original)
+++ cocoon/trunk/subprojects/cocoon-servlet-service/cocoon-servlet-service-impl/src/main/java/org/apache/cocoon/servletservice/util/ServletServiceResponse.java Sun Mar 15 13:15:24 2009
@@ -1,19 +1,19 @@
 /*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements.  See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License.  You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 package org.apache.cocoon.servletservice.util;
 
 import java.io.IOException;
@@ -33,7 +33,7 @@
 
 /**
  * Creates a {@link HttpServletResponse} object that is usable for internal block calls.
- *
+ * 
  * @version $Id$
  * @since 1.0.0
  */
@@ -46,17 +46,16 @@
     private Locale locale;
     private int statusCode;
 
-    private Map headers;
+    private Map<String, String> headers;
 
     /**
      * format definied by RFC 822, see http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3
      */
     final SimpleDateFormat dateFormat = new SimpleDateFormat("EEE', 'dd' 'MMM' 'yyyy' 'HH:mm:ss' 'Z", Locale.US);
 
-
     public ServletServiceResponse() {
-        headers = new HashMap();
-        statusCode = HttpServletResponse.SC_OK;
+        this.headers = new HashMap<String, String>();
+        this.statusCode = HttpServletResponse.SC_OK;
     }
 
     public void addCookie(Cookie cookie) {
@@ -64,22 +63,22 @@
     }
 
     public void addDateHeader(String name, long date) {
-        //this class does not support multivalue headers
-        setDateHeader(name, date);
+        // this class does not support multivalue headers
+        this.setDateHeader(name, date);
     }
 
     public void addHeader(String name, String value) {
-        //this class does not support multivalue headers
-        setHeader(name, value);
+        // this class does not support multivalue headers
+        this.setHeader(name, value);
     }
 
     public void addIntHeader(String name, int value) {
-        //this class does not support multivalue headers
-        setIntHeader(name, value);
+        // this class does not support multivalue headers
+        this.setIntHeader(name, value);
     }
 
     public boolean containsHeader(String name) {
-        return headers.containsKey(name);
+        return this.headers.containsKey(name);
     }
 
     public String encodeRedirectUrl(String url) {
@@ -121,31 +120,33 @@
 
     public ServletOutputStream getOutputStream() throws IOException {
         if (this.writer != null) {
-            throw new IllegalStateException( "Tried to create output stream; writer already exists" );
+            throw new IllegalStateException("Tried to create output stream; writer already exists");
         }
 
         if (this.servletStream == null) {
             this.servletStream = new ServletOutputStream() {
 
+                @Override
                 public void flush() throws IOException {
                     ServletServiceResponse.this.outputStream.flush();
                 }
 
+                @Override
                 public void write(int b) throws IOException {
                     ServletServiceResponse.this.outputStream.write(b);
                     ServletServiceResponse.this.committed = true;
                 }
 
                 /*
-                 * This method is probably never called, the close will be
-                 * initiated directly on this.outputStream by the one who set
-                 * it via BlockCallHttpServletResponse.setOutputStream()
+                 * This method is probably never called, the close will be initiated directly on
+                 * this.outputStream by the one who set it via
+                 * BlockCallHttpServletResponse.setOutputStream()
                  */
+                @Override
                 public void close() throws IOException {
                     ServletServiceResponse.this.outputStream.close();
                 }
 
-
             };
         }
 
@@ -154,12 +155,11 @@
 
     public PrintWriter getWriter() throws IOException {
         if (this.servletStream != null) {
-            throw new IllegalStateException( "Tried to create writer; output stream already exists" );
+            throw new IllegalStateException("Tried to create writer; output stream already exists");
         }
 
         if (this.writer == null) {
-            this.writer =
-                    new PrintWriter(new OutputStreamWriter(this.outputStream, this.getCharacterEncoding()));
+            this.writer = new PrintWriter(new OutputStreamWriter(this.outputStream, this.getCharacterEncoding()));
         }
 
         return this.writer;
@@ -174,9 +174,10 @@
     }
 
     public void resetBuffer() {
-        //this class does not buffer anything so if first byte is written to output stream
-        //there is no way to reset anything
-        //Servlet Service Framework uses for buffering a wrapper called HttpServletResponseBufferingWrapper
+        // this class does not buffer anything so if first byte is written to output stream
+        // there is no way to reset anything
+        // Servlet Service Framework uses for buffering a wrapper called
+        // HttpServletResponseBufferingWrapper
         if (this.committed) {
             throw new IllegalStateException("May not resetBuffer after response is committed");
         }
@@ -203,40 +204,44 @@
     }
 
     public void setContentType(String type) {
-        setHeader("Content-Type", type);
+        this.setHeader("Content-Type", type);
     }
 
     public void setDateHeader(String name, long date) {
-        setHeader(name, dateFormat.format(new Date(date)));
+        this.setHeader(name, this.dateFormat.format(new Date(date)));
     }
 
     public long getDateHeader(String name) {
-        String header = getHeader(name);
+        String header = this.getHeader(name);
         if (header == null) {
             return -1;
         }
 
         try {
-            return dateFormat.parse(header).getTime();
+            return this.dateFormat.parse(header).getTime();
         } catch (ParseException e) {
             throw new RuntimeException(e);
         }
     }
 
     public void setHeader(String name, String value) {
-        headers.put(name, value);
+        this.headers.put(name, value);
     }
 
     public String getHeader(String name) {
-        return (String) headers.get(name);
+        return this.headers.get(name);
+    }
+
+    public Map<String, String> getHeaders() {
+        return this.headers;
     }
 
     public void setIntHeader(String name, int value) {
-        setHeader(name, String.valueOf(value));
+        this.setHeader(name, String.valueOf(value));
     }
 
     public int getIntHeader(String name) {
-        String header = getHeader(name);
+        String header = this.getHeader(name);
         if (header == null) {
             return -1;
         }
@@ -265,11 +270,10 @@
     }
 
     public String getContentType() {
-        return getHeader("Content-Type");
+        return this.getHeader("Content-Type");
     }
 
     public void setCharacterEncoding(String arg0) {
         // TODO Auto-generated method stub
     }
-
 }