myfaces-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From lof...@apache.org
Subject svn commit: r906879 - in /myfaces/tobago/trunk/core/src: main/java/org/apache/myfaces/tobago/internal/context/ test/java/org/apache/myfaces/tobago/internal/context/
Date Fri, 05 Feb 2010 09:42:15 GMT
Author: lofwyr
Date: Fri Feb  5 09:42:14 2010
New Revision: 906879

URL: http://svn.apache.org/viewvc?rev=906879&view=rev
Log:
TOBAGO-846: New class ResponseWriterDivider to write output in different order the renderer
was called.

Added:
    myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/internal/context/ResponseWriterDivider.java
  (with props)
    myfaces/tobago/trunk/core/src/test/java/org/apache/myfaces/tobago/internal/context/
    myfaces/tobago/trunk/core/src/test/java/org/apache/myfaces/tobago/internal/context/ResponseWriterDividerUnitTest.java
  (with props)

Added: myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/internal/context/ResponseWriterDivider.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/internal/context/ResponseWriterDivider.java?rev=906879&view=auto
==============================================================================
--- myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/internal/context/ResponseWriterDivider.java
(added)
+++ myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/internal/context/ResponseWriterDivider.java
Fri Feb  5 09:42:14 2010
@@ -0,0 +1,141 @@
+package org.apache.myfaces.tobago.internal.context;
+
+/*
+ * 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.
+ */
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.myfaces.tobago.util.FastStringWriter;
+
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Sometimes the rendered output must be places in the Response in a different order than
it was rendered.
+ * The <code>ResponseWriterDivider</code> helps to manage a list of buffers which
holds the temporary output.
+ */
+public class ResponseWriterDivider {
+
+  private static final Log LOG = LogFactory.getLog(ResponseWriterDivider.class);
+
+  private static final String NAME_IN_REQUEST = ResponseWriterDivider.class.getName();
+
+  private List<ResponseWriter> writers;
+  private List<FastStringWriter> buffers;
+  
+  private ResponseWriter original;
+  
+  private int current;
+
+  public static ResponseWriterDivider getInstance(FacesContext facesContext) {
+    final Map<String,Object> map = facesContext.getExternalContext().getRequestMap();
+    ResponseWriterDivider divider = (ResponseWriterDivider) map.get(NAME_IN_REQUEST);
+    if (divider == null) {
+      divider = new ResponseWriterDivider(facesContext);
+      map.put(NAME_IN_REQUEST, divider);
+    }
+    return divider;
+  }
+
+  private ResponseWriterDivider(FacesContext facesContext) {
+    writers = new ArrayList<ResponseWriter>();
+    buffers = new ArrayList<FastStringWriter>();
+    current = -1;
+    original = facesContext.getResponseWriter();
+  }
+
+  /**
+   * Create (if needed) and activate a new branch. 
+   * After this call, all output will be stored in this new branch. 
+   * @return true if the branch was not created new. So the branch was already existent.
+   */
+  public boolean activateBranch(FacesContext facesContext) {
+
+    assert writers.size() == buffers.size();
+
+    boolean created = true;
+    current++;
+    if (writers.size() == current) {
+      FastStringWriter buffer = new FastStringWriter();
+      buffers.add(buffer);
+      ResponseWriter newWriter = facesContext.getResponseWriter().cloneWithWriter(buffer);
+      writers.add(newWriter);
+      created = false;
+    }
+    facesContext.setResponseWriter(writers.get(current));
+    if (LOG.isDebugEnabled()) {
+      LOG.debug(this);
+    }
+    return created;
+  }
+  
+  /**
+   * Passivate the current branch. 
+   * After this call, all output will be written in the former branch (if any) or into the
original writer.
+   * @return true, if the current writer is not the original writer. So the "stack" is at
the bottom. 
+   */
+  public boolean passivateBranch(FacesContext facesContext) {
+
+    assert writers.size() == buffers.size();
+    
+    current--;
+    if (current >= 0) {
+      facesContext.setResponseWriter(writers.get(current));
+      if (LOG.isDebugEnabled()) {
+        LOG.debug(this);
+      }
+      return true;
+    } else {
+      facesContext.setResponseWriter(original);
+      if (LOG.isDebugEnabled()) {
+        LOG.debug(this);
+      }
+      return false;
+    }
+  }
+
+  /**
+   * Write the collected stuff in the original writer.
+   * This is always the last call on this object.
+   */
+  public void writeOut(FacesContext facesContext) throws IOException {
+    facesContext.setResponseWriter(original);
+    for (FastStringWriter buffer : buffers) {
+      original.write(buffer.toString());
+    }
+    // clean up.
+    writers = null;
+    buffers = null;
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder builder = new StringBuilder();
+    builder.append("StringBuilder("+System.identityHashCode(this)+") current=" + current
+ "\n");
+    int i = 0;
+    for (FastStringWriter buffer : buffers) {
+      builder.append("\n- buffer "+ i++ +" ------------------------------------------------------------\n");
+      builder.append(buffer.toString());
+    }
+    builder.append("\n-----------------------------------------------------------------------\n");
+    return builder.toString();
+  }
+}

