You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2006/07/24 01:54:45 UTC

svn commit: r424862 - in /tapestry/tapestry5/tapestry-core/trunk/src: main/java/org/apache/tapestry/internal/ioc/ main/java/org/apache/tapestry/internal/ioc/services/ main/java/org/apache/tapestry/util/ test/java/org/apache/tapestry/internal/transform/...

Author: hlship
Date: Sun Jul 23 16:54:45 2006
New Revision: 424862

URL: http://svn.apache.org/viewvc?rev=424862&view=rev
Log:
Move and refactor BodyBuilder from HiveMind to Tapestry 5 (IoC).
Add a short delay to the test for ComponentInstantiatorSourceImpl since it can outrace the Java clock in some circumstances.

Added:
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/BodyBuilder.java
      - copied, changed from r424849, hivemind/trunk/framework/src/java/org/apache/hivemind/service/BodyBuilder.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/util/BodyBuilderTest.java
Modified:
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ModuleImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/LoggingDecoratorImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/ComponentInstantiatorSourceImplTest.java

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ModuleImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ModuleImpl.java?rev=424862&r1=424861&r2=424862&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ModuleImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/ModuleImpl.java Sun Jul 23 16:54:45 2006
@@ -14,12 +14,6 @@
 
 package org.apache.tapestry.internal.ioc;
 
-import static org.apache.tapestry.util.CollectionFactory.newList;
-import static org.apache.tapestry.util.CollectionFactory.newMap;
-import static org.apache.tapestry.util.CollectionFactory.newSet;
-import static org.apache.tapestry.util.Defense.notBlank;
-import static org.apache.tapestry.util.Defense.notNull;
-
 import java.lang.reflect.Modifier;
 import java.util.Collection;
 import java.util.List;
@@ -27,7 +21,6 @@
 import java.util.Set;
 
 import org.apache.commons.logging.Log;
-import org.apache.hivemind.service.BodyBuilder;
 import org.apache.tapestry.internal.annotations.SuppressNullCheck;
 import org.apache.tapestry.ioc.IOCConstants;
 import org.apache.tapestry.ioc.ServiceCreator;
@@ -42,6 +35,13 @@
 import org.apache.tapestry.ioc.services.ClassFactory;
 import org.apache.tapestry.ioc.services.MethodIterator;
 import org.apache.tapestry.ioc.services.MethodSignature;
