Author: hlship
Date: Thu Nov  6 15:08:16 2008
New Revision: 712004

URL: http://svn.apache.org/viewvc?rev=712004&view=rev
Log:
TAP5-323: Fields marked with @Persist should not allow default values

Modified:
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Grid.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformationImpl.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/PageImpl.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/StructureMessages.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PersistWorker.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/structure/StructureStrings.properties
    
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/ExceptionEventDemo.java

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Grid.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Grid.java?rev=712004&r1=712003&r2=712004&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Grid.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Grid.java
 Thu Nov  6 15:08:16 2008
@@ -222,13 +222,14 @@
     private boolean didRenderZoneDiv;
 
     @Persist
-    private int currentPage = 1;
+    private Integer currentPage;
 
     @Persist
     private String sortColumnId;
 
     @Persist
-    private boolean sortAscending = true;
+    private Boolean sortAscending;
+
 
     @Inject
     private ComponentResources resources;
@@ -359,7 +360,7 @@
 
         private ColumnSort getColumnSort()
         {
-            return sortAscending ? ColumnSort.ASCENDING : 
ColumnSort.DESCENDING;
+            return getSortAscending() ? ColumnSort.ASCENDING : 
ColumnSort.DESCENDING;
         }
 
 
@@ -369,12 +370,12 @@
 
             if (columnId.equals(sortColumnId))
             {
-                sortAscending = !sortAscending;
+                setSortAscending(!getSortAscending());
                 return;
             }
 
             sortColumnId = columnId;
-            sortAscending = true;
+            setSortAscending(true);
         }
 
         public List<SortConstraint> getSortConstraints()
@@ -488,10 +489,12 @@
 
         // This captures when the number of rows has decreased, typically due 
to deletions.
 
-        if (currentPage > maxPage)
-            currentPage = maxPage;
+        int effectiveCurrentPage = getCurrentPage();
+
+        if (effectiveCurrentPage > maxPage)
+            effectiveCurrentPage = maxPage;
 
-        int startIndex = (currentPage - 1) * rowsPerPage;
+        int startIndex = (effectiveCurrentPage - 1) * rowsPerPage;
 
         int endIndex = Math.min(startIndex + rowsPerPage - 1, availableRows - 
1);
 
@@ -564,7 +567,7 @@
 
     public int getCurrentPage()
     {
-        return currentPage;
+        return currentPage == null ? 1 : currentPage;
     }
 
     public void setCurrentPage(int currentPage)
@@ -572,6 +575,16 @@
         this.currentPage = currentPage;
     }
 
+    private boolean getSortAscending()
+    {
+        return sortAscending != null && sortAscending.booleanValue();
+    }
+
+    private void setSortAscending(boolean sortAscending)
+    {
+        this.sortAscending = sortAscending;
+    }
+
     public int getRowsPerPage()
     {
         return rowsPerPage;
@@ -593,7 +606,7 @@
      */
     public void reset()
     {
-        currentPage = 1;
+        setCurrentPage(1);
         sortModel.clear();
     }
 

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformationImpl.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformationImpl.java?rev=712004&r1=712003&r2=712004&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformationImpl.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformationImpl.java
 Thu Nov  6 15:08:16 2008
@@ -1286,40 +1286,17 @@
             builder.commit();
         }
 
+        String initializer = convertConstructorToMethod();
+
         performFieldTransformations();
 
-        addConstructor();
+        addConstructor(initializer);
 
         freeze();
     }
 
-    private void addConstructor()
+    private void addConstructor(String initializer)
     {
-        String initializer = idAllocator.allocateId("initializer");
-
-        try
-        {
-            CtConstructor defaultConstructor = ctClass.getConstructor("()V");
-
-            CtMethod initializerMethod = 
defaultConstructor.toMethod(initializer, ctClass);
-
-            ctClass.addMethod(initializerMethod);
-
-            // Replace the constructor body with one that fails.  This leaves, 
as an open question,
-            // what to do about any other constructors.
-
-            String body = String.format("throw new RuntimeException(\"%s\");",
-                                        
ServicesMessages.forbidInstantiateComponentClass(getClassName()));
-
-            defaultConstructor.setBody(body);
-        }
-        catch (Exception ex)
-        {
-            throw new RuntimeException(ex);
-        }
-
-        formatter.format("convert default constructor: %s();\n\n", 
initializer);
-
         int count = constructorArgs.size();
 
         CtClass[] types = new CtClass[count];
@@ -1366,6 +1343,36 @@
         formatter.format(")\n%s\n\n", constructorBody);
     }
 
