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; 016 017 import org.apache.tapestry.BaseComponent; 018 import org.apache.tapestry.IMarkupWriter; 019 import org.apache.tapestry.IRequestCycle; 020 import org.apache.tapestry.event.PageDetachListener; 021 import org.apache.tapestry.contrib.tree.model.ITreeDataModel; 022 import org.apache.tapestry.contrib.tree.model.ITreeModel; 023 import org.apache.tapestry.contrib.tree.model.ITreeRowSource; 024 import org.apache.tapestry.contrib.tree.model.TreeRowObject; 025 026 import java.util.Iterator; 027 import org.apache.tapestry.event.PageEvent; 028 029 030 /** 031 * @author tsveltin ? 032 */ 033 public abstract class TreeDataView extends BaseComponent implements 034 ITreeRowSource, PageDetachListener { 035 private TreeRowObject m_objTreeRowObject = null; 036 037 private int m_nTreeDeep = -1; 038 039 public abstract TreeView getTreeView(); 040 041 public TreeDataView() 042 { 043 super(); 044 initialize(); 045 } 046 047 public void initialize() 048 { 049 m_objTreeRowObject = null; 050 m_nTreeDeep = -1; 051 } 052 053 public void pageDetached(PageEvent event) { 054 initialize(); 055 } 056 057 public void renderComponent(IMarkupWriter writer, IRequestCycle cycle) 058 { 059 // render data 060 Object objExistedTreeModelSource = cycle.getAttribute(ITreeRowSource.TREE_ROW_SOURCE_ATTRIBUTE); 061 cycle.setAttribute(ITreeRowSource.TREE_ROW_SOURCE_ATTRIBUTE, this); 062 063 TreeView objView = getTreeView(); 064 ITreeModel objTreeModel = objView.getTreeModel(); 065 ITreeDataModel objTreeDataModel = objTreeModel.getTreeDataModel(); 066 067 Object objRoot = objTreeDataModel.getRoot(); 068 Object objRootUID = objTreeDataModel.getUniqueKey(objRoot, null); 069 070 if (getShowRootNode()) { 071 072 walkTree(objRoot, objRootUID, 0, objTreeModel, writer, cycle, 073 TreeRowObject.FIRST_LAST_ROW, new int[0], true); 074 } else { 075 076 boolean bFirst = true; 077 078 int nChildenCount = objTreeModel.getTreeDataModel().getChildCount(objRoot); 079 int nRowPossiotionType = nChildenCount == 1 ? TreeRowObject.FIRST_LAST_ROW : TreeRowObject.FIRST_ROW; 080 081 for (Iterator iter = objTreeModel.getTreeDataModel().getChildren(objRoot); iter.hasNext();) 082 { 083 Object objChild = iter.next(); 084 Object objChildUID = objTreeModel.getTreeDataModel().getUniqueKey(objChild, objRoot); 085 086 boolean bChildLast = !iter.hasNext(); 087 if (!bFirst) { 088 089 if (bChildLast) 090 nRowPossiotionType = TreeRowObject.LAST_ROW; 091 else 092 nRowPossiotionType = TreeRowObject.MIDDLE_ROW; 093 } 094 095 walkTree(objChild, objChildUID, 0, objTreeModel, writer, cycle, 096 nRowPossiotionType, new int[0], bChildLast); 097 098 bFirst = false; 099 } 100 } 101 102 cycle.setAttribute(ITreeRowSource.TREE_ROW_SOURCE_ATTRIBUTE, objExistedTreeModelSource); 103 } 104 105 public void walkTree(Object objParent, Object objParentUID, int nDepth, 106 ITreeModel objTreeModel, IMarkupWriter writer, IRequestCycle cycle, 107 int nRowPossiotionType, int[] arrConnectImages, boolean bLast) 108 { 109 int rowPositionType = nRowPossiotionType; 110 m_nTreeDeep = nDepth; 111 int nNumberOfChildren = objTreeModel.getTreeDataModel().getChildCount( 112 objParent); 113 boolean bLeaf = (nNumberOfChildren == 0) ? true : false; 114 m_objTreeRowObject = new TreeRowObject(objParent, objParentUID, nDepth, 115 bLeaf, rowPositionType, arrConnectImages); 116 117 super.renderComponent(writer, cycle); 118 119 boolean bContain = objTreeModel.getTreeStateModel() 120 .isUniqueKeyExpanded(objParentUID); 121 if (bContain) { 122 int[] arrConnectImagesNew = new int[arrConnectImages.length + 1]; 123 System.arraycopy(arrConnectImages, 0, arrConnectImagesNew, 0, 124 arrConnectImages.length); 125 if (bLast) 126 arrConnectImagesNew[arrConnectImagesNew.length - 1] = TreeRowObject.EMPTY_CONN_IMG; 127 else arrConnectImagesNew[arrConnectImagesNew.length - 1] = TreeRowObject.LINE_CONN_IMG; 128 129 for (Iterator iter = objTreeModel.getTreeDataModel().getChildren( 130 objParent); iter.hasNext();) { 131 Object objChild = iter.next(); 132 Object objChildUID = objTreeModel.getTreeDataModel() 133 .getUniqueKey(objChild, objParentUID); 134 boolean bChildLast = !iter.hasNext(); 135 if (bChildLast) 136 rowPositionType = TreeRowObject.LAST_ROW; 137 else rowPositionType = TreeRowObject.MIDDLE_ROW; 138 walkTree(objChild, objChildUID, nDepth + 1, objTreeModel, 139 writer, cycle, rowPositionType, arrConnectImagesNew, 140 bChildLast); 141 } 142 } 143 } 144 145 public int getTreeDeep() 146 { 147 return m_nTreeDeep; 148 } 149 150 /** 151 * @see org.apache.tapestry.contrib.tree.model.ITreeRowSource#getTreeRow() 152 */ 153 public TreeRowObject getTreeRow() 154 { 155 return getTreeRowObject(); 156 } 157 158 public TreeRowObject getTreeRowObject() 159 { 160 return m_objTreeRowObject; 161 } 162 163 public void setTreeRowObject(TreeRowObject object) 164 { 165 m_objTreeRowObject = object; 166 } 167 168 public abstract boolean getShowRootNode(); 169 170 }