You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by we...@apache.org on 2008/11/21 14:56:58 UTC
svn commit: r719581 - in /myfaces/core/branches/2_0_0:
api/src/main/java/javax/faces/context/
impl/src/main/java/org/apache/myfaces/context/servlet/
impl/src/test/java/org/apache/myfaces/context/
Author: werpu
Date: Fri Nov 21 05:56:57 2008
New Revision: 719581
URL: http://svn.apache.org/viewvc?rev=719581&view=rev
Log:
blaTODO #48 Response suppression via a boolean switch in the faces context done
Added:
myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/context/servlet/ResponseSwitch.java
myfaces/core/branches/2_0_0/impl/src/test/java/org/apache/myfaces/context/
myfaces/core/branches/2_0_0/impl/src/test/java/org/apache/myfaces/context/ResponseWrapperSwitchTest.java
Modified:
myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/context/FacesContext.java
myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/context/servlet/FacesContextImpl.java
Modified: myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/context/FacesContext.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/context/FacesContext.java?rev=719581&r1=719580&r2=719581&view=diff
==============================================================================
--- myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/context/FacesContext.java (original)
+++ myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/context/FacesContext.java Fri Nov 21 05:56:57 2008
@@ -105,7 +105,7 @@
public void enableResponseWriting(boolean enable)
{
- // TODO: JSF 2.0 #48
+ //do nothing per default we switch in the derived classes!
}
public abstract Application getApplication();
Modified: myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/context/servlet/FacesContextImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/context/servlet/FacesContextImpl.java?rev=719581&r1=719580&r2=719581&view=diff
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/context/servlet/FacesContextImpl.java (original)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/context/servlet/FacesContextImpl.java Fri Nov 21 05:56:57 2008
@@ -18,6 +18,7 @@
*/
package org.apache.myfaces.context.servlet;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
@@ -26,6 +27,8 @@
import java.util.Map;
import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import javax.el.ELContext;
import javax.el.ELContextEvent;
import javax.el.ELContextListener;
@@ -45,6 +48,8 @@
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.apache.myfaces.context.ReleaseableExternalContext;
import org.apache.myfaces.el.unified.FacesELContext;
import org.apache.myfaces.shared_impl.util.NullIterator;
@@ -76,23 +81,30 @@
private boolean _released = false;
private ELContext _elContext;
private Map<Object,Object> _attributes = null;
+ private ResponseSwitch _responseWrapper = null;
// ~ Constructors -------------------------------------------------------------------------------
public FacesContextImpl(final ServletContext servletContext, final ServletRequest servletRequest,
- final ServletResponse servletResponse)
- {
- this(new ServletExternalContextImpl(servletContext, servletRequest, servletResponse));
+ final ServletResponse servletResponse) {
+ try {
+ //we wrap the servlet response to get our switching behavior!
+ _responseWrapper = new ResponseSwitch(servletResponse);
+ init(new ServletExternalContextImpl(servletContext, servletRequest, _responseWrapper));
+ } catch (IOException ex) {
+ Log log = LogFactory.getLog(this.getClass());
+ log.fatal("Could not obtain the response writers! Detail:"+ex.toString());
+ }
}
- private FacesContextImpl(final ReleaseableExternalContext externalContext)
- {
+ private void init(final ReleaseableExternalContext externalContext) {
_application = ((ApplicationFactory) FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY)).getApplication();
_renderKitFactory = (RenderKitFactory) FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
_externalContext = externalContext;
FacesContext.setCurrentInstance(this); // protected method, therefore must be called from here
}
+
// ~ Methods ------------------------------------------------------------------------------------
@Override
@@ -444,4 +456,20 @@
}
return _attributes;
}
+
+ /**
+ * if set to false the response writing is suppressed
+ * this construct has been added to deal with
+ * subview lifecycles in the ajax cycle
+ *
+ * @param enable if set to true the response is routed through if set to false
+ * the response is suppressed!
+ */
+ @Override
+ public void enableResponseWriting(boolean enable) {
+ _responseWrapper.setEnabled(enable);
+ super.enableResponseWriting(enable);
+ }
+
+
}
Added: myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/context/servlet/ResponseSwitch.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/context/servlet/ResponseSwitch.java?rev=719581&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/context/servlet/ResponseSwitch.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/context/servlet/ResponseSwitch.java Fri Nov 21 05:56:57 2008
@@ -0,0 +1,219 @@
+/**
+ * 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.context.servlet;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.ServletResponse;
+import javax.servlet.ServletResponseWrapper;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.io.Writer;
+
+/**
+ * implementation of a switching response
+ * wrapper to turn output on and off according to
+ * the JSF spec 2.p.
+ * <p/>
+ * The Response has to be switchable between on and off according
+ * to the JSF spec 2.0!
+ * <p/>
+ * we use an internal delegate to enable the switchting
+ * between on and off states!
+ *
+ * @author Werner Punz(latest modification by $Author$)
+ * @version $Revision$ $Date$
+ */
+class ResponseSwitch extends ServletResponseWrapper {
+
+ boolean _enabled = true;
+ /**
+ * one writer and
+ * one stream per response
+ */
+ Writer _switchableWriter;
+ OutputStream _switchableOutputStream;
+
+ public ResponseSwitch(ServletResponse response) throws IOException {
+ super(response);
+ }
+
+ public void setEnabled(boolean enabled) {
+ _enabled = enabled;
+ }
+
+ public boolean isEnabled() {
+ return _enabled;
+ }
+
+ @Override
+ public int getBufferSize() {
+ if (_enabled) {
+ return super.getBufferSize();
+ }
+ return 0;
+ }
+
+ @Override
+ public boolean isCommitted() {
+ if (_enabled) {
+ return super.isCommitted();
+ }
+ return false;
+ }
+
+ @Override
+ public void reset() {
+ if (_enabled) {
+ super.reset();
+ }
+ }
+
+ @Override
+ public void resetBuffer() {
+ if (_enabled) {
+ super.resetBuffer();
+ }
+ }
+
+ @Override
+ public ServletOutputStream getOutputStream() throws IOException {
+ if (_switchableOutputStream == null) {
+ _switchableOutputStream = new SwitchableOutputStream(super.getOutputStream());
+ }
+ return (SwitchableOutputStream) _switchableOutputStream;
+ }
+
+ @Override
+ public PrintWriter getWriter() throws IOException {
+ if (_switchableWriter == null) {
+ _switchableWriter = new PrintWriter(new SwitchableWriter(super.getWriter()));
+ }
+ return (PrintWriter) _switchableWriter;
+ }
+
+ class SwitchableOutputStream extends ServletOutputStream {
+
+ OutputStream _delegate = null;
+
+ public SwitchableOutputStream(ServletOutputStream delegate) {
+ _delegate = delegate;
+ }
+
+ public void write(int i) throws IOException {
+ if (_enabled) {
+ _delegate.write(i);
+ }
+ }
+
+ public void write(byte[] bytes) throws IOException {
+ if (_enabled) {
+ _delegate.write(bytes);
+ }
+ }
+
+ public void write(byte[] bytes, int i, int i1) throws IOException {
+ if (_enabled) {
+ _delegate.write(bytes, i, i1);
+ }
+ }
+
+ public void flush() throws IOException {
+ if (_enabled) {
+ _delegate.flush();
+ }
+ }
+
+ public void close() throws IOException {
+ if (_enabled) {
+ _delegate.close();
+ }
+ }
+ }
+
+ class SwitchableWriter extends Writer {
+
+ Writer _delegate = null;
+
+ public SwitchableWriter(Writer delegate) {
+ _delegate = delegate;
+ }
+
+ public void write(String arg0, int arg1, int arg2) throws IOException {
+ if (_enabled) {
+ _delegate.write(arg0, arg1, arg2);
+ }
+ }
+
+ public void write(String arg0) throws IOException {
+ if (_enabled) {
+ _delegate.write(arg0);
+ }
+ }
+
+ public void write(char[] arg0, int arg1, int arg2) throws IOException {
+ if (_enabled) {
+ _delegate.write(arg0, arg1, arg2);
+ }
+ }
+
+ public void write(char[] arg0) throws IOException {
+ if (_enabled) {
+ _delegate.write(arg0);
+
+ }
+ }
+
+ public void write(int arg0) throws IOException {
+ if (_enabled) {
+ _delegate.write(arg0);
+ }
+ }
+
+ public void flush() throws IOException {
+ if (_enabled) {
+ _delegate.flush();
+ }
+ }
+
+ public void close() throws IOException {
+ if (_enabled) {
+ _delegate.close();
+ }
+ }
+
+ public Writer append(char arg0) throws IOException {
+ if (_enabled) {
+ return _delegate.append(arg0);
+ }
+ return this;
+ }
+
+ public Writer append(CharSequence arg0, int arg1, int arg2) throws IOException {
+ if (_enabled) {
+ return _delegate.append(arg0, arg1, arg2);
+ }
+ return this;
+ }
+
+ public Writer append(CharSequence arg0) throws IOException {
+ if (_enabled) {
+ return _delegate.append(arg0);
+ }
+ return this;
+ }
+ }
+}
Added: myfaces/core/branches/2_0_0/impl/src/test/java/org/apache/myfaces/context/ResponseWrapperSwitchTest.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/test/java/org/apache/myfaces/context/ResponseWrapperSwitchTest.java?rev=719581&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/test/java/org/apache/myfaces/context/ResponseWrapperSwitchTest.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/test/java/org/apache/myfaces/context/ResponseWrapperSwitchTest.java Fri Nov 21 05:56:57 2008
@@ -0,0 +1,253 @@
+/*
+ * Copyright 2008 werpu.
+ *
+ * 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.
+ * under the License.
+ */
+package org.apache.myfaces.context;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.ServletResponse;
+import javax.servlet.ServletResponseWrapper;
+
+import org.apache.myfaces.context.servlet.FacesContextImpl;
+import org.apache.shale.test.base.AbstractJsfTestCase;
+import org.apache.shale.test.mock.MockResponseWriter;
+
+/**
+ * Testcase for the response switching
+ *
+ * @author Werner Punz(latest modification by $Author$)
+ * @version $Revision$ $Date$
+ */
+public class ResponseWrapperSwitchTest extends AbstractJsfTestCase {
+
+ public ResponseWrapperSwitchTest() {
+ super("ResponseWrapperSwitchTest");
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ /**
+ * we define our own response class to be able to test the output suppression!
+ */
+ class NewStreamingMockResponse extends ServletResponseWrapper {
+
+ PrintWriter _writer;
+ ServletOutputStream _strm;
+ ServletResponse _response;
+
+ public NewStreamingMockResponse(ServletResponse response, ServletOutputStream strm, PrintWriter writer) {
+ super(response);
+ _strm = strm;
+ _writer = writer;
+ _response = response;
+ }
+
+ @Override
+ public ServletResponse getResponse() {
+ return _response;
+ }
+
+ @Override
+ public ServletOutputStream getOutputStream() throws IOException {
+ return _strm;
+ }
+
+ @Override
+ public PrintWriter getWriter() throws IOException {
+ return _writer;
+ }
+ }
+
+ /**
+ * we need to define our own mockup for the output stream
+ * so that we can simulate a servlet one
+ */
+ class ServletOutputStreamMock extends ServletOutputStream {
+
+ private OutputStream _bos = null;
+
+ ServletOutputStreamMock(OutputStream ostr) {
+ _bos = ostr;
+ }
+
+ public void write(byte[] arg0) throws IOException {
+ _bos.write(arg0);
+ }
+
+ public void flush() throws IOException {
+ _bos.flush();
+ }
+
+ public String toString() {
+ return _bos.toString();
+ }
+
+ public void close() throws IOException {
+ _bos.close();
+ }
+
+ /**
+ * @return the _bos
+ */
+ public OutputStream getBos() {
+ return _bos;
+ }
+
+ /**
+ * @param bos the _bos to set
+ */
+ public void setBos(OutputStream bos) {
+ this._bos = bos;
+ }
+
+ @Override
+ public void write(int arg0) throws IOException {
+ _bos.write(arg0);
+ }
+ }
+
+ /**
+ * testing the off switch for the
+ * response
+ */
+ public void testSwitchOnWriter() {
+
+ ByteArrayOutputStream ostr = new ByteArrayOutputStream();
+ ByteArrayOutputStream ostrWriter = new ByteArrayOutputStream();
+ PrintWriter writer = new PrintWriter(ostrWriter);
+ ServletOutputStreamMock sOstr = new ServletOutputStreamMock(ostr);
+ NewStreamingMockResponse resp = new NewStreamingMockResponse(response, sOstr, writer);
+
+ FacesContext context = new FacesContextImpl(servletContext, request, resp);
+
+
+ ResponseWriter responseWriter = context.getResponseWriter();
+ if (responseWriter == null) {
+ try {
+ responseWriter = new MockResponseWriter(((ServletResponse) context.getExternalContext().getResponse()).getWriter(), null, null);
+ } catch (IOException ex) {
+ super.fail(ex.getMessage());
+ }
+ context.setResponseWriter(responseWriter);
+ }
+
+
+
+ assertTrue("responsewriter not null", responseWriter != null);
+
+ try {
+ responseWriter.append("hello world");
+ responseWriter.flush();
+ responseWriter.close();
+
+ } catch (IOException ex) {
+ super.fail(ex.getMessage());
+ }
+
+ assertTrue(ostrWriter.toString().trim().equals("hello world"));
+
+ }
+
+ /**
+ * Test switch off on the writer api
+ */
+ public void testSwitchOffWriter() {
+ ByteArrayOutputStream ostr = new ByteArrayOutputStream();
+ ByteArrayOutputStream ostrWriter = new ByteArrayOutputStream();
+ PrintWriter writer = new PrintWriter(ostrWriter);
+ ServletOutputStreamMock sOstr = new ServletOutputStreamMock(ostr);
+ NewStreamingMockResponse resp = new NewStreamingMockResponse(response, sOstr, writer);
+
+ FacesContext context = new FacesContextImpl(servletContext, request, resp);
+
+
+ ResponseWriter responseWriter = context.getResponseWriter();
+ if (responseWriter == null) {
+ try {
+ responseWriter = new MockResponseWriter(((ServletResponse) context.getExternalContext().getResponse()).getWriter(), null, null);
+ } catch (IOException ex) {
+ super.fail(ex.getMessage());
+ }
+ context.setResponseWriter(responseWriter);
+ }
+
+
+
+ assertTrue("responsewriter not null", responseWriter != null);
+ context.enableResponseWriting(false);
+
+ try {
+ responseWriter.append("hello world");
+ responseWriter.flush();
+ responseWriter.close();
+
+ } catch (IOException ex) {
+ super.fail(ex.getMessage());
+ }
+
+
+ assertTrue(ostrWriter.toString().trim().equals(""));
+
+
+ }
+
+ /**
+ * test switch off on the stream api
+ * if this works then the stream switch
+ * shoud work on the facesContext should work as well!
+ * @throws java.io.IOException
+ */
+ public void testSwitchOffOstr() {
+ ByteArrayOutputStream ostr = new ByteArrayOutputStream();
+ ByteArrayOutputStream ostrWriter = new ByteArrayOutputStream();
+ PrintWriter writer = new PrintWriter(ostrWriter);
+ ServletOutputStreamMock sOstr = new ServletOutputStreamMock(ostr);
+ NewStreamingMockResponse resp = new NewStreamingMockResponse(response, sOstr, writer);
+
+ FacesContext context = new FacesContextImpl(servletContext, request, resp);
+ context.enableResponseWriting(false);
+ try {
+ OutputStream finalOstr = (OutputStream) ((ServletResponse) context.getExternalContext().getResponse()).getOutputStream();
+ PrintWriter finalWriter = new PrintWriter(finalOstr);
+
+ finalWriter.write("hello world");
+ finalOstr.write('a');
+ finalOstr.flush();
+ finalOstr.close();
+
+ } catch (IOException ex) {
+ super.fail(ex.getMessage());
+ }
+
+
+ assertTrue(ostr.toString().trim().equals(""));
+
+
+ }
+}