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 }