You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by th...@apache.org on 2014/12/21 20:56:56 UTC

[30/35] tapestry-5 git commit: Second pass creating the BeanModel and Commons packages.

Second pass creating the BeanModel and Commons packages.


Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo
Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/d54315f6
Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/d54315f6
Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/d54315f6

Branch: refs/heads/master
Commit: d54315f6721d846b66a3081f93e47d8392fe661f
Parents: 7ba99e0
Author: Thiago H. de Paula Figueiredo <th...@apache.org>
Authored: Sat Dec 6 16:42:10 2014 -0200
Committer: Thiago H. de Paula Figueiredo <th...@apache.org>
Committed: Sat Dec 6 20:32:39 2014 -0200

----------------------------------------------------------------------
 beanmodel/.gitignore                            |   4 +
 beanmodel/build.gradle                          |  51 ++++-
 .../tapestry5/internal/BeanModelUtils.java      | 145 +++++++++++++
 .../internal/beaneditor/BeanModelImpl.java      |   4 +-
 .../internal/beaneditor/PropertyModelImpl.java  |  14 +-
 .../services/PropertyConduitDelegate.java       |   1 -
 .../services/PropertyConduitSourceImpl.java     |  10 +-
 .../org/apache/tapestry5/ioc/ObjectLocator.java |   3 +-
 .../ioc/internal/util/InternalStringUtils.java  | 203 +++++++++++++++++++
 .../ioc/internal/util/TapestryException.java    |  23 ++-
 .../tapestry5/ioc/util/AvailableValues.java     |   4 +-
 tapestry-core/build.gradle                      |  37 ----
 .../internal/TapestryInternalUtils.java         |  46 +----
 .../ioc/internal/util/InternalUtils.java        | 142 +++----------
 14 files changed, 472 insertions(+), 215 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/d54315f6/beanmodel/.gitignore
----------------------------------------------------------------------
diff --git a/beanmodel/.gitignore b/beanmodel/.gitignore
new file mode 100644
index 0000000..f739972
--- /dev/null
+++ b/beanmodel/.gitignore
@@ -0,0 +1,4 @@
+docs
+/.externalToolBuilders
+src/main/generated
+src/test/generated

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/d54315f6/beanmodel/build.gradle
----------------------------------------------------------------------
diff --git a/beanmodel/build.gradle b/beanmodel/build.gradle
index ccdeb37..c09ebdd 100644
--- a/beanmodel/build.gradle
+++ b/beanmodel/build.gradle
@@ -6,7 +6,18 @@ description = "Fast class property discovery, reading and writing library based
 //apply plugin: JavaPlugin
 
 buildDir = 'target/gradle-build'
-       
+
+project.ext {
+	antlrSource = "src/main/antlr"
+	mainGeneratedDir = "src/main/generated"
+	testGeneratedDir = "src/test/generated"
+	antlrOutput = "$mainGeneratedDir/antlr"
+}
+
+configurations {
+	antlr3
+}
+      
 project.ext.libraryVersions = [
 	jcache: '1.0.0',
 ]
@@ -15,12 +26,50 @@ dependencies {
 	compile project(":plastic")
 	compile project(":tapestry5-annotations")
 	compile project(":commons")
+	
+	// Antlr3 tool path used with the antlr3 task
+	antlr3 "org.antlr:antlr:3.5.2"
+
 	// Transitive will bring in the unwanted string template library as well
 	compile "org.antlr:antlr-runtime:3.5.2", {
 		exclude group: "org.antlr", module: "stringtemplate"
 	}
 }
 
