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++;",
+ " }",
+ "}"
+
+ ));
+
+ }
+}