+    private String convertConstructorToMethod()
+    {
+        String initializer = idAllocator.allocateId("initializer");
+
+        try
+        {
+            CtConstructor defaultConstructor = ctClass.getConstructor("()V");
+
+            CtMethod initializerMethod = 
defaultConstructor.toMethod(initializer, ctClass);
+
+            ctClass.addMethod(initializerMethod);
+
+            // Replace the constructor body with one that fails.  This leaves, 
as an open question,
+            // what to do about any other constructors.
+
+            String body = String.format("throw new RuntimeException(\"%s\");",
+                                        
ServicesMessages.forbidInstantiateComponentClass(getClassName()));
+
+            defaultConstructor.setBody(body);
+        }
+        catch (Exception ex)
+        {
+            throw new RuntimeException(ex);
+        }
+
+        formatter.format("convert default constructor: %s();\n\n", 
initializer);
+
+        return initializer;
+    }
+
     public Instantiator createInstantiator()
     {
         String componentClassName = ctClass.getName();

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/PageImpl.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/PageImpl.java?rev=712004&r1=712003&r2=712004&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/PageImpl.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/PageImpl.java
 Thu Nov  6 15:08:16 2008
@@ -49,6 +49,8 @@
 
     private int dirtyCount;
 
+    private boolean loadComplete;
+
     /**
      * Obtained from the [EMAIL PROTECTED] 
org.apache.tapestry5.internal.services.PersistentFieldManager} when first 
needed,
      * discarded at the end of the request.
@@ -141,6 +143,13 @@
     {
         for (PageLifecycleListener listener : listeners)
             listener.containingPageDidLoad();
+
+        loadComplete = true;
+    }
+
+    public boolean isLoadComplete()
+    {
+        return loadComplete;
     }
 
     public void attached()
@@ -177,6 +186,9 @@
 
     public void persistFieldChange(ComponentResources resources, String 
fieldName, Object newValue)
     {
+        if (!loadComplete)
+            throw new 
RuntimeException(StructureMessages.persistChangeBeforeLoadComplete());
+
         persistentFieldManager.postChange(logicalPageName, resources, 
fieldName, newValue);
     }
 

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/StructureMessages.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/StructureMessages.java?rev=712004&r1=712003&r2=712004&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/StructureMessages.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/StructureMessages.java
 Thu Nov  6 15:08:16 2008
@@ -113,4 +113,9 @@
     {
         return MESSAGES.format("render-variable-set-when-not-rendering", 
completeId, name);
     }
+
+    static String persistChangeBeforeLoadComplete()
+    {
+        return MESSAGES.get("persist-change-before-load-complete");
+    }
 }

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PersistWorker.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PersistWorker.java?rev=712004&r1=712003&r2=712004&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PersistWorker.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PersistWorker.java
 Thu Nov  6 15:08:16 2008
@@ -19,7 +19,6 @@
 import org.apache.tapestry5.model.MutableComponentModel;
 import org.apache.tapestry5.services.*;
 
-import static java.lang.String.format;
 import java.lang.reflect.Modifier;
 
 /**
@@ -50,22 +49,18 @@
         Persist annotation = transformation.getFieldAnnotation(fieldName, 
Persist.class);
 
         transformation.claimField(fieldName, annotation);
-        
+
         // Record the type of persistence, until needed later.
 
         String logicalFieldName = model.setFieldPersistenceStrategy(fieldName, 
annotation.value());
 
-        String defaultFieldName = transformation.addField(Modifier.PRIVATE, 
fieldType, fieldName
-                + "_default");
+        String defaultValue = TransformUtils.getDefaultValue(fieldType);
 
-        
transformation.extendMethod(TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE,
 format(
-                "%s = %s;",
-                defaultFieldName,
-                fieldName));
+        // Force the field back to its default value (null, 0, false) at the 
end of each request.
 
         transformation.extendMethod(
                 TransformConstants.CONTAINING_PAGE_DID_DETACH_SIGNATURE,
-                format("%s = %s;", fieldName, defaultFieldName));
+                String.format("%s = %s;", fieldName, defaultValue));
 
         String resourcesFieldName = transformation.getResourcesFieldName();
 
@@ -83,7 +78,7 @@
 
         transformation.addMethod(new 
TransformMethodSignature(Modifier.PRIVATE, "void", writeMethodName,
                                                               new String[]
-                                                                      { 
fieldType }, null), builder.toString());
+                                                                      
{fieldType}, null), builder.toString());
 
         transformation.replaceWriteAccess(fieldName, writeMethodName);
 
@@ -118,6 +113,5 @@
         transformation.extendMethod(
                 TransformConstants.CONTAINING_PAGE_DID_ATTACH_SIGNATURE,
                 builder.toString());
-
     }
 }

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/structure/StructureStrings.properties
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/structure/StructureStrings.properties?rev=712004&r1=712003&r2=712004&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/structure/StructureStrings.properties
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/structure/StructureStrings.properties
 Thu Nov  6 15:08:16 2008
@@ -34,3 +34,5 @@
 field-persist-failure=Error persisting field %s:%s: %s
 missing-render-variable=Component %s does not contain a stored render variable 
with name '%s'.  Stored render variables: %s.
 render-variable-set-when-not-rendering=Component %s is not rendering, so 
render variable '%s' may not be updated.
+persist-change-before-load-complete=Persistent fields may not be updated until 
after the page has finished loading. \
+  This may be due to a persistent field with a default value. The default 
value should be removed.
\ No newline at end of file

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/ExceptionEventDemo.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/ExceptionEventDemo.java?rev=712004&r1=712003&r2=712004&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/ExceptionEventDemo.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/ExceptionEventDemo.java
 Thu Nov  6 15:08:16 2008
@@ -22,7 +22,7 @@
     private String message;
 
     @Persist
-    private boolean intercept = true;
+    private boolean intercept;
 
     public Object getInvalidContext()
     {


Reply via email to