+import org.apache.tapestry.util.BodyBuilder;
+
+import static org.apache.tapestry.util.CollectionFactory.newList;
+import static org.apache.tapestry.util.CollectionFactory.newMap;
+import static org.apache.tapestry.util.CollectionFactory.newSet;
+import static org.apache.tapestry.util.Defense.notBlank;
+import static org.apache.tapestry.util.Defense.notNull;
 
 /**
  * @author Howard M. Lewis Ship
@@ -335,7 +335,7 @@
 
         builder.addln("if (_delegate == null)");
         builder.begin();
-        builder.addln("_delegate = ({0}) _creator.createService();", serviceInterface.getName());
+        builder.addln("_delegate = (%s) _creator.createService();", serviceInterface.getName());
         builder.addln("_creator = null;");
         builder.end();
 

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/LoggingDecoratorImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/LoggingDecoratorImpl.java?rev=424862&r1=424861&r2=424862&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/LoggingDecoratorImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/LoggingDecoratorImpl.java Sun Jul 23 16:54:45 2006
@@ -19,13 +19,13 @@
 import java.lang.reflect.Modifier;
 
 import org.apache.commons.logging.Log;
-import org.apache.hivemind.service.BodyBuilder;
 import org.apache.tapestry.ioc.LoggingDecorator;
 import org.apache.tapestry.ioc.services.ClassFab;
 import org.apache.tapestry.ioc.services.ClassFabUtils;
 import org.apache.tapestry.ioc.services.ClassFactory;
 import org.apache.tapestry.ioc.services.MethodIterator;
 import org.apache.tapestry.ioc.services.MethodSignature;
+import org.apache.tapestry.util.BodyBuilder;
 
 import static java.lang.String.format;
 import static org.apache.tapestry.ioc.services.ClassFabUtils.getJavaClassName;
@@ -113,15 +113,15 @@
         builder.addln("boolean debug = _logger.isDebugEnabled();");
 
         builder.addln("if (debug)");
-        builder.addln(format("  _logger.entry(%s, $args);", name));
+        builder.addln("  _logger.entry(%s, $args);", name);
 
         builder.addln("try");
         builder.begin();
 
         if (!isVoid)
-            builder.add(format("%s result = ", getJavaClassName(returnType)));
+            builder.add("%s result = ", getJavaClassName(returnType));
 
-        builder.addln(format("_delegate.%s($$);", signature.getName()));
+        builder.addln("_delegate.%s($$);", signature.getName());
 
         if (isVoid)
         {
@@ -156,10 +156,10 @@
     private void addExceptionHandler(BodyBuilder builder, String quotedMethodName,
             Class exceptionType)
     {
-        builder.addln(format("catch (%s ex)", exceptionType.getName()));
+        builder.addln("catch (%s ex)", exceptionType.getName());
         builder.begin();
         builder.addln("if (debug)");
-        builder.addln(format("  _logger.fail(%s, ex);", quotedMethodName));
+        builder.addln("  _logger.fail(%s, ex);", quotedMethodName);
         builder.addln("throw ex;");
         builder.end();
     }

Copied: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/BodyBuilder.java (from r424849, hivemind/trunk/framework/src/java/org/apache/hivemind/service/BodyBuilder.java)
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/BodyBuilder.java?p2=tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/BodyBuilder.java&p1=hivemind/trunk/framework/src/java/org/apache/hivemind/service/BodyBuilder.java&r1=424849&r2=424862&rev=424862&view=diff
==============================================================================
--- hivemind/trunk/framework/src/java/org/apache/hivemind/service/BodyBuilder.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/BodyBuilder.java Sun Jul 23 16:54:45 2006
@@ -12,26 +12,34 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package org.apache.hivemind.service;
+package org.apache.tapestry.util;
 
-import java.text.MessageFormat;
+import java.util.Formatter;
 
 /**
- * Utility class for assembling the <em>body</em> used with Javassist as a method or catch block.
+ * Utility class for assembling the <em>body</em> used with Javassist as a method. Basically,
+ * assists with formatting and with indentation. This makes the code that assembles a method body
+ * much simpler ... and it makes the result neater, which will be easier to debug (debugging
+ * dynamically generated code is hard enough that it should be easy to read the input code before
+ * worrying about why it doesn't compile or execute properly).
+ * <p>
+ * This class is not threadsafe.
  * 
  * @author Howard Lewis Ship
  */
 
-public class BodyBuilder
+public final class BodyBuilder
 {
     /**
      * Feels right for the size of a typical body.
      */
     private static final int DEFAULT_LENGTH = 200;
 
-    private static final char QUOTE = '"';
+    private final StringBuffer _buffer = new StringBuffer(DEFAULT_LENGTH);
 
-    private StringBuffer _buffer = new StringBuffer(DEFAULT_LENGTH);
+    private final Formatter _formatter = new Formatter(_buffer);
+
+    // Per level of nesting depth (two spaces).
 
     private static final String INDENT = "  ";
 
@@ -50,127 +58,41 @@
     }
 
     /**
-     * Adds text to the current line, without terminating the line.
-     */
-    public void add(String text)
-    {
-        indent();
-
-        _buffer.append(text);
-    }
-
-    /**
-     * Adds text to the current line, without terminating the line.
+     * Adds text to the current line, without ending the line.
      * 
-     * @param pattern
-     *            a string pattern, used with
-     *            {@link java.text.MessageFormat#format(java.lang.String, java.lang.Object[])}
-     * @param arguments
-     *            arguments used witht the format string
-     */
-
-    public void add(String pattern, Object[] arguments)
-    {
-        add(MessageFormat.format(pattern, arguments));
-    }
-
-    /**
-     * Convience for {@link #add(String, Object[])}
+     * @param a
+     *            string format, as per {@link java.util.Formatter}
+     * @param args
+     *            arguments referenced by format specifiers
      */
