/******************************************************************************* * Copyright (c) 2007 Exadel, Inc. and Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Exadel, Inc. and Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.jsf.vpe.richfaces.template; import static org.jboss.tools.vpe.xulrunner.util.XPCOM.queryInterface; import org.jboss.tools.jsf.vpe.richfaces.ComponentUtil; import org.jboss.tools.vpe.editor.context.VpePageContext; import org.jboss.tools.vpe.editor.template.VpeAbstractTemplate; import org.jboss.tools.vpe.editor.template.VpeChildrenInfo; import org.jboss.tools.vpe.editor.template.VpeCreationData; import org.jboss.tools.vpe.editor.util.Constants; import org.jboss.tools.vpe.editor.util.HTML; import org.mozilla.interfaces.nsIDOMDocument; import org.mozilla.interfaces.nsIDOMElement; import org.mozilla.interfaces.nsIDOMNode; import org.mozilla.interfaces.nsIDOMNodeList; import org.mozilla.xpcom.XPCOMException; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** * Create template for rich:tree element. * * @author dsakovich@exadel.com * */ public class RichFacesTreeTemplate extends RichFacesAbstractTreeTemplate{ private static final String STYLE_PATH = "/tree/tree.css"; //$NON-NLS-1$ private static final String ICON_ATTR = "icon"; //$NON-NLS-1$ private static final String TREE_STYLE_CLASS_ATR_NAME = "styleClass"; //$NON-NLS-1$ private static final String ICON_COLLAPSED_ATTR_NAME = "iconExpanded"; //$NON-NLS-1$ /** * Creates a node of the visual tree on the node of the source tree. This * visual node should not have the parent node This visual node can have * child nodes. * * @param pageContext * Contains the information on edited page. * @param sourceNode * The current node of the source tree. * @param visualDocument * The document of the visual tree. * @return The information on the created node of the visual tree. */ public VpeCreationData create(VpePageContext pageContext, Node sourceNode, nsIDOMDocument visualDocument) { // sets css for tree on page ComponentUtil.setCSSLink(pageContext, STYLE_PATH, TREE); nsIDOMElement visualElement = visualDocument .createElement(HTML.TAG_DIV); Element sourceElement = (Element) sourceNode; if (sourceElement.hasAttribute(HTML.ATTR_STYLE)) { String style = sourceElement.getAttribute(HTML.ATTR_STYLE); visualElement.setAttribute(HTML.ATTR_STYLE, style); } if (sourceElement.hasAttribute(HTML.ATTR_CLASS)) { String styleClass = sourceElement.getAttribute(HTML.ATTR_CLASS); visualElement.setAttribute(HTML.ATTR_CLASS, styleClass); } VpeCreationData vpeCreationData = new VpeCreationData(visualElement); vpeCreationData.addChildrenInfo(new VpeChildrenInfo(null)); parseTree(pageContext, sourceNode, visualDocument, vpeCreationData, visualElement); setStylesAttributesToTree(visualElement, (Element) sourceNode); return vpeCreationData; } /** * Sets to tree basic style attributes * * @param tree * @param sourceNode */ private void setStylesAttributesToTree(nsIDOMElement treeTable, Element sourceNode) { if (sourceNode.hasAttribute(HTML.ATTR_STYLE)) { String styleAttr = sourceNode.getAttribute(HTML.ATTR_STYLE); setAttributeToTree(treeTable, HTML.ATTR_STYLE, removeFromStyleWithAndHeight(styleAttr)); treeTable.setAttribute(HTML.ATTR_STYLE, styleAttr); } if (sourceNode.hasAttribute(TREE_STYLE_CLASS_ATR_NAME)) { String styleClassAttr = sourceNode .getAttribute(TREE_STYLE_CLASS_ATR_NAME); setAttributeToTree(treeTable, HTML.ATTR_CLASS, styleClassAttr); } } /** * * @param styleArgs * @return */ private String removeFromStyleWithAndHeight(String styleArgs) { StringBuffer result = new StringBuffer(); String[] mas = styleArgs.split(Constants.SEMICOLON); for (String styleAttr : mas) { if ((styleAttr.indexOf(HTML.ATTR_WIDTH) != -1) || (styleAttr.indexOf(HTML.ATTR_HEIGHT) != -1)) { continue; } result.append(styleAttr + Constants.SEMICOLON); } return result.toString(); } /** * Sets to tree tables attributes * * @param node * @param sourceNode * @param attrValue */ private void setAttributeToTree(nsIDOMNode node, String attrName, String attrValue) { try { nsIDOMElement element = queryInterface(node, nsIDOMElement.class); if (node.getNodeName().equalsIgnoreCase(HTML.TAG_TABLE)) { element.setAttribute(attrName, attrValue); } nsIDOMNodeList list2 = node.getChildNodes(); for (int i = 0; i < list2.getLength(); i++) { setAttributeToTree(list2.item(i), attrName, attrValue); } } catch (XPCOMException exception) { // Ignore return; } } /** * Is invoked after construction of all child nodes of the current visual * node. * * @param pageContext * Contains the information on edited page. * @param sourceNode * The current node of the source tree. * @param visualDocument * The document of the visual tree. * @param data * Object <code>VpeCreationData</code>, built by a method * <code>create</code> */ @Override public void validate(VpePageContext pageContext, Node sourceNode, nsIDOMDocument visualDocument, VpeCreationData data) { super.validate(pageContext, sourceNode, visualDocument, data); revertTableRows(data.getNode()); } /** * Revert tree elements in right order. * * @param node */ private void revertTableRows(nsIDOMNode node) { try { nsIDOMNodeList list = node.getChildNodes(); nsIDOMElement element = queryInterface(node, nsIDOMElement.class); String id = element .hasAttribute(RichFacesTreeNodesAdaptorTemplate.ID_ATTR_NAME) ? element .getAttribute(RichFacesTreeNodesAdaptorTemplate.ID_ATTR_NAME) : Constants.EMPTY; if (node.getNodeName().equalsIgnoreCase(HTML.TAG_DIV) && list.getLength() == 2 && !(id.equalsIgnoreCase(TREE_NODES_ADAPTOR) || id.equalsIgnoreCase(TREE_MODEL_ADAPTOR) || id.equalsIgnoreCase(TREE_MODEL_RECURSIVE_ADAPTOR) || id.equalsIgnoreCase(RECURSIVE_TREE_NODES_ADAPTOR))) { nsIDOMNode table1 = list.item(0); nsIDOMNode table2 = list.item(1); node.removeChild(table1); node.removeChild(table2); node.appendChild(table2); node.appendChild(table1); } nsIDOMNodeList list2 = node.getChildNodes(); for (int i = 0; i < list2.getLength(); i++) { revertTableRows(list2.item(i)); } } catch (XPCOMException e) { // Ignore return; } } /** * * Function for parsing tree by tree nodes; * * @param pageContext * @param sourceNode * @param visualDocument * @return */ @Override public void parseTree(VpePageContext pageContext, Node sourceNode, nsIDOMDocument visualDocument, VpeCreationData vpeCreationData, nsIDOMElement parentDiv) { NodeList nodeList = sourceNode.getChildNodes(); Element element = null; nsIDOMElement div = null; nsIDOMElement childTree = null; nsIDOMElement childLast = null; int lenght = nodeList.getLength(); VpeChildrenInfo vpeChildrenInfo = null; for (int i = 0; i < lenght; i++) { if (!(nodeList.item(i) instanceof Element)) { continue; } element = (Element) nodeList.item(i); childTree = null; if (element.getNodeName().endsWith(Constants.COLON + TREE_NODE) || element.getNodeName().endsWith(Constants.COLON + TREE_NODES_ADAPTOR) || element.getNodeName().endsWith(Constants.COLON + RECURSIVE_TREE_NODES_ADAPTOR) || element.getNodeName().endsWith(Constants.COLON + TREE_MODEL_ADAPTOR) || element.getNodeName().endsWith(Constants.COLON + TREE_MODEL_RECURSIVE_ADAPTOR)) { if (div == null) { vpeChildrenInfo = new VpeChildrenInfo(parentDiv); vpeCreationData.addChildrenInfo(vpeChildrenInfo); vpeChildrenInfo.addSourceChild(element); div = createBasicTree(visualDocument); childLast = parentDiv; continue; } else if (childTree == null) { vpeChildrenInfo = new VpeChildrenInfo(div); vpeCreationData.addChildrenInfo(vpeChildrenInfo); vpeChildrenInfo.addSourceChild(element); childLast.appendChild(div); childLast = div; div = createBasicTree(visualDocument); continue; } } } } @Override public boolean recreateAtAttrChange(VpePageContext pageContext, Element sourceElement, nsIDOMDocument visualDocument, nsIDOMElement visualNode, Object data, String name, String value) { if (ICON_COLLAPSED_ATTR_NAME.equals(name) || SHOW_LINES_ATTR_NAME.equals(name) || ICON_ATTR.equals(name) || RichFacesTreeNodeTemplate.NODE_ICON_LEAF_ATTR_NAME.equals(name)) { return true; } return false; } @Override public void setAttribute(VpePageContext pageContext, Element sourceElement, nsIDOMDocument visualDocument, nsIDOMNode visualNode, Object data, String name, String value) { if (TREE_STYLE_CLASS_ATR_NAME.equalsIgnoreCase(name)) { setAttributeToTree(visualNode, HTML.ATTR_CLASS, value); } else if (HTML.ATTR_STYLE.equalsIgnoreCase(name)) { setAttributeToTree(visualNode, HTML.ATTR_STYLE, removeFromStyleWithAndHeight(value)); nsIDOMElement visualElement = queryInterface(visualNode, nsIDOMElement.class); visualElement.setAttribute(HTML.ATTR_STYLE, value); } } @Override public void removeAttribute(VpePageContext pageContext, Element sourceElement, nsIDOMDocument visualDocument, nsIDOMNode visualNode, Object data, String name) { if (TREE_STYLE_CLASS_ATR_NAME.equalsIgnoreCase(name)) { setAttributeToTree(visualNode, HTML.ATTR_CLASS, Constants.EMPTY); } else if (HTML.ATTR_STYLE.equalsIgnoreCase(name)) { setAttributeToTree(visualNode, HTML.ATTR_STYLE, Constants.EMPTY); } } /** * Create simple tree node attribute.Used for creating more complex trees. * * @param treeNodeTitle * @param visualDocument * @return tree */ private nsIDOMElement createBasicTree(nsIDOMDocument visualDocument) { nsIDOMElement div = visualDocument.createElement(HTML.TAG_DIV); div.setAttribute(HTML.ATTR_CLASS, "dr-tree-h-ic-div"); //$NON-NLS-1$ return div; } }