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.common;
016    
017    import org.apache.tapestry.IComponent;
018    import org.apache.tapestry.IRender;
019    import org.apache.tapestry.IRequestCycle;
020    import org.apache.tapestry.components.Block;
021    import org.apache.tapestry.contrib.table.model.IAdvancedTableColumn;
022    import org.apache.tapestry.contrib.table.model.ITableModelSource;
023    import org.apache.tapestry.contrib.table.model.ITableRendererSource;
024    import org.apache.tapestry.valid.RenderString;
025    
026    import java.io.Serializable;
027    import java.util.Comparator;
028    
029    /**
030     * A base implementation of
031     * {@link org.apache.tapestry.contrib.table.model.ITableColumn} that allows
032     * renderers to be set via aggregation.
033     *
034     * @see org.apache.tapestry.contrib.table.model.ITableRendererSource
035     * @author mindbridge
036     * @since 2.3
037     */
038    public class AbstractTableColumn implements IAdvancedTableColumn, Serializable
039    {
040        /**
041         * The suffix of the name of the Block that will be used as the column
042         * renderer for this column.
043         */
044        public static final String COLUMN_RENDERER_BLOCK_SUFFIX = "ColumnHeader";
045    
046        /**
047         * The suffix of the name of the Block that will be used as the value
048         * renderer for this column.
049         */
050        public static final String VALUE_RENDERER_BLOCK_SUFFIX = "ColumnValue";
051    
052        private static final long serialVersionUID = 1L;
053    
054        private String m_strColumnName;
055        private boolean m_bSortable;
056        private Comparator m_objComparator;
057    
058        private ITableRendererSource m_objColumnRendererSource;
059        private ITableRendererSource m_objValueRendererSource;
060    
061        public AbstractTableColumn()
062        {
063            this("", false, null);
064        }
065    
066        public AbstractTableColumn(String strColumnName, boolean bSortable,
067                                   Comparator objComparator)
068        {
069            this(strColumnName, bSortable, objComparator, null, null);
070        }
071    
072        public AbstractTableColumn(String strColumnName, boolean bSortable,
073                                   Comparator objComparator,
074                                   ITableRendererSource objColumnRendererSource,
075                                   ITableRendererSource objValueRendererSource)
076        {
077            setColumnName(strColumnName);
078            setSortable(bSortable);
079            setComparator(objComparator);
080            setColumnRendererSource(objColumnRendererSource);
081            setValueRendererSource(objValueRendererSource);
082        }
083    
084        /**
085         * @see org.apache.tapestry.contrib.table.model.ITableColumn#getColumnName()
086         */
087        public String getColumnName()
088        {
089            return m_strColumnName;
090        }
091    
092        /**
093         * Sets the columnName.
094         *
095         * @param columnName
096         *            The columnName to set
097         */
098        public void setColumnName(String columnName)
099        {
100            if (columnName != null)
101                columnName = columnName.replace('.', '_');
102            
103            m_strColumnName = columnName;
104        }
105    
106        /**
107         * @see org.apache.tapestry.contrib.table.model.ITableColumn#getSortable()
108         */
109        public boolean getSortable()
110        {
111            return m_bSortable;
112        }
113    
114        /**
115         * Sets whether the column is sortable.
116         *
117         * @param sortable
118         *            The sortable flag to set
119         */
120        public void setSortable(boolean sortable)
121        {
122            m_bSortable = sortable;
123        }
124    
125        /**
126         * @see org.apache.tapestry.contrib.table.model.ITableColumn#getComparator()
127         */
128        public Comparator getComparator()
129        {
130            return m_objComparator;
131        }
132    
133        /**
134         * Sets the comparator.
135         *
136         * @param comparator
137         *            The comparator to set
138         */
139        public void setComparator(Comparator comparator)
140        {
141            m_objComparator = comparator;
142        }
143    
144        /**
145         * @see org.apache.tapestry.contrib.table.model.ITableColumn#getColumnRenderer(IRequestCycle,
146         *      ITableModelSource)
147         */
148        public IRender getColumnRenderer(IRequestCycle objCycle,
149                                         ITableModelSource objSource)
150        {
151            ITableRendererSource objRendererSource = getColumnRendererSource();
152    
153            if (objRendererSource == null)
154            {
155                // log error
156                return new RenderString("");
157            }
158    
159            return objRendererSource.getRenderer(objCycle, objSource, this, null);
160        }
161    
162        /**
163         * @see org.apache.tapestry.contrib.table.model.ITableColumn#getValueRenderer(IRequestCycle,
164         *      ITableModelSource, Object)
165         */
166        public IRender getValueRenderer(IRequestCycle objCycle,
167                                        ITableModelSource objSource, Object objRow)
168        {
169            ITableRendererSource objRendererSource = getValueRendererSource();
170    
171            if (objRendererSource == null)
172            {
173                // log error
174                return new RenderString("");
175            }
176    
177            return objRendererSource.getRenderer(objCycle, objSource, this, objRow);
178        }
179    
180        /**
181         * Returns the columnRendererSource.
182         *
183         * @return ITableColumnRendererSource
184         */
185        public ITableRendererSource getColumnRendererSource()
186        {
187            return m_objColumnRendererSource;
188        }
189    
190        /**
191         * Sets the columnRendererSource.
192         *
193         * @param columnRendererSource
194         *            The columnRendererSource to set
195         */
196        public void setColumnRendererSource(
197          ITableRendererSource columnRendererSource)
198        {
199            m_objColumnRendererSource = columnRendererSource;
200        }
201    
202        /**
203         * Returns the valueRendererSource.
204         *
205         * @return the valueRendererSource of this column
206         */
207        public ITableRendererSource getValueRendererSource()
208        {
209            return m_objValueRendererSource;
210        }
211    
212        /**
213         * Sets the valueRendererSource.
214         *
215         * @param valueRendererSource
216         *            The valueRendererSource to set
217         */
218        public void setValueRendererSource(ITableRendererSource valueRendererSource)
219        {
220            m_objValueRendererSource = valueRendererSource;
221        }
222    
223        /**
224         * Use the column name to get the column and value renderer sources from the
225         * provided component. Use the column and value renderer sources for all
226         * columns if necessary.
227         *
228         * @param container
229         *            the component from which to get the settings
230         */
231        public void loadSettings(IComponent container)
232        {
233            IComponent objColumnRendererSource =
234              (IComponent) container.getComponents().get(getColumnName() + COLUMN_RENDERER_BLOCK_SUFFIX);
235    
236            if (objColumnRendererSource == null)
237                objColumnRendererSource = (IComponent) container.getComponents().get(COLUMN_RENDERER_BLOCK_SUFFIX);
238    
239            if (objColumnRendererSource != null
240                && objColumnRendererSource instanceof Block)
241            {
242                setColumnRendererSource(new BlockTableRendererSource((Block) objColumnRendererSource));
243            }
244    
245            IComponent objValueRendererSource =
246              (IComponent) container.getComponents().get(getColumnName() + VALUE_RENDERER_BLOCK_SUFFIX);
247    
248            if (objValueRendererSource == null)
249            {
250                objValueRendererSource = (IComponent) container.getComponents().get(VALUE_RENDERER_BLOCK_SUFFIX);
251            }
252    
253            if (objValueRendererSource != null
254                && objValueRendererSource instanceof Block)
255            {
256                setValueRendererSource(new BlockTableRendererSource((Block) objValueRendererSource));
257            }
258        }
259    
260    }