/*******************************************************************************
* 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));
}
}