Author: hlship
Date: Sat Jan 31 22:40:14 2009
New Revision: 739646

URL: http://svn.apache.org/viewvc?rev=739646&view=rev
Log:
TAP5-79: Improve Tapestry's property expression language to include OGNL-like 
features

Added:
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/antlr/BaseParser.java
Modified:
    tapestry/tapestry5/trunk/quickstart/src/site/apt/index.apt
    
tapestry/tapestry5/trunk/tapestry-core/src/main/antlr/org/apache/tapestry5/internal/antlr/PropertyExpressionParser.g
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/antlr/BaseLexer.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImpl.java
    
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImplTest.java

Modified: tapestry/tapestry5/trunk/quickstart/src/site/apt/index.apt
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/quickstart/src/site/apt/index.apt?rev=739646&r1=739645&r2=739646&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/quickstart/src/site/apt/index.apt (original)
+++ tapestry/tapestry5/trunk/quickstart/src/site/apt/index.apt Sat Jan 31 
22:40:14 2009
@@ -11,75 +11,53 @@
   What you end up with is a basic Maven project, ready to build and deploy.
   
   First, you must decide on your group id, artifact id, and version number. 
For example, let's choose <<org.example>> for our group id,
-  <<myapp>> for the artifactId, and <<1.0.0-SNAPSHOT>> for the version number. 
 We also need a root package name, which we'll create by combining the group id
+  <<myapp>> for the artifactId, and <<1.0-SNAPSHOT>> for the version number.  
We also need a root package name, which we'll create by combining the group id
   and the artifact id.
   
-  From the command line, you execute the following command (it's a bit of a 
doozy):
-  
-  mvn archetype:create -DarchetypeGroupId=org.apache.tapestry 
-DarchetypeArtifactId=quickstart -DgroupId=<<org.example>> 
-DartifactId=<<myapp>> -DpackageName=<<org.example.myapp>> 
-Dversion=<<1.0.0-SNAPSHOT>>
-  
-  Maven will use the information from that massive command line to locate and 
configure the archetype, and produce the project:
-  
+  From the command line, you execute the following command:
+
+  <<<mvn archetype:generate 
-DarchetypeCatalog=http://tapestry.formos.com/maven-snapshot-repository>>>
+
+  Maven uses the archetypeCatalog to get a list of available archetypes; in 
this case, the only option is the Tapestry Quickstart.
+  It will then ask you to enter the groupId, artifactId, version, and package.
+
 +---+
-$ mvn archetype:create -DarchetypeGroupId=org.apache.tapestry 
-DarchetypeArtifactId=quickstart -DgroupId=org.example -DartifactId=myapp 
-DpackageName=org.example.myapp -Dversion=1.0.0-SNAPSHOT
+$ mvn archetype:generate 
-DarchetypeCatalog=http://tapestry.formos.com/maven-snapshot-repository
 [INFO] Scanning for projects...
 [INFO] Searching repository for plugin with prefix: 'archetype'.
-[INFO] 
----------------------------------------------------------------------------
+[INFO] ------------------------------------------------------------------------
 [INFO] Building Maven Default Project
-[INFO]    task-segment: [archetype:create] (aggregator-style)
-[INFO] 
----------------------------------------------------------------------------
+[INFO]    task-segment: [archetype:generate] (aggregator-style)
+[INFO] ------------------------------------------------------------------------
+[INFO] Preparing archetype:generate
+[INFO] No goals needed for project - skipping
 [INFO] Setting property: classpath.resource.loader.class => 
'org.codehaus.plexus.velocity.ContextClassLoaderResourceLoader'.
 [INFO] Setting property: velocimacro.messages.on => 'false'.
 [INFO] Setting property: resource.loader => 'classpath'.
 [INFO] Setting property: resource.manager.logwhenfound => 'false'.
