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";