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.tree.components.table;
016    
017    import java.util.ArrayList;
018    import java.util.Iterator;
019    import java.util.List;
020    
021    import org.apache.tapestry.BaseComponent;
022    import org.apache.tapestry.IMarkupWriter;
023    import org.apache.tapestry.IRequestCycle;
024    import org.apache.tapestry.contrib.table.model.ITableColumn;
025    import org.apache.tapestry.contrib.table.model.ITableModel;
026    import org.apache.tapestry.contrib.table.model.ITableSessionStateManager;
027    import org.apache.tapestry.contrib.table.model.simple.SimpleListTableDataModel;
028    import org.apache.tapestry.contrib.table.model.simple.SimpleTableColumnModel;
029    import org.apache.tapestry.contrib.table.model.simple.SimpleTableModel;
030    import org.apache.tapestry.contrib.table.model.simple.SimpleTableSessionStateManager;
031    import org.apache.tapestry.contrib.tree.model.ITreeDataModel;
032    import org.apache.tapestry.contrib.tree.model.ITreeModel;
033    import org.apache.tapestry.contrib.tree.model.ITreeModelSource;
034    import org.apache.tapestry.contrib.tree.model.ITreeRowSource;
035    import org.apache.tapestry.contrib.tree.model.TreeRowObject;
036    import org.apache.tapestry.event.PageDetachListener;
037    import org.apache.tapestry.event.PageEvent;
038    
039    /**
040     */
041    public abstract class TreeTableDataView extends BaseComponent implements ITreeRowSource,
042            PageDetachListener
043    {
044        private int m_nTreeDeep = -1;
045    
046        private TreeRowObject m_objTreeRowObject = null;
047    
048        private ArrayList m_arrAllExpandedNodes = null;
049    
050        public TreeTableDataView()
051        {
052            super();
053            initialize();
054        }
055    
056        public void initialize()
057        {
058            m_nTreeDeep = -1;
059            // m_objTableModel = null;
060            m_objTreeRowObject = null;
061            m_arrAllExpandedNodes = null;
062        }
063    
064        /**
065         * @see org.apache.tapestry.event.PageDetachListener#pageDetached(org.apache.tapestry.event.PageEvent)
066         */
067        public void pageDetached(PageEvent event)
068        {
069            initialize();
070        }
071    
072        public abstract ITreeModelSource getTreeViewParameter();
073    
074        public ITreeModelSource getTreeModelSource()
075        {
076            ITreeModelSource objSource = (ITreeModelSource) getPage().getRequestCycle().getAttribute(
077                    ITreeModelSource.TREE_MODEL_SOURCE_ATTRIBUTE);
078    
079            return objSource == null ? getTreeViewParameter() : objSource;
080        }
081    
082        public List generateNodeList()
083        {
084            if (m_arrAllExpandedNodes == null)
085            {
086                ArrayList arrAllExpandedNodes = new ArrayList();
087    
088                // render data
089                ITreeModelSource objTreeModelSource = getTreeModelSource();
090                ITreeModel objTreeModel = objTreeModelSource.getTreeModel();
091                ITreeDataModel objTreeDataModel = objTreeModel.getTreeDataModel();
092    
093                Object objRoot = objTreeDataModel.getRoot();
094                Object objRootUID = objTreeDataModel.getUniqueKey(objRoot, null);
095                if (getShowRootNode())
096                {
097                    walkTree(
098                            arrAllExpandedNodes,
099                            objRoot,
100                            objRootUID,
101                            0,
102                            objTreeModel,
103                            TreeRowObject.FIRST_LAST_ROW,
104                            new int[0],
105                            true);
106                }
107                else
108                {
109                    int nChildenCount = objTreeModel.getTreeDataModel().getChildCount(objRoot);
110                    int nRowPossiotionType = nChildenCount == 1 ? TreeRowObject.FIRST_LAST_ROW
111                            : TreeRowObject.FIRST_ROW;
112                    boolean bFirst = true;
113                    for (Iterator iter = objTreeModel.getTreeDataModel().getChildren(objRoot); iter
114                            .hasNext();)
115                    {
116                        Object objChild = iter.next();
117                        Object objChildUID = objTreeModel.getTreeDataModel().getUniqueKey(
118                                objChild,
119                                objRoot);
120                        boolean bChildLast = !iter.hasNext();
121                        if (!bFirst)
122                        {
123                            if (bChildLast)
124                                nRowPossiotionType = TreeRowObject.LAST_ROW;
125                            else
126                                nRowPossiotionType = TreeRowObject.MIDDLE_ROW;
127                        }
128                        walkTree(
129                                arrAllExpandedNodes,
130                                objChild,
131                                objChildUID,
132                                0,
133                                objTreeModel,
134                                nRowPossiotionType,
135                                new int[0],
136                                bChildLast);
137                        bFirst = false;
138                    }
139                }
140    
141                m_arrAllExpandedNodes = arrAllExpandedNodes;
142            }
143    
144            return m_arrAllExpandedNodes;
145        }
146    
147        public void walkTree(ArrayList arrAllExpandedNodes, Object objParent, Object objParentUID,
148                int nDepth, ITreeModel objTreeModel, int nRowPossiotionType, int[] arrConnectImages,
149                boolean bLast)
150        {
151            m_nTreeDeep = nDepth;
152    
153            int nNumberOfChildren = objTreeModel.getTreeDataModel().getChildCount(objParent);
154            boolean bLeaf = (nNumberOfChildren == 0) ? true : false;
155            TreeRowObject objTreeRowObject = new TreeRowObject(objParent, objParentUID, nDepth, bLeaf,
156                    nRowPossiotionType, arrConnectImages);
157            arrAllExpandedNodes.add(objTreeRowObject);
158    
159            boolean bContain = objTreeModel.getTreeStateModel().isUniqueKeyExpanded(objParentUID);
160            if (bContain)
161            {
162                int[] arrConnectImagesNew = new int[arrConnectImages.length + 1];
163                System.arraycopy(arrConnectImages, 0, arrConnectImagesNew, 0, arrConnectImages.length);
164                if (bLast)
165                    arrConnectImagesNew[arrConnectImagesNew.length - 1] = TreeRowObject.EMPTY_CONN_IMG;
166                else
167                    arrConnectImagesNew[arrConnectImagesNew.length - 1] = TreeRowObject.LINE_CONN_IMG;
168                Iterator colChildren = objTreeModel.getTreeDataModel().getChildren(objParent);
169                for (Iterator iter = colChildren; iter.hasNext();)
170                {
171                    Object objChild = iter.next();
172                    Object objChildUID = objTreeModel.getTreeDataModel().getUniqueKey(
173                            objChild,
174                            objParentUID);
175                    boolean bChildLast = !iter.hasNext();
176                    if (bChildLast)
177                        nRowPossiotionType = TreeRowObject.LAST_ROW;
178                    else
179                        nRowPossiotionType = TreeRowObject.MIDDLE_ROW;
180                    walkTree(
181                            arrAllExpandedNodes,
182                            objChild,
183                            objChildUID,
184                            nDepth + 1,
185                            objTreeModel,
186                            nRowPossiotionType,
187                            arrConnectImagesNew,
188                            bChildLast);
189                }
190            }
191        }
192    
193        /**
194         * Returns the treeDeep.
195         * 
196         * @return int
197         */
198        public int getTreeDeep()
199        {
200            return m_nTreeDeep;
201        }
202    
203        /*
204         * public ITableModel getTableModel() { if(m_objTableModel == null){ m_objTableModel =
205         * createTableModel(); } return m_objTableModel; }
206         */
207        public ITableModel getTableModel()
208        {
209            return createTableModel();
210        }
211    
212        private ITableModel createTableModel()
213        {
214            List arrAllNodes = generateNodeList();
215            Object[] arrAllExpandedNodes = new Object[arrAllNodes.size()];
216            arrAllNodes.toArray(arrAllExpandedNodes);
217    
218            SimpleTableModel objTableModel = new SimpleTableModel(arrAllExpandedNodes,
219                    getTableColumns());
220            objTableModel.getPagingState().setPageSize(getEntriesPerTablePage());
221    
222            return objTableModel;
223        }
224    
225        public ITableColumn[] getTableColumns()
226        {
227            ArrayList arrColumnsList = new ArrayList();
228            arrColumnsList.add(new TreeTableColumn("Name", false, null));
229    
230            List arrTableColumns = getTableColumnsParameter();
231            if (arrTableColumns != null)
232                arrColumnsList.addAll(arrTableColumns);
233    
234            ITableColumn[] arrColumns = new ITableColumn[arrColumnsList.size()];
235            arrColumnsList.toArray(arrColumns);
236    
237            return arrColumns;
238        }
239    
240        public abstract List getTableColumnsParameter();
241    
242        public abstract int getEntriesPerTablePage();
243    
244        /**
245         * @see org.apache.tapestry.contrib.tree.model.ITreeRowSource#getTreeRow()
246         */
247        public TreeRowObject getTreeRow()
248        {
249            return getTreeRowObject();
250        }
251    
252        public ITableSessionStateManager getTableSessionStateManager()
253        {
254            SimpleListTableDataModel objDataModel = new SimpleListTableDataModel(generateNodeList());
255            SimpleTableColumnModel objColumnModel = new SimpleTableColumnModel(getTableColumns());
256            SimpleTableSessionStateManager objStateManager = new SimpleTableSessionStateManager(
257                    objDataModel, objColumnModel);
258            return objStateManager;
259            // return NullTableSessionStateManager.NULL_STATE_MANAGER;
260        }
261    
262        /**
263         * @see org.apache.tapestry.BaseComponent#renderComponent(org.apache.tapestry.IMarkupWriter,
264         *      org.apache.tapestry.IRequestCycle)
265         */
266        protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle)
267        {
268            Object objExistedTreeModelSource = cycle
269                    .getAttribute(ITreeRowSource.TREE_ROW_SOURCE_ATTRIBUTE);
270            cycle.setAttribute(ITreeRowSource.TREE_ROW_SOURCE_ATTRIBUTE, this);
271    
272            super.renderComponent(writer, cycle);
273    
274            cycle.setAttribute(ITreeRowSource.TREE_ROW_SOURCE_ATTRIBUTE, objExistedTreeModelSource);
275        }
276    
277        /**
278         * @see org.apache.tapestry.AbstractComponent#renderBody(org.apache.tapestry.IMarkupWriter,
279         *      org.apache.tapestry.IRequestCycle)
280         */
281        public void renderBody(IMarkupWriter writer, IRequestCycle cycle)
282        {
283            Object objExistedTreeModelSource = cycle
284                    .getAttribute(ITreeRowSource.TREE_ROW_SOURCE_ATTRIBUTE);
285            cycle.setAttribute(ITreeRowSource.TREE_ROW_SOURCE_ATTRIBUTE, this);
286    
287            super.renderBody(writer, cycle);
288    
289            cycle.setAttribute(ITreeRowSource.TREE_ROW_SOURCE_ATTRIBUTE, objExistedTreeModelSource);
290        }
291    
292        public TreeRowObject getTreeRowObject()
293        {
294            return m_objTreeRowObject;
295        }
296    
297        public void setTreeRowObject(TreeRowObject object)
298        {
299            m_objTreeRowObject = object;
300        }
301    
302        public abstract boolean getShowRootNode();
303    }