Package org.apache.shale.remoting.faces

Source Code of org.apache.shale.remoting.faces.ResponseFactory

/*
* 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.shale.remoting.faces;

import java.io.OutputStream;
import java.io.Writer;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.faces.FacesException;
import javax.faces.FactoryFinder;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseStream;
import javax.faces.context.ResponseWriter;
import javax.faces.render.RenderKit;
import javax.faces.render.RenderKitFactory;
import javax.servlet.http.HttpServletResponse;

/**
* <p>Factory class for returning <code>ResponseStream</code> or
* <code>ResponseWriter</code> instances that may be used to produce output
* response content that is independent of whether we are running in a servlet
* or portlet environment.  The <code>RenderKit</code> for the current request
* will be used to manufacture stream or writer instances, if necessary.</p>
*/
public class ResponseFactory {


    // ------------------------------------------------------------ Constructors



    // ---------------------------------------------------------- Public Methods


    /**
     * <p>Return the configured <code>ResponseStream</code> for the current
     * request, creating and installing a new one if necessary.</p>
     *
     * @param context <code>FacesContext</code> for the current request
     * @param contentType Content type to be set on the response,
     *  or <code>null</code> to let this be defaulted
     */
    public ResponseStream getResponseStream(FacesContext context, String contentType) {

        ResponseStream stream = context.getResponseStream();
        if (stream == null) {
            stream = createResponseStream(context, contentType);
            context.setResponseStream(stream);
        }
        return stream;

    }


    /**
     * <p>Return the configured <code>ResponseWriter</code> for the current
     * request, creating and installing a new one if necessary.</p>
     *
     * @param context <code>FacesContext</code> for the current request
     * @param contentType Content type to be set on the response,
     *  or <code>null</code> to let this be defaulted
     */
    public ResponseWriter getResponseWriter(FacesContext context, String contentType) {

        ResponseWriter writer = context.getResponseWriter();
        if (writer == null) {
            writer = createResponseWriter(context, contentType);
            context.setResponseWriter(writer);
        }
        return writer;

    }


    // ------------------------------------------------------- Protected Methods


    /**
     * <p>Create a new <code>ResponseStream</code> that writes to the servlet
     * or portlet response stream for the current request.</p>
     *
     * @param context <code>FacesContext</code> for the current request
     * @param contentType Content type to be set on the response,
     *  or <code>null</code> to let this be defaulted
     *
     * @exception IllegalStateException if a writer for the current response
     *  has already been acquired
     */
    protected ResponseStream createResponseStream(FacesContext context, String contentType) {

        Object response = context.getExternalContext().getResponse();

        // Set the content type (if specified)
        if (contentType != null) {
            try {
                Method method =
                  response.getClass().getMethod("setContentType",
                                                new Class[] { String.class });
                method.invoke(response, new Object[] { contentType });
            } catch (IllegalAccessException e) {
                throw new FacesException(e);
            } catch (InvocationTargetException e) {
                throw new FacesException(e);
            } catch (NoSuchMethodException e) {
                throw new FacesException(e);
            }
        }

        // Acquire the output stream we will be wrapping
        final OutputStream stream;
        try {
            String methodName =
              (response instanceof HttpServletResponse) ? "getOutputStream" : "getPortletOutputStream";
            Method method =
              response.getClass().getMethod(methodName, new Class[] { });
            stream = (OutputStream) method.invoke(response, new Object[] { });
        } catch (IllegalAccessException e) {
            throw new FacesException(e);
        } catch (InvocationTargetException e) {
            throw new FacesException(e);
        } catch (NoSuchMethodException e) {
            throw new FacesException(e);
        }

        // Construct a ResponseStream that wraps this stream
        return renderKit(context).createResponseStream(stream);

    }


    /**
     * <p>Create a new <code>ResponseWriter</code> that writes to the servlet
     * or portlet response writer for the current request.</p>
     *
     * @param context <code>FacesContext</code> for the current request
     * @param contentType Content type to be set on the response,
     *  or <code>null</code> to let this be defaulted
     *
     * @exception IllegalStateException if a writer for the current response
     *  has already been acquired
     */
    protected ResponseWriter createResponseWriter(FacesContext context, String contentType) {

        Object response = context.getExternalContext().getResponse();

        // Set the content type (if specified)
        if (contentType != null) {
            try {
                Method method =
                  response.getClass().getMethod("setContentType",
                                                new Class[] { String.class });
                method.invoke(response, new Object[] { contentType });
            } catch (IllegalAccessException e) {
                throw new FacesException(e);
            } catch (InvocationTargetException e) {
                throw new FacesException(e);
            } catch (NoSuchMethodException e) {
                throw new FacesException(e);
            }
        }

        // Acquire the writer we will be wrapping
        final Writer writer;
        try {
            String methodName = "getWriter";
            Method method =
              response.getClass().getMethod(methodName, new Class[] { });
            writer = (Writer) method.invoke(response, new Object[] { });
        } catch (IllegalAccessException e) {
            throw new FacesException(e);
        } catch (InvocationTargetException e) {
            throw new FacesException(e);
        } catch (NoSuchMethodException e) {
            throw new FacesException(e);
        }

        // From JSF 1.2 on, we can call ExternalContext.getResponseCharacterEncoding(),
        // but for JSF 1.1 we must use response.getCharacterEncoding() instead
        String encoding = null;
        try {
            String methodName = "getCharacterEncoding";
            Method method =
                response.getClass().getMethod(methodName, new Class[] { });
            encoding = (String) method.invoke(response, new Object[] { });
        } catch (IllegalAccessException e) {
            throw new FacesException(e);
        } catch (InvocationTargetException e) {
            throw new FacesException(e);
        } catch (NoSuchMethodException e) {
            throw new FacesException(e);
        }

        // Construct a ResponseWriter that wraps this stream
        if ((contentType != null) && contentType.startsWith("text/html")) {
            return renderKit(context).createResponseWriter(writer, contentType, encoding);
        } else {
            return new BasicResponseWriter(writer, contentType, encoding);
        }


    }


    /**
     * <p>Return the relevant <code>RenderKit</code> to construct response
     * stream or writer instances for this request.  If there is no render kit
     * identified yet, the default <code>RenderKit</code> will be returned.</p>
     *
     * @param context <code>FacesContext</code> for the current request
     */
    protected RenderKit renderKit(FacesContext context) {

        // Identify the RenderKit we will use to create instances
        String renderKitId = null;
        UIViewRoot root = context.getViewRoot();
        if (root != null) {
            renderKitId = root.getRenderKitId();
        }
        if (renderKitId == null) {
            renderKitId = RenderKitFactory.HTML_BASIC_RENDER_KIT;
        }

        // Return an instance of the requested RenderKit
        RenderKitFactory factory = (RenderKitFactory)
          FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
        return factory.getRenderKit(context, renderKitId);

    }


}
TOP

Related Classes of org.apache.shale.remoting.faces.ResponseFactory

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.