/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jboss.portletbridge.context; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; import java.util.List; import javax.faces.context.FacesContext; import javax.faces.context.PartialResponseWriter; import javax.faces.context.ResponseWriter; import javax.portlet.PortletContext; import javax.portlet.ResourceRequest; import javax.portlet.ResourceResponse; import org.jboss.portletbridge.PortletBridgeConstants; /** * @author asmirnov, <a href="http://community.jboss.org/people/kenfinni">Ken Finnigan</a> */ public class ResourceRequestExternalContextImpl extends MimeExternalContextImpl { protected String facesRequest = null; protected boolean facesRequestSet = false; /** * @param context * @param request * @param response */ public ResourceRequestExternalContextImpl(PortletContext context, ResourceRequest request, ResourceResponse response) { super(context, request, response); } @Override public String getRequestCharacterEncoding() { // TODO - save character encoding from action request. return getResourceRequest().getCharacterEncoding(); } @Override public void setRequestCharacterEncoding(String encoding) throws UnsupportedEncodingException { try { getResourceRequest().setCharacterEncoding(encoding); } catch (IllegalStateException e) { // TODO: handle exception } } @Override public int getRequestContentLength() { return getResourceRequest().getContentLength(); } protected String getRequestHeader(String name) { if ("CONTENT-TYPE".equalsIgnoreCase(name)) { if (null == contentType) { constructContentType(); } return contentType; } if ("CONTENT-LENGTH".equalsIgnoreCase(name)) { if (null == contentLength) { constructContentLength(); } return contentLength; } if (PortletBridgeConstants.FACES_REQUEST_HEADER_PARAM.equals(name)) { if (!facesRequestSet) { constructFacesRequest(); } return facesRequest; } return super.getRequestHeader(name); } protected void constructFacesRequest() { String facesReq = super.getRequestHeader(PortletBridgeConstants.FACES_REQUEST_HEADER_PARAM); if (null != facesReq) { facesRequest = facesReq; } else { String isAjaxParam = getRequestParameterMap().get(PortletBridgeConstants.AJAX_PARAM); if (null != isAjaxParam && Boolean.parseBoolean(isAjaxParam)) { facesRequest = PortletBridgeConstants.FACES_REQUEST_PARTIAL; } } facesRequestSet = true; } protected Enumeration<String> getRequestHeaderNames() { List<String> names = new ArrayList<String>(); Enumeration<String> propNames = super.getRequestHeaderNames(); while (propNames.hasMoreElements()) { String name = (String) propNames.nextElement(); names.add(name); } names.add("CONTENT-TYPE"); names.add("CONTENT-LENGTH"); names.add(PortletBridgeConstants.FACES_REQUEST_HEADER_PARAM); return Collections.enumeration(names); } protected String[] getRequestHeaderValues(String name) { if ("CONTENT-TYPE".equalsIgnoreCase(name)) { if (null == contentType) { constructContentType(); } return new String[] { contentType }; } if ("CONTENT-LENGTH".equalsIgnoreCase(name)) { if (null == contentLength) { constructContentLength(); } return new String[] { contentLength }; } if (PortletBridgeConstants.FACES_REQUEST_HEADER_PARAM.equals(name)) { if (!facesRequestSet) { constructFacesRequest(); } return new String[] { facesRequest }; } return super.getRequestHeaderValues(name); } public void redirect(String url) throws IOException { if (null == url || url.length() < 0) { throw new IllegalArgumentException("Path to redirect is null"); } FacesContext facesContext = FacesContext.getCurrentInstance(); getPortletFlash().doLastPhaseActions(facesContext, true); if (facesContext.getPartialViewContext().isPartialRequest()) { ResourceResponse resourceResponse = getResourceResponse(); resourceResponse.setContentType("text/xml"); resourceResponse.setCharacterEncoding("UTF-8"); PartialResponseWriter partialResponseWriter; ResponseWriter responseWriter = facesContext.getResponseWriter(); if (responseWriter instanceof PartialResponseWriter) { partialResponseWriter = (PartialResponseWriter) responseWriter; } else { partialResponseWriter = facesContext.getPartialViewContext().getPartialResponseWriter(); } partialResponseWriter.startDocument(); partialResponseWriter.redirect(url); partialResponseWriter.endDocument(); facesContext.responseComplete(); } else { throw new UnsupportedEncodingException( "Can only redirect during RESOURCE_PHASE if a JSF partial/Ajax request has been triggered"); } } @Override public String encodeNamespace(String name) { // PBR-385 Don't add namespace to org.richfaces.extension otherwise JS is unable to process response if ("org.richfaces.extension".equalsIgnoreCase(name)) { return name; } return super.encodeNamespace(name); } public ResourceRequest getResourceRequest() { return (ResourceRequest) super.getRequest(); } public ResourceResponse getResourceResponse() { return (ResourceResponse) super.getResponse(); } @Override public void setResponseStatus(int statusCode) { ResourceResponse resourceResponse = (ResourceResponse) getResponse(); resourceResponse.setProperty(ResourceResponse.HTTP_STATUS_CODE, Integer.toString(statusCode)); } }