/**
* Copyright 2004 The Apache Software Foundation.
*
* Licensed 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.myfaces.custom.graphicimageajax;
import java.io.IOException;
import java.io.OutputStream;
import javax.faces.component.UIComponent;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.el.MethodBinding;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.myfaces.application.jsp.JspStateManagerImpl;
import org.apache.myfaces.renderkit.RendererUtils;
/**
* @author Martin Marinschek
* @version $Revision: 292080 $ $Date: $
* <p/>
* $Log: $
*/
public class GraphicImageAjaxPhaseListener implements PhaseListener
{
private static Log log=LogFactory.getLog(GraphicImageAjaxPhaseListener.class);
public void afterPhase(PhaseEvent event)
{
FacesContext context = event.getFacesContext();
if(context.getExternalContext().getRequestParameterMap().containsKey("affectedGraphicImageComponent"))
{
UIViewRoot root = context.getViewRoot();
String componentId = (String)context.getExternalContext().getRequestParameterMap().get("affectedGraphicImageComponent");
UIComponent component = root.findComponent( componentId );
if(component instanceof GraphicImageAjax)
{
GraphicImageAjax graphicImageAjax = (GraphicImageAjax)component;
try
{
MethodBinding mbContentType = graphicImageAjax.getGetContentTypeMethod();
String contentType = (String)mbContentType.invoke(context,new Object[]{});
MethodBinding mbBytes = graphicImageAjax.getGetBytesMethod();
byte[] bytes = (byte[])mbBytes.invoke(context,new Object[]{});
//todo: fix this to work in PortletRequest as well
if(context.getExternalContext().getResponse() instanceof HttpServletResponse)
{
HttpServletResponse response = (HttpServletResponse)context.getExternalContext().getResponse();
response.setContentType( contentType );
OutputStream outS = response.getOutputStream();
try{
outS.write( bytes );
}finally{
// TODO : Check this.
outS.flush();
outS.close();
}
}
}
catch (IOException e)
{
log.error("Exception while rendering GraphicImageAjax-response",e);
}
}
else
{
log.error("Found component is no GraphicImageAjax : "+RendererUtils.getPathToComponent(component));
}
if (!context.getApplication().getStateManager().isSavingStateInClient(context)){
((JspStateManagerImpl) context.getApplication().getStateManager()).saveSerializedView(context);
}
context.responseComplete();
}
}
public void beforePhase(PhaseEvent event)
{
// NoOp
}
/**
* We need to hang our AJAX phase listener in the invoke application phase as it is
* impossible to stop rendering in the render response phase.
*
* @return PhaseId The AJAX phase listener will be invoked after the invoke application phase.
*/
public PhaseId getPhaseId()
{
//return PhaseId.ANY_PHASE;
//return PhaseId.RESTORE_VIEW;
return PhaseId.INVOKE_APPLICATION;
}
}