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 2013/08/17 02:49:11 UTC
git commit: TAP5-1446: Coercion from List to SelectModel should use
the SelectModelFactory service
Updated Branches:
refs/heads/master e16e5fb50 -> cc5c53df4
TAP5-1446: Coercion from List to SelectModel should use the SelectModelFactory service
Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo
Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/cc5c53df
Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/cc5c53df
Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/cc5c53df
Branch: refs/heads/master
Commit: cc5c53df446417924a2ce79151c62192c9645453
Parents: e16e5fb
Author: Howard M. Lewis Ship <hl...@apache.org>
Authored: Fri Aug 16 17:49:05 2013 -0700
Committer: Howard M. Lewis Ship <hl...@apache.org>
Committed: Fri Aug 16 17:49:05 2013 -0700
----------------------------------------------------------------------
.../internal/DefaultValueLabelProvider.java | 39 +++++++++++++
.../services/EnumValueLabelProvider.java | 41 ++++++++++++++
.../services/PropertyValueLabelProvider.java | 58 ++++++++++++++++++++
.../services/SelectModelFactoryImpl.java | 47 +++++++++-------
.../tapestry5/modules/TapestryModule.java | 38 +++++++++++--
.../tapestry5/services/SelectModelFactory.java | 21 +++++--
.../tapestry5/services/ValueLabelProvider.java | 33 +++++++++++
.../src/test/app1/SelectModelCoercionDemo.tml | 20 +++++++
.../test/app1/SelectModelFromObjectsDemo.tml | 20 +++++++
tapestry-core/src/test/app1/css/app.css | 3 -
.../tapestry5/integration/app1/FormTests.java | 24 ++++++++
.../tapestry5/integration/app1/pages/Index.java | 6 ++
.../app1/pages/SelectModelCoercionDemo.java | 25 +++++++++
.../app1/pages/SelectModelFromObjectsDemo.java | 32 +++++++++++
.../integration/app1/services/AppModule.java | 12 +++-
.../integration/app1/components/Border.tml | 2 +-
16 files changed, 385 insertions(+), 36 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/cc5c53df/tapestry-core/src/main/java/org/apache/tapestry5/internal/DefaultValueLabelProvider.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/DefaultValueLabelProvider.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/DefaultValueLabelProvider.java
new file mode 100644
index 0000000..12309ac
--- /dev/null
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/DefaultValueLabelProvider.java
@@ -0,0 +1,39 @@
+// Copyright 2013 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;
+
+import org.apache.tapestry5.ioc.services.TypeCoercer;
+import org.apache.tapestry5.services.ValueLabelProvider;
+
+/**
+ * Uses the {@link TypeCoercer} to convert an arbitrary value to a string.
+ *
+ * @since 5.4
+ */
+public class DefaultValueLabelProvider implements ValueLabelProvider<Object>
+{
+ private final TypeCoercer coercer;
+
+ public DefaultValueLabelProvider(TypeCoercer coercer)
+ {
+ this.coercer = coercer;
+ }
+
+ public String getLabel(Object value)
+ {
+ return coercer.coerce(value, String.class);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/cc5c53df/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/EnumValueLabelProvider.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/EnumValueLabelProvider.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/EnumValueLabelProvider.java
new file mode 100644
index 0000000..ff64ae6
--- /dev/null
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/EnumValueLabelProvider.java
@@ -0,0 +1,41 @@
+// Copyright 2013 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.services;
+
+import org.apache.tapestry5.internal.TapestryInternalUtils;
+import org.apache.tapestry5.ioc.Messages;
+import org.apache.tapestry5.services.ValueLabelProvider;
+
+/**
+ * Provides a label from enum.
+ *
+ * @since 5.4
+ */
+public class EnumValueLabelProvider<T extends Enum> implements ValueLabelProvider<T>
+{
+ private final Messages messages;
+
+ public EnumValueLabelProvider(Messages messages)
+ {
+ this.messages = messages;
+ }
+
+ public String getLabel(T value)
+ {
+ return TapestryInternalUtils.getLabelForEnum(messages, value.getDeclaringClass()
+ .getSimpleName(), value);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/cc5c53df/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PropertyValueLabelProvider.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PropertyValueLabelProvider.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PropertyValueLabelProvider.java
new file mode 100644
index 0000000..f296d25
--- /dev/null
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PropertyValueLabelProvider.java
@@ -0,0 +1,58 @@
+// Copyright 2013 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.services;
+
+import org.apache.tapestry5.ValueEncoder;
+import org.apache.tapestry5.ioc.services.ClassPropertyAdapter;
+import org.apache.tapestry5.ioc.services.PropertyAccess;
+import org.apache.tapestry5.ioc.services.PropertyAdapter;
+import org.apache.tapestry5.services.ValueEncoderSource;
+import org.apache.tapestry5.services.ValueLabelProvider;
+
+/**
+ * Provides a label from a property of the passed object.
+ *
+ * @since 5.4
+ */
+public class PropertyValueLabelProvider implements ValueLabelProvider<Object>
+{
+ private final PropertyAccess propertyAccess;
+ private final ValueEncoderSource valueEncoderSource;
+ private final String labelProperty;
+
+ public PropertyValueLabelProvider(ValueEncoderSource valueEncoderSource,
+ PropertyAccess propertyAccess, String labelProperty)
+ {
+ this.valueEncoderSource = valueEncoderSource;
+ this.propertyAccess = propertyAccess;
+ this.labelProperty = labelProperty;
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public String getLabel(Object object)
+ {
+ final ClassPropertyAdapter classPropertyAdapter = this.propertyAccess.getAdapter(object);
+
+ final PropertyAdapter propertyAdapter = classPropertyAdapter
+ .getPropertyAdapter(labelProperty);
+
+ final ValueEncoder encoder = this.valueEncoderSource.getValueEncoder(propertyAdapter
+ .getType());
+
+ final Object label = propertyAdapter.get(object);
+
+ return encoder.toClient(label);
+ }
+}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/cc5c53df/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/SelectModelFactoryImpl.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/SelectModelFactoryImpl.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/SelectModelFactoryImpl.java
index 4cee478..c5c1aee 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/SelectModelFactoryImpl.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/SelectModelFactoryImpl.java
@@ -1,4 +1,4 @@
-// Copyright 2010 The Apache Software Foundation
+// Copyright 2010-2013 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.
@@ -13,51 +13,56 @@
// limitations under the License.
package org.apache.tapestry5.internal.services;
-import java.util.List;
-
import org.apache.tapestry5.OptionModel;
import org.apache.tapestry5.SelectModel;
-import org.apache.tapestry5.ValueEncoder;
import org.apache.tapestry5.internal.OptionModelImpl;
import org.apache.tapestry5.internal.SelectModelImpl;
import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
-import org.apache.tapestry5.ioc.services.ClassPropertyAdapter;
import org.apache.tapestry5.ioc.services.PropertyAccess;
-import org.apache.tapestry5.ioc.services.PropertyAdapter;
import org.apache.tapestry5.services.SelectModelFactory;
import org.apache.tapestry5.services.ValueEncoderSource;
+import org.apache.tapestry5.services.ValueLabelProvider;
+
+import java.util.List;
public class SelectModelFactoryImpl implements SelectModelFactory
{
private final PropertyAccess propertyAccess;
+
private final ValueEncoderSource valueEncoderSource;
- public SelectModelFactoryImpl(final PropertyAccess propertyAccess,
- final ValueEncoderSource valueEncoderSource)
+ private final ValueLabelProvider<Object> valueLabelProvider;
+
+ public SelectModelFactoryImpl(PropertyAccess propertyAccess, ValueEncoderSource valueEncoderSource, ValueLabelProvider<Object> valueLabelProvider)
{
- super();
this.propertyAccess = propertyAccess;
this.valueEncoderSource = valueEncoderSource;
+ this.valueLabelProvider = valueLabelProvider;
}
- @SuppressWarnings("unchecked")
- public SelectModel create(final List<?> objects, final String labelProperty)
- {
- final List<OptionModel> options = CollectionFactory.newList();
- for (final Object object : objects)
- {
- final ClassPropertyAdapter classPropertyAdapter = this.propertyAccess
- .getAdapter(object);
+ public SelectModel create(List<?> objects, String labelProperty)
+ {
+ PropertyValueLabelProvider propertyValueLabelProvider = new PropertyValueLabelProvider(
+ valueEncoderSource, propertyAccess, labelProperty);
- final PropertyAdapter propertyAdapter = classPropertyAdapter.getPropertyAdapter(labelProperty);
+ return createSelectModel(objects, propertyValueLabelProvider);
+ }
- final ValueEncoder encoder = this.valueEncoderSource.getValueEncoder(propertyAdapter.getType());
+ public SelectModel create(List<?> objects)
+ {
+ return createSelectModel(objects, valueLabelProvider);
+ }
- final Object label = propertyAdapter.get(object);
+ private SelectModel createSelectModel(List<?> objects, ValueLabelProvider<Object> labelProvider)
+ {
+ final List<OptionModel> options = CollectionFactory.newList();
- options.add(new OptionModelImpl(encoder.toClient(label), object));
+ for (Object object : objects)
+ {
+ String label = labelProvider.getLabel(object);
+ options.add(new OptionModelImpl(label, object));
}
return new SelectModelImpl(null, options);
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/cc5c53df/tapestry-core/src/main/java/org/apache/tapestry5/modules/TapestryModule.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/modules/TapestryModule.java b/tapestry-core/src/main/java/org/apache/tapestry5/modules/TapestryModule.java
index 17ddbeb..8b7b969 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/modules/TapestryModule.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/modules/TapestryModule.java
@@ -921,8 +921,7 @@ public final class TapestryModule
*/
public static void contributeTypeCoercer(Configuration<CoercionTuple> configuration,
- @Builtin
- TypeCoercer coercer,
+ final ObjectLocator objectLocator,
@Builtin
final ThreadLocale threadLocale,
@@ -980,10 +979,19 @@ public final class TapestryModule
configuration.add(CoercionTuple.create(List.class, SelectModel.class, new Coercion<List, SelectModel>()
{
+ private SelectModelFactory selectModelFactory;
+
@SuppressWarnings("unchecked")
public SelectModel coerce(List input)
{
- return TapestryInternalUtils.toSelectModel(input);
+ // This doesn't look thread safe, but it is because its a one-time transition from null
+ // to another value, and a race condition is harmless.
+ if (selectModelFactory == null)
+ {
+ selectModelFactory = objectLocator.getService(SelectModelFactory.class);
+ }
+
+ return selectModelFactory.create(input);
}
}));
@@ -2086,8 +2094,8 @@ public final class TapestryModule
configuration.add(SymbolConstants.SESSION_LOCKING_ENABLED, true);
- // TAP5-2070 keep the old behavior, defaults to false
- configuration.add(MetaDataConstants.UNKNOWN_ACTIVATION_CONTEXT_CHECK, false);
+ // TAP5-2070 keep the old behavior, defaults to false
+ configuration.add(MetaDataConstants.UNKNOWN_ACTIVATION_CONTEXT_CHECK, false);
}
@@ -2469,7 +2477,7 @@ public final class TapestryModule
configuration.add(Secure.class, new FixedExtractor(MetaDataConstants.SECURE_PAGE));
configuration.addInstance(ContentType.class, ContentTypeExtractor.class);
configuration.add(WhitelistAccessOnly.class, new FixedExtractor(MetaDataConstants.WHITELIST_ONLY_PAGE));
- configuration.addInstance(UnknownActivationContextCheck.class, UnknownActivationContextExtractor.class);
+ configuration.addInstance(UnknownActivationContextCheck.class, UnknownActivationContextExtractor.class);
}
/**
@@ -2593,4 +2601,22 @@ public final class TapestryModule
}
});
}
+
+ /**
+ * @since 5.4
+ */
+ @Contribute(ValueLabelProvider.class)
+ public void defaultValueLabelProviders(MappedConfiguration<Class, ValueLabelProvider> configuration)
+ {
+ configuration.addInstance(Object.class, DefaultValueLabelProvider.class);
+ configuration.addInstance(Enum.class, EnumValueLabelProvider.class);
+ }
+
+ /**
+ * @since 5.4
+ */
+ public ValueLabelProvider<?> buildValueLabelProvider(Map<Class, ValueLabelProvider> configuration)
+ {
+ return strategyBuilder.build(ValueLabelProvider.class, configuration);
+ }
}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/cc5c53df/tapestry-core/src/main/java/org/apache/tapestry5/services/SelectModelFactory.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/services/SelectModelFactory.java b/tapestry-core/src/main/java/org/apache/tapestry5/services/SelectModelFactory.java
index 8307b3a..c324e87 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/services/SelectModelFactory.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/services/SelectModelFactory.java
@@ -1,4 +1,4 @@
-// Copyright 2010 The Apache Software Foundation
+// Copyright 2010-2013 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.
@@ -13,17 +13,17 @@
// limitations under the License.
package org.apache.tapestry5.services;
-import java.util.List;
-
import org.apache.tapestry5.SelectModel;
+import java.util.List;
+
/**
* Used to create an {@link org.apache.tapestry5.SelectModel}.
*
* @since 5.2.0
*/
public interface SelectModelFactory
-{
+{
/**
* Creates a {@link org.apache.tapestry5.SelectModel} from a list of objects of the same type and a label property name.
* The returned model creates for every object in the list a selectable option and relies on existing
@@ -34,4 +34,17 @@ public interface SelectModelFactory
* @return the model
*/
public SelectModel create(List<?> objects, String labelProperty);
+
+ /**
+ * Creates a {@link org.apache.tapestry5.SelectModel} from a list of objects of the same type.
+ *
+ * The returned model creates for every object in the list a selectable option and relies on existing
+ * {@link org.apache.tapestry5.ValueEncoder} for the object type.
+ *
+ * @param objects objects to create model from
+ * @return the model
+ *
+ * @since 5.4
+ */
+ public SelectModel create(List<?> objects);
}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/cc5c53df/tapestry-core/src/main/java/org/apache/tapestry5/services/ValueLabelProvider.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/services/ValueLabelProvider.java b/tapestry-core/src/main/java/org/apache/tapestry5/services/ValueLabelProvider.java
new file mode 100644
index 0000000..4f96bb3
--- /dev/null
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/services/ValueLabelProvider.java
@@ -0,0 +1,33 @@
+// Copyright 2013 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.services;
+
+/**
+ * An object capable of providing a user-presentable label from a value. A special case exists for
+ * {@linkplain org.apache.tapestry5.internal.services.EnumValueLabelProvider handling enum types}.
+ *
+ * @since 5.4
+ */
+public interface ValueLabelProvider<V>
+{
+
+ /**
+ * Gets label from the value. The label is used as user-presentable label for a value.
+ * @param value the value to be label provided from
+ * @return
+ */
+ public String getLabel(V value);
+
+}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/cc5c53df/tapestry-core/src/test/app1/SelectModelCoercionDemo.tml
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/app1/SelectModelCoercionDemo.tml b/tapestry-core/src/test/app1/SelectModelCoercionDemo.tml
new file mode 100644
index 0000000..39a864d
--- /dev/null
+++ b/tapestry-core/src/test/app1/SelectModelCoercionDemo.tml
@@ -0,0 +1,20 @@
+<t:border xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd">
+ <t:form clientValidation="NONE">
+ <p>
+ <t:errors />
+ </p>
+ <p>
+ <t:select t:id="track" model="tracks" />
+
+ </p>
+
+ <p>
+ <t:submit value="literal:Submit" />
+ </p>
+ </t:form>
+
+ <t:if test="track">
+ <p> Selected track: ${track.title}, ${track.album}</p>
+ </t:if>
+
+</t:border>
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/cc5c53df/tapestry-core/src/test/app1/SelectModelFromObjectsDemo.tml
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/app1/SelectModelFromObjectsDemo.tml b/tapestry-core/src/test/app1/SelectModelFromObjectsDemo.tml
new file mode 100644
index 0000000..9694067
--- /dev/null
+++ b/tapestry-core/src/test/app1/SelectModelFromObjectsDemo.tml
@@ -0,0 +1,20 @@
+<t:border xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd">
+ <t:form clientValidation="NONE">
+ <p>
+ <t:errors />
+ </p>
+ <p>
+ <t:select t:id="track" model="model" />
+
+ </p>
+
+ <p>
+ <t:submit value="literal:Submit" />
+ </p>
+ </t:form>
+
+ <t:if test="track">
+ <p> Selected track: ${track.title}, ${track.album}</p>
+ </t:if>
+
+</t:border>
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/cc5c53df/tapestry-core/src/test/app1/css/app.css
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/app1/css/app.css b/tapestry-core/src/test/app1/css/app.css
index 84fdd9f..af23567 100644
--- a/tapestry-core/src/test/app1/css/app.css
+++ b/tapestry-core/src/test/app1/css/app.css
@@ -1,6 +1,3 @@
-BODY {
- padding-top: 60px;
-}
SPAN.inherit {
font-style: italic;
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/cc5c53df/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/FormTests.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/FormTests.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/FormTests.java
index 24558d2..6c4bd07 100644
--- a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/FormTests.java
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/FormTests.java
@@ -1048,6 +1048,30 @@ public class FormTests extends TapestryCoreTestCase
}
@Test
+ public void create_select_model_from_objects() throws Exception
+ {
+ openLinks("SelectModel from objects");
+
+ select("track", "label=The Calling");
+
+ clickAndWait(SUBMIT);
+
+ assertTextPresent("Selected track: The Calling, Synaesthetic");
+ }
+
+ @Test
+ public void create_select_model_coercion() throws Exception
+ {
+ openLinks("SelectModel coercion");
+
+ select("track", "label=The Calling");
+
+ clickAndWait(SUBMIT);
+
+ assertTextPresent("Selected track: The Calling, Synaesthetic");
+ }
+
+ @Test
public void validation_macro() throws Exception
{
openLinks("Validator Macro Demo");
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/cc5c53df/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java
index d5cd730..af510b6 100644
--- a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java
@@ -489,6 +489,12 @@ public class Index
new Item("SelectModelFromObjectsAndPropertyNameDemo", "SelectModel from objects and property name",
"Creating a SelectModel from a list of objects and a label property name"),
+
+ new Item("SelectModelFromObjectsDemo", "SelectModel from objects",
+ "Creating a SelectModel from a list of objects"),
+
+ new Item("SelectModelCoercionDemo", "SelectModel coercion",
+ "Creating a SelectModel from a list of objects using coercion"),
new Item("DecoratePageRenderLinkDemo", "Decorate Page Render Link Demo",
"Decorating page render links"),
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/cc5c53df/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/SelectModelCoercionDemo.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/SelectModelCoercionDemo.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/SelectModelCoercionDemo.java
new file mode 100644
index 0000000..131b186
--- /dev/null
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/SelectModelCoercionDemo.java
@@ -0,0 +1,25 @@
+package org.apache.tapestry5.integration.app1.pages;
+
+import org.apache.tapestry5.annotations.Persist;
+import org.apache.tapestry5.annotations.Property;
+import org.apache.tapestry5.integration.app1.data.Track;
+import org.apache.tapestry5.integration.app1.services.MusicLibrary;
+import org.apache.tapestry5.ioc.annotations.Inject;
+
+import java.util.List;
+
+public class SelectModelCoercionDemo
+{
+ @Inject
+ private MusicLibrary library;
+
+ @Property
+ @Persist
+ private Track track;
+
+ public List<Track> getTracks(){
+ return library.getTracks();
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/cc5c53df/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/SelectModelFromObjectsDemo.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/SelectModelFromObjectsDemo.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/SelectModelFromObjectsDemo.java
new file mode 100644
index 0000000..ba64455
--- /dev/null
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/SelectModelFromObjectsDemo.java
@@ -0,0 +1,32 @@
+package org.apache.tapestry5.integration.app1.pages;
+
+import org.apache.tapestry5.SelectModel;
+import org.apache.tapestry5.annotations.Persist;
+import org.apache.tapestry5.annotations.Property;
+import org.apache.tapestry5.integration.app1.data.Track;
+import org.apache.tapestry5.integration.app1.services.MusicLibrary;
+import org.apache.tapestry5.ioc.annotations.Inject;
+import org.apache.tapestry5.services.SelectModelFactory;
+
+public class SelectModelFromObjectsDemo
+{
+ @Inject
+ private MusicLibrary library;
+
+ @Inject
+ private SelectModelFactory modelFactory;
+
+ @Property
+ private SelectModel model;
+
+ @Property
+ @Persist
+ private Track track;
+
+ void onPrepare()
+ {
+ model = modelFactory.create(library.getTracks());
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/cc5c53df/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/services/AppModule.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/services/AppModule.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/services/AppModule.java
index 7a2c812..f095270 100644
--- a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/services/AppModule.java
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/services/AppModule.java
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007, 2008, 2009, 2010, 2011 The Apache Software Foundation
+// Copyright 2006-2013 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.
@@ -287,6 +287,16 @@ public class AppModule
{
configuration.add("properties");
}
+
+ public void contributeValueLabelProvider(MappedConfiguration<Class, ValueLabelProvider> configuration)
+ {
+ configuration.add(Track.class, new ValueLabelProvider<Track>() {
+
+ public String getLabel(Track value) {
+ return value.getTitle();
+ }
+ });
+ }
@Contribute(ComponentClassResolver.class)
public static void setupAlphaLibrary(Configuration<LibraryMapping> configuration)
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/cc5c53df/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/components/Border.tml
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/components/Border.tml b/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/components/Border.tml
index af75055..9e8d76c 100644
--- a/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/components/Border.tml
+++ b/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/components/Border.tml
@@ -6,7 +6,7 @@
<body data-floating-console="true">
-<div class="navbar navbar-inverse navbar-fixed-top">
+<div class="navbar navbar-inverse navbar-static-top">
<div class="navbar-inner">
<div class="container">