You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2009/02/11 03:22:18 UTC
svn commit: r743195 - in /tapestry/tapestry5/trunk: src/site/ src/site/apt/
tapestry-core/src/main/java/org/apache/tapestry5/
tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/
tapestry-core/src/main/java/org/apache/tapestry5/internal...
Author: hlship
Date: Wed Feb 11 02:22:17 2009
New Revision: 743195
URL: http://svn.apache.org/viewvc?rev=743195&view=rev
Log:
TAP5-165: Components which use PrimaryKeyEncoder should be changed to use ValueEncoder, and PrimaryKeyEncoder should be deprecated
Added:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/util/PrimaryKeyEncoder2ValueEncoder.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/util/PrimaryKeyEncoder2ValueEncoderTest.java
Modified:
tapestry/tapestry5/trunk/src/site/apt/upgrade.apt
tapestry/tapestry5/trunk/src/site/site.xml
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/EventConstants.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/PrimaryKeyEncoder.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/AjaxFormLoop.java
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/corelib/components/GridRows.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Loop.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/util/DefaultPrimaryKeyEncoder.java
tapestry/tapestry5/trunk/tapestry-core/src/test/app1/GridFormEncoderDemo.tml
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/DateFieldAjaxFormLoop.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/FormInjectorDemo.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/GridFormEncoderDemo.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/ToDoList.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/services/AppModule.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/util/DefaultPrimaryKeyEncoderTest.java
Modified: tapestry/tapestry5/trunk/src/site/apt/upgrade.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/src/site/apt/upgrade.apt?rev=743195&r1=743194&r2=743195&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/src/site/apt/upgrade.apt (original)
+++ tapestry/tapestry5/trunk/src/site/apt/upgrade.apt Wed Feb 11 02:22:17 2009
@@ -15,6 +15,24 @@
Release 5.1.0.0
+* Primary Key Encoder
+
+ <<This is the change between releases that is most likely to affect your upgrade.>>
+
+ The {{{apidocs/org/apache/tapestry5/PrimaryKeyEncoder.html}PrimaryKeyEncoder}}
+ interface has been deprecated and will be removed in a later release.
+ See {{{https://issues.apache.org/jira/browse/TAP5-165}TAP5-165}} for the rationale.
+
+ You may see type coercion errors on pages where you have specified the encoder parameter of
+ the Grid, Loop or AjaxFormLoop components as a PrimaryKeyEncoder.
+ These errors indicate that Tapestry was unable to automatically convert your PrimaryKeyEncoder instance into
+ a {{{apidocs/org/apache/tapestry5/ValueEncoder.html}ValueEncoder}}. Generally, the only change is to invoke the new constructor for
+ {{{apdiocs/org/apache/tapestry5/util/DefaultPrimaryKeyEncoder.html}DefaultPrimaryKeyEncoder}}, to identify
+ the type of key used.
+
+ If you don't use DefaultPrimaryKeyEncoder, you will see compile errors about the new method, getKeyType().
+ You will have to change your code to implement that new method.
+
* Performance Improvements
As part of the changes related to
@@ -28,10 +46,11 @@
* Tapestry/Spring
There have been some significant changes to the {{{tapestry-spring/}tapestry-spring}} module, to
- support injection of Tapestry services into Springbeans.
+ support injection of Tapestry services into Spring beans. You may find you need to add some new configuration
+ to revert to the Tapestry 5.0 behavior.
* Session Persisted Objects
-
+
Tapestry is now more aggressive about automatically re-storing any session persisted object
back into the session at the end of the request (this used to only apply to application state objects). See the
{{{guide/persist.html}persistent page data}} notes for more details.
@@ -39,7 +58,8 @@
* Module Classes
Many questionable practices in Tapestry module classes that used to produce warnings
- have been changed to fail early with exceptions. The rationale is that the warnings would be ignored,
+ have been changed to fail early (that is, throw exceptions). The rationale is that the warnings
+ are almost always ignored,
resulting in more difficult to diagnose runtime errors.
Extra public methods on module classes (methods that do not define services, contribute to services,
@@ -47,3 +67,7 @@
+
+
+
+
Modified: tapestry/tapestry5/trunk/src/site/site.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/src/site/site.xml?rev=743195&r1=743194&r2=743195&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/src/site/site.xml (original)
+++ tapestry/tapestry5/trunk/src/site/site.xml Wed Feb 11 02:22:17 2009
@@ -51,7 +51,7 @@
</menu>
<menu name="Upgrade Notes">
- <item name="From Tapestry 5" href="upgrade.html"/>
+ <item name="From Tapestry 5.0" href="upgrade.html"/>
<item name="From Tapestry 4" href="upgrade4.html"/>
<item name="Upgrade Notes (5.0)" href="upgrade5.0.html"/>
<item name="Release Notes (5.0)" href="release-notes-5.0.html"/>
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/EventConstants.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/EventConstants.java?rev=743195&r1=743194&r2=743195&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/EventConstants.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/EventConstants.java Wed Feb 11 02:22:17 2009
@@ -1,4 +1,4 @@
-// Copyright 2008 The Apache Software Foundation
+// Copyright 2008, 2009 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -123,4 +123,13 @@
* also be visible in the {@link org.apache.tapestry5.PrimaryKeyEncoder encoder parameter}.
*/
public static final String ADD_ROW = "addRow";
+
+ /**
+ * Event triggered by the {@link org.apache.tapestry5.corelib.components.Loop} component to inform its container of
+ * all the values that were supplied from the client during a form submission. The event handler method should have
+ * a single parameter, of type Object[] or type List, to receive the values.
+ *
+ * @since 5.1.0.0
+ */
+ public static final String SYNCHRONIZE_VALUES = "synchronizeValues";
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/PrimaryKeyEncoder.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/PrimaryKeyEncoder.java?rev=743195&r1=743194&r2=743195&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/PrimaryKeyEncoder.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/PrimaryKeyEncoder.java Wed Feb 11 02:22:17 2009
@@ -1,4 +1,4 @@
-// Copyright 2007, 2008 The Apache Software Foundation
+// Copyright 2007, 2008, 2009 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -27,6 +27,12 @@
* @param <K> the type of the primary key, used to identify the value (which must be serializable)
* @param <V> the type of value identified by the key
* @see org.apache.tapestry5.ValueEncoder
+ * @deprecated This interface overlaps with {@link org.apache.tapestry5.ValueEncoder} and has been deprecated in release
+ * 5.1. The interface itself will be removed in a later release of Tapestry. The components that used this
+ * interface ({@link org.apache.tapestry5.corelib.components.AjaxFormLoop}, {@link
+ * org.apache.tapestry5.corelib.components.Grid}, {@link org.apache.tapestry5.corelib.components.GridRows}
+ * and {@link org.apache.tapestry5.corelib.components.Loop}) have been changed to expect ValueEncoder
+ * instead, and an automatic coercion from PrimaryKeyEncoder to ValueEncoder has been provided.
*/
public interface PrimaryKeyEncoder<K extends Serializable, V>
{
@@ -55,4 +61,13 @@
* @return the value object for the key
*/
V toValue(K key);
+
+ /**
+ * Returns the type of key. This is primarily used when Tapestry must convert an existing PrimaryKeyConverter into a
+ * {@link org.apache.tapestry5.ValueEncoder}.
+ *
+ * @return key type or null if not known
+ * @since 5.1.0.0
+ */
+ Class<K> getKeyType();
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/AjaxFormLoop.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/AjaxFormLoop.java?rev=743195&r1=743194&r2=743195&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/AjaxFormLoop.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/AjaxFormLoop.java Wed Feb 11 02:22:17 2009
@@ -26,7 +26,6 @@
import org.apache.tapestry5.json.JSONObject;
import org.apache.tapestry5.services.*;
-import java.io.Serializable;
import java.util.Collections;
import java.util.Iterator;
@@ -99,7 +98,7 @@
* Required parameter used to convert server-side objects (provided from the source) into client-side ids and back.
*/
@Parameter(required = true, allowNull = false)
- private PrimaryKeyEncoder encoder;
+ private ValueEncoder<Object> encoder;
@InjectComponent
private ClientElement rowInjector;
@@ -159,11 +158,7 @@
public void addRemoveRowTrigger(String clientId)
{
- Serializable id = idForCurrentValue();
-
- String idType = id.getClass().getName();
-
- Link link = resources.createEventLink("triggerRemoveRow", id, idType);
+ Link link = resources.createEventLink("triggerRemoveRow", toClientValue());
String asURI = link.toAbsoluteURI();
@@ -184,26 +179,26 @@
/**
- * Action for synchronizing the current element of the loop by recording its client value / primary key.
+ * Action for synchronizing the current element of the loop by recording its client value.
*/
static class SyncValue implements ComponentAction<AjaxFormLoop>
{
- private final Serializable id;
+ private final String clientValue;
- public SyncValue(Serializable id)
+ public SyncValue(String clientValue)
{
- this.id = id;
+ this.clientValue = clientValue;
}
public void execute(AjaxFormLoop component)
{
- component.syncValue(id);
+ component.syncValue(clientValue);
}
@Override
public String toString()
{
- return String.format("AjaxFormLoop.SyncValue[%s]", id);
+ return String.format("AjaxFormLoop.SyncValue[%s]", clientValue);
}
}
@@ -274,13 +269,13 @@
@SuppressWarnings({ "unchecked" })
@Log
- private void syncValue(Serializable id)
+ private void syncValue(String clientValue)
{
- Object value = encoder.toValue(id);
+ Object value = encoder.toValue(clientValue);
if (value == null)
throw new RuntimeException(
- String.format("Unable to convert serialized id '%s' back into an object.", id));
+ String.format("Unable to convert client value '%s' back into a server-side object.", clientValue));
this.value = value;
}
@@ -296,21 +291,22 @@
private void syncCurrentValue()
{
- Serializable id = idForCurrentValue();
+ String id = toClientValue();
- // Add the command that restores value from the value id,
+ // Add the command that restores value from the value clientValue,
// when the form is submitted.
formSupport.store(this, new SyncValue(id));
}
/**
- * Uses the {@link org.apache.tapestry5.PrimaryKeyEncoder} to convert the current row value to an id.
+ * Uses the {@link org.apache.tapestry5.ValueEncoder} to convert the current server-side value to a client-side
+ * value.
*/
@SuppressWarnings({ "unchecked" })
- private Serializable idForCurrentValue()
+ private String toClientValue()
{
- return encoder.toKey(value);
+ return encoder.toClient(value);
}
@@ -396,8 +392,7 @@
if (value == null)
throw new IllegalArgumentException(
String.format("Event handler for event 'addRow' from %s should have returned a non-null value.",
- resources.getCompleteId())
- );
+ resources.getCompleteId()));
renderingInjector = true;
@@ -418,13 +413,9 @@
}
@Log
- Object onTriggerRemoveRow(String rowId, String idTypeName)
+ Object onTriggerRemoveRow(String rowId)
{
- Class idType = componentClassCache.forName(idTypeName);
-
- Serializable coerced = (Serializable) typeCoercer.coerce(rowId, idType);
-
- Object value = encoder.toValue(coerced);
+ Object value = encoder.toValue(rowId);
resources.triggerEvent(EventConstants.REMOVE_ROW, new Object[] { value }, null);
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=743195&r1=743194&r2=743195&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 Wed Feb 11 02:22:17 2009
@@ -1,4 +1,4 @@
-// Copyright 2007, 2008 The Apache Software Foundation
+// Copyright 2007, 2008, 2009 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -26,10 +26,7 @@
import org.apache.tapestry5.internal.services.ClientBehaviorSupport;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.ioc.internal.util.Defense;
-import org.apache.tapestry5.services.BeanModelSource;
-import org.apache.tapestry5.services.ComponentEventResultProcessor;
-import org.apache.tapestry5.services.FormSupport;
-import org.apache.tapestry5.services.Request;
+import org.apache.tapestry5.services.*;
import java.io.IOException;
import java.util.Collections;
@@ -88,7 +85,7 @@
* provided to override the default cell renderer for a particular column ... the components within the block can
* use the property bound to the row parameter to know what they should render.
*/
- @Parameter
+ @Parameter(principal = true)
private Object row;
/**
@@ -206,12 +203,12 @@
private boolean inPlace;
/**
- * Changes how state is recorded into the form to store the {@linkplain org.apache.tapestry5.PrimaryKeyEncoder#toKey(Object)
- * primary key} for each row (rather than the index), and restore the {@linkplain
- * org.apache.tapestry5.PrimaryKeyEncoder#toValue(java.io.Serializable) row values} from the primary keys.
+ * Changes how state is recorded into the form to store the {@linkplain org.apache.tapestry5.ValueEncoder#toClient(Object)
+ * client value} for each row (rather than the index), and restore the {@linkplain
+ * org.apache.tapestry5.ValueEncoder#toValue(String)row values} from the client value.
*/
@Parameter
- private PrimaryKeyEncoder encoder;
+ private ValueEncoder encoder;
/**
* The name of the psuedo-zone that encloses the Grid.
@@ -245,7 +242,7 @@
"index=inherit:columnIndex",
"lean=inherit:lean",
"overrides=overrides",
- "zone=zone"})
+ "zone=zone" })
private GridColumns columns;
@Component(
@@ -259,14 +256,14 @@
"overrides=overrides",
"volatile=inherit:volatile",
"encoder=inherit:encoder",
- "lean=inherit:lean"})
+ "lean=inherit:lean" })
private GridRows rows;
@Component(parameters = {
"source=dataSource",
"rowsPerPage=rowsPerPage",
"currentPage=currentPage",
- "zone=zone"})
+ "zone=zone" })
private GridPager pager;
@Component(parameters = "to=pagerTop")
@@ -301,6 +298,14 @@
@Environmental
private ComponentEventResultProcessor componentEventResultProcessor;
+ @Inject
+ private ComponentDefaultProvider defaultsProvider;
+
+ ValueEncoder defaultEncoder()
+ {
+ return defaultsProvider.defaultValueEncoder("row", resources);
+ }
+
/**
* A version of GridDataSource that caches the availableRows property. This addresses TAPESTRY-2245.
*/
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/GridRows.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/GridRows.java?rev=743195&r1=743194&r2=743195&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/GridRows.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/GridRows.java Wed Feb 11 02:22:17 2009
@@ -1,4 +1,4 @@
-// Copyright 2007, 2008 The Apache Software Foundation
+// Copyright 2007, 2008, 2009 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -28,8 +28,8 @@
package org.apache.tapestry5.corelib.components;
import org.apache.tapestry5.ComponentAction;
-import org.apache.tapestry5.PrimaryKeyEncoder;
import org.apache.tapestry5.PropertyOverrides;
+import org.apache.tapestry5.ValueEncoder;
import org.apache.tapestry5.annotations.Environmental;
import org.apache.tapestry5.annotations.Parameter;
import org.apache.tapestry5.annotations.Property;
@@ -41,7 +41,6 @@
import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
import org.apache.tapestry5.services.FormSupport;
-import java.io.Serializable;
import java.util.List;
/**
@@ -52,7 +51,7 @@
* form render and the form submission, this can cause unexpected results, including applying changes to the wrong
* objects.
*/
-@SuppressWarnings({"unchecked"})
+@SuppressWarnings({ "unchecked" })
public class GridRows
{
private int startRow;
@@ -87,52 +86,26 @@
}
/**
- * This action is used when a {@link org.apache.tapestry5.PrimaryKeyEncoder} is provided.
+ * This action is used when a {@link org.apache.tapestry5.ValueEncoder} is provided.
*/
- static class SetupForRowByKey implements ComponentAction<GridRows>
+ static class SetupForRowWithClientValue implements ComponentAction<GridRows>
{
- private final Serializable rowKey;
+ private final String clientValue;
- SetupForRowByKey(Serializable rowKey)
+ SetupForRowWithClientValue(String clientValue)
{
- this.rowKey = rowKey;
+ this.clientValue = clientValue;
}
public void execute(GridRows component)
{
- component.setupForRowByKey(rowKey);
+ component.setupForRowWithClientValue(clientValue);
}
@Override
public String toString()
{
- return String.format("GridRows.SetupForRowByKey[%s]", rowKey);
- }
- }
-
-
- /**
- * This action is also associated with the {@link org.apache.tapestry5.PrimaryKeyEncoder}; it allows the PKE to be
- * informed of the series of keys to expect with the form submission.
- */
- static class PrepareForKeys implements ComponentAction<GridRows>
- {
- private List<Serializable> storedKeys;
-
- public PrepareForKeys(List<Serializable> storedKeys)
- {
- this.storedKeys = storedKeys;
- }
-
- public void execute(GridRows component)
- {
- component.prepareForKeys(storedKeys);
- }
-
- @Override
- public String toString()
- {
- return "GridRows.PrepareForKeys" + storedKeys.toString();
+ return String.format("GridRows.SetupForRowWithClientValue[%s]", clientValue);
}
}
@@ -192,12 +165,13 @@
private boolean volatileState;
/**
- * Changes how state is recorded into the form to store the {@linkplain org.apache.tapestry5.PrimaryKeyEncoder#toKey(Object)
- * primary key} for each row (rather than the index), and restore the {@linkplain
- * org.apache.tapestry5.PrimaryKeyEncoder#toValue(java.io.Serializable) row values} from the primary keys.
+ * Changes how state is recorded into the form to store the {@linkplain org.apache.tapestry5.ValueEncoder#toClient(Object)
+ * client value} for each row (rather than the index), and restore the {@linkplain
+ * org.apache.tapestry5.ValueEncoder#toValue(String) row values} from the client value.
*/
@Parameter
- private PrimaryKeyEncoder encoder;
+ private ValueEncoder encoder;
+
/**
* Optional output parameter (only set during rendering) that identifies the current row index. This is the index on
@@ -230,8 +204,6 @@
@Property(write = false)
private PropertyModel columnModel;
- private List<Serializable> encodedPrimaryKeys;
-
public String getRowClass()
{
List<String> classes = CollectionFactory.newList();
@@ -298,16 +270,6 @@
recordStateByIndex = recordingStateInsideForm && (encoder == null);
recordStateByEncoder = recordingStateInsideForm && (encoder != null);
-
- if (recordStateByEncoder)
- {
- encodedPrimaryKeys = CollectionFactory.newList();
-
- // As we render, we'll fill in encodedPrimaryKeys. That's ok, because nothing is serialized
- // until later. When the form is submitted, this will give us a chance to inform
- // the PKE about the keys to expect.
- formSupport.store(this, new PrepareForKeys(encodedPrimaryKeys));
- }
}
/**
@@ -320,24 +282,15 @@
/**
* Callback method that bypasses the data source and converts a primary key back into a row value (via {@link
- * org.apache.tapestry5.PrimaryKeyEncoder#toValue(java.io.Serializable)}).
+ * org.apache.tapestry5.ValueEncoder#toValue(String)}).
*/
- void setupForRowByKey(Serializable rowKey)
+ void setupForRowWithClientValue(String clientValue)
{
- row = encoder.toValue(rowKey);
+ row = encoder.toValue(clientValue);
if (row == null)
throw new IllegalArgumentException(
- String.format("%s returned null for key %s.", encoder, rowKey));
- }
-
- /**
- * Callback method that allows the primary key encoder to prepare for the keys that will be resolved to row values
- * in this request.
- */
- private void prepareForKeys(List<Serializable> storedKeys)
- {
- encoder.prepareForKeys(storedKeys);
+ String.format("%s returned null for client value '%s'.", encoder, clientValue));
}
@@ -360,10 +313,8 @@
if (recordStateByEncoder)
{
- Serializable key = encoder.toKey(row);
- encodedPrimaryKeys.add(key);
-
- formSupport.store(this, new SetupForRowByKey(key));
+ String key = encoder.toClient(row);
+ formSupport.store(this, new SetupForRowWithClientValue(key));
}
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Loop.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Loop.java?rev=743195&r1=743194&r2=743195&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Loop.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Loop.java Wed Feb 11 02:22:17 2009
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007, 2008 The Apache Software Foundation
+// Copyright 2006, 2007, 2008, 2009 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@
import org.apache.tapestry5.annotations.*;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry5.services.ComponentDefaultProvider;
import org.apache.tapestry5.services.FormSupport;
import org.apache.tapestry5.services.Heartbeat;
@@ -32,6 +33,9 @@
* For a non-volatile Loop inside the form, the Loop stores a series of commands that start and end heartbeats and store
* state (either as full objects when there the encoder parameter is not bound, or as client-side objects when there is
* an encoder).
+ * <p/>
+ * When the Loop is used inside a Form, it will generate an {@link org.apache.tapestry5.EventConstants#SYNCHRONIZE_VALUES}
+ * event to inform its container what values were submitted and in what order.
*/
@SupportsInformalParameters
public class Loop
@@ -144,57 +148,58 @@
/**
* Restores the value using a stored primary key via {@link PrimaryKeyEncoder#toValue(Serializable)}.
*/
- static class RestoreStateViaEncodedPrimaryKey implements ComponentAction<Loop>
+ static class RestoreStateFromStoredClientValue implements ComponentAction<Loop>
{
- private static final long serialVersionUID = -2422790241589517336L;
+ private final String clientValue;
- private final Serializable primaryKey;
-
- public RestoreStateViaEncodedPrimaryKey(final Serializable primaryKey)
+ public RestoreStateFromStoredClientValue(final String clientValue)
{
- this.primaryKey = primaryKey;
+ this.clientValue = clientValue;
}
public void execute(Loop component)
{
- component.restoreStateViaEncodedPrimaryKey(primaryKey);
+ component.restoreStateFromStoredClientValue(clientValue);
}
@Override
public String toString()
{
- return String.format("Loop.RestoreStateViaEncodedPrimaryKey[%s]", primaryKey);
+ return String.format("Loop.RestoreStateFromStoredClientValue[%s]", clientValue);
}
}
/**
- * Stores a list of keys to be passed to {@link PrimaryKeyEncoder#prepareForKeys(List)}.
+ * Start of processing event that allows the Loop to set up internal bookeeping, to track which values have come up
+ * in the form submission.
*/
- static class PrepareForKeys implements ComponentAction<Loop>
+ static final ComponentAction<Loop> PREPARE_FOR_SUBMISSION = new ComponentAction<Loop>()
{
- private static final long serialVersionUID = -6515255627142956828L;
-
- /**
- * The variable is final, the contents are mutable while the Loop renders.
- */
- private final List<Serializable> keys;
+ public void execute(Loop component)
+ {
+ component.prepareForSubmission();
+ }
- public PrepareForKeys(final List<Serializable> keys)
+ @Override
+ public String toString()
{
- this.keys = keys;
+ return "Loop.PrepareForSubmission";
}
+ };
+ static final ComponentAction<Loop> NOTIFY_CONTAINER = new ComponentAction<Loop>()
+ {
public void execute(Loop component)
{
- component.prepareForKeys(keys);
+ component.notifyContainer();
}
@Override
public String toString()
{
- return "Loop.PrepareForKeys" + keys;
+ return "Loop.NotifyContainer";
}
- }
+ };
/**
* Defines the collection of values for the loop to iterate over. If not specified, defaults to a property of the
@@ -204,11 +209,12 @@
private Iterable<?> source;
/**
- * Optional primary key converter; if provided and inside a form and not volatile, then each iterated value is
- * converted and stored into the form.
+ * Optional value converter; if provided (or defaulted) and inside a form and not volatile, then each iterated value
+ * is converted and stored into the form. A default for this is calculated from the type of the property bound to
+ * the value parameter.
*/
@Parameter
- private PrimaryKeyEncoder<Serializable, Object> encoder;
+ private ValueEncoder<Object> encoder;
/**
* If true and the Loop is enclosed by a Form, then the normal state saving logic is turned off. Defaults to false,
@@ -230,7 +236,7 @@
/**
* The current value, set before the component renders its body.
*/
- @Parameter
+ @Parameter(principal = true)
private Object value;
/**
@@ -255,14 +261,28 @@
@Inject
private ComponentResources resources;
+ @Inject
+ private ComponentDefaultProvider defaultProvider;
+
private Block cleanupBlock;
+ /**
+ * Objects that have been recovered via {@link org.apache.tapestry5.ValueEncoder#toValue(String)} during the
+ * processing of the loop. These are sent to the container via an event.
+ */
+ private List<Object> synchonizedValues;
+
String defaultElement()
{
return resources.getElementName();
}
+ ValueEncoder defaultEncoder()
+ {
+ return defaultProvider.defaultValueEncoder("value", resources);
+ }
+
@SetupRender
boolean setup()
{
@@ -272,6 +292,9 @@
storeRenderStateInForm = formSupport != null && !volatileState;
+ if (storeRenderStateInForm)
+ formSupport.store(this, PREPARE_FOR_SUBMISSION);
+
// Only render the body if there is something to iterate over
boolean hasContent = iterator != null && iterator.hasNext();
@@ -279,16 +302,6 @@
if (formSupport != null && hasContent)
{
formSupport.store(this, volatileState ? SETUP_FOR_VOLATILE : RESET_INDEX);
-
- if (encoder != null)
- {
- List<Serializable> keyList = CollectionFactory.newList();
-
- // We'll keep updating the _keyList while the Loop renders, the values will "lock
- // down" when the Form serializes all the data.
-
- formSupport.store(this, new PrepareForKeys(keyList));
- }
}
cleanupBlock = hasContent ? null : empty;
@@ -298,21 +311,17 @@
return hasContent;
}
+
/**
* Returns the empty block, or null, after the render has finished. It will only be the empty block (which itself
* may be null) if the source was null or empty.
*/
Block cleanupRender()
{
- return cleanupBlock;
- }
-
- private void prepareForKeys(List<Serializable> keys)
- {
- // Again, the encoder existed when we rendered, we better have another available
- // when the enclosing Form is submitted.
+ if (storeRenderStateInForm)
+ formSupport.store(this, NOTIFY_CONTAINER);
- encoder.prepareForKeys(keys);
+ return cleanupBlock;
}
private void setupForVolatile()
@@ -344,8 +353,9 @@
}
else
{
- Serializable primaryKey = encoder.toKey(value);
- formSupport.store(this, new RestoreStateViaEncodedPrimaryKey(primaryKey));
+ String clientValue = encoder.toClient(value);
+
+ formSupport.store(this, new RestoreStateFromStoredClientValue(clientValue));
}
}
@@ -405,14 +415,28 @@
/**
* Restores state previously encoded by the Loop and stored into the Form.
*/
- private void restoreStateViaEncodedPrimaryKey(Serializable primaryKey)
+ private void restoreStateFromStoredClientValue(String clientValue)
{
- // We assume that if a encoder is available when we rendered, that one will be available
- // when the form is submitted. TODO: Check for this.
+ // We assume that if an encoder is available when we rendered, that one will be available
+ // when the form is submitted.
- Object restoredValue = encoder.toValue(primaryKey);
+ Object restoredValue = encoder.toValue(clientValue);
restoreState(restoredValue);
+
+ synchonizedValues.add(restoredValue);
+ }
+
+ private void prepareForSubmission()
+ {
+ synchonizedValues = CollectionFactory.newList();
+ }
+
+ private void notifyContainer()
+ {
+ Object[] values = synchonizedValues.toArray();
+
+ resources.triggerEvent(EventConstants.SYNCHRONIZE_VALUES, values, null);
}
// For testing:
Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/util/PrimaryKeyEncoder2ValueEncoder.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/util/PrimaryKeyEncoder2ValueEncoder.java?rev=743195&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/util/PrimaryKeyEncoder2ValueEncoder.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/util/PrimaryKeyEncoder2ValueEncoder.java Wed Feb 11 02:22:17 2009
@@ -0,0 +1,84 @@
+// Copyright 2009 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.internal.util;
+
+import org.apache.tapestry5.PrimaryKeyEncoder;
+import org.apache.tapestry5.ValueEncoder;
+import org.apache.tapestry5.ioc.services.Coercion;
+import org.apache.tapestry5.ioc.services.TypeCoercer;
+import org.apache.tapestry5.util.DefaultPrimaryKeyEncoder;
+
+import java.io.Serializable;
+
+/**
+ * This is a key part of the plan to eliminate {@link org.apache.tapestry5.PrimaryKeyEncoder}.
+ *
+ * @since 5.1.0.0
+ */
+@SuppressWarnings({ "unchecked" })
+public class PrimaryKeyEncoder2ValueEncoder implements Coercion<PrimaryKeyEncoder, ValueEncoder>
+{
+ // The magic of proxies: a coercion within TypeCoercer can use TypeCoercer as part of its job!
+ private final TypeCoercer coercer;
+
+ public PrimaryKeyEncoder2ValueEncoder(TypeCoercer coercer)
+ {
+ this.coercer = coercer;
+ }
+
+ public ValueEncoder coerce(final PrimaryKeyEncoder input)
+ {
+ final Class keyType = input.getKeyType();
+
+ if (keyType == null)
+ {
+ String message = String.format("Unable to extract primary key type from %s. " +
+ "This represents a change from Tapestry 5.0 to Tapestry 5.1.", input);
+
+ if (input instanceof DefaultPrimaryKeyEncoder)
+ message +=
+ " Class DefaultPrimaryKeyEncoder now includes a constructor for specifying the key type. " +
+ "You should change the code that instantiates the encoder.";
+ else
+ message += " You should ensure that the getKeyType() method returns the correct Class.";
+
+ throw new RuntimeException(message);
+ }
+
+ return new ValueEncoder()
+ {
+ public String toClient(Object value)
+ {
+ Object key = input.toKey(value);
+
+ return coercer.coerce(key, String.class);
+ }
+
+ public Object toValue(String clientValue)
+ {
+ Serializable key = (Serializable) coercer.coerce(clientValue, keyType);
+
+ return input.toValue(key);
+ }
+
+ @Override
+ public String toString()
+ {
+ return String.format("<ValueEncoder coercion wrapper around PrimaryKeyEncoder[%s]>",
+ keyType.getName());
+ }
+ };
+ }
+}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java?rev=743195&r1=743194&r2=743195&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java Wed Feb 11 02:22:17 2009
@@ -32,6 +32,7 @@
import org.apache.tapestry5.internal.services.*;
import org.apache.tapestry5.internal.transform.*;
import org.apache.tapestry5.internal.translator.*;
+import org.apache.tapestry5.internal.util.PrimaryKeyEncoder2ValueEncoder;
import org.apache.tapestry5.internal.util.RenderableAsBlock;
import org.apache.tapestry5.internal.util.StringRenderable;
import org.apache.tapestry5.ioc.*;
@@ -802,10 +803,10 @@
* component) to {@link org.apache.tapestry5.ComponentResources} <li>String to {@link
* org.apache.tapestry5.corelib.data.BlankOption} <li> {@link org.apache.tapestry5.ComponentResources} to {@link
* org.apache.tapestry5.PropertyOverrides} <li>String to {@link org.apache.tapestry5.Renderable} <li>{@link
- * org.apache.tapestry5.Renderable} to {@link org.apache.tapestry5.Block} <li>String to {@link
- * java.text.DateFormat}</ul>
+ * org.apache.tapestry5.Renderable} to {@link org.apache.tapestry5.Block} <li>String to {@link java.text.DateFormat}
+ * <li>{@link org.apache.tapestry5.PrimaryKeyEncoder} to {@link org.apache.tapestry5.ValueEncoder}</ul>
*/
- public static void contributeTypeCoercer(Configuration<CoercionTuple> configuration)
+ public static void contributeTypeCoercer(Configuration<CoercionTuple> configuration, @Builtin TypeCoercer coercer)
{
add(configuration, ComponentResources.class, PropertyOverrides.class,
new Coercion<ComponentResources, PropertyOverrides>()
@@ -908,6 +909,8 @@
return new SimpleDateFormat(input);
}
});
+
+ add(configuration, PrimaryKeyEncoder.class, ValueEncoder.class, new PrimaryKeyEncoder2ValueEncoder(coercer));
}
/**
@@ -1026,7 +1029,7 @@
UpdateListenerHub updateListenerHub,
@ClasspathProvider AssetFactory classpathAssetFactory,
-
+
ClasspathURLConverter classpathURLConverter)
{
ValidationMessagesSourceImpl service = new ValidationMessagesSourceImpl(configuration,
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/util/DefaultPrimaryKeyEncoder.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/util/DefaultPrimaryKeyEncoder.java?rev=743195&r1=743194&r2=743195&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/util/DefaultPrimaryKeyEncoder.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/util/DefaultPrimaryKeyEncoder.java Wed Feb 11 02:22:17 2009
@@ -1,4 +1,4 @@
-// Copyright 2007 The Apache Software Foundation
+// Copyright 2007, 2009 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -32,6 +32,7 @@
*
* @param <K> the key type (which must be serializable)
* @param <V> the value type
+ * @deprecated See deprecation notes for {@link org.apache.tapestry5.PrimaryKeyEncoder}.
*/
public class DefaultPrimaryKeyEncoder<K extends Serializable, V> implements PrimaryKeyEncoder<K, V>
{
@@ -43,6 +44,31 @@
private K currentKey;
+ private final Class<K> keyType;
+
+ /**
+ * Compatibility with 5.0: new encoder, key type unknown. You <em>will</em> want to use the other constructor and
+ * specify the key type.
+ */
+ public DefaultPrimaryKeyEncoder()
+ {
+ this(null);
+ }
+
+ /**
+ * @since 5.1.0.0
+ */
+ public DefaultPrimaryKeyEncoder(Class<K> keyType)
+ {
+ this.keyType = keyType;
+ }
+
+
+ public Class<K> getKeyType()
+ {
+ return keyType;
+ }
+
/**
* Adds a new key/value pair to the encoder.
*/
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/app1/GridFormEncoderDemo.tml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/app1/GridFormEncoderDemo.tml?rev=743195&r1=743194&r2=743195&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/app1/GridFormEncoderDemo.tml (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/app1/GridFormEncoderDemo.tml Wed Feb 11 02:22:17 2009
@@ -9,7 +9,6 @@
<t:errors/>
<table t:id="grid" t:type="Grid" source="items" row="item" pagerposition="top"
- encoder="encoder"
add="id" reorder="id,title,urgency"
rowsperpage="5">
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/DateFieldAjaxFormLoop.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/DateFieldAjaxFormLoop.java?rev=743195&r1=743194&r2=743195&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/DateFieldAjaxFormLoop.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/DateFieldAjaxFormLoop.java Wed Feb 11 02:22:17 2009
@@ -1,4 +1,4 @@
-// Copyright 2008 The Apache Software Foundation
+// Copyright 2008, 2009 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -45,7 +45,6 @@
{
List<DateHolder> result = CollectionFactory.newList(database.values());
-
Collections.sort(result, new Comparator<DateHolder>()
{
public int compare(DateHolder o1, DateHolder o2)
@@ -59,7 +58,8 @@
public PrimaryKeyEncoder<Integer, DateHolder> getDateHolderConverter()
{
- DefaultPrimaryKeyEncoder<Integer, DateHolder> result = new DefaultPrimaryKeyEncoder<Integer, DateHolder>();
+ DefaultPrimaryKeyEncoder<Integer, DateHolder> result =
+ new DefaultPrimaryKeyEncoder<Integer, DateHolder>(Integer.class);
for (DateHolder dh : getDateHolders())
{
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/FormInjectorDemo.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/FormInjectorDemo.java?rev=743195&r1=743194&r2=743195&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/FormInjectorDemo.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/FormInjectorDemo.java Wed Feb 11 02:22:17 2009
@@ -1,4 +1,4 @@
-// Copyright 2008 The Apache Software Foundation
+// Copyright 2008, 2009 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -68,6 +68,11 @@
{
return DB.get(key);
}
+
+ public Class<Long> getKeyType()
+ {
+ return Long.class;
+ }
};
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/GridFormEncoderDemo.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/GridFormEncoderDemo.java?rev=743195&r1=743194&r2=743195&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/GridFormEncoderDemo.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/GridFormEncoderDemo.java Wed Feb 11 02:22:17 2009
@@ -1,4 +1,4 @@
-// Copyright 2008 The Apache Software Foundation
+// Copyright 2008, 2009 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -14,11 +14,8 @@
package org.apache.tapestry5.integration.app1.pages;
-import org.apache.tapestry5.PrimaryKeyEncoder;
import org.apache.tapestry5.annotations.InjectComponent;
import org.apache.tapestry5.corelib.components.Grid;
-import org.apache.tapestry5.integration.app1.data.ToDoItem;
-import org.apache.tapestry5.util.DefaultPrimaryKeyEncoder;
public class GridFormEncoderDemo extends GridFormDemo
{
@@ -31,15 +28,4 @@
grid.getSortModel().updateSort("title");
}
- public PrimaryKeyEncoder<Long, ToDoItem> getEncoder()
- {
- DefaultPrimaryKeyEncoder<Long, ToDoItem> result = new DefaultPrimaryKeyEncoder<Long, ToDoItem>();
-
- for (ToDoItem item : getItems())
- {
- result.add(item.getId(), item);
- }
-
- return result;
- }
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/ToDoList.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/ToDoList.java?rev=743195&r1=743194&r2=743195&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/ToDoList.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/ToDoList.java Wed Feb 11 02:22:17 2009
@@ -1,4 +1,4 @@
-// Copyright 2007 The Apache Software Foundation
+// Copyright 2007, 2009 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -65,7 +65,7 @@
{
List<ToDoItem> items = database.findAll();
- encoder = new DefaultPrimaryKeyEncoder<Long, ToDoItem>();
+ encoder = new DefaultPrimaryKeyEncoder<Long, ToDoItem>(long.class);
for (ToDoItem item : items)
{
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/services/AppModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/services/AppModule.java?rev=743195&r1=743194&r2=743195&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/services/AppModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/services/AppModule.java Wed Feb 11 02:22:17 2009
@@ -16,6 +16,7 @@
import org.apache.tapestry5.SymbolConstants;
import org.apache.tapestry5.ValueEncoder;
+import org.apache.tapestry5.integration.app1.data.ToDoItem;
import org.apache.tapestry5.integration.app1.data.Track;
import org.apache.tapestry5.internal.services.GenericValueEncoderFactory;
import org.apache.tapestry5.ioc.Configuration;
@@ -206,9 +207,10 @@
}
public static void contributeValueEncoderSource(MappedConfiguration<Class, ValueEncoderFactory> configuration,
- final MusicLibrary library)
+ final MusicLibrary library,
+ final ToDoDatabase todoDatabase)
{
- ValueEncoder<Track> encoder = new ValueEncoder<Track>()
+ ValueEncoder<Track> trackEncoder = new ValueEncoder<Track>()
{
public String toClient(Track value)
{
@@ -224,7 +226,24 @@
};
- configuration.add(Track.class, GenericValueEncoderFactory.create(encoder));
+ configuration.add(Track.class, GenericValueEncoderFactory.create(trackEncoder));
+
+ ValueEncoder<ToDoItem> todoEncoder = new ValueEncoder<ToDoItem>()
+ {
+ public String toClient(ToDoItem value)
+ {
+ return String.valueOf(value.getId());
+ }
+
+ public ToDoItem toValue(String clientValue)
+ {
+ long id = Long.parseLong(clientValue);
+
+ return todoDatabase.get(id);
+ }
+ };
+
+ configuration.add(ToDoItem.class, GenericValueEncoderFactory.create(todoEncoder));
}
Added: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/util/PrimaryKeyEncoder2ValueEncoderTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/util/PrimaryKeyEncoder2ValueEncoderTest.java?rev=743195&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/util/PrimaryKeyEncoder2ValueEncoderTest.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/util/PrimaryKeyEncoder2ValueEncoderTest.java Wed Feb 11 02:22:17 2009
@@ -0,0 +1,125 @@
+// Copyright 2009 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.internal.util;
+
+import org.apache.tapestry5.PrimaryKeyEncoder;
+import org.apache.tapestry5.ValueEncoder;
+import org.apache.tapestry5.internal.test.InternalBaseTestCase;
+import org.apache.tapestry5.ioc.services.TypeCoercer;
+import org.apache.tapestry5.util.DefaultPrimaryKeyEncoder;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.io.Serializable;
+import java.util.List;
+
+public class PrimaryKeyEncoder2ValueEncoderTest extends InternalBaseTestCase
+{
+
+ private PrimaryKeyEncoder2ValueEncoder coercion;
+
+ @BeforeClass
+ public void setup()
+ {
+ TypeCoercer coercer = getService(TypeCoercer.class);
+
+ coercion = new PrimaryKeyEncoder2ValueEncoder(coercer);
+ }
+
+ @Test
+ public void key_type_is_known()
+ {
+ PrimaryKeyEncoder pke = newMock(PrimaryKeyEncoder.class);
+
+ Object value = new Object();
+ Long primaryKey = new Long(99);
+
+ expect(pke.getKeyType()).andReturn(Long.class);
+
+ expect(pke.toKey(value)).andReturn(primaryKey);
+
+ expect(pke.toValue(primaryKey)).andReturn(value);
+
+ replay();
+
+ ValueEncoder ve = coercion.coerce(pke);
+
+ assertEquals(ve.toClient(value), "99");
+ assertEquals(ve.toValue("99"), value);
+
+ verify();
+ }
+
+ @Test
+ public void unknown_key_type()
+ {
+ PrimaryKeyEncoder pke = new PrimaryKeyEncoder()
+ {
+ public Serializable toKey(Object value)
+ {
+ return null;
+ }
+
+ public void prepareForKeys(List keys)
+ {
+ }
+
+ public Object toValue(Serializable key)
+ {
+ return null;
+ }
+
+ public Class getKeyType()
+ {
+ return null;
+ }
+
+ @Override
+ public String toString()
+ {
+ return "<Dummy>";
+ }
+ };
+
+ try
+ {
+ coercion.coerce(pke);
+ unreachable();
+ }
+ catch (RuntimeException ex)
+ {
+ assertMessageContains(ex,
+ "Unable to extract primary key type from <Dummy>.",
+ "You should ensure that the getKeyType() method returns the correct Class.");
+ }
+ }
+
+ @Test
+ public void unknown_key_type_for_default_pke()
+ {
+ try
+ {
+ coercion.coerce(new DefaultPrimaryKeyEncoder());
+ unreachable();
+ }
+ catch (RuntimeException ex)
+ {
+ assertMessageContains(ex,
+ "Class DefaultPrimaryKeyEncoder now includes a constructor for specifying the key type.");
+ }
+ }
+
+
+}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/util/DefaultPrimaryKeyEncoderTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/util/DefaultPrimaryKeyEncoderTest.java?rev=743195&r1=743194&r2=743195&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/util/DefaultPrimaryKeyEncoderTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/util/DefaultPrimaryKeyEncoderTest.java Wed Feb 11 02:22:17 2009
@@ -1,4 +1,4 @@
-// Copyright 2007 The Apache Software Foundation
+// Copyright 2007, 2009 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -23,11 +23,12 @@
{
static class IntStringEncoder extends DefaultPrimaryKeyEncoder<Integer, String>
{
-
+ public IntStringEncoder()
+ {
+ super(Integer.class);
+ }
}
- ;
-
private final int FRED_ID = 1;
private final String FRED = "FRED";