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.commons.logging.Log;
018    import org.apache.commons.logging.LogFactory;
019    import org.apache.tapestry.BaseComponent;
020    import org.apache.tapestry.IBinding;
021    import org.apache.tapestry.IMarkupWriter;
022    import org.apache.tapestry.IRequestCycle;
023    import org.apache.tapestry.Tapestry;
024    import org.apache.tapestry.contrib.tree.model.ISessionStoreManager;
025    import org.apache.tapestry.contrib.tree.model.ITreeModel;
026    import org.apache.tapestry.contrib.tree.model.ITreeModelSource;
027    import org.apache.tapestry.contrib.tree.model.ITreeSessionStateManager;
028    import org.apache.tapestry.contrib.tree.model.ITreeStateListener;
029    import org.apache.tapestry.contrib.tree.simple.FullTreeSessionStateManager;
030    import org.apache.tapestry.event.PageBeginRenderListener;
031    import org.apache.tapestry.event.PageDetachListener;
032    import org.apache.tapestry.event.PageEvent;
033    import org.apache.tapestry.util.ComponentAddress;
034    
035    /**
036     */
037    public abstract class TreeView extends BaseComponent implements
038            PageDetachListener, PageBeginRenderListener, ITreeModelSource
039    {
040    
041        private static final Log LOG = LogFactory.getLog(TreeView.class);
042    
043        private IBinding m_objSessionStoreManagerBinding;
044    
045        private IBinding m_objTreeModelBinding;
046    
047        private IBinding m_objSessionStateManagerBinding;
048    
049        private ITreeModel m_objTreeModel;
050    
051        private ITreeSessionStateManager m_objTreeSessionStateManager;
052    
053        private ISessionStoreManager m_objSessionStoreManager;
054    
055        private Object m_objTreeSessionState;
056    
057        private ComponentAddress m_objComponentAddress;
058    
059        public TreeView()
060        {
061            super();
062            initialize();
063        }
064    
065        private void initialize()
066        {
067            m_objTreeModel = null;
068            m_objTreeSessionStateManager = null;
069            m_objSessionStoreManager = null;
070            m_objTreeSessionState = null;
071            m_objComponentAddress = null;
072        }
073    
074        /**
075         * @see org.apache.tapestry.AbstractComponent#renderComponent(IMarkupWriter,
076         *      IRequestCycle)
077         */
078    
079        /**
080         * @see org.apache.tapestry.event.PageDetachListener#pageDetached(PageEvent)
081         */
082        public void pageDetached(PageEvent arg0)
083        {
084            initialize();
085        }
086    
087        /**
088         * @see org.apache.tapestry.event.PageRenderListener#pageBeginRender(PageEvent)
089         */
090        public void pageBeginRender(PageEvent arg0)
091        {
092            if (arg0.getRequestCycle().isRewinding()) { return; }
093            storeSesion();
094        }
095    
096        /**
097         * Returns the treeModelBinding.
098         * 
099         * @return IBinding
100         */
101        public IBinding getTreeModelBinding()
102        {
103            return m_objTreeModelBinding;
104        }
105    
106        /**
107         * Sets the treeModelBinding.
108         * 
109         * @param treeModelBinding
110         *            The treeModelBinding to set
111         */
112        public void setTreeModelBinding(IBinding treeModelBinding)
113        {
114            m_objTreeModelBinding = treeModelBinding;
115        }
116    
117        /**
118         * Returns the SessionStoreManagerBinding.
119         * 
120         * @return IBinding
121         */
122        public IBinding getSessionStoreManagerBinding()
123        {
124            return m_objSessionStoreManagerBinding;
125        }
126    
127        /**
128         * Returns the sessionStateManagerBinding.
129         * 
130         * @return IBinding
131         */
132        public IBinding getSessionStateManagerBinding()
133        {
134            return m_objSessionStateManagerBinding;
135        }
136    
137        /**
138         * Sets the SessionStoreManagerBinding.
139         * 
140         * @param sessionStoreManagerBinding
141         *            The SessionStoreManagerBinding to set
142         */
143        public void setSessionStoreManagerBinding(
144                IBinding sessionStoreManagerBinding)
145        {
146            m_objSessionStoreManagerBinding = sessionStoreManagerBinding;
147        }
148    
149        /**
150         * Sets the sessionStateManagerBinding.
151         * 
152         * @param sessionStateManagerBinding
153         *            The sessionStateManagerBinding to set
154         */
155        public void setSessionStateManagerBinding(
156                IBinding sessionStateManagerBinding)
157        {
158            m_objSessionStateManagerBinding = sessionStateManagerBinding;
159        }
160    
161        private void extractTreeModel()
162        {
163            if (LOG.isDebugEnabled())
164            {
165                LOG.debug("TreeView.extractTreeModel()");
166            }
167    
168            ISessionStoreManager objHolder = getSessionStoreManager();
169            ITreeSessionStateManager objSessionManager = getTreeSessionStateMgr();
170            Object objSessionState;
171            if (objHolder == null)
172            {
173                objSessionState = getTreeSessionState();
174            }
175            else
176            {
177                objSessionState = objHolder.getSessionState(this.getPage(),
178                        "treeSessionState");
179            }
180    
181            if (objSessionState != null)
182            {
183                m_objTreeModel = objSessionManager.getModel(objSessionState);
184            }
185            else
186            {
187                if (LOG.isDebugEnabled())
188                {
189                    LOG.debug("TreeView.extractTreeModel() from BINDING");
190                }
191    
192                m_objTreeModel = (ITreeModel) getTreeModelBinding().getObject();
193            }
194    
195        }
196    
197        private void storeSesion()
198        {
199            if (LOG.isDebugEnabled())
200            {
201                LOG.debug("TreeView.storeSesion()");
202            }
203    
204            ITreeSessionStateManager objSessionManager = getTreeSessionStateMgr();
205            Object objSessionState = objSessionManager
206                    .getSessionState(getTreeModel());
207    
208            store(objSessionState);
209        }
210    
211        private void store(Object objSessionState)
212        {
213            ISessionStoreManager objHolder = getSessionStoreManager();
214    
215            if (objHolder == null)
216            {
217                Tapestry.fireObservedChange(this, "treeSessionState",
218                        objSessionState);
219            }
220            else
221            {
222                // String strPath = "treeSessionState";
223                String strPath = getExtendedId();
224                if (LOG.isDebugEnabled())
225                    LOG.debug("store(): setting state with: " + strPath);
226                objHolder.setSessionState(this.getPage(), strPath, objSessionState);
227            }
228        }
229    
230        /**
231         * @see ITreeComponent#resetState()
232         */
233        public void resetState()
234        {
235            if (LOG.isDebugEnabled())
236            {
237                LOG.debug("TreeView.resetState()");
238            }
239            initialize();
240            store(null);
241        }
242    
243        /**
244         * Returns the SessionStoreManager.
245         * 
246         * @return ISessionStoreManager
247         */
248        public ISessionStoreManager getSessionStoreManager()
249        {
250            if (m_objSessionStoreManager == null
251                    && getSessionStoreManagerBinding() != null)
252            {
253                m_objSessionStoreManager = (ISessionStoreManager) getSessionStoreManagerBinding()
254                        .getObject();
255            }
256    
257            return m_objSessionStoreManager;
258        }
259    
260        /**
261         * Returns the wizardSessionStateMgr.
262         * 
263         * @return IWizardSessionStateManager
264         */
265        public ITreeSessionStateManager getTreeSessionStateMgr()
266        {
267            if (m_objTreeSessionStateManager == null)
268            {
269                IBinding objBinding = getSessionStateManagerBinding();
270                if (objBinding != null)
271                {
272                    Object objManager = objBinding.getObject();
273                    m_objTreeSessionStateManager = (ITreeSessionStateManager) objManager;
274                }
275                else
276                {
277                    m_objTreeSessionStateManager = new FullTreeSessionStateManager();
278                }
279            }
280            return m_objTreeSessionStateManager;
281        }
282    
283        public ComponentAddress getComponentPath()
284        {
285            if (m_objComponentAddress == null)
286            {
287                m_objComponentAddress = new ComponentAddress(this);
288            }
289            return m_objComponentAddress;
290        }
291    
292        /**
293         * Returns the treeModel.
294         * 
295         * @return ITreeModel
296         */
297        public ITreeModel getTreeModel()
298        {
299            if (m_objTreeModel == null)
300            {
301                extractTreeModel();
302            }
303            return m_objTreeModel;
304        }
305    
306        /**
307         * Sets the treeModel.
308         * 
309         * @param treeModel
310         *            The treeModel to set
311         */
312        public void setTreeModel(ITreeModel treeModel)
313        {
314            m_objTreeModel = treeModel;
315        }
316    
317        /**
318         * Returns the treeSessionState.
319         * 
320         * @return Object
321         */
322        public Object getTreeSessionState()
323        {
324            return m_objTreeSessionState;
325        }
326    
327        /**
328         * Sets the treeSessionState.
329         * 
330         * @param treeSessionState
331         *            The treeSessionState to set
332         */
333        public void setTreeSessionState(Object treeSessionState)
334        {
335            m_objTreeSessionState = treeSessionState;
336        }
337    
338        public String getSelectedNodeStyleID()
339        {
340            return getId() + ":selected";
341        }
342    
343        /**
344         * @see org.apache.tapestry.BaseComponent#renderComponent(org.apache.tapestry.IMarkupWriter,
345         *      org.apache.tapestry.IRequestCycle)
346         */
347        protected void renderComponent(IMarkupWriter arg0, IRequestCycle arg1)
348        {
349            Object objExistedTreeModelSource = arg1
350                    .getAttribute(ITreeModelSource.TREE_MODEL_SOURCE_ATTRIBUTE);
351            arg1.setAttribute(ITreeModelSource.TREE_MODEL_SOURCE_ATTRIBUTE, this);
352    
353            super.renderComponent(arg0, arg1);
354            arg1.setAttribute(ITreeModelSource.TREE_MODEL_SOURCE_ATTRIBUTE,
355                    objExistedTreeModelSource);
356        }
357    
358        /**
359         * @see org.apache.tapestry.contrib.tree.model.ITreeModelSource#getTreeStateListener()
360         */
361        public ITreeStateListener getTreeStateListener()
362        {
363            ITreeStateListener objListener = null;
364            IBinding objBinding = getBinding("treeStateListener");
365            if (objBinding != null)
366            {
367                objListener = (ITreeStateListener) objBinding.getObject();
368            }
369            return objListener;
370        }
371    
372    }