You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2008/02/23 03:36:17 UTC
svn commit: r630378 - in /tapestry/tapestry5/trunk/tapestry-core/src:
main/java/org/apache/tapestry/ main/java/org/apache/tapestry/internal/
main/java/org/apache/tapestry/internal/services/
main/java/org/apache/tapestry/internal/structure/ main/java/or...
Author: hlship
Date: Fri Feb 22 18:36:14 2008
New Revision: 630378
URL: http://svn.apache.org/viewvc?rev=630378&view=rev
Log:
TAPESTRY-1475: Tapestry is missing an API for clearing out persistent properties of a particular pag
Added:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PersistentFieldManager.java
- copied, changed from r630031, tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/PersistentFieldManager.java
tapestry/tapestry5/trunk/tapestry-core/src/test/app1/PersistentDemo.tml
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/PersistentDemo.java
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ComponentResources.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/InternalComponentResources.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AbstractSessionPersistentFieldStrategy.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClientPersistentFieldStorageImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClientPersistentFieldStrategy.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageLoaderImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageLoaderProcessor.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PersistentFieldManagerImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/Page.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/PageImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/PersistentFieldStrategy.java
tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/persist.apt
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Start.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ClientPersistentFieldStorageImplTest.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PersistentFieldManagerImplTest.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/SessionPersistentFieldStrategyTest.java
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ComponentResources.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ComponentResources.java?rev=630378&r1=630377&r2=630378&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ComponentResources.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ComponentResources.java Fri Feb 22 18:36:14 2008
@@ -174,4 +174,11 @@
* target paget
*/
Link createPageLink(String pageName, boolean override, Object... context);
+
+ /**
+ * Discards all persistent field changes for the page containing the component. Changes are eliminated from
+ * persistent storage (such as the {@link org.apache.tapestry.services.Session}) which will take effect in the
+ * <em>next</em> request (the attached page instance is not affected).
+ */
+ void discardPersistentFieldChanges();
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/InternalComponentResources.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/InternalComponentResources.java?rev=630378&r1=630377&r2=630378&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/InternalComponentResources.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/InternalComponentResources.java Fri Feb 22 18:36:14 2008
@@ -15,13 +15,13 @@
package org.apache.tapestry.internal;
import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.internal.services.PersistentFieldManager;
import org.apache.tapestry.internal.structure.Page;
import org.apache.tapestry.runtime.RenderQueue;
-import org.apache.tapestry.services.PersistentFieldManager;
/**
- * An extension of {@link org.apache.tapestry.ComponentResources} that represents additional methods
- * that are private to the framework and not exposed in any public APIs.
+ * An extension of {@link org.apache.tapestry.ComponentResources} that represents additional methods that are private to
+ * the framework and not exposed in any public APIs.
*/
public interface InternalComponentResources extends ComponentResources, InternalComponentResourcesCommon
{
@@ -39,10 +39,9 @@
boolean hasFieldChange(String fieldName);
/**
- * Posts a change to a persistent field. If the component is still loading, then this change is
- * ignored. Otherwise, it is propagated, via the
- * {@link Page#persistFieldChange(org.apache.tapestry.ComponentResources, String, Object) page}
- * to the {@link PersistentFieldManager}.
+ * Posts a change to a persistent field. If the component is still loading, then this change is ignored. Otherwise,
+ * it is propagated, via the {@link Page#persistFieldChange(org.apache.tapestry.ComponentResources, String, Object)
+ * page} to the {@link PersistentFieldManager}.
*/
void persistFieldChange(String fieldName, Object newValue);
@@ -60,15 +59,15 @@
* Used by generated component code to read a parameter value.
*
* @param parameterName the name of the parameter to read
- * @param desiredTypeName the class name of the desired value (classes will be resolved in the
- * component class loader)
+ * @param desiredTypeName the class name of the desired value (classes will be resolved in the component class
+ * loader)
* @return the value coerced to the correct type
*/
Object readParameter(String parameterName, String desiredTypeName);
/**
- * Updates a parameter. It is an error to update a parameter which is not bound. The parameter
- * {@link org.apache.tapestry.Binding binding} may also not support updates.
+ * Updates a parameter. It is an error to update a parameter which is not bound. The parameter {@link
+ * org.apache.tapestry.Binding binding} may also not support updates.
*
* @param <T>
* @param parameterName of parameter to update
@@ -77,9 +76,8 @@
<T> void writeParameter(String parameterName, T parameterValue);
/**
- * Returns true if the named parameter's {@link org.apache.tapestry.Binding} is invariant, false
- * if otherwise, or if the parameter is not bound. Invariant bindings are cached more
- * aggressively than variant bindings.
+ * Returns true if the named parameter's {@link org.apache.tapestry.Binding} is invariant, false if otherwise, or if
+ * the parameter is not bound. Invariant bindings are cached more aggressively than variant bindings.
*
* @param parameterName the name of parameter to check for invariance
* @return true if the binding is an invariant, false if the binding has no fixed value
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AbstractSessionPersistentFieldStrategy.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AbstractSessionPersistentFieldStrategy.java?rev=630378&r1=630377&r2=630378&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AbstractSessionPersistentFieldStrategy.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AbstractSessionPersistentFieldStrategy.java Fri Feb 22 18:36:14 2008
@@ -1,4 +1,4 @@
-// Copyright 2007 The Apache Software Foundation
+// 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.
@@ -26,8 +26,8 @@
import java.util.List;
/**
- * Base class for strategies that store their values as keys in the session. Implements a uniform
- * format for the keys, based on a prefix to identify the particular strategy.
+ * Base class for strategies that store their values as keys in the session. Implements a uniform format for the keys,
+ * based on a prefix to identify the particular strategy.
*/
public abstract class AbstractSessionPersistentFieldStrategy implements PersistentFieldStrategy
{
@@ -63,9 +63,23 @@
return result;
}
+ public void discardChanges(String pageName)
+ {
+ Session session = _request.getSession(false);
+
+ if (session == null) return;
+
+ String fullPrefix = _prefix + pageName + ":";
+
+ for (String name : session.getAttributeNames(fullPrefix))
+ {
+ session.setAttribute(name, null);
+ }
+ }
+
/**
- * Called after each key is read by {@link #gatherFieldChanges(String)}. This implementation
- * does nothing, subclasses may override.
+ * Called after each key is read by {@link #gatherFieldChanges(String)}. This implementation does nothing,
+ * subclasses may override.
*
* @param session the session from which a value was just read
* @param attributeName the name of the attribute used to read a value
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClientPersistentFieldStorageImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClientPersistentFieldStorageImpl.java?rev=630378&r1=630377&r2=630378&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClientPersistentFieldStorageImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClientPersistentFieldStorageImpl.java Fri Feb 22 18:36:14 2008
@@ -1,4 +1,4 @@
-// Copyright 2007 The Apache Software Foundation
+// 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.
@@ -32,9 +32,9 @@
import java.util.Map;
/**
- * Manages client-persistent values on behalf of a {@link ClientPersistentFieldStorageImpl}. Some
- * effort is made to ensure that we don't uncessarily convert between objects and Base64 (the
- * encoding used to record the value on the client).
+ * Manages client-persistent values on behalf of a {@link ClientPersistentFieldStorageImpl}. Some effort is made to
+ * ensure that we don't uncessarily convert between objects and Base64 (the encoding used to record the value on the
+ * client).
*/
@Scope(PERTHREAD_SCOPE)
public class ClientPersistentFieldStorageImpl implements ClientPersistentFieldStorage
@@ -150,6 +150,24 @@
return result;
}
+ public void discardChanges(String pageName)
+ {
+ refreshMap();
+
+ Collection<Key> removedKeys = CollectionFactory.newList();
+
+ for (Key key : _persistedValues.keySet())
+ {
+ if (key._pageName.equals(pageName)) removedKeys.add(key);
+ }
+
+ for (Key key : removedKeys)
+ {
+ _persistedValues.remove(key);
+ _clientData = null;
+ }
+ }
+
public void postChange(String pageName, String componentId, String fieldName, Object newValue)
{
refreshMap();
@@ -170,6 +188,9 @@
_clientData = null;
}
+ /**
+ * Refreshes the _persistedValues map if it is not up to date.
+ */
@SuppressWarnings("unchecked")
private void refreshMap()
{
@@ -182,6 +203,9 @@
_mapUptoDate = true;
}
+ /**
+ * Restores the _persistedValues map from the client data provided in the incoming Request.
+ */
private void restoreMapFromClientData()
{
_persistedValues.clear();
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClientPersistentFieldStrategy.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClientPersistentFieldStrategy.java?rev=630378&r1=630377&r2=630378&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClientPersistentFieldStrategy.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClientPersistentFieldStrategy.java Fri Feb 22 18:36:14 2008
@@ -1,4 +1,4 @@
-// Copyright 2007 The Apache Software Foundation
+// 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.
@@ -21,10 +21,9 @@
import java.util.Collection;
/**
- * Implements simple client-persistent properties. Most of the logic is delegated to an instance of
- * {@link ClientPersistentFieldStorage}. This division of layer allows this service to be a true
- * singleton, and a listener to the {@link LinkFactory}, and allow per-request state to be isolated
- * inside the other service.
+ * Implements simple client-persistent properties. Most of the logic is delegated to an instance of {@link
+ * ClientPersistentFieldStorage}. This division of layer allows this service to be a true singleton, and a listener to
+ * the {@link LinkFactory}, and allow per-request state to be isolated inside the other service.
*/
public class ClientPersistentFieldStrategy implements PersistentFieldStrategy, LinkFactoryListener
{
@@ -53,5 +52,10 @@
public void createdPageLink(Link link)
{
_storage.updateLink(link);
+ }
+
+ public void discardChanges(String pageName)
+ {
+ _storage.discardChanges(pageName);
}
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageLoaderImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageLoaderImpl.java?rev=630378&r1=630377&r2=630378&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageLoaderImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageLoaderImpl.java Fri Feb 22 18:36:14 2008
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007 The Apache Software Foundation
+// Copyright 2006, 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.
@@ -18,12 +18,11 @@
import org.apache.tapestry.internal.events.InvalidationListener;
import org.apache.tapestry.internal.structure.Page;
import org.apache.tapestry.services.ComponentClassResolver;
-import org.apache.tapestry.services.PersistentFieldManager;
import java.util.Locale;
public class PageLoaderImpl extends InvalidationEventHubImpl implements PageLoader,
- InvalidationListener
+ InvalidationListener
{
private final ComponentTemplateSource _templateSource;
@@ -61,8 +60,8 @@
}
/**
- * When the page loader receives an invalidation event, it respawns the event for its listeners.
- * Those listeners will include page caches and the like.
+ * When the page loader receives an invalidation event, it respawns the event for its listeners. Those listeners
+ * will include page caches and the like.
*/
public void objectWasInvalidated()
{
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageLoaderProcessor.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageLoaderProcessor.java?rev=630378&r1=630377&r2=630378&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageLoaderProcessor.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageLoaderProcessor.java Fri Feb 22 18:36:14 2008
@@ -34,7 +34,6 @@
import org.apache.tapestry.model.EmbeddedComponentModel;
import org.apache.tapestry.runtime.RenderQueue;
import org.apache.tapestry.services.BindingSource;
-import org.apache.tapestry.services.PersistentFieldManager;
import org.slf4j.Logger;
import java.util.List;
Copied: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PersistentFieldManager.java (from r630031, tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/PersistentFieldManager.java)
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PersistentFieldManager.java?p2=tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PersistentFieldManager.java&p1=tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/PersistentFieldManager.java&r1=630031&r2=630378&rev=630378&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/PersistentFieldManager.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PersistentFieldManager.java Fri Feb 22 18:36:14 2008
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007 The Apache Software Foundation
+// Copyright 2006, 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.
@@ -12,15 +12,17 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package org.apache.tapestry.services;
+package org.apache.tapestry.internal.services;
import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.services.PersistentFieldBundle;
/**
- * Handle persistent property changes. Primarily, delegates to a number of
- * {@link PersistentFieldStrategy} instances.
+ * Handle persistent property changes. Primarily, delegates to a number of {@link org.apache.tapestry.services.PersistentFieldStrategy}
+ * instances.
*
- * @see org.apache.tapestry.services.TapestryModule#contributePersistentFieldManager(org.apache.tapestry.ioc.MappedConfiguration, Request, PersistentFieldStrategy)
+ * @see org.apache.tapestry.services.TapestryModule#contributePersistentFieldManager(org.apache.tapestry.ioc.MappedConfiguration,
+ * org.apache.tapestry.services.Request , org.apache.tapestry.services.PersistentFieldStrategy)
*/
public interface PersistentFieldManager
{
@@ -28,19 +30,26 @@
* Posts a change of a persistent property.
*
* @param pageName the logical name of the page containing the component
- * @param resources the resources for the component or mixin (used to determine the persistence
- * strategy)
+ * @param resources the resources for the component or mixin (used to determine the persistence strategy)
* @param fieldName the name of the field whose persistent value has changed
* @param newValue the new value for the field, possibly null
*/
void postChange(String pageName, ComponentResources resources, String fieldName, Object newValue);
/**
- * Locates all persistently stored changes to all properties within the page (for the current
- * session and request) and gathers them together into a bundle.
+ * Locates all persistently stored changes to all properties within the page (for the current session and request)
+ * and gathers them together into a bundle.
*
* @param pageName the logical name of the page to gather changes for
* @return a bundle identifying all such changes
*/
PersistentFieldBundle gatherChanges(String pageName);
+
+ /**
+ * Discards all changes for the indicated page. This will not affect pages that have already been attached to this
+ * request, but will affect subsequent page attachments in this and later requests.
+ *
+ * @param pageName logical name of page whose persistent field data is to be discarded
+ */
+ void discardChanges(String pageName);
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PersistentFieldManagerImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PersistentFieldManagerImpl.java?rev=630378&r1=630377&r2=630378&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PersistentFieldManagerImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PersistentFieldManagerImpl.java Fri Feb 22 18:36:14 2008
@@ -18,7 +18,10 @@
import org.apache.tapestry.ioc.internal.util.CollectionFactory;
import org.apache.tapestry.ioc.internal.util.InternalUtils;
import org.apache.tapestry.model.ComponentModel;
-import org.apache.tapestry.services.*;
+import org.apache.tapestry.services.MetaDataLocator;
+import org.apache.tapestry.services.PersistentFieldBundle;
+import org.apache.tapestry.services.PersistentFieldChange;
+import org.apache.tapestry.services.PersistentFieldStrategy;
import java.util.Collection;
import java.util.Map;
@@ -63,6 +66,14 @@
}
return new PersistentFieldBundleImpl(allChanges);
+ }
+
+ public void discardChanges(String pageName)
+ {
+ for (PersistentFieldStrategy strategy : _strategies.values())
+ {
+ strategy.discardChanges(pageName);
+ }
}
public void postChange(String pageName, ComponentResources resources, String fieldName,
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java?rev=630378&r1=630377&r2=630378&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java Fri Feb 22 18:36:14 2008
@@ -128,6 +128,11 @@
return _page.createPageLink(pageName, override, context);
}
+ public void discardPersistentFieldChanges()
+ {
+ _page.discardPersistentFieldChanges();
+ }
+
public String getCompleteId()
{
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/Page.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/Page.java?rev=630378&r1=630377&r2=630378&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/Page.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/Page.java Fri Feb 22 18:36:14 2008
@@ -154,4 +154,11 @@
* Called as a component finishes rendering itself.
*/
void decrementDirtyCount();
+
+ /**
+ * Discards all persistent field changes for the page containing the component. Changes are eliminated from
+ * persistent storage (such as the {@link org.apache.tapestry.services.Session}) which will take effect in the
+ * <em>next</em> request (the attached page instance is not affected).
+ */
+ void discardPersistentFieldChanges();
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/PageImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/PageImpl.java?rev=630378&r1=630377&r2=630378&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/PageImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/PageImpl.java Fri Feb 22 18:36:14 2008
@@ -17,13 +17,13 @@
import org.apache.tapestry.ComponentResources;
import org.apache.tapestry.Link;
import org.apache.tapestry.internal.services.LinkFactory;
+import org.apache.tapestry.internal.services.PersistentFieldManager;
import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newList;
import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
import org.apache.tapestry.ioc.internal.util.InternalUtils;
import org.apache.tapestry.runtime.Component;
import org.apache.tapestry.runtime.PageLifecycleListener;
import org.apache.tapestry.services.PersistentFieldBundle;
-import org.apache.tapestry.services.PersistentFieldManager;
import org.slf4j.Logger;
import java.util.List;
@@ -46,8 +46,8 @@
private int _dirtyCount;
/**
- * Obtained from the {@link PersistentFieldManager} when first needed, discarded at the end of
- * the request.
+ * Obtained from the {@link org.apache.tapestry.internal.services.PersistentFieldManager} when first needed,
+ * discarded at the end of the request.
*/
private PersistentFieldBundle _fieldBundle;
@@ -176,6 +176,11 @@
public void decrementDirtyCount()
{
_dirtyCount--;
+ }
+
+ public void discardPersistentFieldChanges()
+ {
+ _persistentFieldManager.discardChanges(_logicalPageName);
}
public void incrementDirtyCount()
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/PersistentFieldStrategy.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/PersistentFieldStrategy.java?rev=630378&r1=630377&r2=630378&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/PersistentFieldStrategy.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/PersistentFieldStrategy.java Fri Feb 22 18:36:14 2008
@@ -1,26 +1,25 @@
-// Copyright 2006 The Apache Software Foundation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
+// Copyright 2006, 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.tapestry.services;
import java.util.Collection;
/**
* Defines how changes to fields (within components, within pages) may have their values persisted between requests.
- * Different implementations store the field values
- * {@linkplain org.apache.tapestry.internal.services.SessionPersistentFieldStrategy in the session},
- * {@linkplain org.apache.tapestry.internal.services.ClientPersistentFieldStrategy on the client}, or
+ * Different implementations store the field values {@linkplain org.apache.tapestry.internal.services.SessionPersistentFieldStrategy
+ * in the session}, {@linkplain org.apache.tapestry.internal.services.ClientPersistentFieldStrategy on the client}, or
* elsewhere.
*/
public interface PersistentFieldStrategy
@@ -36,8 +35,16 @@
void postChange(String pageName, String componentId, String fieldName, Object newValue);
/**
- * Finds all persistent changes previously stored for the named page (for the current active
- * session or client).
+ * Finds all persistent changes previously stored for the named page (for the current active session or client).
*/
Collection<PersistentFieldChange> gatherFieldChanges(String pageName);
+
+ /**
+ * Discards any saved changes for the name page. There is no expectation that data already gathered from the
+ * strategy and persumably dumped into component instance fields will be affected, but future field access (within
+ * this request or a later one) will show no data for the indicated page.
+ *
+ * @param pageName logical name of page whose field persistent data should be discarded
+ */
+ void discardChanges(String pageName);
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/persist.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/persist.apt?rev=630378&r1=630377&r2=630378&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/persist.apt (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/persist.apt Fri Feb 22 18:36:14 2008
@@ -95,4 +95,12 @@
Servlet API. Changing a persistent field's value to null <removes> the
field's attribute from the session. On later requests, the field will reset to its
default value. Since that is usually null, this is not a problem ... it is only a problem
- if a field has a non-null default value and may be changed to null.
\ No newline at end of file
+ if a field has a non-null default value and may be changed to null.
+
+Clearing Persistent Fields
+
+ If you reach a point where you know that all data for a page can be discarded, you can do exactly that.
+
+ The method <<<discardPersistentFieldChanges()>>> of ComponentResources will discard all persistent fields
+ for the page, regardless of which strategy is used to store the property. This will not affect the
+ page in memory, but takes effect for subsequent requests.
\ No newline at end of file
Added: tapestry/tapestry5/trunk/tapestry-core/src/test/app1/PersistentDemo.tml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/app1/PersistentDemo.tml?rev=630378&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/app1/PersistentDemo.tml (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/app1/PersistentDemo.tml Fri Feb 22 18:36:14 2008
@@ -0,0 +1,21 @@
+<html t:type="Border"
+ xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+ <p>
+ Message:
+ <span id="message">${message}</span>
+ </p>
+
+ <ul>
+ <li>
+ <t:actionlink t:id="updateMessage" context="literal:updated">Update the message field</t:actionlink>
+ </li>
+ <li>
+ <t:actionlink t:id="discardChanges">Discard persistent field changes</t:actionlink>
+ </li>
+ <li>
+ <t:pagelink page="persistentdemo">Refresh page</t:pagelink>
+ </li>
+ </ul>
+</html>
+
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java?rev=630378&r1=630377&r2=630378&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java Fri Feb 22 18:36:14 2008
@@ -1729,4 +1729,27 @@
assertText("message", "from getActionURL()");
}
+
+ /**
+ * TAPESTRY-1475
+ */
+ @Test
+ public void discard_persistent_field_changes()
+ {
+ start("Persistent Demo");
+
+ assertText("message", "");
+
+ clickAndWait("link=Update the message field");
+
+ assertText("message", "updated");
+
+ clickAndWait("link=Refresh page");
+
+ assertText("message", "updated");
+
+ clickAndWait("link=Discard persistent field changes");
+
+ assertText("message", "");
+ }
}
Added: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/PersistentDemo.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/PersistentDemo.java?rev=630378&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/PersistentDemo.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/PersistentDemo.java Fri Feb 22 18:36:14 2008
@@ -0,0 +1,43 @@
+// Copyright 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.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.annotations.Persist;
+import org.apache.tapestry.ioc.annotations.Inject;
+
+public class PersistentDemo
+{
+ @Persist
+ private String _message;
+
+ @Inject
+ private ComponentResources _resources;
+
+ void onActionFromUpdateMessage(String message)
+ {
+ _message = message;
+ }
+
+ void onActionFromDiscardChanges()
+ {
+ _resources.discardPersistentFieldChanges();
+ }
+
+ public String getMessage()
+ {
+ return _message;
+ }
+}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Start.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Start.java?rev=630378&r1=630377&r2=630378&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Start.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Start.java Fri Feb 22 18:36:14 2008
@@ -62,6 +62,8 @@
private static final List<Item> ITEMS = CollectionFactory.newList(
new Item("actionpage", "Action Page", "tests fixture for ActionLink component"),
+ new Item("PersistentDemo", "Persistent Demo", "storing and clearing persistent properties"),
+
new Item("ActionViaLinkDemo", "Action via Link Demo", "tests creating an action link explicitly"),
new Item("FormFragmentDemo", "Form Fragment Demo", "page with dynamic form sections"),
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ClientPersistentFieldStorageImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ClientPersistentFieldStorageImplTest.java?rev=630378&r1=630377&r2=630378&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ClientPersistentFieldStorageImplTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ClientPersistentFieldStorageImplTest.java Fri Feb 22 18:36:14 2008
@@ -175,6 +175,35 @@
verify();
}
+ /**
+ * TAPESTRY-1475
+ */
+ @Test
+ public void discard_changes()
+ {
+ Request request = mockRequest(null);
+ Link link = mockLink();
+
+ String pageName = "Foo";
+ String componentId = "bar.baz";
+ String fieldName = "woops";
+
+ replay();
+
+ ClientPersistentFieldStorage storage = new ClientPersistentFieldStorageImpl(request);
+
+ storage.postChange(pageName, componentId, fieldName, 99);
+
+ storage.discardChanges(pageName);
+
+ storage.updateLink(link);
+
+ assertTrue(storage.gatherFieldChanges(pageName).isEmpty());
+
+ verify();
+ }
+
+
@Test
public void value_not_serializable()
{
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PersistentFieldManagerImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PersistentFieldManagerImplTest.java?rev=630378&r1=630377&r2=630378&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PersistentFieldManagerImplTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PersistentFieldManagerImplTest.java Fri Feb 22 18:36:14 2008
@@ -19,7 +19,10 @@
import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newList;
import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newMap;
import org.apache.tapestry.model.ComponentModel;
-import org.apache.tapestry.services.*;
+import org.apache.tapestry.services.MetaDataLocator;
+import org.apache.tapestry.services.PersistentFieldBundle;
+import org.apache.tapestry.services.PersistentFieldChange;
+import org.apache.tapestry.services.PersistentFieldStrategy;
import org.testng.annotations.Test;
import java.util.Collection;
@@ -60,6 +63,33 @@
ex.getMessage(),
"\'braveheart\' is not a defined persistent strategy. Defined strategies: bar, foo.");
}
+
+ verify();
+ }
+
+ /**
+ * TAPESTRY-1475
+ */
+ @Test
+ public void discard_changes()
+ {
+ PersistentFieldStrategy strat1 = newPersistentFieldStrategy();
+ PersistentFieldStrategy strat2 = newPersistentFieldStrategy();
+
+ Map<String, PersistentFieldStrategy> strategies = newMap();
+ strategies.put("foo", strat1);
+ strategies.put("bar", strat2);
+
+ String pageName = "gnip.gnop";
+
+ strat1.discardChanges(pageName);
+ strat2.discardChanges(pageName);
+
+ replay();
+
+ PersistentFieldManager manager = new PersistentFieldManagerImpl(null, strategies);
+
+ manager.discardChanges(pageName);
verify();
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/SessionPersistentFieldStrategyTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/SessionPersistentFieldStrategyTest.java?rev=630378&r1=630377&r2=630378&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/SessionPersistentFieldStrategyTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/SessionPersistentFieldStrategyTest.java Fri Feb 22 18:36:14 2008
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007 The Apache Software Foundation
+// Copyright 2006, 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.
@@ -61,6 +61,49 @@
SessionPersistentFieldStrategy strategy = new SessionPersistentFieldStrategy(request);
strategy.postChange("foo.Bar", "fee.fum", "field", value);
+
+ verify();
+ }
+
+ /**
+ * TAPESTRY-1475
+ */
+ @Test
+ public void discard_changes_with_no_session()
+ {
+ Request request = mockRequest();
+
+ train_getSession(request, false, null);
+
+ replay();
+
+ SessionPersistentFieldStrategy strategy = new SessionPersistentFieldStrategy(request);
+
+ strategy.discardChanges("foo.Bar");
+
+ verify();
+ }
+
+ /**
+ * TAPESTRY-1475
+ */
+ @Test
+ public void discard_changes()
+ {
+ Session session = mockSession();
+ Request request = mockRequest();
+
+ train_getSession(request, false, session);
+
+ train_getAttributeNames(session, "state:foo.Bar:", "state:foo.Bar:baz:field");
+
+ session.setAttribute("state:foo.Bar:baz:field", null);
+
+ replay();
+
+ SessionPersistentFieldStrategy strategy = new SessionPersistentFieldStrategy(request);
+
+ strategy.discardChanges("foo.Bar");
verify();
}