/******************************************************************************* * 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 java.util.ArrayList; import java.util.List; import java.util.Map; import org.jboss.tools.jsf.vpe.richfaces.ComponentUtil; import org.jboss.tools.vpe.editor.context.VpePageContext; import org.jboss.tools.vpe.editor.mapping.VpeDomMapping; 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.HTML; import org.jboss.tools.vpe.editor.util.SourceDomUtil; import org.jboss.tools.vpe.editor.util.VisualDomUtil; import org.jboss.tools.vpe.editor.util.VpeStyleUtil; import org.mozilla.interfaces.nsIDOMDocument; import org.mozilla.interfaces.nsIDOMElement; import org.mozilla.interfaces.nsIDOMNode; import org.w3c.dom.Element; import org.w3c.dom.Node; public class RichFacesColumnTemplate extends VpeAbstractTemplate { private static final String HEADER_ICON_STYLE = "vertical-align:middle;"; //$NON-NLS-1$ private static final String SORTABLE_PATH = "column/sortable.gif"; //$NON-NLS-1$ public VpeCreationData create(VpePageContext pageContext, Node sourceNode, nsIDOMDocument visualDocument) { Element sourceElement = (Element)sourceNode; boolean visible = isVisible(sourceElement); nsIDOMElement td = visualDocument.createElement(HTML.TAG_TD); if (!visible) { VisualDomUtil.setSubAttribute(td, HTML.ATTR_STYLE, HTML.STYLE_PARAMETER_DISPLAY, HTML.STYLE_VALUE_NONE); } String columnClass = getColumnClass(sourceElement); VisualDomUtil.copyAttributes(sourceNode, td); td.setAttribute(HTML.ATTR_CLASS, columnClass); final VpeCreationData creationData = new VpeCreationData(td); Element headerFacet = SourceDomUtil.getFacetByName(pageContext, sourceElement, RichFaces.NAME_FACET_HEADER); Element footerFacet = SourceDomUtil.getFacetByName(pageContext, sourceElement, RichFaces.NAME_FACET_FOOTER); Map<String, List<Node>> headerFacetChildren = VisualDomUtil .findFacetElements(headerFacet, pageContext); Map<String, List<Node>> footerFacetChildren = VisualDomUtil .findFacetElements(footerFacet, pageContext); boolean headerHtmlElementPresents = headerFacetChildren.get(VisualDomUtil.FACET_HTML_TAGS).size() > 0; boolean footerHtmlElementPresents = footerFacetChildren.get(VisualDomUtil.FACET_HTML_TAGS).size() > 0; /* * Encode html elements from facets to the column body */ VpeChildrenInfo tdInfo = new VpeChildrenInfo(td); if (headerHtmlElementPresents) { for (Node child : headerFacetChildren.get(VisualDomUtil.FACET_HTML_TAGS)) { tdInfo.addSourceChild(child); } } if (footerHtmlElementPresents) { for (Node child : footerFacetChildren.get(VisualDomUtil.FACET_HTML_TAGS)) { tdInfo.addSourceChild(child); } } /* * Encode body */ List<Node> children = ComponentUtil.getChildren(sourceElement,true); for (Node child : children) { if (!isFacet(child)) { tdInfo.addSourceChild(child); } } creationData.addChildrenInfo(tdInfo); return creationData; } /**@param child a node * @return <code>true</code>, if the <code>node</code> is <code>rich:facet</code> tag, * <code>false</code> otherwise*/ private boolean isFacet(Node child) { boolean ret = child.getNodeName().endsWith(RichFaces.TAG_FACET); return ret; } private String getColumnClass(Element sourceElement) { String columnClass; if(isHeader(sourceElement)) { columnClass = "dr-table-headercell rich-table-headercell"; //$NON-NLS-1$ } else if(isFooter(sourceElement)) { columnClass = "dr-table-footercell rich-table-footercell"; //$NON-NLS-1$ } else { columnClass = "dr-table-cell rich-table-cell"; //$NON-NLS-1$ } if (sourceElement.hasAttribute(RichFaces.ATTR_STYLE_CLASS)) { String styleClass = sourceElement.getAttribute(RichFaces.ATTR_STYLE_CLASS); columnClass += " " + styleClass; //$NON-NLS-1$ } return columnClass; } private boolean isHeader(Element sourceElement) { return icludedInFacet(sourceElement, RichFaces.NAME_FACET_HEADER); } private boolean isFooter(Element sourceElement) { return icludedInFacet(sourceElement, RichFaces.NAME_FACET_FOOTER); } private boolean icludedInFacet(Element sourceElement, String facetName) { Node parent = sourceElement.getParentNode(); if(parent!=null) { if(ComponentUtil.isFacet(parent, facetName)) { return true; } else if (parent.getNodeName().endsWith(RichFaces.TAG_COLUMN_GROUP)) { return ComponentUtil.isFacet(parent.getParentNode(), facetName); } } return false; } @Override public boolean recreateAtAttrChange(VpePageContext pageContext, Element sourceElement, nsIDOMDocument visualDocument, nsIDOMElement visualNode, Object data, String name, String value) { return true; } /* (non-Javadoc) * @see org.jboss.tools.vpe.editor.template.VpeAbstractTemplate#getNodeForUpdate(org.jboss.tools.vpe.editor.context.VpePageContext, org.w3c.dom.Node, org.mozilla.interfaces.nsIDOMNode, java.lang.Object) */ @Override public Node getNodeForUpdate(VpePageContext pageContext, Node sourceNode, nsIDOMNode visualNode, Object data) { /* XXX: The implementation is a little tricky, it returns first n-th parent * that has a nodeMapping. */ final VpeDomMapping domMapping = pageContext.getDomMapping(); SourceDomUtil.getParentHavingDomMapping(sourceNode, domMapping); final Node parent = SourceDomUtil.getParentHavingDomMapping(sourceNode, domMapping); if (parent != null) { return parent; } else { return sourceNode; } } /** Creates <code>IMG</code> tag if it is specified by <code><rich:column></code> * attributes. * @param pageContext * * @param column source <code><rich:column></code> element * @param visualDocument Mozilla's Visual Document * @return <code>IMG</code> tag if it is necessary, <code>null</code> otherwise */ public static nsIDOMElement getHeaderIcon(VpePageContext pageContext, Element column, nsIDOMDocument visualDocument) { String sortable = ComponentUtil.getAttribute(column, RichFaces.ATTR_SORTABLE); if (RichFaces.VALUE_TRUE.equals(sortable) || column.hasAttribute(RichFaces.ATTR_SORT_BY)) { nsIDOMElement img = visualDocument.createElement(HTML.TAG_IMG); if (column.hasAttribute(RichFaces.ATTR_SORT_ICON)) { String sortIcon = column.getAttribute(RichFaces.ATTR_SORT_ICON); sortIcon = VpeStyleUtil.addFullPathToImgSrc(sortIcon, pageContext, true); sortIcon = sortIcon.replace('\\', '/'); img.setAttribute(HTML.ATTR_SRC, sortIcon); } else { ComponentUtil.setImg(img, SORTABLE_PATH); } img.setAttribute(HTML.ATTR_STYLE, HEADER_ICON_STYLE); return img; } else { return null; } } public static boolean isBreakBefore(Node node) { if (node instanceof Element) { Element element = (Element) node; String breakBeforeVal = element.getAttribute(RichFaces.ATTR_BREAK_BEFORE); String brealRowBeforeVal = element.getAttribute(RichFaces.ATTR_BREAK_ROW_BEFORE); return RichFaces.VALUE_TRUE.equals(breakBeforeVal) || RichFaces.VALUE_TRUE.equals(brealRowBeforeVal); } else { return false; } } /** * Returns {@code true} if the {@code column} is visible. * * @param column should be not {@code null} */ public static boolean isVisible(Element column) { return !RichFaces.VALUE_FALSE.equals(column.getAttribute(RichFaces.ATTR_VISIBLE)); } }