-
-    public void add(String pattern, Object arg0)
-    {
-        add(pattern, new Object[]
-        { arg0 });
-    }
-
-    /**
-     * Convience for {@link #add(String, Object[])}
-     */
-
-    public void add(String pattern, Object arg0, Object arg1)
+    public void add(String format, Object... args)
     {
-        add(pattern, new Object[]
-        { arg0, arg1 });
+        add(format, args, false);
     }
 
     /**
-     * Convience for {@link #add(String, Object[])}
-     */
-
-    public void add(String pattern, Object arg0, Object arg1, Object arg2)
-    {
-        add(pattern, new Object[]
-        { arg0, arg1, arg2 });
-    }
-
-    /**
-     * Adds text to the current line then terminates the line.
+     * Adds text to the current line and ends the line.
      * 
-     * @param pattern
-     *            a string pattern, used with
-     *            {@link java.text.MessageFormat#format(java.lang.String, java.lang.Object[])}
-     * @param arguments
-     *            arguments used witht the format string
-     */
-
-    public void addln(String pattern, Object[] arguments)
-    {
-        addln(MessageFormat.format(pattern, arguments));
-    }
-
-    /**
-     * Convience for {@link #addln(String, Object[])}
-     */
-
-    public void addln(String pattern, Object arg0)
-    {
-        addln(pattern, new Object[]
-        { arg0 });
-    }
-
-    /**
-     * Convience for {@link #addln(String, Object[])}.
-     */
-
-    public void addln(String pattern, Object arg0, Object arg1)
-    {
-        addln(pattern, new Object[]
-        { arg0, arg1 });
-    }
-
-    /**
-     * Convience for {@link #addln(String, Object[])}.
+     * @param a
+     *            string format, as per {@link java.util.Formatter}
+     * @param args
+     *            arguments referenced by format specifiers
      */
-
-    public void addln(String pattern, Object arg0, Object arg1, Object arg2)
+    public void addln(String format, Object... args)
     {
-        addln(pattern, new Object[]
-        { arg0, arg1, arg2 });
+        add(format, args, true);
     }
 
-    /**
-     * Adds the text to the current line, surrounded by double quotes.
-     * <em>Does not escape quotes in the text</em>.
-     */
-
-    public void addQuoted(String text)
+    private void add(String format, Object[] args, boolean newLine)
     {
         indent();
-        _buffer.append(QUOTE);
-        _buffer.append(text);
-        _buffer.append(QUOTE);
-    }
 
-    /**
-     * Adds the text to the current line, and terminates the line.
-     */
+        // Format output, send to buffer
 
-    public void addln(String text)
-    {
-        add(text);
+        _formatter.format(format, args);
 
-        newline();
+        if (newLine)
+            newline();
     }
 
     private void newline()
@@ -202,6 +124,8 @@
         if (!_atNewLine)
             newline();
 
+        // TODO: Could check here if nesting depth goes below zero.
+
         _nestingDepth--;
 
         indent();
@@ -222,8 +146,14 @@
     }
 
     /**
-     * Returns the current contents of the buffer.
+     * Returns the current contents of the buffer. This value is often passed to methods such as
+     * {@link org.apache.tapestry.ioc.services.ClassFab#addConstructor(Class[], Class[], String)} or
+     * {@link org.apache.tapestry.ioc.services.ClassFab#addMethod(int, MethodSignature, String)}.
+     * <p>
+     * A BodyBuilder can be used again after invoking toString(), typically by invoking
+     * {@link #clear()}.
      */