-[INFO] ************************************************************** 
-[INFO] Starting Jakarta Velocity v1.4
-[INFO] RuntimeInstance initializing.
-[INFO] Default Properties File: 
org/apache/velocity/runtime/defaults/velocity.properties
-[INFO] Default ResourceManager initializing. (class 
org.apache.velocity.runtime.resource.ResourceManagerImpl)
-[INFO] Resource Loader Instantiated: 
org.codehaus.plexus.velocity.ContextClassLoaderResourceLoader
-[INFO] ClasspathResourceLoader : initialization starting.
-[INFO] ClasspathResourceLoader : initialization complete.
-[INFO] ResourceCache : initialized. (class 
org.apache.velocity.runtime.resource.ResourceCacheImpl)
-[INFO] Default ResourceManager initialization complete.
-[INFO] Loaded System Directive: org.apache.velocity.runtime.directive.Literal
-[INFO] Loaded System Directive: org.apache.velocity.runtime.directive.Macro
-[INFO] Loaded System Directive: org.apache.velocity.runtime.directive.Parse
-[INFO] Loaded System Directive: org.apache.velocity.runtime.directive.Include
-[INFO] Loaded System Directive: org.apache.velocity.runtime.directive.Foreach
-[INFO] Created: 20 parsers.
-[INFO] Velocimacro : initialization starting.
-[INFO] Velocimacro : adding VMs from VM library template : VM_global_library.vm
-[ERROR] ResourceManager : unable to find resource 'VM_global_library.vm' in 
any resource loader.
-[INFO] Velocimacro : error using  VM library template VM_global_library.vm : 
org.apache.velocity.exception.ResourceNotFoundException: Unable to find 
resource 'VM_global_library.vm'
-[INFO] Velocimacro :  VM library template macro registration complete.
-[INFO] Velocimacro : allowInline = true : VMs can be defined inline in 
templates
-[INFO] Velocimacro : allowInlineToOverride = false : VMs defined inline may 
NOT replace previous VM definitions
-[INFO] Velocimacro : allowInlineLocal = false : VMs defined inline will be  
global in scope if allowed.
-[INFO] Velocimacro : initialization complete.
-[INFO] Velocity successfully started.
-[INFO] [archetype:create]
-[INFO] artifact org.apache.tapestry:quickstart: checking for updates from 
central
-[INFO] 
----------------------------------------------------------------------------
-[INFO] Using following parameters for creating Archetype: quickstart:RELEASE
-[INFO] 
----------------------------------------------------------------------------
-[INFO] Parameter: groupId, Value: org.example
-[INFO] Parameter: packageName, Value: org.example.myapp
-[INFO] Parameter: basedir, Value: 
/Users/Howard/Documents/workspace/tapestry5/target
-[INFO] Parameter: package, Value: org.example.myapp
-[INFO] Parameter: version, Value: 1.0.0-SNAPSHOT
-[INFO] Parameter: artifactId, Value: myapp
-[WARNING] org.apache.velocity.runtime.exception.ReferenceException: reference 
: template = archetype-resources/pom.xml [line 14,column 22] : 
${tapestry-release-version} is not a valid reference.
-[WARNING] org.apache.velocity.runtime.exception.ReferenceException: reference 
: template = archetype-resources/pom.xml [line 80,column 26] : 
${tapestry-release-version} is not a valid reference.
-[INFO] ********************* End of debug info from resources from generated 
POM ***********************
-[WARNING] org.apache.velocity.runtime.exception.ReferenceException: reference 
: template = archetype-resources/src/main/webapp/Start.tml [line 11,column 34] 
: ${currentTime} is not a valid reference.
-[INFO] Archetype created in dir: 
/Users/Howard/Documents/workspace/tapestry5/target/myapp
+[INFO] [archetype:generate]
+[INFO] Generating project in Interactive mode
+[INFO] No archetype defined. Using maven-archetype-quickstart 
(org.apache.maven.archetypes:maven-archetype-quickstart:1.0)
+Choose archetype:
+1: http://tapestry.formos.com/maven-snapshot-repository -> quickstart 
(Tapestry 5.1.0.0-SNAPSHOT Quickstart Project)
+Choose a number:  (1): 1
+[INFO] snapshot org.apache.tapestry:quickstart:5.1.0.0-SNAPSHOT: checking for 
updates from quickstart-repo
+Define value for groupId: : org.example
+Define value for artifactId: : myapp
+Define value for version:  1.0-SNAPSHOT: :
+Define value for package:  org.example: : org.example.myapp
+Confirm properties configuration:
+groupId: org.example
+artifactId: myapp
+version: 1.0-SNAPSHOT
+package: org.example.myapp
+ Y: :
 [INFO] ------------------------------------------------------------------------
 [INFO] BUILD SUCCESSFUL
 [INFO] ------------------------------------------------------------------------
