| // Copyright 2004, 2005 The Apache Software Foundation |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| package org.apache.tapestry.contrib.tree.components; |
| |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| import org.apache.tapestry.BaseComponent; |
| import org.apache.tapestry.IAsset; |
| import org.apache.tapestry.IMarkupWriter; |
| import org.apache.tapestry.IRender; |
| import org.apache.tapestry.IRequestCycle; |
| import org.apache.tapestry.contrib.tree.model.ITreeModelSource; |
| import org.apache.tapestry.contrib.tree.model.ITreeRowSource; |
| import org.apache.tapestry.contrib.tree.model.ITreeStateListener; |
| import org.apache.tapestry.contrib.tree.model.ITreeStateModel; |
| import org.apache.tapestry.contrib.tree.model.TreeRowObject; |
| import org.apache.tapestry.contrib.tree.model.TreeStateEvent; |
| import org.apache.tapestry.contrib.tree.simple.SimpleNodeRenderFactory; |
| import org.apache.tapestry.engine.IPageLoader; |
| import org.apache.tapestry.event.PageDetachListener; |
| import org.apache.tapestry.event.PageEvent; |
| import org.apache.tapestry.spec.ComponentSpecification; |
| import org.apache.tapestry.util.ComponentAddress; |
| |
| /** |
| * @author tsveltin? |
| */ |
| public abstract class TreeNodeView extends BaseComponent implements |
| PageDetachListener |
| { |
| |
| private static final Log LOG = LogFactory.getLog(TreeNodeView.class); |
| |
| private Boolean m_objNodeState; |
| |
| private Boolean m_objShowNodeImages; |
| |
| private INodeRenderFactory m_objNodeRenderFactory; |
| |
| private IAsset m_objOpenNodeImage; |
| |
| private IAsset m_objCloseNodeImage; |
| |
| private int m_currentForeachConnectImageValue = TreeRowObject.LINE_CONN_IMG; |
| |
| /** |
| * Creates tree . |
| * |
| */ |
| public TreeNodeView() |
| { |
| super(); |
| initialize(); |
| } |
| |
| public abstract INodeRenderFactory getNodeRenderFactoryParameter(); |
| |
| public abstract Boolean getShowNodeImages(); |
| |
| private void initialize() |
| { |
| m_objNodeState = null; |
| m_objShowNodeImages = null; |
| m_objNodeRenderFactory = null; |
| m_currentForeachConnectImageValue = TreeRowObject.LINE_CONN_IMG; |
| } |
| |
| public IRender getCurrentRenderer() |
| { |
| INodeRenderFactory objRenderFactory = getNodeRenderFactory(); |
| ITreeRowSource objTreeRowSource = getTreeRowSource(); |
| return objRenderFactory.getRender(objTreeRowSource.getTreeRow() |
| .getTreeNode(), getTreeModelSource(), getPage() |
| .getRequestCycle()); |
| } |
| |
| public Object[] getNodeContext() |
| { |
| ITreeModelSource objModelSource = getTreeModelSource(); |
| ComponentAddress objModelSourceAddress = new ComponentAddress( |
| objModelSource); |
| ITreeRowSource objTreeRowSource = getTreeRowSource(); |
| TreeRowObject objTreeRowObject = objTreeRowSource.getTreeRow(); |
| Object objValueUID = objTreeRowObject.getTreeNodeUID(); |
| if (LOG.isDebugEnabled()) |
| { |
| LOG.debug("getNodeContext objValueUID = " + objValueUID); |
| } |
| |
| return new Object[] { objValueUID, new Boolean(isNodeOpen()), |
| objModelSourceAddress }; |
| } |
| |
| /** |
| * Called when a node in the tree is clicked by the user. If the node is |
| * expanded, it will be collapsed, and vice-versa, that is, the tree state |
| * model is retrieved, and it is told to collapse or expand the node. |
| * |
| * @param cycle |
| * The Tapestry request cycle object. |
| */ |
| public void nodeExpandCollaps(IRequestCycle cycle) |
| { |
| Object[] context = cycle.getListenerParameters(); |
| Object objValueUID = null; |
| if (context != null && context.length > 0) |
| { |
| objValueUID = context[0]; |
| } |
| ComponentAddress objModelSourceAddress = (ComponentAddress) context[2]; |
| ITreeModelSource objTreeModelSource = (ITreeModelSource) objModelSourceAddress |
| .findComponent(cycle); |
| // ITreeModelSource objTreeModelSource = getTreeModelSource(); |
| ITreeStateModel objStateModel = objTreeModelSource.getTreeModel() |
| .getTreeStateModel(); |
| boolean bState = objStateModel.isUniqueKeyExpanded(objValueUID); |
| |
| if (bState) |
| { |
| objStateModel.collapse(objValueUID); |
| fireNodeCollapsed(objValueUID, objTreeModelSource); |
| } |
| else |
| { |
| objStateModel.expandPath(objValueUID); |
| fireNodeExpanded(objValueUID, objTreeModelSource); |
| } |
| } |
| |
| /** |
| * Called when a node in the tree is selected by the user. the tree state |
| * model is retrieved, and it is told to select the node. |
| * |
| * @param cycle |
| * The Tapestry request cycle object. |
| */ |
| public void nodeSelect(IRequestCycle cycle) |
| { |
| Object[] context = cycle.getListenerParameters(); |
| Object objValueUID = null; |
| if (context != null && context.length > 0) |
| { |
| objValueUID = context[0]; |
| } |
| ComponentAddress objModelSourceAddress = (ComponentAddress) context[2]; |
| ITreeModelSource objTreeModelSource = (ITreeModelSource) objModelSourceAddress |
| .findComponent(cycle); |
| // ITreeModelSource objTreeModelSource = getTreeModelSource(); |
| ITreeStateModel objStateModel = objTreeModelSource.getTreeModel() |
| .getTreeStateModel(); |
| Object objSelectedNodeInState = objStateModel.getSelectedNode(); |
| |
| if (objValueUID.equals(objSelectedNodeInState)) |
| { |
| // do nothing, the selected node in UI is the same as the selected |
| // in |
| // state model. The user should use refresh of back button. |
| return; |
| } |
| |
| objStateModel.setSelectedNode(objValueUID); |
| fireNodeSelected(objValueUID, objTreeModelSource); |
| } |
| |
| private void fireNodeSelected(Object objValueUID, |
| ITreeModelSource objTreeModelSource) |
| { |
| deliverEvent(TreeStateEvent.SELECTED_NODE_CHANGED, objValueUID, |
| objTreeModelSource); |
| } |
| |
| private void fireNodeCollapsed(Object objValueUID, |
| ITreeModelSource objTreeModelSource) |
| { |
| deliverEvent(TreeStateEvent.NODE_COLLAPSED, objValueUID, |
| objTreeModelSource); |
| } |
| |
| private void fireNodeExpanded(Object objValueUID, |
| ITreeModelSource objTreeModelSource) |
| { |
| deliverEvent(TreeStateEvent.NODE_EXPANDED, objValueUID, |
| objTreeModelSource); |
| } |
| |
| private void deliverEvent(int nEventUID, Object objValueUID, |
| ITreeModelSource objTreeModelSource) |
| { |
| ITreeStateListener objListener = objTreeModelSource |
| .getTreeStateListener(); |
| if (objListener != null) |
| { |
| TreeStateEvent objEvent = new TreeStateEvent(nEventUID, |
| objValueUID, objTreeModelSource.getTreeModel() |
| .getTreeStateModel()); |
| objListener.treeStateChanged(objEvent); |
| } |
| |
| } |
| |
| public void pageDetached(PageEvent arg0) |
| { |
| initialize(); |
| } |
| |
| public void finishLoad(IRequestCycle objCycle, IPageLoader arg0, |
| ComponentSpecification arg1) |
| { |
| super.finishLoad(objCycle, arg0, arg1); |
| getPage().addPageDetachListener(this); |
| |
| m_objOpenNodeImage = getAsset("_openNodeImage"); |
| m_objCloseNodeImage = getAsset("_closeNodeImage"); |
| } |
| |
| public boolean isNodeOpen() |
| { |
| if (m_objNodeState == null) |
| { |
| ITreeRowSource objTreeRowSource = getTreeRowSource(); |
| TreeRowObject objTreeRowObject = objTreeRowSource.getTreeRow(); |
| Object objValueUID = objTreeRowObject.getTreeNodeUID(); |
| ITreeModelSource objTreeModelSource = getTreeModelSource(); |
| ITreeStateModel objStateModel = objTreeModelSource.getTreeModel() |
| .getTreeStateModel(); |
| boolean bState = objStateModel.isUniqueKeyExpanded(objValueUID); |
| m_objNodeState = new Boolean(bState); |
| } |
| return m_objNodeState.booleanValue(); |
| } |
| |
| /** |
| * Returns the openNodeImage. |
| * |
| * @return IAsset |
| */ |
| public IAsset getNodeImage() |
| { |
| IAsset objResult = null; |
| ITreeRowSource objRowSource = getTreeRowSource(); |
| boolean bLeaf = objRowSource.getTreeRow().getLeaf(); |
| int nRowType = objRowSource.getTreeRow().getTreeRowPossiotionType(); |
| if (!bLeaf) |
| { |
| if (isNodeOpen()) |
| { |
| switch(nRowType) |
| { |
| case TreeRowObject.FIRST_LAST_ROW: |
| { |
| objResult = getAsset("_topLastOpenNodeImage"); |
| break; |
| } |
| |
| case TreeRowObject.FIRST_ROW: |
| { |
| objResult = getAsset("_topOpenNodeImage"); |
| break; |
| } |
| |
| case TreeRowObject.MIDDLE_ROW: |
| { |
| objResult = getAsset("_middleOpenNodeImage"); |
| break; |
| } |
| |
| case TreeRowObject.LAST_ROW: |
| { |
| objResult = getAsset("_bottomOpenNodeImage"); |
| break; |
| } |
| |
| default: |
| { |
| objResult = getAsset("_openNodeImage"); |
| break; |
| } |
| } |
| } |
| else |
| { |
| switch(nRowType) |
| { |
| case TreeRowObject.FIRST_LAST_ROW: |
| { |
| objResult = getAsset("_topLastCloseNodeImage"); |
| break; |
| } |
| |
| case TreeRowObject.FIRST_ROW: |
| { |
| objResult = getAsset("_topCloseNodeImage"); |
| break; |
| } |
| |
| case TreeRowObject.MIDDLE_ROW: |
| { |
| objResult = getAsset("_middleCloseNodeImage"); |
| break; |
| } |
| |
| case TreeRowObject.LAST_ROW: |
| { |
| objResult = getAsset("_bottomCloseNodeImage"); |
| break; |
| } |
| |
| default: |
| { |
| objResult = getAsset("_closeNodeImage"); |
| break; |
| } |
| } |
| } |
| } |
| else |
| { |
| switch(nRowType) |
| { |
| case TreeRowObject.FIRST_LAST_ROW: |
| { |
| objResult = getAsset("_topLineImage"); |
| break; |
| } |
| |
| case TreeRowObject.FIRST_ROW: |
| { |
| objResult = getAsset("_topLineImage"); |
| break; |
| } |
| |
| case TreeRowObject.MIDDLE_ROW: |
| { |
| objResult = getAsset("_middleCrossLineImage"); |
| break; |
| } |
| |
| case TreeRowObject.LAST_ROW: |
| { |
| objResult = getAsset("_bottomLineImage"); |
| break; |
| } |
| |
| default: |
| { |
| objResult = getAsset("_bottomLineImage"); |
| break; |
| } |
| } |
| |
| } |
| return objResult; |
| } |
| |
| public IAsset getNodeImageOld() |
| { |
| if (isNodeOpen()) |
| { |
| if (m_objOpenNodeImage == null) |
| { |
| m_objOpenNodeImage = getAsset("_openNodeImage"); |
| } |
| return m_objOpenNodeImage; |
| } |
| |
| if (m_objCloseNodeImage == null) |
| { |
| m_objCloseNodeImage = getAsset("_closeNodeImage"); |
| } |
| return m_objCloseNodeImage; |
| } |
| |
| /** |
| * Returns the closeNodeImage. |
| * |
| * @return IAsset |
| */ |
| public IAsset getCloseNodeImage() |
| { |
| return m_objCloseNodeImage; |
| } |
| |
| /** |
| * Returns the openNodeImage. |
| * |
| * @return IAsset |
| */ |
| public IAsset getOpenNodeImage() |
| { |
| return m_objOpenNodeImage; |
| } |
| |
| /** |
| * Sets the closeNodeImage. |
| * |
| * @param closeNodeImage |
| * The closeNodeImage to set |
| */ |
| public void setCloseNodeImage(IAsset closeNodeImage) |
| { |
| m_objCloseNodeImage = closeNodeImage; |
| } |
| |
| /** |
| * Sets the openNodeImage. |
| * |
| * @param openNodeImage |
| * The openNodeImage to set |
| */ |
| public void setOpenNodeImage(IAsset openNodeImage) |
| { |
| m_objOpenNodeImage = openNodeImage; |
| } |
| |
| /** |
| * @see org.apache.tapestry.AbstractComponent#renderComponent(IMarkupWriter, |
| * IRequestCycle) |
| */ |
| protected void renderComponent(IMarkupWriter arg0, IRequestCycle arg1) |
| { |
| super.renderComponent(arg0, arg1); |
| m_objNodeState = null; |
| } |
| |
| /** |
| * Returns the ShowNodeImages. |
| * |
| * @return Boolean |
| */ |
| public Boolean isShowNodeImages() |
| { |
| if (m_objShowNodeImages == null) |
| { |
| if (isParameterBound("nodeRenderFactory")) |
| { |
| m_objShowNodeImages = getShowNodeImages(); |
| } |
| else |
| { |
| m_objShowNodeImages = Boolean.TRUE; |
| } |
| |
| } |
| return m_objShowNodeImages; |
| } |
| |
| public boolean getShowImages() |
| { |
| boolean bResult = isShowNodeImages().booleanValue(); |
| return bResult; |
| } |
| |
| public boolean getShowWithoutImages() |
| { |
| boolean bResult = !isShowNodeImages().booleanValue(); |
| return bResult; |
| } |
| |
| public String getOffsetStyle() |
| { |
| // return "width: " + getTreeDataView().getTreeDeep() * 15; |
| ITreeRowSource objTreeRowSource = getTreeRowSource(); |
| TreeRowObject objTreeRowObject = objTreeRowSource.getTreeRow(); |
| int nTreeRowDepth = 0; |
| if (objTreeRowObject != null) |
| { |
| nTreeRowDepth = objTreeRowObject.getTreeRowDepth(); |
| if (nTreeRowDepth != 0) nTreeRowDepth = nTreeRowDepth - 1; |
| } |
| return "padding-left: " + nTreeRowDepth * 19 + "px"; |
| } |
| |
| public INodeRenderFactory getNodeRenderFactory() |
| { |
| if (m_objNodeRenderFactory == null) |
| { |
| if (isParameterBound("nodeRenderFactory")) |
| m_objNodeRenderFactory = getNodeRenderFactoryParameter(); |
| else m_objNodeRenderFactory = new SimpleNodeRenderFactory(); |
| } |
| return m_objNodeRenderFactory; |
| } |
| |
| public abstract boolean getMakeNodeDirect(); |
| |
| public boolean getMakeNodeNoDirect() |
| { |
| return !getMakeNodeDirect(); |
| } |
| |
| public String getCleanSelectedID() |
| { |
| return getSelectedNodeID(); |
| } |
| |
| public String getSelectedID() |
| { |
| ITreeRowSource objTreeRowSource = getTreeRowSource(); |
| ITreeModelSource objTreeModelSource = getTreeModelSource(); |
| TreeRowObject objTreeRowObject = objTreeRowSource.getTreeRow(); |
| Object objNodeValueUID = objTreeRowObject.getTreeNodeUID(); |
| Object objSelectedNode = objTreeModelSource.getTreeModel() |
| .getTreeStateModel().getSelectedNode(); |
| if (objNodeValueUID.equals(objSelectedNode)) { return getSelectedNodeID(); } |
| return ""; |
| } |
| |
| private String getSelectedNodeID() |
| { |
| // return getTreeDataView().getTreeView().getSelectedNodeID(); |
| return "tree"; |
| } |
| |
| public String getNodeStyleClass() |
| { |
| ITreeRowSource objTreeRowSource = getTreeRowSource(); |
| ITreeModelSource objTreeModelSource = getTreeModelSource(); |
| TreeRowObject objTreeRowObject = objTreeRowSource.getTreeRow(); |
| boolean bResult = false; |
| if (objTreeRowObject != null) |
| { |
| Object objNodeValueUID = objTreeRowObject.getTreeNodeUID(); |
| Object objSelectedNode = objTreeModelSource.getTreeModel() |
| .getTreeStateModel().getSelectedNode(); |
| bResult = objNodeValueUID.equals(objSelectedNode); |
| } |
| if (bResult) { return "selectedNodeViewClass"; } |
| |
| return "notSelectedNodeViewClass"; |
| } |
| |
| public ITreeRowSource getTreeRowSource() |
| { |
| ITreeRowSource objSource = (ITreeRowSource) getPage().getRequestCycle() |
| .getAttribute(ITreeRowSource.TREE_ROW_SOURCE_ATTRIBUTE); |
| return objSource; |
| } |
| |
| public ITreeModelSource getTreeModelSource() |
| { |
| ITreeModelSource objSource = (ITreeModelSource) getPage() |
| .getRequestCycle().getAttribute( |
| ITreeModelSource.TREE_MODEL_SOURCE_ATTRIBUTE); |
| return objSource; |
| } |
| |
| public boolean getShowConnectImage() |
| { |
| ITreeRowSource objRowSource = getTreeRowSource(); |
| int nRowType = objRowSource.getTreeRow().getTreeRowPossiotionType(); |
| if (TreeRowObject.MIDDLE_ROW == nRowType) return true; |
| return false; |
| } |
| |
| public int[] getForeachConnectImageList() |
| { |
| ITreeRowSource objTreeRowSource = getTreeRowSource(); |
| TreeRowObject objTreeRowObject = objTreeRowSource.getTreeRow(); |
| return objTreeRowObject.getLineConnImages(); |
| } |
| |
| public boolean getDisableLink() |
| { |
| ITreeRowSource objRowSource = getTreeRowSource(); |
| boolean bLeaf = objRowSource.getTreeRow().getLeaf(); |
| return bLeaf; |
| } |
| |
| /** |
| * Returns the openNodeImage. |
| * |
| * @return IAsset nevalidno neshto |
| */ |
| public IAsset getConnectImage() |
| { |
| IAsset objResult = null; |
| int nConnectImageType = getCurrentForeachConnectImageValue(); |
| switch(nConnectImageType) |
| { |
| case TreeRowObject.EMPTY_CONN_IMG: |
| { |
| objResult = getAsset("_whiteSpaceImage"); |
| break; |
| } |
| |
| case TreeRowObject.LINE_CONN_IMG: |
| { |
| objResult = getAsset("_middleLineImage"); |
| break; |
| } |
| |
| default: |
| { |
| objResult = getAsset("_whiteSpaceImage"); |
| break; |
| } |
| } |
| return objResult; |
| } |
| |
| /** |
| * @return Returns the m_CurrentForeachConnectImageValue. |
| */ |
| public int getCurrentForeachConnectImageValue() |
| { |
| return m_currentForeachConnectImageValue; |
| } |
| |
| /** |
| * @param currentForeachConnectImageValue |
| * The m_CurrentForeachConnectImageValue to set. |
| */ |
| public void setCurrentForeachConnectImageValue( |
| int currentForeachConnectImageValue) |
| { |
| m_currentForeachConnectImageValue = currentForeachConnectImageValue; |
| } |
| } |