+// This may spin out as a plugin once we've got the details down pat
+
+task generateGrammarSource(type: JavaExec) {
+	description "Generates Java sources from Antlr3 grammars."
+	inputs.source fileTree(dir: antlrSource, include: "**/*.g")
+	outputs.dir file(antlrOutput)
+
+	classpath configurations.antlr3
+
+	main "org.antlr.Tool"
+	args "-o", "${antlrOutput}/org/apache/tapestry5/internal/antlr"
+	args inputs.sourceFiles
+
+	doFirst {
+		logger.info "Executing Antlr3 grammar generation:\n${commandLine.join(' ')}"
+	}
+}
+
+sourceSets {
+	main {
+		output.dir(antlrOutput, builtBy: generateGrammarSource)
+		java {
+			srcDir antlrOutput
+		}
+	}
+}
+
+clean.delete mainGeneratedDir, testGeneratedDir
+
+compileJava {
+	dependsOn generateGrammarSource
+	options.fork(memoryMaximumSize: '512m')
+}
+
 jar {	
 	manifest {	
 	}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/d54315f6/beanmodel/src/main/java/org/apache/tapestry5/internal/BeanModelUtils.java
----------------------------------------------------------------------
diff --git a/beanmodel/src/main/java/org/apache/tapestry5/internal/BeanModelUtils.java b/beanmodel/src/main/java/org/apache/tapestry5/internal/BeanModelUtils.java
new file mode 100644
index 0000000..08cb88a
--- /dev/null
+++ b/beanmodel/src/main/java/org/apache/tapestry5/internal/BeanModelUtils.java
@@ -0,0 +1,145 @@
+// Copyright 2007, 2008 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.tapestry5.internal;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.util.regex.Pattern;
+
+import org.apache.tapestry5.ioc.AnnotationProvider;
+import org.apache.tapestry5.ioc.Messages;
+import org.apache.tapestry5.ioc.internal.NullAnnotationProvider;
+import org.apache.tapestry5.ioc.internal.util.InternalStringUtils;
+
+/**
+ * Some methods broken off tapestry-core's InternalUtils to avoid bringing the whole class
+ * plus its multiple dependencies to the BeanModel package.
+ */
+public class BeanModelUtils {
+	
+	public static final Pattern NON_WORD_PATTERN = Pattern.compile("[^\\w]");
+	
+	/**
+	 * @since 5.3
+	 */
+	private final static AnnotationProvider NULL_ANNOTATION_PROVIDER = new NullAnnotationProvider();
+
+	
+    /**
+     * Used to convert a property expression into a key that can be used to locate various resources (Blocks, messages,
+     * etc.). Strips out any punctuation characters, leaving just words characters (letters, number and the
+     * underscore).
+     *
+     * @param expression a property expression
+     * @return the expression with punctuation removed
+     */
+    public static String extractIdFromPropertyExpression(String expression)
+    {
+        return replace(expression, NON_WORD_PATTERN, "");
+    }
+
+    public static String replace(String input, Pattern pattern, String replacement)
+    {
+        return pattern.matcher(input).replaceAll(replacement);
+    }
+    
+    /**
+     * Looks for a label within the messages based on the id. If found, it is used, otherwise the name is converted to a
+     * user presentable form.
+     */
+    public static String defaultLabel(String id, Messages messages, String propertyExpression)
+    {
+        String key = id + "-label";
+
+        if (messages.contains(key))
+            return messages.get(key);
+
+        return toUserPresentable(extractIdFromPropertyExpression(InternalStringUtils.lastTerm(propertyExpression)));
+    }
+    
+    /**
+     * Capitalizes the string, and inserts a space before each upper case character (or sequence of upper case
+     * characters). Thus "userId" becomes "User Id", etc. Also, converts underscore into space (and capitalizes the
+     * following word), thus "user_id" also becomes "User Id".
+     */
+    public static String toUserPresentable(String id)
+    {
+        StringBuilder builder = new StringBuilder(id.length() * 2);
+
+        char[] chars = id.toCharArray();
+        boolean postSpace = true;
+        boolean upcaseNext = true;
+
+        for (char ch : chars)
+        {
+            if (upcaseNext)
+            {
+                builder.append(Character.toUpperCase(ch));
+                upcaseNext = false;
+
+                continue;
+            }
+
+            if (ch == '_')
+            {
+                builder.append(' ');
+                upcaseNext = true;
+                continue;
+            }
+
+            boolean upperCase = Character.isUpperCase(ch);
+
+            if (upperCase && !postSpace)
+                builder.append(' ');
+
+            builder.append(ch);
+
+            postSpace = upperCase;
+        }
+
+        return builder.toString();
+    }
+    
+    /**
+     * @since 5.3
+     */
+    public static AnnotationProvider toAnnotationProvider(final Class element)
+    {
+        return new AnnotationProvider()
+        {
+            @Override
+            public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
+            {
+                return annotationClass.cast(element.getAnnotation(annotationClass));
+            }
+        };
+    }
+    
+    public static AnnotationProvider toAnnotationProvider(final Method element)
+    {
+        if (element == null)
+            return NULL_ANNOTATION_PROVIDER;
+
+        return new AnnotationProvider()
+        {
+            @Override
+            public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
+            {
+                return element.getAnnotation(annotationClass);
+            }
+        };
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/d54315f6/beanmodel/src/main/java/org/apache/tapestry5/internal/beaneditor/BeanModelImpl.java
----------------------------------------------------------------------
diff --git a/beanmodel/src/main/java/org/apache/tapestry5/internal/beaneditor/BeanModelImpl.java b/beanmodel/src/main/java/org/apache/tapestry5/internal/beaneditor/BeanModelImpl.java
index 26eb309..b72a3d6 100644
--- a/beanmodel/src/main/java/org/apache/tapestry5/internal/beaneditor/BeanModelImpl.java
+++ b/beanmodel/src/main/java/org/apache/tapestry5/internal/beaneditor/BeanModelImpl.java
@@ -22,7 +22,7 @@ import org.apache.tapestry5.internal.services.CoercingPropertyConduitWrapper;
 import org.apache.tapestry5.ioc.Messages;
 import org.apache.tapestry5.ioc.ObjectLocator;
 import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
-import org.apache.tapestry5.ioc.internal.util.InternalUtils;
+import org.apache.tapestry5.ioc.internal.util.InternalStringUtils;
 import org.apache.tapestry5.ioc.services.TypeCoercer;
 import org.apache.tapestry5.ioc.util.AvailableValues;
 import org.apache.tapestry5.ioc.util.UnknownValueException;
@@ -93,7 +93,7 @@ public class BeanModelImpl<T> implements BeanModel<T>
 
     private void validateNewPropertyName(String propertyName)
     {
-        assert InternalUtils.isNonBlank(propertyName);
+        assert InternalStringUtils.isNonBlank(propertyName);
         if (properties.containsKey(propertyName))
             throw new RuntimeException(String.format(
                     "Bean editor model for %s already contains a property model for property '%s'.",

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/d54315f6/beanmodel/src/main/java/org/apache/tapestry5/internal/beaneditor/PropertyModelImpl.java
----------------------------------------------------------------------
diff --git a/beanmodel/src/main/java/org/apache/tapestry5/internal/beaneditor/PropertyModelImpl.java b/beanmodel/src/main/java/org/apache/tapestry5/internal/beaneditor/PropertyModelImpl.java
index 703ce44..b21e5bb 100644
--- a/beanmodel/src/main/java/org/apache/tapestry5/internal/beaneditor/PropertyModelImpl.java
+++ b/beanmodel/src/main/java/org/apache/tapestry5/internal/beaneditor/PropertyModelImpl.java
@@ -14,17 +14,17 @@
 
 package org.apache.tapestry5.internal.beaneditor;
 
+import java.lang.annotation.Annotation;
+
 import org.apache.tapestry5.PropertyConduit;
 import org.apache.tapestry5.beaneditor.BeanModel;
 import org.apache.tapestry5.beaneditor.PropertyModel;
 import org.apache.tapestry5.beaneditor.Sortable;
-import org.apache.tapestry5.internal.TapestryInternalUtils;
+import org.apache.tapestry5.internal.BeanModelUtils;
 import org.apache.tapestry5.ioc.Messages;
-import org.apache.tapestry5.ioc.internal.util.InternalUtils;
+import org.apache.tapestry5.ioc.internal.util.InternalStringUtils;
 import org.apache.tapestry5.plastic.PlasticUtils;
 
-import java.lang.annotation.Annotation;
-
 @SuppressWarnings("all")
 public class PropertyModelImpl implements PropertyModel
 {
@@ -48,9 +48,9 @@ public class PropertyModelImpl implements PropertyModel
         this.name = name;
         this.conduit = conduit;
 
-        id = TapestryInternalUtils.extractIdFromPropertyExpression(name);
+        id = BeanModelUtils.extractIdFromPropertyExpression(name);
 
-        label = TapestryInternalUtils.defaultLabel(id, messages, name);
+        label = BeanModelUtils.defaultLabel(id, messages, name);
 
         // TAP5-2305
         if (conduit != null)
@@ -87,7 +87,7 @@ public class PropertyModelImpl implements PropertyModel
 
     public PropertyModel label(String label)
     {
-        assert InternalUtils.isNonBlank(label);
+        assert InternalStringUtils.isNonBlank(label);
         this.label = label;
 
         return this;

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/d54315f6/beanmodel/src/main/java/org/apache/tapestry5/internal/services/PropertyConduitDelegate.java
----------------------------------------------------------------------
diff --git a/beanmodel/src/main/java/org/apache/tapestry5/internal/services/PropertyConduitDelegate.java b/beanmodel/src/main/java/org/apache/tapestry5/internal/services/PropertyConduitDelegate.java
index 1242031..3849103 100644
--- a/beanmodel/src/main/java/org/apache/tapestry5/internal/services/PropertyConduitDelegate.java
+++ b/beanmodel/src/main/java/org/apache/tapestry5/internal/services/PropertyConduitDelegate.java
@@ -19,7 +19,6 @@ import java.lang.annotation.Annotation;
 import org.apache.tapestry5.internal.InternalPropertyConduit;
 import org.apache.tapestry5.internal.util.IntegerRange;
 import org.apache.tapestry5.ioc.AnnotationProvider;
-import org.apache.tapestry5.ioc.internal.util.InternalUtils;
 import org.apache.tapestry5.ioc.services.TypeCoercer;
 
 /**

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/d54315f6/beanmodel/src/main/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImpl.java
----------------------------------------------------------------------
diff --git a/beanmodel/src/main/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImpl.java b/beanmodel/src/main/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImpl.java
index 701420f..83f67fa 100644
--- a/beanmodel/src/main/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImpl.java
+++ b/beanmodel/src/main/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImpl.java
@@ -19,6 +19,7 @@ import org.antlr.runtime.CommonTokenStream;
 import org.antlr.runtime.tree.Tree;
 import org.apache.tapestry5.PropertyConduit;
 import org.apache.tapestry5.PropertyConduit2;
+import org.apache.tapestry5.internal.BeanModelUtils;
 import org.apache.tapestry5.internal.InternalPropertyConduit;
 import org.apache.tapestry5.internal.antlr.PropertyExpressionLexer;
 import org.apache.tapestry5.internal.antlr.PropertyExpressionParser;
@@ -29,7 +30,7 @@ import org.apache.tapestry5.ioc.annotations.PostInjection;
 import org.apache.tapestry5.ioc.internal.NullAnnotationProvider;
 import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
 import org.apache.tapestry5.ioc.internal.util.GenericsUtils;
-import org.apache.tapestry5.ioc.internal.util.InternalUtils;
+import org.apache.tapestry5.ioc.internal.util.InternalStringUtils;
 import org.apache.tapestry5.ioc.services.*;
 import org.apache.tapestry5.ioc.util.AvailableValues;
 import org.apache.tapestry5.ioc.util.ExceptionUtils;
@@ -1106,7 +1107,7 @@ public class PropertyConduitSourceImpl implements PropertyConduitSource
 
             String message = String.format("Node %s was type %s, but was expected to be (one of) %s.",
                     node.toStringTree(), PropertyExpressionParser.tokenNames[node.getType()],
-                    InternalUtils.joinSorted(tokenNames));
+                    InternalStringUtils.joinSorted(tokenNames));
 
             return new RuntimeException(message);
         }
@@ -1259,7 +1260,7 @@ public class PropertyConduitSourceImpl implements PropertyConduitSource
 
             Type returnType = GenericsUtils.extractActualType(activeType, method);
 
-            return new Term(returnType, toUniqueId(method), InternalUtils.toAnnotationProvider(method), new InstructionBuilderCallback()
+            return new Term(returnType, toUniqueId(method), BeanModelUtils.toAnnotationProvider(method), new InstructionBuilderCallback()
             {
                 public void doBuild(InstructionBuilder builder)
                 {
@@ -1363,7 +1364,7 @@ public class PropertyConduitSourceImpl implements PropertyConduitSource
     public PropertyConduit create(Class rootClass, String expression)
     {
         assert rootClass != null;
-        assert InternalUtils.isNonBlank(expression);
+        assert InternalStringUtils.isNonBlank(expression);
 
         MultiKey key = new MultiKey(rootClass, expression);
 
@@ -1560,4 +1561,5 @@ public class PropertyConduitSourceImpl implements PropertyConduitSource
 
         return builder.append(")").toString();
     }
+    
 }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/d54315f6/commons/src/main/java/org/apache/tapestry5/ioc/ObjectLocator.java
----------------------------------------------------------------------
diff --git a/commons/src/main/java/org/apache/tapestry5/ioc/ObjectLocator.java b/commons/src/main/java/org/apache/tapestry5/ioc/ObjectLocator.java
index 81d1f77..e60c0d9 100644
--- a/commons/src/main/java/org/apache/tapestry5/ioc/ObjectLocator.java
+++ b/commons/src/main/java/org/apache/tapestry5/ioc/ObjectLocator.java
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007, 2010, 2011 The Apache Software Foundation
+// Copyright 2006, 2007, 2010, 2011, 2014 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.
@@ -15,7 +15,6 @@
 package org.apache.tapestry5.ioc;
 
 import org.apache.tapestry5.ioc.annotations.Inject;
-import org.apache.tapestry5.ioc.services.MasterObjectProvider;
 
 import java.lang.annotation.Annotation;
 

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/d54315f6/commons/src/main/java/org/apache/tapestry5/ioc/internal/util/InternalStringUtils.java
----------------------------------------------------------------------
diff --git a/commons/src/main/java/org/apache/tapestry5/ioc/internal/util/InternalStringUtils.java b/commons/src/main/java/org/apache/tapestry5/ioc/internal/util/InternalStringUtils.java
new file mode 100644
index 0000000..e345593
--- /dev/null
+++ b/commons/src/main/java/org/apache/tapestry5/ioc/internal/util/InternalStringUtils.java
@@ -0,0 +1,203 @@
+// Copyright 2006-2014 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.tapestry5.ioc.internal.util;
+
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * String-related utilities used within various internal implementations of the Apache Tapestry subprojects.
+ * Broken off Tapestry-IoC's InternalUtils.
+ */
+@SuppressWarnings("all")
+public class InternalStringUtils
+{
+	
+    /**
+     * Pattern used to eliminate leading and trailing underscores and dollar signs.
+     */
+    private static final Pattern NAME_PATTERN = Pattern.compile("^[_|$]*([\\p{javaJavaIdentifierPart}]+?)[_|$]*$",
+            Pattern.CASE_INSENSITIVE);
+
+    /**
+     * Converts a method to a user presentable string consisting of the containing class name, the method name, and the
+     * short form of the parameter list (the class name of each parameter type, shorn of the package name portion).
+     *
+     * @param method
+     * @return short string representation
+     */
+    public static String asString(Method method)
+    {
+        StringBuilder buffer = new StringBuilder();
+
+        buffer.append(method.getDeclaringClass().getName());
+        buffer.append(".");
+        buffer.append(method.getName());
+        buffer.append("(");
+
+        for (int i = 0; i < method.getParameterTypes().length; i++)
+        {
+            if (i > 0)
+                buffer.append(", ");
+
+            String name = method.getParameterTypes()[i].getSimpleName();
+
+            buffer.append(name);
+        }
+
+        return buffer.append(")").toString();
+    }
+
+    /**
+     * Strips leading "_" and "$" and trailing "_" from the name.
+     */
+    public static String stripMemberName(String memberName)
+    {
+        assert isNonBlank(memberName);
+        Matcher matcher = NAME_PATTERN.matcher(memberName);
+
+        if (!matcher.matches())
+            throw new IllegalArgumentException(String.format("Input '%s' is not a valid Java identifier.", memberName));
+
+        return matcher.group(1);
+    }
+
+    /**
+     * Joins together some number of elements to form a comma separated list.
+     */
+    public static String join(List elements)
+    {
+        return join(elements, ", ");
+    }
+
+    /**
+     * Joins together some number of elements. If a value in the list is the empty string, it is replaced with the
+     * string "(blank)".
+     *
+     * @param elements
+     *         objects to be joined together
+     * @param separator
+     *         used between elements when joining
+     */
+    public static String join(List elements, String separator)
+    {
+        switch (elements.size())
+        {
+            case 0:
+                return "";
+
+            case 1:
+                return elements.get(0).toString();
+
+            default:
+
+                StringBuilder buffer = new StringBuilder();
+                boolean first = true;
+
+                for (Object o : elements)
+                {
+                    if (!first)
+                        buffer.append(separator);
+
+                    String string = String.valueOf(o);
+
+                    if (string.equals(""))
+                        string = "(blank)";
+
+                    buffer.append(string);
+
+                    first = false;
+                }
+
+                return buffer.toString();
+        }
+    }
+
+    /**
+     * Creates a sorted copy of the provided elements, then turns that into a comma separated list.
+     *
+     * @return the elements converted to strings, sorted, joined with comma ... or "(none)" if the elements are null or
+     *         empty
+     */
+    public static String joinSorted(Collection elements)
+    {
+        if (elements == null || elements.isEmpty())
+            return "(none)";
+
+        List<String> list = CollectionFactory.newList();
+
+        for (Object o : elements)
+            list.add(String.valueOf(o));
+
+        Collections.sort(list);
+
+        return join(list);
+    }
+
+    /**
+     * Returns true if the input is null, or is a zero length string (excluding leading/trailing whitespace).
+     */
+
+    public static boolean isBlank(String input)
+    {
+        return input == null || input.length() == 0 || input.trim().length() == 0;
+    }
+
+    public static boolean isNonBlank(String input)
+    {
+        return !isBlank(input);
+    }
+
+    /**
+     * Capitalizes a string, converting the first character to uppercase.
+     */
+    public static String capitalize(String input)
+    {
+        if (input.length() == 0)
+            return input;
+
+        return input.substring(0, 1).toUpperCase() + input.substring(1);
+    }
+
+    /**
+     * Return true if the input string contains the marker for symbols that must be expanded.
+     */
+    public static boolean containsSymbols(String input)
+    {
+        return input.contains("${");
+    }
+
+    /**
+     * Searches the string for the final period ('.') character and returns everything after that. The input string is
+     * generally a fully qualified class name, though tapestry-core also uses this method for the occasional property
+     * expression (which is also dot separated). Returns the input string unchanged if it does not contain a period
+     * character.
+     */
+    public static String lastTerm(String input)
+    {
+        assert isNonBlank(input);
+        int dotx = input.lastIndexOf('.');
+
+        if (dotx < 0)
+            return input;
+
+        return input.substring(dotx + 1);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/d54315f6/commons/src/main/java/org/apache/tapestry5/ioc/internal/util/TapestryException.java
----------------------------------------------------------------------
diff --git a/commons/src/main/java/org/apache/tapestry5/ioc/internal/util/TapestryException.java b/commons/src/main/java/org/apache/tapestry5/ioc/internal/util/TapestryException.java
index ef217cb..d8d8018 100644
--- a/commons/src/main/java/org/apache/tapestry5/ioc/internal/util/TapestryException.java
+++ b/commons/src/main/java/org/apache/tapestry5/ioc/internal/util/TapestryException.java
@@ -34,7 +34,7 @@ public class TapestryException extends RuntimeException implements Locatable
      */
     public TapestryException(String message, Object location, Throwable cause)
     {
-        this(message, InternalUtils.locationOf(location), cause);
+        this(message, locationOf(location), cause);
     }
 
     /**
@@ -71,5 +71,26 @@ public class TapestryException extends RuntimeException implements Locatable
 
         return String.format("%s [at %s]", super.toString(), location);
     }
+    
+    /**
+     * Sniffs the object to see if it is a {@link Location} or {@link Locatable}. Returns null if null or not
+     * convertable to a location.
+     * Copied from InternalUtils to avoid having it moved to BeanModel or Commons subprojects.
+     */
+
+    private static Location locationOf(Object location)
+    {
+        if (location == null)
+            return null;
+
+        if (location instanceof Location)
+            return (Location) location;
+
+        if (location instanceof Locatable)
+            return ((Locatable) location).getLocation();
+
+        return null;
+    }
+
 
 }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/d54315f6/commons/src/main/java/org/apache/tapestry5/ioc/util/AvailableValues.java
----------------------------------------------------------------------
diff --git a/commons/src/main/java/org/apache/tapestry5/ioc/util/AvailableValues.java b/commons/src/main/java/org/apache/tapestry5/ioc/util/AvailableValues.java
index c4c5c6d..8c9cb3f 100644
--- a/commons/src/main/java/org/apache/tapestry5/ioc/util/AvailableValues.java
+++ b/commons/src/main/java/org/apache/tapestry5/ioc/util/AvailableValues.java
@@ -20,7 +20,7 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
-import org.apache.tapestry5.ioc.internal.util.InternalUtils;
+import org.apache.tapestry5.ioc.internal.util.InternalStringUtils;
 
 /**
  * Used (as part of a {@link UnknownValueException} to identify what available values
@@ -81,7 +81,7 @@ public class AvailableValues
     @Override
     public String toString()
     {
-        return String.format("AvailableValues[%s: %s]", valueType, InternalUtils.join(values));
+        return String.format("AvailableValues[%s: %s]", valueType, InternalStringUtils.join(values));
     }
 
 }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/d54315f6/tapestry-core/build.gradle
----------------------------------------------------------------------
diff --git a/tapestry-core/build.gradle b/tapestry-core/build.gradle
index 584200a..d35c166 100644
--- a/tapestry-core/build.gradle
+++ b/tapestry-core/build.gradle
@@ -8,11 +8,6 @@ project.ext {
     antlrSource = "src/main/antlr"
     mainGeneratedDir = "src/main/generated"
     testGeneratedDir = "src/test/generated"
-    antlrOutput = "$mainGeneratedDir/antlr"
-}
-
-configurations {
-    antlr3
 }
 
 dependencies {
@@ -27,30 +22,9 @@ dependencies {
 
     compile "commons-codec:commons-codec:1.5"
 
-    // Antlr3 tool path used with the antlr3 task
-    antlr3 "org.antlr:antlr:3.5.2"
-
     testRuntime "org.hsqldb:hsqldb:1.8.0.10"
 }
 
-// This may spin out as a plugin once we've got the details down pat
-
-task generateGrammarSource(type: JavaExec) {
-    description "Generates Java sources from Antlr3 grammars."
-    inputs.source fileTree(dir: antlrSource, include: "**/*.g")
-    outputs.dir file(antlrOutput)
-
-    classpath configurations.antlr3
-
-    main "org.antlr.Tool"
-    args "-o", "${antlrOutput}/org/apache/tapestry5/internal/antlr"
-    args inputs.sourceFiles
-
-    doFirst {
-        logger.info "Executing Antlr3 grammar generation:\n${commandLine.join(' ')}"
-    }
-}
-
 task preprocessCoffeeScript(type: PreprocessCoffeeScript) {
 }
 
@@ -73,23 +47,12 @@ sourceSets {
     main {
         output.dir(compileCoffeeScript.outputDir, builtBy: compileCoffeeScript)
         output.dir(compileProcessedCoffeescript.outputDir, builtBy: compileProcessedCoffeescript)
-        output.dir(antlrOutput, builtBy: generateGrammarSource)
-        java {
-            srcDir antlrOutput
-        }
     }
     test {
         output.dir(compileTestCoffeeScript.outputDir, builtBy: compileTestCoffeeScript)
     }
 }
 
-clean.delete mainGeneratedDir, testGeneratedDir
-
-compileJava {
-    dependsOn generateGrammarSource
-    options.fork(memoryMaximumSize: '512m')
-}
-
 // Not sure why this is necessary:
 compileTestGroovy.dependsOn compileTestJava
 

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/d54315f6/tapestry-core/src/main/java/org/apache/tapestry5/internal/TapestryInternalUtils.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/TapestryInternalUtils.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/TapestryInternalUtils.java
index 3435d64..aba7225 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/TapestryInternalUtils.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/TapestryInternalUtils.java
@@ -59,40 +59,7 @@ public class TapestryInternalUtils
      */
     public static String toUserPresentable(String id)
     {
-        StringBuilder builder = new StringBuilder(id.length() * 2);
-
-        char[] chars = id.toCharArray();
-        boolean postSpace = true;
-        boolean upcaseNext = true;
-
-        for (char ch : chars)
-        {
-            if (upcaseNext)
-            {
-                builder.append(Character.toUpperCase(ch));
-                upcaseNext = false;
-
-                continue;
-            }
-
-            if (ch == '_')
-            {
-                builder.append(' ');
-                upcaseNext = true;
-                continue;
-            }
-
-            boolean upperCase = Character.isUpperCase(ch);
-
-            if (upperCase && !postSpace)
-                builder.append(' ');
-
-            builder.append(ch);
-
-            postSpace = upperCase;
-        }
-
-        return builder.toString();
+        return BeanModelUtils.toUserPresentable(id);
     }
 
     public static Map<String, String> mapFromKeysAndValues(String... keysAndValues)
@@ -261,7 +228,7 @@ public class TapestryInternalUtils
      */
     public static String extractIdFromPropertyExpression(String expression)
     {
-        return replace(expression, NON_WORD_PATTERN, "");
+        return BeanModelUtils.extractIdFromPropertyExpression(expression);
     }
 
     /**
@@ -270,12 +237,7 @@ public class TapestryInternalUtils
      */
     public static String defaultLabel(String id, Messages messages, String propertyExpression)
     {
-        String key = id + "-label";
-
-        if (messages.contains(key))
-            return messages.get(key);
-
-        return toUserPresentable(extractIdFromPropertyExpression(lastTerm(propertyExpression)));
+        return BeanModelUtils.defaultLabel(id, messages, propertyExpression);
     }
 
     /**
@@ -342,7 +304,7 @@ public class TapestryInternalUtils
 
     private static String replace(String input, Pattern pattern, String replacement)
     {
-        return pattern.matcher(input).replaceAll(replacement);
+        return BeanModelUtils.replace(input, pattern, replacement);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/d54315f6/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/InternalUtils.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/InternalUtils.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/InternalUtils.java
index e9e7806..a40f984 100644
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/InternalUtils.java
+++ b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/InternalUtils.java
@@ -17,16 +17,16 @@ package org.apache.tapestry5.ioc.internal.util;
 import org.apache.tapestry5.func.F;
 import org.apache.tapestry5.func.Mapper;
 import org.apache.tapestry5.func.Predicate;
+import org.apache.tapestry5.internal.BeanModelUtils;
 import org.apache.tapestry5.internal.plastic.PlasticInternalUtils;
 import org.apache.tapestry5.ioc.*;
 import org.apache.tapestry5.ioc.annotations.*;
 import org.apache.tapestry5.ioc.def.*;
-import org.apache.tapestry5.ioc.internal.NullAnnotationProvider;
 import org.apache.tapestry5.ioc.internal.ServiceDefImpl;
 import org.apache.tapestry5.ioc.services.Coercion;
-import org.apache.tapestry5.ioc.services.PlasticProxyFactory;
 import org.apache.tapestry5.ioc.util.ExceptionUtils;
 import org.apache.tapestry5.plastic.PlasticUtils;
+import org.apache.tapestry5.ioc.services.PlasticProxyFactory;
 import org.slf4j.Logger;
 
 import javax.annotation.PostConstruct;
@@ -56,18 +56,6 @@ public class InternalUtils
     public static final boolean SERVICE_CLASS_RELOADING_ENABLED = Boolean.parseBoolean(System.getProperty(
             IOCConstants.SERVICE_CLASS_RELOADING_ENABLED, "true"));
 
-
-    /**
-     * Pattern used to eliminate leading and trailing underscores and dollar signs.
-     */
-    private static final Pattern NAME_PATTERN = Pattern.compile("^[_|$]*([\\p{javaJavaIdentifierPart}]+?)[_|$]*$",
-            Pattern.CASE_INSENSITIVE);
-
-    /**
-     * @since 5.3
-     */
-    public static AnnotationProvider NULL_ANNOTATION_PROVIDER = new NullAnnotationProvider();
-
     /**
      * Converts a method to a user presentable string using a {@link PlasticProxyFactory} to obtain a {@link Location}
      * (where possible). {@link #asString(Method)} is used under the covers, to present a detailed, but not excessive,
@@ -92,27 +80,11 @@ public class InternalUtils
      *
      * @param method
      * @return short string representation
+     * @deprecated use {@link InternalStringUtils#asString(Method)} instead.
      */
     public static String asString(Method method)
     {
-        StringBuilder buffer = new StringBuilder();
-
-        buffer.append(method.getDeclaringClass().getName());
-        buffer.append(".");
-        buffer.append(method.getName());
-        buffer.append("(");
-
-        for (int i = 0; i < method.getParameterTypes().length; i++)
-        {
-            if (i > 0)
-                buffer.append(", ");
-
-            String name = method.getParameterTypes()[i].getSimpleName();
-
-            buffer.append(name);
-        }
-
-        return buffer.append(")").toString();
+        return InternalStringUtils.asString(method);
     }
 
     /**
@@ -131,16 +103,11 @@ public class InternalUtils
 
     /**
      * Strips leading "_" and "$" and trailing "_" from the name.
+     * @deprecated use {@link InternalStringUtils#stripMemberName(String)} instead.
      */
     public static String stripMemberName(String memberName)
     {
-        assert InternalUtils.isNonBlank(memberName);
-        Matcher matcher = NAME_PATTERN.matcher(memberName);
-
-        if (!matcher.matches())
-            throw new IllegalArgumentException(String.format("Input '%s' is not a valid Java identifier.", memberName));
-
-        return matcher.group(1);
+        return InternalStringUtils.stripMemberName(memberName);
     }
 
     /**
@@ -425,10 +392,11 @@ public class InternalUtils
 
     /**
      * Joins together some number of elements to form a comma separated list.
+     * @deprecated use {@link InternalStringUtils#join(List)} instead.
      */
     public static String join(List elements)
     {
-        return join(elements, ", ");
+        return InternalStringUtils.join(elements);
     }
 
     /**
@@ -439,39 +407,11 @@ public class InternalUtils
      *         objects to be joined together
      * @param separator
      *         used between elements when joining
+     * @deprecated use {@link InternalStringUtils#asString(Method, String)} instead.
      */
     public static String join(List elements, String separator)
     {
-        switch (elements.size())
-        {
-            case 0:
-                return "";
-
-            case 1:
-                return elements.get(0).toString();
-
-            default:
-
-                StringBuilder buffer = new StringBuilder();
-                boolean first = true;
-
-                for (Object o : elements)
-                {
-                    if (!first)
-                        buffer.append(separator);
-
-                    String string = String.valueOf(o);
-
-                    if (string.equals(""))
-                        string = "(blank)";
-
-                    buffer.append(string);
-
-                    first = false;
-                }
-
-                return buffer.toString();
-        }
+        return InternalStringUtils.join(elements, separator);
     }
 
     /**
@@ -479,29 +419,21 @@ public class InternalUtils
      *
      * @return the elements converted to strings, sorted, joined with comma ... or "(none)" if the elements are null or
      *         empty
+     * @deprecated use {@link InternalStringUtils#joinSorted(Collection)} instead.
      */
     public static String joinSorted(Collection elements)
     {
-        if (elements == null || elements.isEmpty())
-            return "(none)";
-
-        List<String> list = CollectionFactory.newList();
-
-        for (Object o : elements)
-            list.add(String.valueOf(o));
-
-        Collections.sort(list);
-
-        return join(list);
+        return InternalStringUtils.joinSorted(elements);
     }
 
     /**
      * Returns true if the input is null, or is a zero length string (excluding leading/trailing whitespace).
+     * @deprecated use {@link InternalStringUtils#isBlank(String)} instead.
      */
 
     public static boolean isBlank(String input)
     {
-        return input == null || input.length() == 0 || input.trim().length() == 0;
+        return InternalStringUtils.isBlank(input);
     }
 
     /**
@@ -518,20 +450,21 @@ public class InternalUtils
         return false;
     }
 
+    /**
+     * @deprecated use {@link InternalStringUtils#isNonBlank(String)} instead.
+     */
     public static boolean isNonBlank(String input)
     {
-        return !isBlank(input);
+        return InternalStringUtils.isNonBlank(input);
     }
 
     /**
      * Capitalizes a string, converting the first character to uppercase.
+     * @deprecated use {@link InternalStringUtils#capitalize(String)} instead.
      */
     public static String capitalize(String input)
     {
-        if (input.length() == 0)
-            return input;
-
-        return input.substring(0, 1).toUpperCase() + input.substring(1);
+        return InternalStringUtils.capitalize(input);
     }
 
     /**
@@ -639,10 +572,11 @@ public class InternalUtils
 
     /**
      * Return true if the input string contains the marker for symbols that must be expanded.
+     * @deprecated use {@link InternalStringUtils#containsSymbols(String)} instead.
      */
     public static boolean containsSymbols(String input)
     {
-        return input.contains("${");
+        return InternalStringUtils.containsSymbols(input);
     }
 
     /**
@@ -650,16 +584,11 @@ public class InternalUtils
      * generally a fully qualified class name, though tapestry-core also uses this method for the occasional property
      * expression (which is also dot separated). Returns the input string unchanged if it does not contain a period
      * character.
+     * @deprecated use {@link InternalStringUtils#lastTerm(String)} instead.
      */
     public static String lastTerm(String input)
     {
-        assert InternalUtils.isNonBlank(input);
-        int dotx = input.lastIndexOf('.');
-
-        if (dotx < 0)
-            return input;
-
-        return input.substring(dotx + 1);
+        return InternalStringUtils.lastTerm(input);
     }
 
     /**
@@ -848,18 +777,9 @@ public class InternalUtils
      */
     public static AnnotationProvider toAnnotationProvider(final Class element)
     {
-        return new AnnotationProvider()
-        {
-            @Override
-            public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
-            {
-                return annotationClass.cast(element.getAnnotation(annotationClass));
-            }
-        };
+        return BeanModelUtils.toAnnotationProvider(element);
     }
 
-    ;
-
     /**
      * @since 5.3
      */
@@ -1484,17 +1404,7 @@ public class InternalUtils
 
     public static AnnotationProvider toAnnotationProvider(final Method element)
     {
-        if (element == null)
-            return NULL_ANNOTATION_PROVIDER;
-
-        return new AnnotationProvider()
-        {
-            @Override
-            public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
-            {
-                return element.getAnnotation(annotationClass);
-            }
-        };
+        return BeanModelUtils.toAnnotationProvider(element);
     }
 
     public static <T> ObjectCreator<T> createConstructorConstructionPlan(final OperationTracker tracker, final ObjectLocator locator,