001 // Copyright 2004, 2005 The Apache Software Foundation
002 //
003 // Licensed under the Apache License, Version 2.0 (the "License");
004 // you may not use this file except in compliance with the License.
005 // You may obtain a copy of the License at
006 //
007 // http://www.apache.org/licenses/LICENSE-2.0
008 //
009 // Unless required by applicable law or agreed to in writing, software
010 // distributed under the License is distributed on an "AS IS" BASIS,
011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012 // See the License for the specific language governing permissions and
013 // limitations under the License.
014
015 package org.apache.tapestry.contrib.table.model.simple;
016
017 import java.io.Serializable;
018 import java.util.Comparator;
019
020 import org.apache.tapestry.IComponent;
021 import org.apache.tapestry.contrib.table.model.ITableRendererSource;
022 import org.apache.tapestry.contrib.table.model.common.AbstractTableColumn;
023
024 /**
025 * A simple minimal implementation of the
026 * {@link org.apache.tapestry.contrib.table.model.ITableColumn}interface that provides all the
027 * basic services for displaying a column.
028 *
029 * @author mindbridge
030 */
031 public class SimpleTableColumn extends AbstractTableColumn
032 {
033 private static final long serialVersionUID = 1L;
034
035 // TODO: Unify SimpleTableColumnRendererSource and SimpleTableColumnFormRendererSource
036 // and implement the configuration with HiveMind
037
038 public static final ITableRendererSource DEFAULT_COLUMN_RENDERER_SOURCE = new SimpleTableColumnRendererSource();
039
040 public static final ITableRendererSource FORM_COLUMN_RENDERER_SOURCE = new SimpleTableColumnFormRendererSource();
041
042 public static final ITableRendererSource DEFAULT_VALUE_RENDERER_SOURCE = new SimpleTableValueRendererSource();
043
044 private String m_strDisplayName;
045
046 private ITableColumnEvaluator m_objEvaluator;
047
048 /**
049 * Creates a SimpleTableColumn
050 *
051 * @param strColumnName
052 * the identifying name and display name of the column
053 */
054 public SimpleTableColumn(String strColumnName)
055 {
056 this(strColumnName, strColumnName);
057 }
058
059 /**
060 * Creates a SimpleTableColumn
061 *
062 * @param strColumnName
063 * the identifying name and display name of the column
064 * @param bSortable
065 * whether the column is sortable
066 */
067 public SimpleTableColumn(String strColumnName, boolean bSortable)
068 {
069 this(strColumnName, strColumnName, bSortable);
070 }
071
072 /**
073 * Creates a SimpleTableColumn
074 *
075 * @param strColumnName
076 * the identifying name and display name of the column
077 * @param bSortable
078 * whether the column is sortable
079 * @param objEvaluator
080 * the evaluator to extract the column value from the row
081 */
082 public SimpleTableColumn(String strColumnName, ITableColumnEvaluator objEvaluator,
083 boolean bSortable)
084 {
085 this(strColumnName, strColumnName, objEvaluator, bSortable);
086 }
087
088 /**
089 * Creates a SimpleTableColumn
090 *
091 * @param strColumnName
092 * the identifying name of the column
093 * @param strDisplayName
094 * the display name of the column
095 */
096 public SimpleTableColumn(String strColumnName, String strDisplayName)
097 {
098 this(strColumnName, strDisplayName, false);
099 }
100
101 /**
102 * Creates a SimpleTableColumn
103 *
104 * @param strColumnName
105 * the identifying name of the column
106 * @param strDisplayName
107 * the display name of the column
108 * @param bSortable
109 * whether the column is sortable
110 */
111 public SimpleTableColumn(String strColumnName, String strDisplayName, boolean bSortable)
112 {
113 this(strColumnName, strDisplayName, null, bSortable);
114 }
115
116 /**
117 * Creates a SimpleTableColumn
118 *
119 * @param strColumnName
120 * the identifying name of the column
121 * @param strDisplayName
122 * the display name of the column
123 * @param bSortable
124 * whether the column is sortable
125 * @param objEvaluator
126 * the evaluator to extract the column value from the row
127 */
128 public SimpleTableColumn(String strColumnName, String strDisplayName,
129 ITableColumnEvaluator objEvaluator, boolean bSortable)
130 {
131 super(strColumnName, bSortable, null);
132 setComparator(new DefaultTableComparator());
133 setDisplayName(strDisplayName);
134 setColumnRendererSource(DEFAULT_COLUMN_RENDERER_SOURCE);
135 setValueRendererSource(DEFAULT_VALUE_RENDERER_SOURCE);
136 setEvaluator(objEvaluator);
137 }
138
139 /**
140 * Returns the display name of the column that will be used in the table header. Override for
141 * internationalization.
142 *
143 * @return String the display name of the column
144 */
145 public String getDisplayName()
146 {
147 return m_strDisplayName;
148 }
149
150 /**
151 * Sets the displayName.
152 *
153 * @param displayName
154 * The displayName to set
155 */
156 public void setDisplayName(String displayName)
157 {
158 m_strDisplayName = displayName;
159 }
160
161 /**
162 * Returns the evaluator.
163 *
164 * @return ITableColumnEvaluator
165 */
166 public ITableColumnEvaluator getEvaluator()
167 {
168 return m_objEvaluator;
169 }
170
171 /**
172 * Sets the evaluator.
173 *
174 * @param evaluator
175 * The evaluator to set
176 */
177 public void setEvaluator(ITableColumnEvaluator evaluator)
178 {
179 m_objEvaluator = evaluator;
180 }
181
182 /**
183 * Sets a comparator that compares the values of this column rather than the objects
184 * representing the full rows. <br>
185 * This method allows easier use of standard comparators for sorting the column. It simply wraps
186 * the provided comparator with a row-to-column convertor and invokes the setComparator()
187 * method.
188 *
189 * @param comparator
190 * The column value comparator
191 */
192 public void setColumnComparator(Comparator comparator)
193 {
194 setComparator(new ColumnComparator(this, comparator));
195 }
196
197 /**
198 * Extracts the value of the column from the row object
199 *
200 * @param objRow
201 * the row object
202 * @return Object the column value
203 */
204 public Object getColumnValue(Object objRow)
205 {
206 ITableColumnEvaluator objEvaluator = getEvaluator();
207 if (objEvaluator != null)
208 return objEvaluator.getColumnValue(this, objRow);
209
210 // default fallback
211 return objRow.toString();
212 }
213
214 /**
215 * Use the column name to get the display name, as well as the column and value renderer sources
216 * from the provided component.
217 *
218 * @param objSettingsContainer
219 * the component from which to get the settings
220 */
221 public void loadSettings(IComponent objSettingsContainer)
222 {
223 String strDisplayName = objSettingsContainer.getMessages().getMessage(getColumnName());
224
225 // Hack! the Messages inteface needs to restore the getMessage(key, default), or needs
226 // to add a containsKey(key) method. Looking for the '[' used with invalid/unknown keys.
227
228 if (!strDisplayName.startsWith("["))
229 setDisplayName(strDisplayName);
230
231 super.loadSettings(objSettingsContainer);
232 }
233
234 public class DefaultTableComparator implements Comparator, Serializable
235 {
236 private static final long serialVersionUID = 1L;
237
238 public int compare(Object objRow1, Object objRow2)
239 {
240 Object objValue1 = getColumnValue(objRow1);
241 Object objValue2 = getColumnValue(objRow2);
242
243 if (objValue1 == objValue2)
244 return 0;
245
246 boolean bComparable1 = objValue1 instanceof Comparable;
247 boolean bComparable2 = objValue2 instanceof Comparable;
248
249 // non-comparable values are considered equal
250 if (!bComparable1 && !bComparable2)
251 return 0;
252
253 // non-comparable values (null included) are considered smaller
254 // than the comparable ones
255 if (!bComparable1)
256 return -1;
257
258 if (!bComparable2)
259 return 1;
260
261 return ((Comparable) objValue1).compareTo(objValue2);
262 }
263 }
264
265 }