You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by jk...@apache.org on 2007/02/19 01:04:26 UTC

svn commit: r509035 [2/2] - in /tapestry/tapestry4/trunk: ./ tapestry-annotations/src/descriptor/META-INF/ tapestry-annotations/src/java/org/apache/tapestry/annotations/ tapestry-annotations/src/test/org/apache/tapestry/annotations/ tapestry-examples/T...

Added: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/record/LazyProxyDelegate.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/record/LazyProxyDelegate.java?view=auto&rev=509035
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/record/LazyProxyDelegate.java (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/record/LazyProxyDelegate.java Sun Feb 18 16:04:24 2007
@@ -0,0 +1,48 @@
+// Copyright 2004, 2005 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.record;
+
+import net.sf.cglib.proxy.LazyLoader;
+
+
+/**
+ * Implementation of {@link LazyLoader} interface for {@link CglibProxiedPropertyChangeObserverImpl}.
+ */
+public class LazyProxyDelegate implements LazyLoader
+{
+
+    Object _target;
+    
+    /**
+     * Creates a new lazily loaded proxy delegate object used to create efficient
+     * pass through proxied calls to a specific property instance.
+     * 
+     * @param target
+     *          The object being proxied.
+     */
+    public LazyProxyDelegate(Object target)
+    {
+        _target = target;
+    }
+    
+    /**
+     * {@inheritDoc}
+     */
+    public Object loadObject()
+        throws Exception
+    {
+        return _target;
+    }
+
+}

Added: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/record/ObservableMethodFilter.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/record/ObservableMethodFilter.java?view=auto&rev=509035
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/record/ObservableMethodFilter.java (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/record/ObservableMethodFilter.java Sun Feb 18 16:04:24 2007
@@ -0,0 +1,43 @@
+// Copyright 2004, 2005 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.record;
+
+import java.lang.reflect.Method;
+
+import net.sf.cglib.proxy.CallbackFilter;
+
+
+/**
+ * Acts as a filter for cglib property watching semantics used 
+ * by {@link CglibProxiedPropertyChangeObserverImpl}.
+ */
+public class ObservableMethodFilter implements CallbackFilter
+{
+
+    /**
+     * {@inheritDoc}
+     */
+    public int accept(Method method)
+    {
+        boolean hasParams = method.getParameterTypes() != null && method.getParameterTypes().length > 0;
+        
+        if (method.getReturnType() == void.class && hasParams
+                || method.getReturnType() != boolean.class && hasParams) {
+            
+            return 1;
+        }
+        
+        return 0;
+    }
+}

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/record/PageRecorderImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/record/PageRecorderImpl.java?view=diff&rev=509035&r1=509034&r2=509035
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/record/PageRecorderImpl.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/record/PageRecorderImpl.java Sun Feb 18 16:04:24 2007
@@ -42,8 +42,7 @@
 
     private ErrorLog _log;
 
-    public PageRecorderImpl(String pageName, PropertyPersistenceStrategySource strategySource, 
-            ErrorLog log)
+    public PageRecorderImpl(String pageName, PropertyPersistenceStrategySource strategySource, ErrorLog log)
     {
         Defense.notNull(pageName, "pageName");
         Defense.notNull(strategySource, "strategySource");
@@ -59,6 +58,11 @@
         _locked = true;
     }
 
+    public boolean isLocked()
+    {
+        return _locked;
+    }
+    
     public Collection getChanges()
     {
         return _strategySource.getAllStoredChanges(_pageName);
@@ -82,11 +86,9 @@
     {
         String idPath = change.getComponentPath();
 
-        IComponent component = (idPath == null) ? page : page
-                .getNestedComponent(idPath);
-
-        PropertyUtils.write(component, change.getPropertyName(), change
-                .getNewValue());
+        IComponent component = (idPath == null) ? page : page.getNestedComponent(idPath);
+        
+        PropertyUtils.write(component, change.getPropertyName(), change.getNewValue());
     }
 
     public void observeChange(ObservedChangeEvent event)
@@ -96,33 +98,27 @@
 
         if (_locked)
         {
-            _log.error(RecordMessages.recorderLocked(propertyName, component),
-                    null, null);
+            _log.error(RecordMessages.recorderLocked(propertyName, component), null, null);
             return;
         }
-
-        PropertyPersistenceStrategy strategy = findStrategy(component,
-                propertyName);
+        
+        PropertyPersistenceStrategy strategy = findStrategy(component, propertyName);
 
         if (strategy != null)
-            strategy.store(_pageName, component.getIdPath(), propertyName,
-                    event.getNewValue());
+            strategy.store(_pageName, component.getIdPath(), propertyName, event.getNewValue());
     }
 
     // package private for testing
 
-    PropertyPersistenceStrategy findStrategy(IComponent component,
-            String propertyName)
+    PropertyPersistenceStrategy findStrategy(IComponent component, String propertyName)
     {
         // So much for Law of Demeter!
 
-        IPropertySpecification propertySpecification = component
-                .getSpecification().getPropertySpecification(propertyName);
+        IPropertySpecification propertySpecification = component.getSpecification().getPropertySpecification(propertyName);
 
         if (propertySpecification == null)
         {
-            _log.error(RecordMessages.missingPropertySpecification(
-                    propertyName, component), null, null);
+            _log.error(RecordMessages.missingPropertySpecification(propertyName, component), null, null);
             return null;
         }
 
@@ -139,10 +135,7 @@
         }
         catch (ApplicationRuntimeException ex)
         {
-            _log
-                    .error(ex.getMessage(),
-                            propertySpecification.getLocation(), ex);
-
+            _log.error(ex.getMessage(), propertySpecification.getLocation(), ex);
             return null;
         }
     }

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/record/PersistentPropertyData.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/record/PersistentPropertyData.java?view=diff&rev=509035&r1=509034&r2=509035
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/record/PersistentPropertyData.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/record/PersistentPropertyData.java Sun Feb 18 16:04:24 2007
@@ -119,9 +119,8 @@
             ChangeKey changeKey = (ChangeKey) me.getKey();
             Object value = me.getValue();
 
-            PropertyChange change = new PropertyChangeImpl(changeKey
-                    .getComponentPath(), changeKey.getPropertyName(), value);
-
+            PropertyChange change = new PropertyChangeImpl(changeKey.getComponentPath(), changeKey.getPropertyName(), value);
+            
             result.add(change);
         }
 