Propchange: myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/internal/context/ResponseWriterDivider.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: myfaces/tobago/trunk/core/src/test/java/org/apache/myfaces/tobago/internal/context/ResponseWriterDividerUnitTest.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/core/src/test/java/org/apache/myfaces/tobago/internal/context/ResponseWriterDividerUnitTest.java?rev=906879&view=auto
==============================================================================
--- myfaces/tobago/trunk/core/src/test/java/org/apache/myfaces/tobago/internal/context/ResponseWriterDividerUnitTest.java
(added)
+++ myfaces/tobago/trunk/core/src/test/java/org/apache/myfaces/tobago/internal/context/ResponseWriterDividerUnitTest.java
Fri Feb  5 09:42:14 2010
@@ -0,0 +1,106 @@
+package org.apache.myfaces.tobago.internal.context;
+
+import org.apache.myfaces.test.mock.MockExternalContext;
+import org.apache.myfaces.test.mock.MockFacesContext;
+import org.apache.myfaces.test.mock.MockHttpServletRequest;
+import org.apache.myfaces.tobago.webapp.TobagoResponseWriterImpl;
+import org.junit.Assert;
+import org.junit.Test;
+
+import javax.faces.context.FacesContext;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.TreeNode;
+import java.io.IOException;
+import java.io.StringWriter;
+
+/*
+ * 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.
+ */
+
+public class ResponseWriterDividerUnitTest {
+
+  @Test
+  public void test() throws IOException {
+    // TODO: check how to use this classes
+    MockFacesContext facesContext = new MockFacesContext();
+    MockExternalContext externalContext = new MockExternalContext(null, new MockHttpServletRequest(),
null);
+    facesContext.setExternalContext(externalContext);
+    StringWriter stringWriter = new StringWriter();
+    facesContext.setResponseWriter(new TobagoResponseWriterImpl(stringWriter, "text/xml",
"ISO-8859-1", true));
+
+    DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root");
+    DefaultMutableTreeNode colors = new DefaultMutableTreeNode("Colors");
+    DefaultMutableTreeNode numbers = new DefaultMutableTreeNode("Numbers");
+    DefaultMutableTreeNode integers = new DefaultMutableTreeNode("Integers");
+    DefaultMutableTreeNode doubles = new DefaultMutableTreeNode("Doubles");
+    root.add(colors);
+    root.add(numbers);
+    numbers.add(integers);
+    numbers.add(doubles);
+    integers.add(new DefaultMutableTreeNode("1"));
+    integers.add(new DefaultMutableTreeNode("2"));
+    doubles.add(new DefaultMutableTreeNode("2.7182"));
+    doubles.add(new DefaultMutableTreeNode("3.1415"));
+
+    render(facesContext, root);
+
+    ResponseWriterDivider divider = ResponseWriterDivider.getInstance(facesContext);
+    divider.writeOut(facesContext);
+
+    String expected 
+        = "(Root)\n"
+        + "Colors\n"
+        + "Numbers\n"
+        + "(/Root)\n"
+        + "(Numbers)\n"
+        + "Integers\n"
+        + "Doubles\n"
+        + "(/Numbers)\n"
+        + "(Integers)\n"
+        + "1\n"
+        + "2\n"
+        + "(/Integers)\n"
+        + "(Doubles)\n"
+        + "2.7182\n"
+        + "3.1415\n"
+        + "(/Doubles)\n";
+    
+    Assert.assertEquals(expected, stringWriter.toString());
+  }
+
+  private void render(FacesContext facesContext, DefaultMutableTreeNode node) throws IOException
{
+    ResponseWriterDivider divider = ResponseWriterDivider.getInstance(facesContext);
+
+    String label = (String) node.getUserObject();
+
+    // label
+    if (!node.isRoot()) {
+      facesContext.getResponseWriter().write(label + "\n");
+    }
+
+    // tag
+    if (node.getChildCount() > 0) {
+      divider.activateBranch(facesContext);
+      facesContext.getResponseWriter().write("(" + label + ")\n");
+      for (int i = 0; i < node.getChildCount(); i++) {
+        TreeNode sub = node.getChildAt(i);
+        render(facesContext, (DefaultMutableTreeNode) sub);
+      }
+      facesContext.getResponseWriter().write("(/" + label + ")\n");
+      divider.passivateBranch(facesContext);
+    }
+  }
+}

Propchange: myfaces/tobago/trunk/core/src/test/java/org/apache/myfaces/tobago/internal/context/ResponseWriterDividerUnitTest.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message