You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by mi...@apache.org on 2005/07/04 23:31:39 UTC
cvs commit: jakarta-tapestry/framework/src/java/org/apache/tapestry/components ForBean.java For.jwc IPrimaryKeyConverter.java Else.jwc If.jwc Conditional.jwc IfBean.java
mindbridge 2005/07/04 14:31:39
Modified: framework/src/java/org/apache/tapestry/components Else.jwc
If.jwc Conditional.jwc IfBean.java
Added: framework/src/java/org/apache/tapestry/components
ForBean.java For.jwc IPrimaryKeyConverter.java
Log:
Adding the For component and improving If/Else somewhat
Revision Changes Path
1.4 +4 -12 jakarta-tapestry/framework/src/java/org/apache/tapestry/components/Else.jwc
Index: Else.jwc
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/components/Else.jwc,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- Else.jwc 24 Jun 2005 02:03:58 -0000 1.3
+++ Else.jwc 4 Jul 2005 21:31:38 -0000 1.4
@@ -15,10 +15,9 @@
limitations under the License.
-->
-<!DOCTYPE component-specification
- PUBLIC "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
- "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
-<!-- generated by Spindle, http://spindle.sourceforge.net -->
+<!DOCTYPE component-specification PUBLIC
+ "-//Apache Software Foundation//Tapestry Specification 4.0//EN"
+ "http://jakarta.apache.org/tapestry/dtd/Tapestry_4_0.dtd">
<component-specification class="org.apache.tapestry.components.ElseBean" allow-body="yes" allow-informal-parameters="yes">
@@ -27,17 +26,10 @@
if the condition of the previous If component evaluates to false.
</description>
- <parameter name="element" type="java.lang.String" direction="in" default-value="templateTag">
+ <parameter name="element" default-binding="literal">
<description>
The element to emulate.
</description>
</parameter>
- <parameter name="templateTag" type="java.lang.String" direction="auto" default-value="null">
- <description>
- The tag with which the component was inserted in its parent template.
- This parameter will be bound automatically by the framework.
- </description>
- </parameter>
-
</component-specification>
1.3 +8 -13 jakarta-tapestry/framework/src/java/org/apache/tapestry/components/If.jwc
Index: If.jwc
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/components/If.jwc,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- If.jwc 21 Jun 2005 22:31:37 -0000 1.2
+++ If.jwc 4 Jul 2005 21:31:38 -0000 1.3
@@ -26,37 +26,32 @@
if a condition is met.
</description>
- <parameter name="condition" required="yes">
+ <parameter name="condition" required="yes" default-binding="ognl">
<description>
The condition to evaluate.
</description>
</parameter>
- <parameter name="conditionValue">
+ <parameter name="conditionValue" default-binding="ognl">
<description>
The value of the condition. During render this is obtained from
the condition parameter. During rewind it is the submitted condition.
</description>
</parameter>
- <parameter name="listener"/>
+ <parameter name="listener" default-binding="listener"/>
- <parameter name="formless" default-value="false">
- <description>
- Determines whether to avoid creating hidden fields within a form.
- </description>
- </parameter>
-
- <parameter name="element" default-value="templateTag">
+ <parameter name="element" default-binding="literal">
<description>
The element to emulate.
</description>
</parameter>
- <parameter name="templateTag" default-value="null">
+ <parameter name="volatile" default-value="false" default-binding="ognl">
<description>
- The tag with which the component was inserted in its parent template
- This parameter will be bound automatically by the framework.
+ Only active in a form. Determines whether to avoid creating hidden fields within a form.
+ Using this parameter may make the form structure different during render and rewind,
+ and cause exceptions as a result. Please use with caution.
</description>
</parameter>
1.6 +1 -1 jakarta-tapestry/framework/src/java/org/apache/tapestry/components/Conditional.jwc
Index: Conditional.jwc
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/components/Conditional.jwc,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- Conditional.jwc 18 Apr 2005 17:06:36 -0000 1.5
+++ Conditional.jwc 4 Jul 2005 21:31:38 -0000 1.6
@@ -19,7 +19,7 @@
"-//Apache Software Foundation//Tapestry Specification 4.0//EN"
"http://jakarta.apache.org/tapestry/dtd/Tapestry_4_0.dtd">
-<component-specification class="org.apache.tapestry.components.Conditional">
+<component-specification class="org.apache.tapestry.components.Conditional" deprecated="yes">
<description>
Conditionally emulates an element and its attributes (if element is specified) and/or includes a block of content if a condition is met.
</description>
1.4 +2 -2 jakarta-tapestry/framework/src/java/org/apache/tapestry/components/IfBean.java
Index: IfBean.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/components/IfBean.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- IfBean.java 25 Jun 2005 04:53:50 -0000 1.3
+++ IfBean.java 4 Jul 2005 21:31:38 -0000 1.4
@@ -38,7 +38,7 @@
public abstract IBinding getConditionValueBinding();
public abstract boolean getCondition();
- public abstract boolean getFormless();
+ public abstract boolean getVolatile();
public abstract String getElement();
public abstract IActionListener getListener();
@@ -97,7 +97,7 @@
{
boolean condition;
- if (form == null || getFormless()) {
+ if (form == null || getVolatile()) {
condition = getCondition();
}
else {
1.1 jakarta-tapestry/framework/src/java/org/apache/tapestry/components/ForBean.java
Index: ForBean.java
===================================================================
// Copyright 2004, 2005 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.apache.tapestry.components;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.hivemind.ApplicationRuntimeException;
import org.apache.tapestry.IBinding;
import org.apache.tapestry.IForm;
import org.apache.tapestry.IMarkupWriter;
import org.apache.tapestry.IRequestCycle;
import org.apache.tapestry.Tapestry;
import org.apache.tapestry.TapestryUtils;
import org.apache.tapestry.coerce.ValueConverter;
import org.apache.tapestry.form.AbstractFormComponent;
import org.apache.tapestry.services.DataSqueezer;
import org.apache.tapestry.services.ExpressionEvaluator;
/**
* @author mb
*/
public abstract class ForBean extends AbstractFormComponent {
private static final char DESC_VALUE = 'V';
private static final char DESC_PRIMARY_KEY = 'P';
// parameters
public abstract Object getSource();
public abstract Object getFullSource();
public abstract String getElement();
public abstract boolean getVolatile();
public abstract Object getDefaultValue();
public abstract String getPrimaryKey();
public abstract IPrimaryKeyConverter getConverter();
public abstract String getKeyExpression();
// properties
public abstract Map getPrimaryKeyMap();
public abstract void setPrimaryKeyMap(Map primaryKeys);
// injects
public abstract DataSqueezer getDataSqueezer();
public abstract ValueConverter getValueConverter();
public abstract ExpressionEvaluator getExpressionEvaluator();
private Object _value;
private int _index;
private boolean _rendering;
/**
* Gets the source binding and returns an {@link Iterator}
* representing
* the values identified by the source. Returns an empty {@link Iterator}
* if the binding, or the binding value, is null.
*
* <p>Invokes {@link Tapestry#coerceToIterator(Object)} to perform
* the actual conversion.
*
**/
protected Iterator getSourceData()
{
Object source = getSource();
if (source == null)
return null;
Iterator iteratorSource = (Iterator) getValueConverter().coerceValue(source, Iterator.class);
return iteratorSource;
}
protected Iterator storeSourceData(IForm form, String name)
{
Iterator iteratorSource = getSourceData();
if (iteratorSource == null)
return null;
// extract primary keys from data
StringBuffer pkDesc = new StringBuffer();
List data = new ArrayList();
List pks = new ArrayList();
while (iteratorSource.hasNext()) {
Object value = iteratorSource.next();
data.add(value);
Object pk = getPrimaryKeyFromValue(value);
if (pk == null) {
pk = value;
pkDesc.append(DESC_VALUE);
}
else
pkDesc.append(DESC_PRIMARY_KEY);
pks.add(pk);
}
// store primary keys
form.addHiddenValue(name, pkDesc.toString());
for (Iterator it = pks.iterator(); it.hasNext();) {
Object pk = it.next();
try {
String stringRep = getDataSqueezer().squeeze(pk);
form.addHiddenValue(name, stringRep);
} catch (IOException ex) {
throw new ApplicationRuntimeException(
Tapestry.format("For.unable-to-convert-value", pk),
this,
null,
ex);
}
}
return data.iterator();
}
protected Iterator getStoredData(IRequestCycle cycle, String name)
{
String[] submittedPrimaryKeys = cycle.getParameters(name);
String pkDesc = submittedPrimaryKeys[0];
// unsqueeze data
List data = new ArrayList(submittedPrimaryKeys.length-1);
List pks = new ArrayList(submittedPrimaryKeys.length-1);
for (int i = 1; i < submittedPrimaryKeys.length; i++) {
String stringRep = submittedPrimaryKeys[i];
try {
Object value = getDataSqueezer().unsqueeze(stringRep);
data.add(value);
if (i <= pkDesc.length() && pkDesc.charAt(i-1) == DESC_PRIMARY_KEY)
pks.add(value);
} catch (IOException ex) {
throw new ApplicationRuntimeException(
Tapestry.format("For.unable-to-convert-string", stringRep),
this,
null,
ex);
}
}
// update the binding with the list of primary keys
IBinding primaryKeysBinding = getBinding("primaryKeys");
if (primaryKeysBinding != null)
primaryKeysBinding.setObject(pks);
// convert from primary keys to data
for (int i = 0; i < data.size(); i++) {
if (i <= pkDesc.length() && pkDesc.charAt(i) == DESC_PRIMARY_KEY) {
Object pk = data.get(i);
Object value = getValueFromPrimaryKey(pk);
data.set(i, value);
}
}
return data.iterator();
}
/**
* Gets the source binding and iterates through
* its values. For each, it updates the value binding and render's its wrapped elements.
*
**/
protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle)
{
// form may be null if component is not located in a form
IForm form = (IForm) cycle.getAttribute(TapestryUtils.FORM_ATTRIBUTE);
// If the cycle is rewinding, but not this particular form,
// then do nothing (don't even render the body).
boolean cycleRewinding = cycle.isRewinding();
if (cycleRewinding && form != null && !form.isRewinding())
return;
boolean bInForm = (form != null && !getVolatile());
String name = "";
if (form != null)
name = form.getElementId(this);
// Get the data to be iterated upon. Store in form if needed.
Iterator dataSource;
if (!bInForm)
dataSource = getSourceData();
else if (cycleRewinding)
dataSource = getStoredData(cycle, name);
else
dataSource = storeSourceData(form, name);
// Do not iterate if dataSource is null.
// The dataSource was either not convertable to Iterator, or was empty.
if (dataSource == null)
return;
String element = getElement();
// Perform the iterations
try
{
_index = 0;
_rendering = true;
while (dataSource.hasNext())
{
// Get current value
_value = dataSource.next();
// Update output component parameters
IBinding indexBinding = getBinding("index");
if (indexBinding != null)
indexBinding.setObject(new Integer(_index));
IBinding valueBinding = getBinding("value");
if (valueBinding != null)
valueBinding.setObject(_value);
// Render component
if (element != null)
{
writer.begin(element);
renderInformalParameters(writer, cycle);
}
renderBody(writer, cycle);
if (element != null)
writer.end();
_index++;
}
}
finally
{
_rendering = false;
_value = null;
}
}
private Object restoreValue(IForm form, String name, Object primaryKey)
{
return getValueFromPrimaryKey(primaryKey);
}
private void storeValue(IForm form, String name, Object value)
{
Object convertedValue = getPrimaryKeyFromValue(value);
try
{
String externalValue = getDataSqueezer().squeeze(convertedValue);
form.addHiddenValue(name, externalValue);
}
catch (IOException ex)
{
throw new ApplicationRuntimeException(
Tapestry.format("For.unable-to-convert-value", value),
this,
null,
ex);
}
}
private Object getPrimaryKeyFromValue(Object value) {
Object primaryKey = null;
String keyExpression = getKeyExpression();
if (keyExpression != null)
primaryKey = getExpressionEvaluator().read(value, keyExpression);
if (primaryKey == null) {
IPrimaryKeyConverter converter = getConverter();
if (converter != null)
primaryKey = converter.getPrimaryKey(value);
}
return primaryKey;
}
private Object getValueFromPrimaryKey(Object primaryKey) {
Object value = null;
if (value == null && getKeyExpression() != null) {
String keyExpression = getKeyExpression();
if (keyExpression != null) {
Map primaryKeys = getPrimaryKeyMap();
if (primaryKeys == null)
primaryKeys = initializePrimaryKeysFromSource(keyExpression);
value = primaryKeys.get(primaryKeys);
}
}
if (value == null) {
IPrimaryKeyConverter converter = getConverter();
if (converter != null)
value = converter.getValue(primaryKey);
}
if (value == null)
value = getDefaultValue();
return value;
}
private Map initializePrimaryKeysFromSource(String keyExpression)
{
Map primaryKeys = new HashMap();
Object fullSource = getFullSource();
if (fullSource == null)
fullSource = getSource();
if (fullSource == null)
return primaryKeys;
ExpressionEvaluator evaluator = getExpressionEvaluator();
Iterator iteratorSource = (Iterator) getValueConverter().coerceValue(fullSource, Iterator.class);
while (iteratorSource.hasNext()) {
Object value = iteratorSource.next();
Object primaryKey = evaluator.read(value, keyExpression);
if (primaryKey != null)
primaryKeys.put(primaryKey, value);
}
setPrimaryKeyMap(primaryKeys);
return primaryKeys;
}
/**
* Returns the most recent value extracted from the source parameter.
*
* @throws org.apache.tapestry.ApplicationRuntimeException if the Foreach is not currently rendering.
*
**/
public final Object getValue()
{
if (!_rendering)
throw Tapestry.createRenderOnlyPropertyException(this, "value");
return _value;
}
/**
* The index number, within the {@link #getSource() source}, of the
* the current value.
*
* @throws org.apache.tapestry.ApplicationRuntimeException if the Foreach is not currently rendering.
*
* @since 2.2
*
**/
public int getIndex()
{
if (!_rendering)
throw Tapestry.createRenderOnlyPropertyException(this, "index");
return _index;
}
public boolean isDisabled()
{
return false;
}
// Do nothing in those methods, but make the JVM happy
protected void renderFormComponent(IMarkupWriter writer, IRequestCycle cycle) { }
protected void rewindFormComponent(IMarkupWriter writer, IRequestCycle cycle) { }
}
1.1 jakarta-tapestry/framework/src/java/org/apache/tapestry/components/For.jwc
Index: For.jwc
===================================================================
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright 2005 The Apache Software Foundation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!DOCTYPE component-specification PUBLIC
"-//Apache Software Foundation//Tapestry Specification 4.0//EN"
"http://jakarta.apache.org/tapestry/dtd/Tapestry_4_0.dtd">
<component-specification class="org.apache.tapestry.components.ForBean" allow-body="yes" allow-informal-parameters="yes">
<description>
Loops over a collection of source values. May also emulate an element (like an Any
component). If this component is placed in a Form, it will automatically store
the collection in Hidden fields so that the structure of the page is preserved
during a rewind even if the values in the source change.
</description>
<parameter name="source" required="yes" default-binding="ognl">
<description>
The source of values, a Java collection or array.
</description>
</parameter>
<parameter name="value" property="valueParameter" default-binding="ognl">
<description>
If provided, the parameter is updated with the current value on each iteration.
</description>
</parameter>
<parameter name="index" property="indexParameter" default-binding="ognl">
<description>
If provided, the parameter is updated with the index of the loop on each iteration.
</description>
</parameter>
<parameter name="element" default-binding="literal">
<description>
If provided, the component wraps its content with the requested element.
Informal parameters become attributes of that element.
</description>
</parameter>
<parameter name="keyExpression" default-binding="literal">
<description>
Only active in a form. An OGNL expression that returns the primary key of the iterated value.
The primary keys are stored in hidden fields during rendering and are loaded from the form
during a rewind to ensure that the iterations remain the same.
This is a simpler, but a less efficient alternative of the 'converter' parameter.
If needed, please use in conjuction with 'fullSource' to reference objects
not currently present in 'source'.
Also, use the 'defaultValue' parameter to define the object to be returned if
a value corresponding to a particular primary key cannot be found.
</description>
</parameter>
<parameter name="fullSource" default-binding="ognl">
<description>
Only active in a form and in combination with the 'keyExpression' parameter.
The objects provided by this parameter will be used to determine the values
referred to by the primary keys stored in the form.
If this parameter is not bound, 'source' is used instead.
</description>
</parameter>
<parameter name="defaultValue" default-value="null" default-binding="ognl">
<description>
Only active in a form. The value to be used when no match for a given primary key is found.
</description>
</parameter>
<parameter name="converter" default-value="null" default-binding="ognl">
<description>
Only active in a form. Defines how the items iterated upon
will be stored in the form as hidden values and how the stored information will be
converted back to objects.
This interface allows only the primary key of the items to be stored,
rather than the whole item.
</description>
</parameter>
<parameter name="primaryKeys" default-binding="ognl">
<description>
Only active in a form. If provided, the parameter is automatically updated
before a rewind with the list of primary keys stored in the form.
The parameter is updated right before the iterations begin in a rewind and
could be used to preload the relevant objects in a provided 'converter'.
</description>
</parameter>
<parameter name="volatile" default-value="false" default-binding="ognl">
<description>
Only active in a form. Determines whether to avoid creating hidden fields within a form.
Using this parameter may make the form structure different during render and rewind,
and cause exceptions as a result. Please use with caution.
</description>
</parameter>
<inject property="dataSqueezer" object="service:tapestry.data.DataSqueezer"/>
<inject property="valueConverter" object="service:tapestry.coerce.ValueConverter"/>
<inject property="expressionEvaluator" object="service:tapestry.ognl.ExpressionEvaluator"/>
</component-specification>
1.1 jakarta-tapestry/framework/src/java/org/apache/tapestry/components/IPrimaryKeyConverter.java
Index: IPrimaryKeyConverter.java
===================================================================
// Copyright 2004, 2005 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.apache.tapestry.components;
/**
* An interface for converting an objects to their primary keys and back.
* Typically used to determine how to store a given object as a hidden
* value when rendering a form.
*
* @author mb
* @since 4.0
*/
public interface IPrimaryKeyConverter
{
/**
* Returns the primary key of the given value
*
* @param objValue the value for which a primary key needs to be extracted
* @return the primary key of the value
*/
Object getPrimaryKey(Object value);
/**
* Returns the value corresponding the given primary key
*
* @param objPrimaryKey the primary key for which a value needs to be generated
* @return the generated value corresponding to the given primary key
*/
Object getValue(Object primaryKey);
}
---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-dev-help@jakarta.apache.org