Added: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/record/PropertyChangeObserver.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/record/PropertyChangeObserver.java?view=auto&rev=509035
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/record/PropertyChangeObserver.java (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/record/PropertyChangeObserver.java Sun Feb 18 16:04:24 2007
@@ -0,0 +1,45 @@
+// Copyright 2004, 2005 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.record;
+
+import org.apache.tapestry.IComponent;
+import org.apache.tapestry.Tapestry;
+
+
+/**
+ * Core service that is consulted anytime a specified component property is set. This service
+ * is intended to be used as a means of intercepting component property state objects so that 
+ * their individual properties can be observed independently from basic set/get operations 
+ * done on page/component properties.
+ * 
+ */
+public interface PropertyChangeObserver
+{
+
+    /**
+     * Invoked by the enhanced property workers any time a {@link IComponent} property is set, either
+     * by an initial value binding or explicitly through an abstract setter.
+     * 
+     * @param component
+     *          The component that this property is attached to.
+     * @param property 
+     *          The object to observe changes on, may be null.
+     * @param propertyName
+     *          The name of the property being observed - needed for doing things like calling
+     *          {@link Tapestry#fireObservedChange(IComponent, String, Object)}.
+     * @return Expected to return either the same exact instance passed in or one that is proxied but still
+     *         maintains the original state of the object.
+     */
+    Object observePropertyChanges(IComponent component, Object property, String propertyName);
+}

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/record/SessionPropertyPersistenceStrategy.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/record/SessionPropertyPersistenceStrategy.java?view=diff&rev=509035&r1=509034&r2=509035
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/record/SessionPropertyPersistenceStrategy.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/record/SessionPropertyPersistenceStrategy.java Sun Feb 18 16:04:24 2007
@@ -45,16 +45,14 @@
 
     private WebRequest _request;
 
-    public void store(String pageName, String idPath, String propertyName,
-            Object newValue)
+    public void store(String pageName, String idPath, String propertyName, Object newValue)
     {
         Defense.notNull(pageName, "pageName");
         Defense.notNull(propertyName, "propertyName");
 
         WebSession session = _request.getSession(true);
 
-        String attributeName = RecordUtils.buildChangeKey(STRATEGY_ID,
-                _applicationId, pageName, idPath, propertyName);
+        String attributeName = RecordUtils.buildChangeKey(STRATEGY_ID, _applicationId, pageName, idPath, propertyName);
 
         session.setAttribute(attributeName, newValue);
     }
@@ -65,24 +63,22 @@
 
         WebSession session = _request.getSession(false);
 
-        if (session == null) return Collections.EMPTY_LIST;
+        if (session == null) 
+            return Collections.EMPTY_LIST;
 
         final Collection result = new ArrayList();
 
         WebSessionAttributeCallback callback = new WebSessionAttributeCallback()
         {
-
             public void handleAttribute(WebSession sess, String name)
             {
-                PropertyChange change = RecordUtils.buildChange(name, sess
-                        .getAttribute(name));
+                PropertyChange change = RecordUtils.buildChange(name, sess.getAttribute(name));
 
                 result.add(change);
             }
         };
 
-        RecordUtils.iterateOverMatchingAttributes(STRATEGY_ID, _applicationId,
-                pageName, session, callback);
+        RecordUtils.iterateOverMatchingAttributes(STRATEGY_ID, _applicationId, pageName, session, callback);
 
         return result;
     }