-[INFO] Total time: 2 seconds
-[INFO] Finished at: Fri Oct 26 18:12:49 PDT 2007
-[INFO] Final Memory: 5M/9M
+[INFO] Total time: 16 seconds
+[INFO] Finished at: Sat Jan 31 14:29:27 PST 2009
+[INFO] Final Memory: 7M/14M
 [INFO] ------------------------------------------------------------------------
 $
 +---+
@@ -97,45 +75,78 @@
 $ mvn jetty:run
 [INFO] Scanning for projects...
 [INFO] Searching repository for plugin with prefix: 'jetty'.
-[INFO] 
----------------------------------------------------------------------------
+[INFO] ------------------------------------------------------------------------
 [INFO] Building myapp Tapestry 5 Application
 [INFO]    task-segment: [jetty:run]
-[INFO] 
----------------------------------------------------------------------------
+[INFO] ------------------------------------------------------------------------
 [INFO] Preparing jetty:run
 [INFO] [resources:resources]
-[INFO] Using default encoding to copy filtered resources.
+[WARNING] Using platform encoding (MacRoman actually) to copy filtered 
resources, i.e. build is platform dependent!
+[INFO] Copying 3 resources
 [INFO] [compiler:compile]
-Compiling 1 source file to /Users/Howard/work/myapp/target/classes
+[INFO] Compiling 3 source files to /private/tmp/myapp/target/classes
+[INFO] [resources:testResources]
+[WARNING] Using platform encoding (MacRoman actually) to copy filtered 
resources, i.e. build is platform dependent!
+[INFO] Copying 1 resource
+[INFO] [compiler:testCompile]
+[INFO] Nothing to compile - all classes are up to date
 [INFO] [jetty:run]
 [INFO] Configuring Jetty for project: myapp Tapestry 5 Application
-[INFO] Webapp source directory = /Users/Howard/work/myapp/src/main/webapp
-[INFO] web.xml file = /Users/Howard/work/myapp/src/main/webapp/WEB-INF/web.xml
-[INFO] Classes = /Users/Howard/work/myapp/target/classes
-2007-01-23 12:00:56.656::INFO:  Logging to STDERR via org.mortbay.log.StdErrLog
+[INFO] Webapp source directory = /private/tmp/myapp/src/main/webapp
+[INFO] web.xml file = /private/tmp/myapp/src/main/webapp/WEB-INF/web.xml
+[INFO] Classes = /private/tmp/myapp/target/classes
+2009-01-31 14:31:49.225::INFO:  Logging to STDERR via org.mortbay.log.StdErrLog
 [INFO] Context path = /myapp