+    @Override
     public String toString()
     {
         return _buffer.toString();

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/ComponentInstantiatorSourceImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/ComponentInstantiatorSourceImplTest.java?rev=424862&r1=424861&r2=424862&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/ComponentInstantiatorSourceImplTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/ComponentInstantiatorSourceImplTest.java Sun Jul 23 16:54:45 2006
@@ -155,6 +155,11 @@
 
         assertEquals(named.getName(), "Original");
 
+        // Sometimes this code runs so far that the updated file has the same timestamp as
+        // the original; this little blip seems to help.
+
+        Thread.sleep(250);
+
         createSynthComponentClass("Updated");
 
         // Detect the change and clear out the internal caches

Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/util/BodyBuilderTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/util/BodyBuilderTest.java?rev=424862&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/util/BodyBuilderTest.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/util/BodyBuilderTest.java Sun Jul 23 16:54:45 2006
@@ -0,0 +1,155 @@
+// Copyright 2006 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.tapestry.util;
+
+import org.apache.tapestry.test.BaseTestCase;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * @author Howard M. Lewis Ship
+ */
+public class BodyBuilderTest extends BaseTestCase
+{
+    private static String join(String... inputs)
+    {
+        StringBuffer buffer = new StringBuffer();
+
+        for (String input : inputs)
+        {
+            buffer.append(input);
+            buffer.append("\n");
+        }
+
+        return buffer.toString();
+    }
+
+    @Test
+    public void simple_nesting_and_indentation()
+    {
+        BodyBuilder b = new BodyBuilder();
+
+        b.begin();
+        b.addln("invoke();");
+        b.end();
+
+        assertEquals(b.toString(), join("{", "  invoke();", "}"));
+    }
+
+    @Test
+    public void block_nesting()
+    {
+        BodyBuilder b = new BodyBuilder();
+
+        b.begin();
+
+        b.add("while(true)");
+        b.begin();
+        b.add("_i += 1;");
+        b.end();
+
+        b.end();
+
+        assertEquals(b.toString(), join("{", "  while(true)", "  {", "    _i += 1;", "  }", "}"));
+    }
+
+    @Test
+    public void addln_idents_subsequent_line()
+    {
+        BodyBuilder b = new BodyBuilder();
+
+        b.begin();
+        b.addln("invoke(fred);");
+        b.addln("invoke(barney);");
+        b.end();
+
+        assertEquals(b.toString(), join("{", "  invoke(fred);", "  invoke(barney);", "}"));
+    }
+
+    @Test
+    public void clear()
+    {
+        BodyBuilder b = new BodyBuilder();
+
+        b.begin();
+        b.add("fred");
+        b.end();
+
+        assertEquals(b.toString(), "{\n  fred\n}\n");
+
+        b.clear();
+
+        b.begin();
+        b.add("barney");
+        b.end();
+
+        assertEquals(b.toString(), "{\n  barney\n}\n");
+    }
+
+    @Test
+    public void add_with_format_and_args()
+    {
+        BodyBuilder b = new BodyBuilder();
+
+        b.add("%s = %d;", "i", 3);
+
+        assertEquals(b.toString(), "i = 3;");
+    }
+
+    @Test
+    public void addln_with_format_and_args()
+    {
+        BodyBuilder b = new BodyBuilder();
+
+        b.addln("%s = %d;", "i", 3);
+
+        assertEquals(b.toString(), "i = 3;\n");
+    }
+
+    @Test
+    public void indent_only_on_new_line()
+    {
+        BodyBuilder b = new BodyBuilder();
+
+        b.begin();
+        b.add("if");
+        b.addln(" (debug)");
+        b.add("  log.debug(\"%s\"", "foo");
+        b.addln(");");
+        b.addln("while (true)");
+        b.begin();
+        b.addln("if (%s > 10)", "i");
+        b.addln("  return;");
+        b.add("%s++;", "i");
+        b.end();
+        b.end();
+
+        assertEquals(b.toString(), join(
+                "{",
+                "  if (debug)",
+                "    log.debug(\"foo\");",
+                "  while (true)",
+                "  {",
+                "    if (i > 10)",
+                "      return;",
+                "    i++;",
+                "  }",
+                "}"
+
+        ));
+
+    }
+}