2009/05/20 - Apache Shale has been retired.

For more information, please explore the Attic.

Coverage Report - org.apache.shale.remoting.faces.ResponseFactory
 
Classes in this File Line Coverage Branch Coverage Complexity
ResponseFactory
100%
45/45
N/A
8.6
 
 1  
 /*
 2  
  * Licensed to the Apache Software Foundation (ASF) under one or more
 3  
  * contributor license agreements.  See the NOTICE file distributed with
 4  
  * this work for additional information regarding copyright ownership.
 5  
  * The ASF licenses this file to you under the Apache License, Version 2.0
 6  
  * (the "License"); you may not use this file except in compliance with
 7  
  * the License.  You may obtain a copy of the License at
 8  
  *
 9  
  *      http://www.apache.org/licenses/LICENSE-2.0
 10  
  *
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  */
 17  
 
 18  
 package org.apache.shale.remoting.faces;
 19  
 
 20  
 import java.io.OutputStream;
 21  
 import java.io.Writer;
 22  
 import java.lang.reflect.InvocationTargetException;
 23  
 import java.lang.reflect.Method;
 24  
 import javax.faces.FacesException;
 25  
 import javax.faces.FactoryFinder;
 26  
 import javax.faces.component.UIViewRoot;
 27  
 import javax.faces.context.FacesContext;
 28  
 import javax.faces.context.ResponseStream;
 29  
 import javax.faces.context.ResponseWriter;
 30  
 import javax.faces.render.RenderKit;
 31  
 import javax.faces.render.RenderKitFactory;
 32  
 import javax.servlet.http.HttpServletResponse;
 33  
 
 34  
 /**
 35  
  * <p>Factory class for returning <code>ResponseStream</code> or
 36  
  * <code>ResponseWriter</code> instances that may be used to produce output
 37  
  * response content that is independent of whether we are running in a servlet
 38  
  * or portlet environment.  The <code>RenderKit</code> for the current request
 39  
  * will be used to manufacture stream or writer instances, if necessary.</p>
 40  
  */
 41  8
 public class ResponseFactory {
 42  
 
 43  
 
 44  
     // ------------------------------------------------------------ Constructors
 45  
 
 46  
 
 47  
 
 48  
     // ---------------------------------------------------------- Public Methods
 49  
 
 50  
 
 51  
     /**
 52  
      * <p>Return the configured <code>ResponseStream</code> for the current
 53  
      * request, creating and installing a new one if necessary.</p>
 54  
      *
 55  
      * @param context <code>FacesContext</code> for the current request
 56  
      * @param contentType Content type to be set on the response,
 57  
      *  or <code>null</code> to let this be defaulted
 58  
      */
 59  
     public ResponseStream getResponseStream(FacesContext context, String contentType) {
 60  
 
 61  4
         ResponseStream stream = context.getResponseStream();
 62  4
         if (stream == null) {
 63  4
             stream = createResponseStream(context, contentType);
 64  4
             context.setResponseStream(stream);
 65  
         }
 66  4
         return stream;
 67  
 
 68  
     }
 69  
 
 70  
 
 71  
     /**
 72  
      * <p>Return the configured <code>ResponseWriter</code> for the current
 73  
      * request, creating and installing a new one if necessary.</p>
 74  
      *
 75  
      * @param context <code>FacesContext</code> for the current request
 76  
      * @param contentType Content type to be set on the response,
 77  
      *  or <code>null</code> to let this be defaulted
 78  
      */
 79  
     public ResponseWriter getResponseWriter(FacesContext context, String contentType) {
 80  
 
 81  4
         ResponseWriter writer = context.getResponseWriter();
 82  4
         if (writer == null) {
 83  4
             writer = createResponseWriter(context, contentType);
 84  4
             context.setResponseWriter(writer);
 85  
         }
 86  4
         return writer;
 87  
 
 88  
     }
 89  
 
 90  
 
 91  
     // ------------------------------------------------------- Protected Methods
 92  
 
 93  
 
 94  
     /**
 95  
      * <p>Create a new <code>ResponseStream</code> that writes to the servlet
 96  
      * or portlet response stream for the current request.</p>
 97  
      *
 98  
      * @param context <code>FacesContext</code> for the current request
 99  
      * @param contentType Content type to be set on the response,
 100  
      *  or <code>null</code> to let this be defaulted
 101  
      *
 102  
      * @exception IllegalStateException if a writer for the current response
 103  
      *  has already been acquired
 104  
      */
 105  
     protected ResponseStream createResponseStream(FacesContext context, String contentType) {
 106  
 
 107  4
         Object response = context.getExternalContext().getResponse();
 108  
 
 109  
         // Set the content type (if specified)
 110  4
         if (contentType != null) {
 111  
             try {
 112  4
                 Method method =
 113  
                   response.getClass().getMethod("setContentType",
 114  1
                                                 new Class[] { String.class });
 115  4
                 method.invoke(response, new Object[] { contentType });
 116  
             } catch (IllegalAccessException e) {
 117  
                 throw new FacesException(e);
 118  
             } catch (InvocationTargetException e) {
 119  
                 throw new FacesException(e);
 120  
             } catch (NoSuchMethodException e) {
 121  
                 throw new FacesException(e);
 122  4
             }
 123  
         }
 124  
 
 125  
         // Acquire the output stream we will be wrapping
 126  
         final OutputStream stream;
 127  
         try {
 128  4
             String methodName =
 129  
               (response instanceof HttpServletResponse) ? "getOutputStream" : "getPortletOutputStream";
 130  4
             Method method =
 131  
               response.getClass().getMethod(methodName, new Class[] { });
 132  4
             stream = (OutputStream) method.invoke(response, new Object[] { });
 133  
         } catch (IllegalAccessException e) {
 134  
             throw new FacesException(e);
 135  
         } catch (InvocationTargetException e) {
 136  
             throw new FacesException(e);
 137  
         } catch (NoSuchMethodException e) {
 138  
             throw new FacesException(e);
 139  4
         }
 140  
 
 141  
         // Construct a ResponseStream that wraps this stream
 142  4
         return renderKit(context).createResponseStream(stream);
 143  
 
 144  
     }
 145  
 
 146  
 
 147  
     /**
 148  
      * <p>Create a new <code>ResponseWriter</code> that writes to the servlet
 149  
      * or portlet response writer for the current request.</p>
 150  
      *
 151  
      * @param context <code>FacesContext</code> for the current request
 152  
      * @param contentType Content type to be set on the response,
 153  
      *  or <code>null</code> to let this be defaulted
 154  
      *
 155  
      * @exception IllegalStateException if a writer for the current response
 156  
      *  has already been acquired
 157  
      */
 158  
     protected ResponseWriter createResponseWriter(FacesContext context, String contentType) {
 159  
 
 160  4
         Object response = context.getExternalContext().getResponse();
 161  
 
 162  
         // Set the content type (if specified)
 163  4
         if (contentType != null) {
 164  
             try {
 165  4
                 Method method =
 166  
                   response.getClass().getMethod("setContentType",
 167  
                                                 new Class[] { String.class });
 168  4
                 method.invoke(response, new Object[] { contentType });
 169  
             } catch (IllegalAccessException e) {
 170  
                 throw new FacesException(e);
 171  
             } catch (InvocationTargetException e) {
 172  
                 throw new FacesException(e);
 173  
             } catch (NoSuchMethodException e) {
 174  
                 throw new FacesException(e);
 175  4
             }
 176  
         }
 177  
 
 178  
         // Acquire the writer we will be wrapping
 179  
         final Writer writer;
 180  
         try {
 181  4
             String methodName = "getWriter";
 182  4
             Method method =
 183  
               response.getClass().getMethod(methodName, new Class[] { });
 184  4
             writer = (Writer) method.invoke(response, new Object[] { });
 185  
         } catch (IllegalAccessException e) {
 186  
             throw new FacesException(e);
 187  
         } catch (InvocationTargetException e) {
 188  
             throw new FacesException(e);
 189  
         } catch (NoSuchMethodException e) {
 190  
             throw new FacesException(e);
 191  4
         }
 192  
 
 193  
         // From JSF 1.2 on, we can call ExternalContext.getResponseCharacterEncoding(),
 194  
         // but for JSF 1.1 we must use response.getCharacterEncoding() instead
 195  4
         String encoding = null;
 196  
         try {
 197  4
             String methodName = "getCharacterEncoding";
 198  4
             Method method =
 199  
                 response.getClass().getMethod(methodName, new Class[] { });
 200  4
             encoding = (String) method.invoke(response, new Object[] { });
 201  
         } catch (IllegalAccessException e) {
 202  
             throw new FacesException(e);
 203  
         } catch (InvocationTargetException e) {
 204  
             throw new FacesException(e);
 205  
         } catch (NoSuchMethodException e) {
 206  
             throw new FacesException(e);
 207  4
         }
 208  
 
 209  
         // Construct a ResponseWriter that wraps this stream
 210  4
         if ((contentType != null) && contentType.startsWith("text/html")) {
 211  
             return renderKit(context).createResponseWriter(writer, contentType, encoding);
 212  
         } else {
 213  4
             return new BasicResponseWriter(writer, contentType, encoding);
 214  
         }
 215  
 
 216  
 
 217  
     }
 218  
 
 219  
 
 220  
     /**
 221  
      * <p>Return the relevant <code>RenderKit</code> to construct response
 222  
      * stream or writer instances for this request.  If there is no render kit
 223  
      * identified yet, the default <code>RenderKit</code> will be returned.</p>
 224  
      *
 225  
      * @param context <code>FacesContext</code> for the current request
 226  
      */
 227  
     protected RenderKit renderKit(FacesContext context) {
 228  
 
 229  
         // Identify the RenderKit we will use to create instances
 230  4
         String renderKitId = null;
 231  4
         UIViewRoot root = context.getViewRoot();
 232  4
         if (root != null) {
 233  4
             renderKitId = root.getRenderKitId();
 234  
         }
 235  4
         if (renderKitId == null) {
 236  
             renderKitId = RenderKitFactory.HTML_BASIC_RENDER_KIT;
 237  
         }
 238  
 
 239  
         // Return an instance of the requested RenderKit
 240  4
         RenderKitFactory factory = (RenderKitFactory)
 241  
           FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
 242  4
         return factory.getRenderKit(context, renderKitId);
 243  
 
 244  
     }
 245  
 
 246  
 
 247  
 }