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