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.components;
016    
017    import java.util.Iterator;
018    
019    import org.apache.tapestry.IAsset;
020    import org.apache.tapestry.IMarkupWriter;
021    import org.apache.tapestry.IRender;
022    import org.apache.tapestry.IRequestCycle;
023    import org.apache.tapestry.contrib.table.model.ITableColumn;
024    import org.apache.tapestry.contrib.table.model.ITableColumnModel;
025    
026    /**
027     * A low level Table component that renders the column headers in the table.
028     * This component must be wrapped by
029     * {@link org.apache.tapestry.contrib.table.components.TableView}.
030     * <p>
031     * The component iterates over all column objects in the
032     * {@link org.apache.tapestry.contrib.table.model.ITableColumnModel}and renders
033     * a header for each one of them using the renderer provided by the
034     * getColumnRender() method in
035     * {@link org.apache.tapestry.contrib.table.model.ITableColumn}. The headers
036     * are wrapped in 'th' tags by default.
037     * <p>
038     * Please see the Component Reference for details on how to use this component. [
039     * <a
040     * href="../../../../../../../ComponentReference/contrib.TableColumns.html">Component
041     * Reference </a>]
042     * 
043     * @author mindbridge
044     */
045    public abstract class TableColumns extends AbstractTableViewComponent
046    {
047    
048        public static final String TABLE_COLUMN_ARROW_UP_ATTRIBUTE = "org.apache.tapestry.contrib.table.components.TableColumns.arrowUp";
049    
050        public static final String TABLE_COLUMN_ARROW_DOWN_ATTRIBUTE = "org.apache.tapestry.contrib.table.components.TableColumns.arrowDown";
051    
052        public static final String TABLE_COLUMN_CSS_CLASS_SUFFIX = "ColumnHeader";
053    
054        // Transient
055        private ITableColumn m_objTableColumn = null;
056        
057        public abstract IAsset getArrowDownAsset();
058    
059        public abstract IAsset getArrowUpAsset();
060    
061        public abstract void setColumn(ITableColumn column);
062    
063        /**
064         * Returns the currently rendered table column. You can call this method to
065         * obtain the current column.
066         * 
067         * @return ITableColumn the current table column
068         */
069        public ITableColumn getTableColumn()
070        {
071            return m_objTableColumn;
072        }
073    
074        /**
075         * Sets the currently rendered table column. This method is for internal use
076         * only.
077         * 
078         * @param tableColumn
079         *            The current table column
080         */
081        public void setTableColumn(ITableColumn tableColumn)
082        {
083            m_objTableColumn = tableColumn;
084    
085            if (isParameterBound("column")) setColumn(tableColumn);
086        }
087    
088        /**
089         * Get the list of all table columns to be displayed.
090         * 
091         * @return an iterator of all table columns
092         */
093        public Iterator getTableColumnIterator()
094        {
095            ITableColumnModel objColumnModel = getTableModelSource()
096                    .getTableModel().getColumnModel();
097            return objColumnModel.getColumns();
098        }
099    
100        /**
101         * Returns the renderer to be used to generate the header of the current
102         * column.
103         * 
104         * @return the header renderer of the current column
105         */
106        public IRender getTableColumnRenderer()
107        {
108            return getTableColumn().getColumnRenderer(getPage().getRequestCycle(),
109                    getTableModelSource());
110        }
111    
112        public abstract String getColumnClassParameter();
113    
114        /**
115         * Returns the CSS class of the generated table cell. It uses the class
116         * parameter if it has been bound, or the default value of "[column
117         * name]ColumnHeader" otherwise.
118         * 
119         * @return the CSS class of the cell
120         */
121        public String getColumnClass()
122        {
123            if (isParameterBound("class")) return getColumnClassParameter();
124    
125            return getTableColumn().getColumnName() + TABLE_COLUMN_CSS_CLASS_SUFFIX;
126        }
127    
128        /**
129         * @see org.apache.tapestry.BaseComponent#renderComponent(IMarkupWriter,
130         *      IRequestCycle)
131         */
132        protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle)
133        {
134            Object oldValueUp = cycle.getAttribute(TABLE_COLUMN_ARROW_UP_ATTRIBUTE);
135            Object oldValueDown = cycle
136                    .getAttribute(TABLE_COLUMN_ARROW_DOWN_ATTRIBUTE);
137    
138            try
139            {
140                cycle.setAttribute(TABLE_COLUMN_ARROW_UP_ATTRIBUTE,
141                        getArrowUpAsset());
142                cycle.setAttribute(TABLE_COLUMN_ARROW_DOWN_ATTRIBUTE,
143                        getArrowDownAsset());
144    
145                super.renderComponent(writer, cycle);
146            }
147            finally
148            {
149                cycle.setAttribute(TABLE_COLUMN_ARROW_UP_ATTRIBUTE, oldValueUp);
150                cycle.setAttribute(TABLE_COLUMN_ARROW_DOWN_ATTRIBUTE, oldValueDown);
151    
152                // set the current column to null when the component is not active
153                m_objTableColumn = null;
154            }
155        }
156    
157    }