You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2008/01/21 02:02:20 UTC
svn commit: r613714 - in /tapestry/tapestry5/trunk: ./
tapestry-core/src/main/java/org/apache/tapestry/corelib/components/
tapestry-core/src/main/java/org/apache/tapestry/grid/
tapestry-core/src/main/java/org/apache/tapestry/internal/
tapestry-core/src...
Author: hlship
Date: Sun Jan 20 17:02:17 2008
New Revision: 613714
URL: http://svn.apache.org/viewvc?rev=613714&view=rev
Log:
TAPESTRY-1847: Grid component should output additional CSS classes into TDs to identify first and last column, first and last row
Added:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/grid/GridConstants.java
Modified:
tapestry/tapestry5/trunk/pom.xml
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Form.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Grid.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/GridColumns.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/GridRows.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/TapestryInternalUtils.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/GridColumns.tml
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/TapestryInternalUtilsTest.java
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/InternalUtils.java
Modified: tapestry/tapestry5/trunk/pom.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/pom.xml?rev=613714&r1=613713&r2=613714&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/pom.xml (original)
+++ tapestry/tapestry5/trunk/pom.xml Sun Jan 20 17:02:17 2008
@@ -226,7 +226,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
- <version>2.4-SNAPSHOT</version>
+ <version>2.4</version>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>src/test/conf/testng.xml</suiteXmlFile>
@@ -369,11 +369,6 @@
<pluginRepository>
<id>tapestry</id>
<url>http://tapestry.formos.com/maven-repository</url>
- </pluginRepository>
- <!-- Needed to get surefire 2.4-SNAPSHOT -->
- <pluginRepository>
- <id>apache.snapshots</id>
- <url>http://people.apache.org/repo/m2-snapshot-repository/</url>
</pluginRepository>
<!-- I believe the Cobertura plugin lives here. -->
<pluginRepository>
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Form.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Form.java?rev=613714&r1=613713&r2=613714&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Form.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Form.java Sun Jan 20 17:02:17 2008
@@ -28,6 +28,7 @@
import org.apache.tapestry.internal.services.HeartbeatImpl;
import org.apache.tapestry.internal.util.Base64ObjectInputStream;
import org.apache.tapestry.internal.util.Base64ObjectOutputStream;
+import org.apache.tapestry.ioc.Location;
import org.apache.tapestry.ioc.annotations.Inject;
import org.apache.tapestry.ioc.internal.util.TapestryException;
import org.apache.tapestry.runtime.Component;
@@ -345,7 +346,9 @@
}
catch (Exception ex)
{
- throw new TapestryException(ex.getMessage(), component, ex);
+ Location location = component == null ? null : component.getComponentResources().getLocation();
+
+ throw new TapestryException(ex.getMessage(), location, ex);
}
finally
{
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Grid.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Grid.java?rev=613714&r1=613713&r2=613714&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Grid.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Grid.java Sun Jan 20 17:02:17 2008
@@ -32,15 +32,13 @@
import org.apache.tapestry.services.FormSupport;
/**
- * A grid presents tabular data. It is a composite component, created in terms of several
- * sub-components. The sub-components are statically wired to the Grid, as it provides access to the
- * data and other models that they need.
+ * A grid presents tabular data. It is a composite component, created in terms of several sub-components. The
+ * sub-components are statically wired to the Grid, as it provides access to the data and other models that they need.
* <p/>
- * A Grid may operate inside a {@link Form}. By overriding the cell renderers of properties, the
- * default output only behavior can be changed to produce a complex form with individual control for
- * editing properties of each row. This is currently workable but less than ideal -- if the order of
- * rows provided by the {@link GridDataSource} changes between render and form submission, then
- * there's the possibility that data will be applied to the wrong server-side objects.
+ * A Grid may operate inside a {@link Form}. By overriding the cell renderers of properties, the default output only
+ * behavior can be changed to produce a complex form with individual control for editing properties of each row. This is
+ * currently workable but less than ideal -- if the order of rows provided by the {@link GridDataSource} changes between
+ * render and form submission, then there's the possibility that data will be applied to the wrong server-side objects.
*
* @see BeanModel
* @see BeanModelSource
@@ -49,24 +47,24 @@
public class Grid implements GridModelProvider
{
/**
- * The source of data for the Grid to display. This will usually be a List or array but can also
- * be an explicit {@link GridDataSource}. For Lists and Arrays, a GridDataSource is created
- * automatically as a wrapper around the underlying List.
+ * The source of data for the Grid to display. This will usually be a List or array but can also be an explicit
+ * {@link GridDataSource}. For Lists and Arrays, a GridDataSource is created automatically as a wrapper around the
+ * underlying List.
*/
@Parameter(required = true)
private Object _source;
/**
- * The number of rows of data displayed on each page. If there are more rows than will fit, the
- * Grid will divide up the rows into "pages" and (normally) provide a pager to allow the user to
- * navigate within the overall result set.
+ * The number of rows of data displayed on each page. If there are more rows than will fit, the Grid will divide up
+ * the rows into "pages" and (normally) provide a pager to allow the user to navigate within the overall result
+ * set.
*/
@Parameter("25")
private int _rowsPerPage;
/**
- * Defines where the pager (used to navigate within the "pages" of results) should be displayed:
- * "top", "bottom", "both" or "none".
+ * Defines where the pager (used to navigate within the "pages" of results) should be displayed: "top", "bottom",
+ * "both" or "none".
*/
@Parameter(value = "bottom", defaultPrefix = "literal")
private GridPagerPosition _pagerPosition;
@@ -81,52 +79,50 @@
private boolean _sortAscending = true;
/**
- * Used to store the current object being rendered (for the current row). This is used when
- * parameter blocks are 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.
+ * Used to store the current object being rendered (for the current row). This is used when parameter blocks are
+ * 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
private Object _row;
/**
- * The model used to identify the properties to be presented and the order of presentation. The
- * model may be omitted, in which case a default model is generated from the first object in the
- * data source (this implies that the objects provided by the source are uniform). The model may
- * be explicitly specified to override the default behavior, say to reorder or rename columns or
- * add additional columns.
+ * The model used to identify the properties to be presented and the order of presentation. The model may be
+ * omitted, in which case a default model is generated from the first object in the data source (this implies that
+ * the objects provided by the source are uniform). The model may be explicitly specified to override the default
+ * behavior, say to reorder or rename columns or add additional columns.
*/
@Parameter
private BeanModel _model;
/**
- * A comma-separated list of property names to be removed from the {@link BeanModel}. The names
- * are case-insensitive.
+ * A comma-separated list of property names to be removed from the {@link BeanModel}. The names are
+ * case-insensitive.
*/
@Parameter(defaultPrefix = "literal")
private String _remove;
/**
- * A comma-separated list of property names indicating the order in which the properties should
- * be presented. The names are case insensitive. Any properties not indicated in the list will
- * be appended to the end of the display order.
+ * A comma-separated list of property names indicating the order in which the properties should be presented. The
+ * names are case insensitive. Any properties not indicated in the list will be appended to the end of the display
+ * order.
*/
@Parameter(defaultPrefix = "literal")
private String _reorder;
/**
- * A Block to render instead of the table (and pager, etc.) when the source is empty. The
- * default is simply the text "There is no data to display". This parameter is used to customize
- * that message, possibly including components to allow the user to create new objects.
+ * A Block to render instead of the table (and pager, etc.) when the source is empty. The default is simply the text
+ * "There is no data to display". This parameter is used to customize that message, possibly including components to
+ * allow the user to create new objects.
*/
@Parameter(value = "block:empty")
private Block _empty;
/**
- * If true, then the CSS class on each <TD> and <TH> cell will be omitted, which can reduce
- * the amount of output from the component overall by a considerable amount. Leave this as false, the
- * default, when you are leveraging the CSS to customize the look and feel of particular columns.
+ * If true, then the CSS class on each <TD> and <TH> cell will be omitted, which can reduce the amount
+ * of output from the component overall by a considerable amount. Leave this as false, the default, when you are
+ * leveraging the CSS to customize the look and feel of particular columns.
*/
@Parameter
private boolean _lean;
@@ -145,9 +141,8 @@
private GridDataSource _dataSource;
/**
- * The CSS class for the tr element for each data row. This can be used to highlight particular
- * rows, or cycle between CSS values (for the "zebra effect"). If null or not bound, then no
- * particular CSS class value is used.
+ * The CSS class for the tr element for each data row. This can be used to highlight particular rows, or cycle
+ * between CSS values (for the "zebra effect"). If null or not bound, then no particular CSS class value is used.
*/
@Parameter(cache = false)
private String _rowClass;
@@ -158,7 +153,7 @@
@SuppressWarnings("unused")
@Component(
- parameters = {"rowClass=rowClass", "rowsPerPage=rowsPerPage", "currentPage=currentPage", "row=row", "volatile=inherit:volatile", "lean=inherit:lean"})
+ parameters = {"sortColumnId=sortColumnId", "sortAscending=sortAscending", "rowClass=rowClass", "rowsPerPage=rowsPerPage", "currentPage=currentPage", "row=row", "volatile=inherit:volatile", "lean=inherit:lean"})
private GridRows _rows;
@Component(parameters = {"source=dataSource", "rowsPerPage=rowsPerPage", "currentPage=currentPage"})
@@ -173,11 +168,10 @@
private Delegate _pagerBottom;
/**
- * If true and the Loop is enclosed by a Form, then the normal state persisting logic is turned
- * off. Defaults to false, enabling state saving persisting within Forms. If a Grid is present
- * for some reason within a Form, but does not contain any form control components (such as
- * {@link TextField}), then binding volatile to false will reduce the amount of client-side
- * state that must be persisted.
+ * If true and the Loop is enclosed by a Form, then the normal state persisting logic is turned off. Defaults to
+ * false, enabling state saving persisting within Forms. If a Grid is present for some reason within a Form, but
+ * does not contain any form control components (such as {@link TextField}), then binding volatile to false will
+ * reduce the amount of client-side state that must be persisted.
*/
@Parameter
private boolean _volatile;
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/GridColumns.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/GridColumns.java?rev=613714&r1=613713&r2=613714&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/GridColumns.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/GridColumns.java Sun Jan 20 17:02:17 2008
@@ -19,9 +19,12 @@
import org.apache.tapestry.annotations.Parameter;
import org.apache.tapestry.annotations.Path;
import org.apache.tapestry.beaneditor.PropertyModel;
+import org.apache.tapestry.grid.GridConstants;
import org.apache.tapestry.grid.GridModelProvider;
+import org.apache.tapestry.internal.TapestryInternalUtils;
import org.apache.tapestry.ioc.Messages;
import org.apache.tapestry.ioc.annotations.Inject;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
import java.util.List;
@@ -78,8 +81,18 @@
@Inject
private Messages _messages;
+
+ private int _columnIndex;
+
+ private int _lastColumnIndex;
+
private PropertyModel _columnModel;
+ void setupRender()
+ {
+ _lastColumnIndex = _dataProvider.getDataModel().getPropertyNames().size() - 1;
+ }
+
public boolean isSortDisabled()
{
return !_columnModel.isSortable();
@@ -87,16 +100,27 @@
public String getSortLinkClass()
{
- if (isActiveSortColumn()) return _sortAscending ? "t-sort-column-ascending" : "t-sort-column-descending";
+ if (isActiveSortColumn())
+ return _sortAscending ? GridConstants.SORT_ASCENDING_CLASS : GridConstants.SORT_DESCENDING_CLASS;
return null;
}
public String getHeaderClass()
{
- if (_lean) return null;
+ List<String> classes = CollectionFactory.newList();
+
+ if (!_lean) classes.add(_columnModel.getId() + "-header");
+
+ String sort = getSortLinkClass();
+
+ if (sort != null) classes.add(sort);
+
+ if (_columnIndex == 0) classes.add(GridConstants.FIRST_CLASS);
- return _columnModel.getId() + "-header";
+ if (_columnIndex == _lastColumnIndex) classes.add(GridConstants.LAST_CLASS);
+
+ return TapestryInternalUtils.toClassAttributeValue(classes);
}
public boolean isActiveSortColumn()
@@ -144,5 +168,18 @@
public void setColumnName(String columnName)
{
_columnModel = _dataProvider.getDataModel().get(columnName);
+ }
+
+ /**
+ * Set by the Loop component.
+ */
+ public void setColumnIndex(int columnIndex)
+ {
+ _columnIndex = columnIndex;
+ }
+
+ public int getColumnIndex()
+ {
+ return _columnIndex;
}
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/GridRows.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/GridRows.java?rev=613714&r1=613713&r2=613714&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/GridRows.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/GridRows.java Sun Jan 20 17:02:17 2008
@@ -18,8 +18,11 @@
import org.apache.tapestry.annotations.Environmental;
import org.apache.tapestry.annotations.Parameter;
import org.apache.tapestry.beaneditor.PropertyModel;
+import org.apache.tapestry.grid.GridConstants;
import org.apache.tapestry.grid.GridDataSource;
import org.apache.tapestry.grid.GridModelProvider;
+import org.apache.tapestry.internal.TapestryInternalUtils;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
import org.apache.tapestry.services.FormSupport;
import java.util.List;
@@ -27,13 +30,15 @@
/**
* Renders out a series of rows within the table.
* <p/>
- * Inside a {@link Form}, a series of row index numbers are stored into the form (
- * {@linkplain FormSupport#store(Object, ComponentAction) as ComponentActions}). This is not ideal
- * ... in a situation where the data set can shift between the form render and the form submission,
- * this can cause unexpected results, including applying changes to the wrong objects.
+ * Inside a {@link Form}, a series of row index numbers are stored into the form ( {@linkplain FormSupport#store(Object,
+ * ComponentAction) as ComponentActions}). This is not ideal ... in a situation where the data set can shift between the
+ * form render and the form submission, this can cause unexpected results, including applying changes to the wrong
+ * objects.
*/
public class GridRows
{
+ private int _startRow;
+
static class SetupForRow implements ComponentAction<GridRows>
{
private static final long serialVersionUID = -3216282071752371975L;
@@ -52,8 +57,22 @@
}
/**
- * Parameter used to set the CSS class for each row (each <tr> element) within the
- * <tbody>). This is not cached, so it will be recomputed for each row.
+ * The column which is currently being sorted. This value is the column's {@link PropertyModel#getId() id}, not its
+ * {@link PropertyModel#getPropertyName() name}. This parameter may be null, in which case no column is being used
+ * for sorting.
+ */
+ @Parameter(required = true)
+ private String _sortColumnId;
+
+ /**
+ * If true, then the sort is ascending (A - Z), if false the descending (Z - A).
+ */
+ @Parameter(required = true)
+ private boolean _sortAscending;
+
+ /**
+ * Parameter used to set the CSS class for each row (each <tr> element) within the <tbody>). This is not
+ * cached, so it will be recomputed for each row.
*/
@Parameter(cache = false)
private String _rowClass;
@@ -77,23 +96,23 @@
private int _currentPage;
/**
- * The current row being rendered, this is primarily an output parameter used to allow the Grid,
- * and the Grid's container, to know what object is being rendered.
+ * The current row being rendered, this is primarily an output parameter used to allow the Grid, and the Grid's
+ * container, to know what object is being rendered.
*/
@Parameter(required = true)
private Object _row;
/**
- * If true, then the CSS class on each <TD> cell will be omitted, which can reduce
- * the amount of output from the component overall by a considerable amount. Leave this as false, the
- * default, when you are leveraging the CSS to customize the look and feel of particular columns.
+ * If true, then the CSS class on each <TD> cell will be omitted, which can reduce the amount of output from
+ * the component overall by a considerable amount. Leave this as false, the default, when you are leveraging the CSS
+ * to customize the look and feel of particular columns.
*/
@Parameter
private boolean _lean;
/**
- * If true and the Loop is enclosed by a Form, then the normal state saving logic is turned off.
- * Defaults to false, enabling state saving logic within Forms.
+ * If true and the Loop is enclosed by a Form, then the normal state saving logic is turned off. Defaults to false,
+ * enabling state saving logic within Forms.
*/
@SuppressWarnings("unused")
@Parameter
@@ -114,16 +133,39 @@
public String getRowClass()
{
- return _rowClass;
+ List<String> classes = CollectionFactory.newList();
+
+ // Not a cached parameter, so careful to only access it once.
+
+ String rc = _rowClass;
+
+ if (rc != null) classes.add(rc);
+
+ if (_rowIndex == _startRow) classes.add(GridConstants.FIRST_CLASS);
+
+ if (_rowIndex == _endRow) classes.add(GridConstants.LAST_CLASS);
+
+ return TapestryInternalUtils.toClassAttributeValue(classes);
}
public String getCellClass()
{
- if (_lean) return null;
+ List<String> classes = CollectionFactory.newList();
+
+ if (!_lean)
+ {
+ String id = _provider.getDataModel().get(_propertyName).getId();
+
+ classes.add(id + "-cell");
+ }
- String id = _provider.getDataModel().get(_propertyName).getId();
+ if (_columnModel.getId().equals(_sortColumnId))
+ {
+ String sortClassName = _sortAscending ? GridConstants.SORT_ASCENDING_CLASS : GridConstants.SORT_DESCENDING_CLASS;
+ classes.add(sortClassName);
+ }
- return id + "-cell";
+ return TapestryInternalUtils.toClassAttributeValue(classes);
}
void setupRender()
@@ -138,17 +180,16 @@
if (_currentPage > maxPages) _currentPage = maxPages;
- int startRow = (_currentPage - 1) * _rowsPerPage;
- _endRow = Math.min(availableRows - 1, startRow + _rowsPerPage - 1);
+ _startRow = (_currentPage - 1) * _rowsPerPage;
+ _endRow = Math.min(availableRows - 1, _startRow + _rowsPerPage - 1);
- _rowIndex = startRow;
+ _rowIndex = _startRow;
_recordingStateInsideForm = !_volatile && _formSupport != null;
}
/**
- * Callback method, used when recording state to a form, or called directly when not recording
- * state.
+ * Callback method, used when recording state to a form, or called directly when not recording state.
*/
void setupForRow(int rowIndex)
{
Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/grid/GridConstants.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/grid/GridConstants.java?rev=613714&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/grid/GridConstants.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/grid/GridConstants.java Sun Jan 20 17:02:17 2008
@@ -0,0 +1,43 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.grid;
+
+public class GridConstants
+{
+ /**
+ * CSS class for the first column or the first row. May be applied to a <th> (in the <thead>) or a
+ * <tr> (in the <tbody>).
+ */
+ public static final String FIRST_CLASS = "t-first";
+
+ /**
+ * CSS class for the last column or the last row. May be applied to a <th> (in the <thead>) or a
+ * <tr> (in the <tbody>).
+ */
+ public static final String LAST_CLASS = "t-last";
+
+ /**
+ * Marks the column that is currently sorted for sort ascending. May be applied to a <th> (in the
+ * <thead> or a <td> in the <tbody>).
+ */
+ public static final String SORT_ASCENDING_CLASS = "t-sort-column-ascending";
+
+ /**
+ * Marks the column that is currently sorted for sort descending. May be applied to a <th> (in the
+ * <thead> or a <td> in the <tbody>).
+ */
+
+ public static final String SORT_DESCENDING_CLASS = "t-sort-column-descending";
+}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/TapestryInternalUtils.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/TapestryInternalUtils.java?rev=613714&r1=613713&r2=613714&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/TapestryInternalUtils.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/TapestryInternalUtils.java Sun Jan 20 17:02:17 2008
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007 The Apache Software Foundation
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -26,6 +26,7 @@
import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newList;
import org.apache.tapestry.ioc.internal.util.Defense;
import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
import org.apache.tapestry.ioc.internal.util.Orderer;
import org.apache.tapestry.ioc.services.ClassFactory;
import org.apache.tapestry.ioc.services.ClassPropertyAdapter;
@@ -81,9 +82,9 @@
}
/**
- * Capitalizes the string, and inserts a space before each upper case character (or sequence of
- * upper case characters). Thus "userId" becomes "User Id", etc. Also, converts underscore into
- * space (and capitalizes the following word), thus "user_id" also becomes "User Id".
+ * Capitalizes the string, and inserts a space before each upper case character (or sequence of upper case
+ * characters). Thus "userId" becomes "User Id", etc. Also, converts underscore into space (and capitalizes the
+ * following word), thus "user_id" also becomes "User Id".
*/
public static String toUserPresentable(String id)
{
@@ -139,8 +140,8 @@
}
/**
- * Converts a string to an {@link OptionModel}. The string is of the form "value=label". If the
- * equals sign is omitted, then the same value is used for both value and label.
+ * Converts a string to an {@link OptionModel}. The string is of the form "value=label". If the equals sign is
+ * omitted, then the same value is used for both value and label.
*
* @param input
* @return
@@ -160,8 +161,8 @@
}
/**
- * Parses a string input into a series of value=label pairs compatible with
- * {@link #toOptionModel(String)}. Splits on commas. Ignores whitespace around commas.
+ * Parses a string input into a series of value=label pairs compatible with {@link #toOptionModel(String)}. Splits
+ * on commas. Ignores whitespace around commas.
*
* @param input comma seperated list of terms
* @return list of option models
@@ -179,8 +180,7 @@
}
/**
- * Wraps the result of {@link #toOptionModels(String)} as a {@link SelectModel} (with no option
- * groups).
+ * Wraps the result of {@link #toOptionModels(String)} as a {@link SelectModel} (with no option groups).
*
* @param input
* @return
@@ -208,8 +208,7 @@
}
/**
- * Processes a map input into a series of map entries compatible with
- * {@link #toOptionModel(Map.Entry)}.
+ * Processes a map input into a series of map entries compatible with {@link #toOptionModel(Map.Entry)}.
*
* @param input map of elements
* @return list of option models
@@ -227,8 +226,7 @@
}
/**
- * Wraps the result of {@link #toOptionModels(Map)} as a {@link SelectModel} (with no option
- * groups).
+ * Wraps the result of {@link #toOptionModels(Map)} as a {@link SelectModel} (with no option groups).
*
* @param input
* @return
@@ -254,8 +252,7 @@
}
/**
- * Processes a list input into a series of objects compatible with
- * {@link #toOptionModel(Object)}.
+ * Processes a list input into a series of objects compatible with {@link #toOptionModel(Object)}.
*
* @param input list of elements
* @return list of option models
@@ -273,8 +270,7 @@
}
/**
- * Wraps the result of {@link #toOptionModels(List)} as a {@link SelectModel} (with no option
- * groups).
+ * Wraps the result of {@link #toOptionModels(List)} as a {@link SelectModel} (with no option groups).
*
* @param input
* @return
@@ -287,8 +283,8 @@
}
/**
- * Parses a key/value pair where the key and the value are seperated by an equals sign. The key
- * and value are trimmed of leading and trailing whitespace, and returned as a {@link KeyValue}.
+ * Parses a key/value pair where the key and the value are seperated by an equals sign. The key and value are
+ * trimmed of leading and trailing whitespace, and returned as a {@link KeyValue}.
*
* @param input
* @return
@@ -306,9 +302,9 @@
}
/**
- * Used to convert a property expression into a key that can be used to locate various resources
- * (Blocks, messages, etc.). Strips out any punctuation characters, leaving just words
- * characters (letters, number and the underscore).
+ * Used to convert a property expression into a key that can be used to locate various resources (Blocks, messages,
+ * etc.). Strips out any punctuation characters, leaving just words characters (letters, number and the
+ * underscore).
*
* @param expression
* @return
@@ -319,8 +315,8 @@
}
/**
- * Looks for a label within the messages based on the id. If found, it is used, otherwise the
- * name is converted to a user presentable form.
+ * Looks for a label within the messages based on the id. If found, it is used, otherwise the name is converted to a
+ * user presentable form.
*/
public static String defaultLabel(String id, Messages messages, String propertyExpression)
{
@@ -332,8 +328,8 @@
}
/**
- * Strips a dotted sequence (such as a property expression, or a qualified class name) down to
- * the last term of that expression, by locating the last period ('.') in the string.
+ * Strips a dotted sequence (such as a property expression, or a qualified class name) down to the last term of that
+ * expression, by locating the last period ('.') in the string.
*/
public static String lastTerm(String input)
{
@@ -342,6 +338,20 @@
return input.substring(dotx + 1);
}
+ /**
+ * Converts an list of strings into a space-separated string combining them all, suitable for use as an HTML class
+ * attribute value.
+ *
+ * @param classes classes to combine
+ * @return the joined classes, or null if classes is empty
+ */
+ public static String toClassAttributeValue(List<String> classes)
+ {
+ if (classes.isEmpty()) return null;
+
+ return InternalUtils.join(classes, " ");
+ }
+
private static class PropertyOrder implements Comparable<PropertyOrder>
{
final String _propertyName;
@@ -370,10 +380,9 @@
}
/**
- * Sorts the property names into presentation order. Filters out any properties that have an
- * explicit {@link OrderBefore}, leaving the remainder. Estimates each propertie's position
- * based on the relative position of the property's getter. The code assumes that all methods
- * are readable (have a getter method).
+ * Sorts the property names into presentation order. Filters out any properties that have an explicit {@link
+ * OrderBefore}, leaving the remainder. Estimates each propertie's position based on the relative position of the
+ * property's getter. The code assumes that all methods are readable (have a getter method).
*
* @param classAdapter defines the bean that contains the properties
* @param classFactory used to access method line number information
@@ -511,8 +520,8 @@
}
/**
- * Determines if the two values are equal. They are equal if they are the exact same value
- * (including if they are both null). Otherwise standard equals() comparison is used.
+ * Determines if the two values are equal. They are equal if they are the exact same value (including if they are
+ * both null). Otherwise standard equals() comparison is used.
*
* @param <T>
* @param left
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java?rev=613714&r1=613713&r2=613714&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java Sun Jan 20 17:02:17 2008
@@ -830,22 +830,28 @@
public boolean handleEvent(ComponentEvent event)
{
- // Simple case: no mixins
+ try
+ { // Simple case: no mixins
- if (_components == null) return _coreComponent.handleComponentEvent(event);
+ if (_components == null) return _coreComponent.handleComponentEvent(event);
- // Otherwise, iterate over mixins + core component
+ // Otherwise, iterate over mixins + core component
- boolean result = false;
+ boolean result = false;
- for (Component component : _components)
- {
- result |= component.handleComponentEvent(event);
+ for (Component component : _components)
+ {
+ result |= component.handleComponentEvent(event);
- if (event.isAborted()) break;
- }
+ if (event.isAborted()) break;
+ }
- return result;
+ return result;
+ }
+ catch (RuntimeException ex)
+ {
+ throw new TapestryException(ex.getMessage(), this, ex);
+ }
}
/**
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/GridColumns.tml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/GridColumns.tml?rev=613714&r1=613713&r2=613714&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/GridColumns.tml (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/GridColumns.tml Sun Jan 20 17:02:17 2008
@@ -1,6 +1,7 @@
<thead xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
<tr>
- <th t:type="Loop" source="columnNames" value="columnName" volatile="true" class="prop:headerClass">
+ <th t:type="Loop" source="columnNames" value="columnName" volatile="true" class="prop:headerClass"
+ index="columnIndex">
<a t:id="sort">${columnModel.label}</a>
<t:if test="columnModel.sortable">
<a t:id="sort2">
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/TapestryInternalUtilsTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/TapestryInternalUtilsTest.java?rev=613714&r1=613713&r2=613714&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/TapestryInternalUtilsTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/TapestryInternalUtilsTest.java Sun Jan 20 17:02:17 2008
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007 The Apache Software Foundation
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@
import org.apache.tapestry.SelectModel;
import org.apache.tapestry.internal.test.InternalBaseTestCase;
import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
import org.apache.tapestry.ioc.services.ClassFactory;
import org.apache.tapestry.ioc.services.ClassPropertyAdapter;
import org.apache.tapestry.ioc.services.PropertyAccess;
@@ -432,7 +433,6 @@
assertSame(actual, resources);
verify();
-
}
@Test
@@ -469,5 +469,21 @@
String input = "\u65E5\u672C\u8A9E";
String expected = "%E6%97%A5%E6%9C%AC%E8%AA%9E";
assertEquals(TapestryInternalUtils.encodeContext(input), expected);
+ }
+
+ @Test
+ public void to_class_attribute_value_empty()
+ {
+ List<String> classes = Collections.emptyList();
+
+ assertNull(TapestryInternalUtils.toClassAttributeValue(classes));
+ }
+
+ @Test
+ public void to_class_attribute_value_normal()
+ {
+ List<String> classes = CollectionFactory.newList("fred", "barney", "wilma");
+
+ assertEquals(TapestryInternalUtils.toClassAttributeValue(classes), "fred barney wilma");
}
}
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/InternalUtils.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/InternalUtils.java?rev=613714&r1=613713&r2=613714&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/InternalUtils.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/InternalUtils.java Sun Jan 20 17:02:17 2008
@@ -33,22 +33,20 @@
import java.util.*;
/**
- * Utilities used within various internal implemenations of Tapestry IOC and the rest of the
- * tapestry-core framework.
+ * Utilities used within various internal implemenations of Tapestry IOC and the rest of the tapestry-core framework.
*/
public class InternalUtils
{
/**
- * Leading punctiation on member names that is stripped off to form a property name or new
- * member name.
+ * Leading punctiation on member names that is stripped off to form a property name or new member name.
*/
private static final String NAME_PREFIX = "_$";
/**
- * Converts a method to a user presentable string using a {@link ClassFactory} to obtain a
- * {@link Location} (where possible). {@link #asString(Method)} is used under the covers,
- * to present a detailed, but not excessive, description of the class, method and parameters.
+ * Converts a method to a user presentable string using a {@link ClassFactory} to obtain a {@link Location} (where
+ * possible). {@link #asString(Method)} is used under the covers, to present a detailed, but not excessive,
+ * description of the class, method and parameters.
*
* @param method method to convert to a string
* @param classFactory used to obtain the {@link Location}
@@ -62,9 +60,8 @@
}
/**
- * Converts a method to a user presentable string consisting of the containing class name, the
- * method name, and the short form of the parameter list (the class name of each parameter type,
- * shorn of the package name portion).
+ * Converts a method to a user presentable string consisting of the containing class name, the method name, and the
+ * short form of the parameter list (the class name of each parameter type, shorn of the package name portion).
*
* @param method
* @return short string representation
@@ -125,8 +122,7 @@
}
/**
- * Strips leading characters defined by {@link InternalUtils#NAME_PREFIX}, then adds the prefix
- * back in.
+ * Strips leading characters defined by {@link InternalUtils#NAME_PREFIX}, then adds the prefix back in.
*/
public static String createMemberName(String memberName)
{
@@ -250,26 +246,48 @@
*/
public static String join(List elements)
{
- StringBuilder buffer = new StringBuilder();
- boolean first = true;
+ return join(elements, ", ");
+ }
- for (Object o : elements)
+ /**
+ * Joins together some number of elements.
+ *
+ * @param elements objects to be joined together
+ * @param separator used between elements when joining
+ */
+ public static String join(List elements, String separator)
+ {
+ switch (elements.size())
{
- if (!first) buffer.append(", ");
+ case 0:
+ return "";
- buffer.append(String.valueOf(o));
+ case 1:
+ return elements.get(0).toString();
- first = false;
- }
+ default:
+
+ StringBuilder buffer = new StringBuilder();
+ boolean first = true;
- return buffer.toString();
+ for (Object o : elements)
+ {
+ if (!first) buffer.append(separator);
+
+ buffer.append(String.valueOf(o));
+
+ first = false;
+ }
+
+ return buffer.toString();
+ }
}
/**
* Creates a sorted copy of the provided elements, then turns that into a comma separated list.
*
- * @return the elements converted to strings, sorted, joined with comma ... or "(none)" if the elements
- * are null or empty
+ * @return the elements converted to strings, sorted, joined with comma ... or "(none)" if the elements are null or
+ * empty
*/
public static String joinSorted(Collection elements)
{
@@ -286,8 +304,7 @@
}
/**
- * Returns true if the input is null, or is a zero length string (excluding leading/trailing
- * whitespace).
+ * Returns true if the input is null, or is a zero length string (excluding leading/trailing whitespace).
*/
public static boolean isBlank(String input)
@@ -311,8 +328,8 @@
}
/**
- * Sniffs the object to see if it is a {@link Location} or {@link Locatable}. Returns null if
- * null or not convertable to a location.
+ * Sniffs the object to see if it is a {@link Location} or {@link Locatable}. Returns null if null or not
+ * convertable to a location.
*/
public static Location locationOf(Object location)
@@ -327,8 +344,7 @@
}
/**
- * Extracts the string keys from a map and returns them in sorted order. The keys are converted
- * to strings.
+ * Extracts the string keys from a map and returns them in sorted order. The keys are converted to strings.
*
* @param map the map to extract keys from (may be null)
* @return the sorted keys, or the empty set if map is null
@@ -407,10 +423,10 @@
}
/**
- * Searches the string for the final period ('.') character and returns everything after that.
- * The input string is generally a fully qualified class name, though tapestry-core also uses
- * this method for the occasional property expression (which is also dot separated). Returns the
- * input string unchanged if it does not contain a period character.
+ * Searches the string for the final period ('.') character and returns everything after that. The input string is
+ * generally a fully qualified class name, though tapestry-core also uses this method for the occasional property
+ * expression (which is also dot separated). Returns the input string unchanged if it does not contain a period
+ * character.
*/
public static String lastTerm(String input)
{
@@ -424,14 +440,12 @@
}
/**
- * Searches a class for the "best" constructor, the public constructor with the most parameters.
- * Returns null if there are no public constructors. If there is more than one constructor with
- * the maximum number of parameters, it is not determined which will be returned (don't build a
- * class like that!).
+ * Searches a class for the "best" constructor, the public constructor with the most parameters. Returns null if
+ * there are no public constructors. If there is more than one constructor with the maximum number of parameters, it
+ * is not determined which will be returned (don't build a class like that!).
*
* @param clazz to search for a constructor for
- * @return the constructor to be used to instantiate the class, or null if no appropriate
- * constructor was found
+ * @return the constructor to be used to instantiate the class, or null if no appropriate constructor was found
*/
public static Constructor findAutobuildConstructor(Class clazz)
{
@@ -467,8 +481,8 @@
}
/**
- * Adds a value to a specially organized map where the values are lists of objects. This
- * somewhat simulates a map that allows mutiple values for the same key.
+ * Adds a value to a specially organized map where the values are lists of objects. This somewhat simulates a map
+ * that allows mutiple values for the same key.
*
* @param map to store value into
* @param key for which a value is added