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