-[INFO] Tmp directory = /Users/Howard/work/myapp/target/work
-[INFO] Web defaults =  jetty default
-[INFO] Webapp directory = /Users/Howard/work/myapp/src/main/webapp
-[INFO] Starting jetty 6.1.0pre0 ...
-2007-01-23 12:00:56.739::INFO:  jetty-6.1.0pre0
-[INFO] Classpath = [file:/Users/Howard/work/myapp/target/classes/, 
file:/Users/Howard/.m2/repository/commons-codec/commons-codec/1.3/commons-codec-1.3.jar,
 . . .
-[INFO] TapestryFilter Startup time: 306 ms to build IoC Registry, 761 ms 
overall.
-2007-01-23 12:00:57.962::INFO:  Started SelectChannelConnector @ 0.0.0.0:8080
+[INFO] Tmp directory =  determined at runtime
+[INFO] Web defaults = org/mortbay/jetty/webapp/webdefault.xml
+[INFO] Web overrides =  none
+[INFO] Webapp directory = /private/tmp/myapp/src/main/webapp
+[INFO] Starting jetty 6.1.9 ...
+2009-01-31 14:31:49.312::INFO:  jetty-6.1.9
+2009-01-31 14:31:49.502::INFO:  No Transaction manager found - if your webapp 
requires one, please configure one.
+[INFO] ioc.RegistryBuilder Adding module definition for class 
org.apache.tapestry5.ioc.services.TapestryIOCModule
+[INFO] ioc.RegistryBuilder Adding module definition for class 
org.apache.tapestry5.services.TapestryModule
+[INFO] ioc.RegistryBuilder Adding module definition for class 
org.apache.tapestry5.internal.services.InternalModule
+[INFO] ioc.RegistryBuilder Adding module definition for class 
org.example.myapp.services.AppModule
+[INFO] TapestryModule.ComponentClassResolver Available pages:
+              (blank): org.example.myapp.pages.Index
+      ExceptionReport: org.apache.tapestry5.corelib.pages.ExceptionReport
+                Index: org.example.myapp.pages.Index
+PropertyDisplayBlocks: org.apache.tapestry5.corelib.pages.PropertyDisplayBlocks
+   PropertyEditBlocks: org.apache.tapestry5.corelib.pages.PropertyEditBlocks
+        ServiceStatus: org.apache.tapestry5.corelib.pages.ServiceStatus
+
+[INFO] TapestryModule.ComponentClassResolver Available components:
+      ActionLink: org.apache.tapestry5.corelib.components.ActionLink
+      AddRowLink: org.apache.tapestry5.corelib.components.AddRowLink
+    AjaxFormLoop: org.apache.tapestry5.corelib.components.AjaxFormLoop
+             Any: org.apache.tapestry5.corelib.components.Any
+.
+.
+.
+                    ValidateBindingFactory: DEFINED
+             ValidationConstraintGenerator: DEFINED
+                  ValidationMessagesSource: DEFINED
+                        ValueEncoderSource: DEFINED
+
+82.89% unrealized services (126/152)
+
+2009-01-31 14:31:50.937::INFO:  Started selectchannelconnec...@0.0.0.0:8080
 [INFO] Started Jetty Server
 +---+
 
   <Again, the first time you do this, you'll see a large number of download 
messages.>
   
-  You can now see your running application as 
{{{http://localhost:8080/myapp}http://localhost:8080/myapp}}.
+  You can now see your running application as 
{{{http://localhost:8080/myapp}http://localhost:8080/myapp}}
   
   You can hit Control-C to stop Jetty.
   
 About Snapshots
 
-  Tapestry 5 is currently in a pre-release stage. The Tapestry libraries, 
including this archetype, are being distributed as snapshots and are rebuilt 
nightly. Being snapshots, these artifacts are not in the central Maven 
repository.
-  To make use of the Tapestry snapshots, append  
<<<-DremoteRepositories=http://tapestry.formos.com/maven-snapshot-repository/>>>
 and <<<-DarchetypeVersion=5.0.x-SNAPSHOT>>>  (you'll have to figure out what
-  the latest snapshot version is) to the command line when invoking Maven. 
-  
-  The generated POM includes entries to automatically search the snapshot 
repository, so you won't need to use <<<-DremoteRepositories>>> after creating 
your initial project.
-  
+  By referencing the application catalog in Tapestry's snapshot repository,
+  http://tapestry.formos.com/maven-snapshot-repository,
+  you are directing Maven to download a snapshot version of the quickstart 
archetype; your application
+  will then be dependent on snapshot versions of the JARs. These are rebuilt 
every night, so you may see
+  Maven redownload the Tapestry JARs more often than you'd like. You can edit 
the generated pom.xml file
+  to switch to a more stable version of Tapestry 5, such as the most recent 
stable release, 5.0.18.
   
\ No newline at end of file

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/antlr/org/apache/tapestry5/internal/antlr/PropertyExpressionParser.g
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/antlr/org/apache/tapestry5/internal/antlr/PropertyExpressionParser.g?rev=739646&r1=739645&r2=739646&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/antlr/org/apache/tapestry5/internal/antlr/PropertyExpressionParser.g
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/antlr/org/apache/tapestry5/internal/antlr/PropertyExpressionParser.g
 Sat Jan 31 22:40:14 2009
@@ -1,4 +1,4 @@
-// Copyright 2008 The Apache Software Foundation
+// Copyright 2008, 2009 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.
@@ -17,6 +17,7 @@
 
 options
 {
+  superClass='org.apache.tapestry5.internal.antlr.BaseParser';
   output=AST;          
   ASTLabelType=CommonTree;
   tokenVocab=PropertyExpressionLexer;

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/antlr/BaseLexer.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/antlr/BaseLexer.java?rev=739646&r1=739645&r2=739646&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/antlr/BaseLexer.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/antlr/BaseLexer.java
 Sat Jan 31 22:40:14 2009
@@ -1,4 +1,4 @@
-// Copyright 2008 The Apache Software Foundation
+// Copyright 2008, 2009 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.
@@ -17,6 +17,7 @@
 import org.antlr.runtime.CharStream;
 import org.antlr.runtime.Lexer;
 import org.antlr.runtime.RecognizerSharedState;
+import org.antlr.runtime.RecognitionException;
 
 public abstract class BaseLexer extends Lexer
 {
@@ -42,4 +43,12 @@
             setText(text.substring(1));
         }
     }
+
+    @Override
+    public void reportError(RecognitionException e)
+    {
+        throw new RuntimeException(String.format("Unable to parse input at 
character position %d",
+                                                 e.charPositionInLine + 1),
+                                   e);
+    }
 }

Added: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/antlr/BaseParser.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/antlr/BaseParser.java?rev=739646&view=auto
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/antlr/BaseParser.java
 (added)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/antlr/BaseParser.java
 Sat Jan 31 22:40:14 2009
@@ -0,0 +1,40 @@
+// Copyright 2009 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.antlr;
+
+import org.antlr.runtime.Parser;
+import org.antlr.runtime.TokenStream;
+import org.antlr.runtime.RecognizerSharedState;
+
+public class BaseParser extends Parser
+{
+    public BaseParser(TokenStream tokenStream)
+    {
+        super(tokenStream);
+    }
+
+    public BaseParser(TokenStream tokenStream,
+                      RecognizerSharedState recognizerSharedState)
+    {
+        super(tokenStream, recognizerSharedState);
+    }
+
+    @Override
+    public void emitErrorMessage(String message)
+    {
+        // This is caught and more properly reported later.
+        throw new RuntimeException(message);
+    }
+}

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImpl.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImpl.java?rev=739646&r1=739645&r2=739646&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImpl.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImpl.java
 Sat Jan 31 22:40:14 2009
@@ -16,7 +16,6 @@
 
 import org.antlr.runtime.ANTLRInputStream;
 import org.antlr.runtime.CommonTokenStream;
-import org.antlr.runtime.RecognitionException;
 import org.antlr.runtime.tree.Tree;
 import org.apache.tapestry5.PropertyConduit;
 import org.apache.tapestry5.internal.antlr.PropertyExpressionLexer;
@@ -1235,9 +1234,12 @@
         {
             return (Tree) parser.start().getTree();
         }
-        catch (RecognitionException ex)
+        catch (Exception ex)
         {
-            throw new RuntimeException(ex);
+            throw new RuntimeException(String.format("Error parsing property 
expression '%s': %s.",
+                                                     expression,
+                                                     ex.getMessage()),
+                                       ex);
         }
     }
 

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImplTest.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImplTest.java?rev=739646&r1=739645&r2=739646&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImplTest.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImplTest.java
 Sat Jan 31 22:40:14 2009
@@ -416,4 +416,34 @@
 
         assertEquals(conduit.get(b), "Do You Grok Ze Block?");
     }
+
+    @Test
+    public void parse_error_in_property_expression()
+    {
+        try
+        {
+            source.create(IntegerHolder.class, "getValue(");
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(ex.getMessage(),
+                         "Error parsing property expression 'getValue(': line 
1:0 no viable alternative at input 'getValue'.");
+        }
+    }
+
+    @Test
+    public void lexer_error_in_property_expression()
+    {
+        try
+        {
+            source.create(IntegerHolder.class, "fred {");
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(ex.getMessage(),
+                         "Error parsing property expression 'fred {': Unable 
to parse input at character position 6.");
+        }
+    }
 }


Reply via email to