@@ -95,7 +91,6 @@
 
         WebSessionAttributeCallback callback = new WebSessionAttributeCallback()
         {
-
             public void handleAttribute(WebSession sess, String name)
             {
                 sess.setAttribute(name, null);

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/RequestLocaleManagerImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/RequestLocaleManagerImpl.java?view=diff&rev=509035&r1=509034&r2=509035
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/RequestLocaleManagerImpl.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/RequestLocaleManagerImpl.java Sun Feb 18 16:04:24 2007
@@ -91,9 +91,8 @@
     {
         String localeName = _cookieSource.readCookieValue(TapestryConstants.LOCALE_COOKIE_NAME);
 
-        String requestedLocale = (localeName != null) ? localeName : _request.getLocale()
-                .toString();
-
+        String requestedLocale = (localeName != null) ? localeName : _request.getLocale().toString();
+        
         _requestLocale = filterRequestedLocale(requestedLocale);
 
         _threadLocale.setLocale(_requestLocale);

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/spec/IPropertySpecification.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/spec/IPropertySpecification.java?view=diff&rev=509035&r1=509034&r2=509035
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/spec/IPropertySpecification.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/spec/IPropertySpecification.java Sun Feb 18 16:04:24 2007
@@ -51,7 +51,38 @@
     void setName(String name);
 
     void setType(String type);
-
+    
+    /**
+     * Checks if this property has previously had it's type information examined to
+     * determine if it is elligable for proxying. Meaning {@link #canProxy()} should
+     * be a real value.
+     * 
+     * @return True if the proxy type has been checked, false otherwise.
+     */
+    boolean isProxyChecked();
+    
+    /**
+     * Sets the state of this property so that it is known whether or not the type
+     * it represents has been checked as being compatible with proxying or not.
+     * 
+     * @param checked
+     */
+    void setProxyChecked(boolean checked);
+    
+    /**
+     * Checks if this parameter can be proxied. 
+     * 
+     * @return True if the type can be proxied, false otherwise.
+     */
+    boolean canProxy();
+    
+    /**
+     * Sets whether or not this property can be proxied.
+     * 
+     * @param canProxy
+     */
+    void setCanProxy(boolean canProxy);
+    
     /**
      * A string indicating how the property is persisted.
      * 

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/spec/PropertySpecification.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/spec/PropertySpecification.java?view=diff&rev=509035&r1=509034&r2=509035
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/spec/PropertySpecification.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/spec/PropertySpecification.java Sun Feb 18 16:04:24 2007
@@ -38,6 +38,10 @@
 
     private String _persistence;
 
+    private boolean _proxyChecked;
+    
+    private boolean _canProxy;
+    
     public String getInitialValue()
     {
         return _initialValue;
@@ -96,5 +100,37 @@
     public void setPersistence(String persistence)
     {
         _persistence = persistence;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean canProxy()
+    {
+        return _canProxy;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean isProxyChecked()
+    {
+        return _proxyChecked;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void setCanProxy(boolean canProxy)
+    {
+        _canProxy = canProxy;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void setProxyChecked(boolean checked)
+    {
+        _proxyChecked = checked;
     }
 }

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/scripts/TestDefaultParameterValues.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/scripts/TestDefaultParameterValues.xml?view=diff&rev=509035&r1=509034&r2=509035
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/scripts/TestDefaultParameterValues.xml (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/scripts/TestDefaultParameterValues.xml Sun Feb 18 16:04:24 2007
@@ -92,18 +92,6 @@
 ]]>
 		</assert-output>
 		
-		<assert-output name="b tag">
-<![CDATA[
-<b id="Any_1">b tag</b>
-]]>
-		</assert-output>
-		
-		<assert-output name="i tag">
-<![CDATA[
-<i id="Any_2">i tag</i>
-]]>
-		</assert-output>
-		
 	</request>
 		
  </mock-test>

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/test-data/context27/Home.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/test-data/context27/Home.html?view=diff&rev=509035&r1=509034&r2=509035
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/test-data/context27/Home.html (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/test-data/context27/Home.html Sun Feb 18 16:04:24 2007
@@ -15,9 +15,5 @@
 
 	<div jwcid="@Any">div tag</div>
 
-	<div jwcid="@Any" templateTag="b">b tag</div>
-
-	<div jwcid="any">i tag</div>
-
 </body>
 </html>

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/test-data/context27/WEB-INF/Home.page
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/test-data/context27/WEB-INF/Home.page?view=diff&rev=509035&r1=509034&r2=509035
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/test-data/context27/WEB-INF/Home.page (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/test-data/context27/WEB-INF/Home.page Sun Feb 18 16:04:24 2007
@@ -20,9 +20,5 @@
   "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
 
 <page-specification>
-	
-	<component id="any" type="Any">
-		<binding name="templateTag" expression='"i"'/>
-	</component>
 
 </page-specification>

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/enhance/TestSpecifiedPropertyWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/enhance/TestSpecifiedPropertyWorker.java?view=diff&rev=509035&r1=509034&r2=509035
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/enhance/TestSpecifiedPropertyWorker.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/enhance/TestSpecifiedPropertyWorker.java Sun Feb 18 16:04:24 2007
@@ -98,6 +98,19 @@
         return buildComponentSpecification(buildPropertySpecs(name, type, persistent));
     }
 
+    public enum TestEnum {
+        First,
+        Second
+    }
+    
+    public void test_Can_Proxy_Enum() 
+    {
+        Object obj = TestEnum.First;
+        
+        assert !EnhanceUtils.canProxyPropertyType(obj.getClass());
+        assert EnhanceUtils.canProxyPropertyType(List.class);
+    }
+    
     public void testAddNormal() throws Exception
     {
         Location l = newLocation();
@@ -218,7 +231,7 @@
         verify();
     }
 
-    public void testAddPersistent() throws Exception
+    public void test_Add_Persistent() throws Exception
     {
         IComponentSpecification spec = buildComponentSpecification(
                 "barney",

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/junit/mock/TestMockApplications.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/junit/mock/TestMockApplications.java?view=diff&rev=509035&r1=509034&r2=509035
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/junit/mock/TestMockApplications.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/junit/mock/TestMockApplications.java Sun Feb 18 16:04:24 2007
@@ -54,7 +54,8 @@
 import org.jdom.Document;
 import org.jdom.Element;
 import org.jdom.input.SAXBuilder;
-import org.testng.annotations.Configuration;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.AfterMethod;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 
@@ -126,7 +127,7 @@
     /**
      * Closes System.out and System.err, then restores them to their original values.
      */
-    @Configuration(afterTestMethod = true)
+    @AfterMethod
     public void tearDown() throws Exception
     {
         System.err.close();
@@ -483,9 +484,6 @@
 
     private boolean evaluate(String expression) throws DocumentParseException
     {
-        // if (_ognlContext == null)
-           // _ognlContext = Ognl.createDefaultContext(this);
-
         Object value = null;
 
         try
@@ -615,9 +613,6 @@
 
     private PatternMatcher getMatcher()
     {
-        //if (_matcher == null)
-          //  _matcher = new Perl5Matcher();
-
         return _matcher;
     }
 
@@ -629,9 +624,6 @@
         if (result != null)
             return result;
 
-        // if (_compiler == null)
-           // _compiler = new Perl5Compiler();
-
         try
         {
             result = _compiler.compile(pattern, Perl5Compiler.MULTILINE_MASK);
@@ -945,7 +937,7 @@
         return new PrintStream(bos, true);
     }
     
-    @Configuration(afterTestClass = true)
+    @AfterClass
     public static void deleteDir()
     {
         File file = new File(getBaseDirectory() + "/target/.private");

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/record/PageFixture.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/record/PageFixture.java?view=diff&rev=509035&r1=509034&r2=509035
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/record/PageFixture.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/record/PageFixture.java Sun Feb 18 16:04:24 2007
@@ -15,16 +15,14 @@
 package org.apache.tapestry.record;
 
 import org.apache.tapestry.html.BasePage;
-import org.testng.annotations.Test;
 
 /**
  * @author Howard Lewis Ship
  * @since 4.0
  */
-@Test
 public abstract class PageFixture extends BasePage
 {
     public abstract String getCartoonName();
 
     public abstract void setCartoonName(String value);
-}
\ No newline at end of file
+}

Added: tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/record/SimpleState.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/record/SimpleState.java?view=auto&rev=509035
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/record/SimpleState.java (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/record/SimpleState.java Sun Feb 18 16:04:24 2007
@@ -0,0 +1,119 @@
+// Copyright 2004, 2005 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.record;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
+
+
+/**
+ * Simple object used for testing object property changes.
+ */
+public class SimpleState implements Serializable
+{
+    /** serialVersionUID */
+    private static final long serialVersionUID = 8466422593705479396L;
+
+    long _id;
+    String _name;
+    boolean _isValid;
+    Date _date;
+    Map _keys = new HashMap();
+    
+    public SimpleState() {}
+
+    public SimpleState(long id, String name)
+    {
+        _id = id;
+        _name = name;
+    }
+    
+    public long getId()
+    {
+        return _id;
+    }
+    
+    public void setId(long id)
+    {
+        _id = id;
+    }
+    
+    /**
+     * @return Returns the name.
+     */
+    public String getName()
+    {
+        return _name;
+    }
+    
+    /**
+     * @param name The name to set.
+     */
+    public void setName(String name)
+    {
+        _name = name;
+    }
+
+    /**
+     * @return Returns the isValid.
+     */
+    public boolean isValid()
+    {
+        return _isValid;
+    }
+
+    /**
+     * @param isValid The isValid to set.
+     */
+    public void setValid(boolean isValid)
+    {
+        _isValid = isValid;
+    }
+   
+    /**
+     * @return Returns the date.
+     */
+    public Date getDate()
+    {
+        return _date;
+    }
+    
+    /**
+     * @param date The date to set.
+     */
+    public void setDate(Date date)
+    {
+        _date = date;
+    }
+    
+    public Map getKeys()
+    {
+        return _keys;
+    }
+    
+    public String toString()
+    {
+        return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
+        .append("id", _id)
+        .append("name", _name)
+        .append("isValid", _isValid)
+        .append("date", _date)
+        .toString();
+    }
+}

Added: tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/record/TestPropertyChangeObserver.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/record/TestPropertyChangeObserver.java?view=auto&rev=509035
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/record/TestPropertyChangeObserver.java (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/record/TestPropertyChangeObserver.java Sun Feb 18 16:04:24 2007
@@ -0,0 +1,272 @@
+// Copyright 2004, 2005 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.record;
+
+import static org.easymock.EasyMock.checkOrder;
+import static org.easymock.EasyMock.expect;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import net.sf.cglib.proxy.Enhancer;
+
+import org.apache.tapestry.BaseComponentTestCase;
+import org.apache.tapestry.IPage;
+import org.apache.tapestry.dojo.form.DefaultAutocompleteModel;
+import org.apache.tapestry.dojo.form.IAutocompleteModel;
+import org.apache.tapestry.event.ChangeObserver;
+import org.apache.tapestry.event.ObservedChangeEvent;
+import org.testng.annotations.Test;
+
+
+/**
+ * Tests watching persistent object properties via proxy objects.
+ */
+@Test
+public class TestPropertyChangeObserver extends BaseComponentTestCase
+{
+    static final long NANOSECONDS_IN_MILLIS = 1000000;
+    
+    class CglibChangeObserver implements ChangeObserver {
+
+        int _changes = 0;
+        
+        public int getChanges()
+        {
+            return _changes;
+        }
+        
+        public boolean isLocked()
+        {
+            return false;
+        }
+        
+        /**
+         * {@inheritDoc}
+         */
+        public void observeChange(ObservedChangeEvent event)
+        {
+            _changes++;
+        }
+    }
+    
+    public void test_Null_Property_Proxy() 
+    throws Exception
+    {
+        PropertyChangeObserver propObserver = new CglibProxiedPropertyChangeObserverImpl();
+        IPage page = newMock(IPage.class);
+        
+        replay();
+        
+        assert propObserver.observePropertyChanges(page, null, "state") == null;
+        
+        verify();
+    }
+    
+    void callState(SimpleState o1, SimpleState o2)
+    {
+        o1.getDate();
+        o2.getDate();
+    }
+    
+    public void test_Proxy_Access_Changes() 
+    throws Exception
+    {
+        SimpleState rawState = new SimpleState();
+        CglibChangeObserver pageObserver = new CglibChangeObserver();
+        PropertyChangeObserver propObserver = new CglibProxiedPropertyChangeObserverImpl();
+        
+        IPage page = newMock(IPage.class);
+        checkOrder(page, false);
+        
+        expect(page.getPage()).andReturn(page).anyTimes();
+        expect(page.getIdPath()).andReturn(null).anyTimes();
+        expect(page.getChangeObserver()).andReturn(pageObserver).anyTimes();
+        
+        replay();
+        
+        SimpleState state = (SimpleState) propObserver.observePropertyChanges(page, rawState, "state");
+        
+        // test that same instance is returned unmolested
+        assert state == (SimpleState) propObserver.observePropertyChanges(page, state, "state");
+        
+        assert state != null;
+        assert state.getKeys().size() == 0;
+        assert SimpleState.class.isAssignableFrom(state.getClass());
+        
+        assertEquals(pageObserver.getChanges(), 0);
+        
+        for (int i=0; i < 40; i++) {
+            callState(rawState, state);
+        }
+        
+        assertEquals(pageObserver.getChanges(), 0);
+        
+        long otime = System.nanoTime();
+        rawState.getDate();
+        otime = System.nanoTime() - otime;
+        
+        long etime = System.nanoTime();
+        state.getDate();
+        etime = System.nanoTime() - etime;
+        
+        long otimems = otime / NANOSECONDS_IN_MILLIS;
+        long etimems = etime / NANOSECONDS_IN_MILLIS;
+        
+        assertEquals(otimems, etimems, "Enhanced property access times not equal to normal access times: \n"
+                + "original time: " + otime + "ns : " + otimems + " ms , "
+                + "enhanced time: " + etime + "ns : " + etimems + " ms");
+        
+        verify();
+    }
+    
+    void setState(SimpleState raw, SimpleState enhanced, Date date) 
+    {
+        raw.setDate(date);
+        enhanced.setDate(date);
+    }
+    
+    public void test_Proxy_Set_Changes() 
+    throws Exception
+    {
+        SimpleState rawState = new SimpleState();
+        CglibChangeObserver pageObserver = new CglibChangeObserver();
+        PropertyChangeObserver propObserver = new CglibProxiedPropertyChangeObserverImpl();
+        
+        IPage page = newMock(IPage.class);
+        checkOrder(page, false);
+        
+        expect(page.getPage()).andReturn(page).anyTimes();
+        expect(page.getIdPath()).andReturn(null).anyTimes();
+        expect(page.getChangeObserver()).andReturn(pageObserver).anyTimes();
+        
+        replay();
+        
+        SimpleState state = (SimpleState) propObserver.observePropertyChanges(page, rawState, "state");
+        
+        assertEquals(pageObserver.getChanges(), 0);
+        
+        Date testDate = new Date();
+        for (int i=0; i < 2000; i++) {
+            setState(rawState, state, testDate);
+        }
+        
+        assertEquals(pageObserver.getChanges(), 2000);
+        
+        long otime = System.nanoTime();
+        rawState.setDate(new Date());
+        otime = System.nanoTime() - otime;
+        
+        long etime = System.nanoTime();
+        state.setDate(new Date());
+        etime = System.nanoTime() - etime;
+        
+        long otimems = otime / NANOSECONDS_IN_MILLIS;
+        long etimems = etime / NANOSECONDS_IN_MILLIS;
+        
+        assertEquals(otimems, etimems, "Enhanced property set times not equal to normal set times: \n"
+                + "original setDate() time: " + otime + "ns : " + otimems + " ms , "
+                + "enhanced setDate() time: " + etime + "ns : " + etimems + " ms");
+        
+        verify();
+    }
+    
+    public void test_Proxy_Class_Cached()
+    {
+        SimpleState rawState = new SimpleState();
+        CglibChangeObserver pageObserver = new CglibChangeObserver();
+        PropertyChangeObserver propObserver = new CglibProxiedPropertyChangeObserverImpl();
+        
+        IPage page = newMock(IPage.class);
+        checkOrder(page, false);
+        
+        expect(page.getPage()).andReturn(page).anyTimes();
+        
+        expect(page.getIdPath()).andReturn(null).anyTimes();
+        
+        expect(page.getChangeObserver()).andReturn(pageObserver).anyTimes();
+        
+        replay();
+        
+        SimpleState state = (SimpleState) propObserver.observePropertyChanges(page, rawState, "fooBar");
+        
+        SimpleState state2 = (SimpleState) propObserver.observePropertyChanges(page, state, "fooBar");
+        
+        assert state == state2;
+        
+        SimpleState newState = new SimpleState();
+        
+        SimpleState enewState = (SimpleState) propObserver.observePropertyChanges(page, newState, "fooBar");
+        
+        assert enewState != state;
+        
+        assert enewState != newState;
+        
+        SimpleState newState2 = (SimpleState) propObserver.observePropertyChanges(page, newState, "fooBar");
+        
+        assert Enhancer.isEnhanced(state.getClass());
+        assert Enhancer.isEnhanced(state.getClass());
+        assert Enhancer.isEnhanced(state2.getClass());
+        assert !Enhancer.isEnhanced(newState.getClass());
+        assert Enhancer.isEnhanced(enewState.getClass());
+        assert Enhancer.isEnhanced(newState2.getClass());
+        
+        assert newState2 != enewState;
+        assert newState2.getClass() == enewState.getClass();
+        assert state.getClass() == state2.getClass();
+        assert state.getClass() != newState.getClass();
+        assert enewState.getClass() == state2.getClass();
+        
+        verify();
+    }
+    
+    public void test_Proxy_Values_Equal()
+    {
+        CglibChangeObserver pageObserver = new CglibChangeObserver();
+        PropertyChangeObserver propObserver = new CglibProxiedPropertyChangeObserverImpl();
+        
+        IPage page = newMock(IPage.class);
+        checkOrder(page, false);
+        
+        expect(page.getPage()).andReturn(page).anyTimes();
+        expect(page.getIdPath()).andReturn(null).anyTimes();
+        expect(page.getChangeObserver()).andReturn(pageObserver).anyTimes();
+        
+        replay();
+        
+        List list = new ArrayList();
+        list.add(new SimpleState(1, "First"));
+        list.add(new SimpleState(2, "Second"));
+        list.add(new SimpleState(3, "Third"));
+        
+        IAutocompleteModel model = new DefaultAutocompleteModel( list , "id", "name");
+        
+        SimpleState selected = (SimpleState)list.get(1);
+        
+        assertEquals(model.getPrimaryKey(selected), Long.valueOf(2));
+        assertEquals(model.getLabelFor(selected), "Second");
+        
+        assertEquals(selected.getId(), 2);
+        
+        SimpleState sel = (SimpleState)propObserver.observePropertyChanges(page, selected, "foo");
+        
+        assertEquals(sel.getId(), selected.getId());
+        
+        assertEquals(model.getPrimaryKey(sel), Long.valueOf(2));
+        assertEquals(model.getLabelFor(sel), "Second");
+        
+        verify();
+    }
+}