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