Author: dsakovich
Date: 2008-10-10 10:37:12 -0400 (Fri, 10 Oct 2008)
New Revision: 10776
Added:
trunk/jsf/plugins/org.jboss.tools.jsf.vpe.richfaces/src/org/jboss/tools/jsf/vpe/richfaces/template/RichFacesExtendedDataTableTemplate.java
Modified:
trunk/jsf/plugins/org.jboss.tools.jsf.vpe.richfaces/templates/vpe-templates-richfaces.xml
Log:
https://jira.jboss.org/jira/browse/JBIDE-2761
Added:
trunk/jsf/plugins/org.jboss.tools.jsf.vpe.richfaces/src/org/jboss/tools/jsf/vpe/richfaces/template/RichFacesExtendedDataTableTemplate.java
===================================================================
---
trunk/jsf/plugins/org.jboss.tools.jsf.vpe.richfaces/src/org/jboss/tools/jsf/vpe/richfaces/template/RichFacesExtendedDataTableTemplate.java
(rev 0)
+++
trunk/jsf/plugins/org.jboss.tools.jsf.vpe.richfaces/src/org/jboss/tools/jsf/vpe/richfaces/template/RichFacesExtendedDataTableTemplate.java 2008-10-10
14:37:12 UTC (rev 10776)
@@ -0,0 +1,559 @@
+/*******************************************************************************
+ * 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 org.jboss.tools.jsf.vpe.richfaces.ComponentUtil;
+import org.jboss.tools.jsf.vpe.richfaces.template.util.RichFaces;
+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.HTML;
+import org.mozilla.interfaces.nsIDOMDocument;
+import org.mozilla.interfaces.nsIDOMElement;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * Displays template for extendedDataTable
+ *
+ * @author dsakovich(a)exadel.com
+ *
+ */
+public class RichFacesExtendedDataTableTemplate extends VpeAbstractTemplate {
+
+ final static String DEFAULT_HEIGHT = "500px";
+ final static String DEFAULT_WIDTH = "100%";
+ final static String HEADER = "header";
+ final static String HEADER_CLASS = "headerClass";
+ final static String FOOTER = "footer";
+ final static String FOOTER_CLASS = "footerClass";
+ final static String CAPTION_CLASS = "captionClass";
+ final static String CAPTION_STYLE = "captionStyle";
+ final static String SPACE = " ";
+
+ private static String STYLE_FOR_LOW_SCROLL = "overflow: scroll; width: 100%;
height: 17px;";
+ private static String STYLE_FOR_RIGHT_SCROLL = "overflow: scroll; width: 17px;
height: 100%;";
+
+ private static final int NUM_ROW = 5;
+
+ /**
+ * 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) {
+
+ Element sourceElement = (Element) sourceNode;
+
+ String width = sourceElement.getAttribute(HTML.ATTR_WIDTH);
+ String height = sourceElement.getAttribute(HTML.ATTR_HEIGHT);
+
+ // -----------CommonTable
+ nsIDOMElement tableCommon = visualDocument
+ .createElement(HTML.TAG_TABLE);
+
+ VpeCreationData creationData = new VpeCreationData(tableCommon);
+
+ nsIDOMElement tr1 = visualDocument.createElement(HTML.TAG_TR);
+
+ nsIDOMElement tr2 = visualDocument.createElement(HTML.TAG_TR);
+
+ tableCommon.appendChild(tr1);
+ tableCommon.appendChild(tr2);
+
+ // ---------tr2
+ nsIDOMElement tr2_TD = visualDocument.createElement(HTML.TAG_TD);
+ tr2.appendChild(tr2_TD);
+
+ nsIDOMElement tr2_td_DIV = visualDocument.createElement(HTML.TAG_DIV);
+ tr2_td_DIV.setAttribute(HTML.ATTR_STYLE, STYLE_FOR_LOW_SCROLL);
+ tr2_TD.appendChild(tr2_td_DIV);
+
+ // --------------------------------------------
+
+ // ---------------------tr1------------------------
+ nsIDOMElement tr1_TD1 = visualDocument.createElement(HTML.TAG_TD);
+ tr1.appendChild(tr1_TD1);
+
+ nsIDOMElement tr1_TD2 = visualDocument.createElement(HTML.TAG_TD);
+ tr1.appendChild(tr1_TD2);
+
+ nsIDOMElement tr1_td2_DIV = visualDocument.createElement(HTML.TAG_DIV);
+ tr1_td2_DIV.setAttribute(HTML.ATTR_STYLE, STYLE_FOR_RIGHT_SCROLL);
+ tr1_TD2.appendChild(tr1_td2_DIV);
+
+ // -------------------------------------------------------
+ nsIDOMElement div = visualDocument.createElement(HTML.TAG_DIV);
+ tr1_TD1.appendChild(div);
+ div.setAttribute(HTML.ATTR_CLASS, "dr-table-hidden");
+
+ String divStyle = HTML.ATTR_WIDTH + " : "
+ + (width == null ? DEFAULT_WIDTH : width) + ";"
+ + HTML.ATTR_HEIGHT + " : "
+ + (height == null ? DEFAULT_HEIGHT : height) + ";";
+
+ div.setAttribute(HTML.ATTR_STYLE, divStyle);
+
+ nsIDOMElement table = visualDocument.createElement(HTML.TAG_TABLE);
+ ComponentUtil.copyAttributes(sourceNode, table);
+ table.removeAttribute(HTML.ATTR_HEIGHT);
+ div.appendChild(table);
+
+ ComponentUtil.setCSSLink(pageContext,
+ "scrollableDataTable/scrollableDataTable.css",
+ "richFacesDataTable");
+ String tableClass = sourceElement
+ .getAttribute(RichFaces.ATTR_STYLE_CLASS);
+ table.setAttribute(HTML.ATTR_CLASS, "dr-table rich-table "
+ + (tableClass == null ? "" : tableClass));
+
+ // Encode colgroup definition.
+ ArrayList<Element> columns = getColumns(sourceElement);
+ int columnsLength = getColumnsCount(sourceElement, columns);
+ nsIDOMElement colgroup = visualDocument
+ .createElement(HTML.TAG_COLGROUP);
+ colgroup.setAttribute(HTML.TAG_SPAN, String.valueOf(columnsLength));
+ table.appendChild(colgroup);
+
+ // Encode Caption
+ encodeCaption(creationData, sourceElement, visualDocument, table);
+
+ // Encode Header
+ Element header = ComponentUtil.getFacet(sourceElement, HEADER);
+ ArrayList<Element> columnsHeaders = getColumnsWithFacet(columns, HEADER);
+ if (header != null || !columnsHeaders.isEmpty()) {
+ nsIDOMElement thead = visualDocument.createElement(HTML.TAG_THEAD);
+ table.appendChild(thead);
+ String headerClass = (String) sourceElement
+ .getAttribute(HEADER_CLASS);
+ if (header != null) {
+ encodeTableHeaderOrFooterFacet(creationData, thead,
+ columnsLength, visualDocument, header,
+ "dr-table-header rich-table-header",
+ "dr-table-header-continue rich-table-header-continue",
+ "dr-table-headercell rich-table-headercell",
+ headerClass, HTML.TAG_TD);
+ }
+ if (!columnsHeaders.isEmpty()) {
+ nsIDOMElement tr = visualDocument.createElement(HTML.TAG_TR);
+ thead.appendChild(tr);
+ String styleClass = encodeStyleClass(null,
+ "dr-table-subheader rich-table-subheader", null,
+ headerClass);
+ if (styleClass != null) {
+ tr.setAttribute(HTML.ATTR_CLASS, styleClass);
+ }
+ encodeHeaderOrFooterFacets(creationData, tr, visualDocument,
+ columnsHeaders,
+ "dr-table-subheadercell rich-table-subheadercell",
+ headerClass, HEADER, HTML.TAG_TD);
+ }
+ }
+
+ // Encode Footer
+ Element footer = ComponentUtil.getFacet(sourceElement, FOOTER);
+ ArrayList<Element> columnsFooters = getColumnsWithFacet(columns, FOOTER);
+ if (footer != null || !columnsFooters.isEmpty()) {
+ nsIDOMElement tfoot = visualDocument.createElement(HTML.TAG_TFOOT);
+ table.appendChild(tfoot);
+ String footerClass = (String) sourceElement
+ .getAttribute(FOOTER_CLASS);
+ if (!columnsFooters.isEmpty()) {
+ nsIDOMElement tr = visualDocument.createElement(HTML.TAG_TR);
+ tfoot.appendChild(tr);
+ String styleClass = encodeStyleClass(null,
+ "dr-table-subfooter rich-table-subfooter", null,
+ footerClass);
+ if (styleClass != null) {
+ tr.setAttribute(HTML.ATTR_CLASS, styleClass);
+ }
+ encodeHeaderOrFooterFacets(creationData, tr, visualDocument,
+ columnsFooters,
+ "dr-table-subfootercell rich-table-subfootercell",
+ footerClass, FOOTER, HTML.TAG_TD);
+ }
+ if (footer != null) {
+ encodeTableHeaderOrFooterFacet(creationData, tfoot,
+ columnsLength, visualDocument, footer,
+ "dr-table-footer rich-table-footer",
+ "dr-table-footer-continue rich-table-footer-continue",
+ "dr-table-footercell rich-table-footercell",
+ footerClass, HTML.TAG_TD);
+ }
+ }
+
+ nsIDOMElement tbody = visualDocument.createElement(HTML.TAG_TBODY);
+ table.appendChild(tbody);
+
+ // Create mapping to Encode body
+ for (int i = 0; i < NUM_ROW; i++) {
+ List<Node> children = ComponentUtil.getChildren(sourceElement);
+ boolean firstRow = true;
+ nsIDOMElement tr = null;
+ VpeChildrenInfo trInfo = null;
+ for (Node child : children) {
+ if (child.getNodeName().endsWith(":column")) {
+ String breakBefore = ((Element) child)
+ .getAttribute("breakBefore");
+ if (breakBefore != null
+ && breakBefore.equalsIgnoreCase("true")) {
+ tr = null;
+ }
+ if (tr == null) {
+ tr = visualDocument.createElement(HTML.TAG_TR);
+ if (firstRow) {
+ tr.setAttribute(HTML.ATTR_CLASS,
+ "dr-table-firstrow rich-table-firstrow");
+ firstRow = false;
+ } else {
+ tr.setAttribute(HTML.ATTR_CLASS,
+ "dr-table-row rich-table-row");
+ }
+ trInfo = new VpeChildrenInfo(tr);
+ tbody.appendChild(tr);
+ creationData.addChildrenInfo(trInfo);
+ }
+ trInfo.addSourceChild(child);
+ } else if (child.getNodeName().endsWith(":columnGroup")) {
+ RichFacesColumnGroupTemplate.DEFAULT_INSTANCE.encode(
+ creationData, (Element) child, visualDocument,
+ tbody);
+ tr = null;
+ } else if (child.getNodeName().endsWith(":subTable")) {
+ RichFacesSubTableTemplate.DEFAULT_INSTANCE.encode(
+ creationData, (Element) child, visualDocument,
+ tbody);
+ tr = null;
+ } else {
+ VpeChildrenInfo childInfo = new VpeChildrenInfo(tbody);
+ childInfo.addSourceChild(child);
+ creationData.addChildrenInfo(childInfo);
+ tr = null;
+ }
+ }
+ }
+
+ return creationData;
+ }
+
+ /**
+ *
+ * @param creationData
+ * @param sourceElement
+ * @param visualDocument
+ * @param table
+ */
+ protected void encodeCaption(VpeCreationData creationData,
+ Element sourceElement, nsIDOMDocument visualDocument,
+ nsIDOMElement table) {
+ // Encode caption
+ Element captionFromFacet = ComponentUtil.getFacet(sourceElement,
+ HTML.TAG_CAPTION);
+ if (captionFromFacet != null) {
+ String captionClass = (String) table.getAttribute(CAPTION_CLASS);
+ String captionStyle = (String) table.getAttribute(CAPTION_STYLE);
+
+ nsIDOMElement caption = visualDocument
+ .createElement(HTML.TAG_CAPTION);
+ table.appendChild(caption);
+ if (captionClass != null && captionClass.length() > 0) {
+ captionClass = "dr-table-caption rich-table-caption "
+ + captionClass;
+ } else {
+ captionClass = "dr-table-caption rich-table-caption";
+ }
+ caption.setAttribute(HTML.ATTR_CLASS, captionClass);
+ if (captionStyle != null && captionStyle.length() > 0) {
+ caption.setAttribute(HTML.ATTR_STYLE, captionStyle);
+ }
+
+ VpeChildrenInfo cap = new VpeChildrenInfo(caption);
+ cap.addSourceChild(captionFromFacet);
+ creationData.addChildrenInfo(cap);
+ }
+
+ }
+
+ /**
+ *
+ * @param creationData
+ * @param parentTr
+ * @param visualDocument
+ * @param headersOrFooters
+ * @param skinCellClass
+ * @param headerClass
+ * @param facetName
+ * @param element
+ */
+ public static void encodeHeaderOrFooterFacets(VpeCreationData creationData,
+ nsIDOMElement parentTr, nsIDOMDocument visualDocument,
+ ArrayList<Element> headersOrFooters, String skinCellClass,
+ String headerClass, String facetName, String element) {
+ for (Element column : headersOrFooters) {
+ String classAttribute = facetName + "Class";
+ String columnHeaderClass = column.getAttribute(classAttribute);
+ nsIDOMElement td = visualDocument.createElement(element);
+ parentTr.appendChild(td);
+ String styleClass = encodeStyleClass(null, skinCellClass,
+ headerClass, columnHeaderClass);
+ td.setAttribute(HTML.ATTR_CLASS, styleClass);
+ td.setAttribute("scop", "col");
+ String colspan = column.getAttribute(HTML.ATTR_COLSPAN);
+ if (colspan != null && colspan.length() > 0) {
+ td.setAttribute(HTML.ATTR_COLSPAN, colspan);
+ }
+ Element facetBody = ComponentUtil.getFacet(column, facetName);
+
+ VpeChildrenInfo child = new VpeChildrenInfo(td);
+ child.addSourceChild(facetBody);
+ creationData.addChildrenInfo(child);
+ }
+ }
+
+ /**
+ *
+ * @param creationData
+ * @param parentTheadOrTfood
+ * @param columns
+ * @param visualDocument
+ * @param facetBody
+ * @param skinFirstRowClass
+ * @param skinRowClass
+ * @param skinCellClass
+ * @param facetBodyClass
+ * @param element
+ */
+ protected void encodeTableHeaderOrFooterFacet(VpeCreationData creationData,
+ nsIDOMElement parentTheadOrTfood, int columns,
+ nsIDOMDocument visualDocument, Element facetBody,
+ String skinFirstRowClass, String skinRowClass,
+ String skinCellClass, String facetBodyClass, String element) {
+ boolean isColumnGroup = facetBody.getNodeName()
+ .endsWith(":columnGroup");
+ boolean isSubTable = facetBody.getNodeName().endsWith(":subTable");
+ if (isColumnGroup) {
+ RichFacesColumnGroupTemplate.DEFAULT_INSTANCE.encode(creationData,
+ facetBody, visualDocument, parentTheadOrTfood);
+ } else if (isSubTable) {
+ RichFacesSubTableTemplate.DEFAULT_INSTANCE.encode(creationData,
+ facetBody, visualDocument, parentTheadOrTfood);
+ } else {
+ nsIDOMElement tr = visualDocument.createElement(HTML.TAG_TR);
+ parentTheadOrTfood.appendChild(tr);
+
+ String styleClass = encodeStyleClass(null, skinFirstRowClass,
+ facetBodyClass, null);
+ if (styleClass != null) {
+ tr.setAttribute(HTML.ATTR_CLASS, styleClass);
+ }
+ String style = ComponentUtil.getHeaderBackgoundImgStyle();
+ tr.setAttribute(HTML.ATTR_STYLE, style);
+
+ nsIDOMElement td = visualDocument.createElement(element);
+ tr.appendChild(td);
+
+ styleClass = encodeStyleClass(null, skinCellClass, facetBodyClass,
+ null);
+ if (styleClass != null) {
+ td.setAttribute(HTML.ATTR_CLASS, styleClass);
+ }
+
+ if (columns > 0) {
+ td.setAttribute(HTML.ATTR_COLSPAN, String.valueOf(columns));
+ }
+ td.setAttribute(HTML.ATTR_SCOPE, HTML.TAG_COLGROUP);
+
+ VpeChildrenInfo child = new VpeChildrenInfo(td);
+ child.addSourceChild(facetBody);
+ creationData.addChildrenInfo(child);
+ }
+ }
+
+ /**
+ *
+ * @param parentSourceElement
+ * @return list of columns
+ */
+ public static ArrayList<Element> getColumns(Element parentSourceElement) {
+ ArrayList<Element> columns = new ArrayList<Element>();
+ NodeList children = parentSourceElement.getChildNodes();
+ for (int i = 0; i < children.getLength(); i++) {
+ Node child = children.item(i);
+ if ((child instanceof Element)
+ && child.getNodeName().endsWith(":column")) {
+ columns.add((Element) child);
+ }
+ }
+ return columns;
+ }
+
+ /**
+ *
+ * @param columns
+ * @param facetName
+ * @return list of columns with facet
+ */
+ public static ArrayList<Element> getColumnsWithFacet(
+ ArrayList<Element> columns, String facetName) {
+ ArrayList<Element> columnsWithFacet = new ArrayList<Element>();
+ for (Element column : columns) {
+ Element body = ComponentUtil.getFacet(column, facetName);
+ if (body != null) {
+ columnsWithFacet.add(column);
+ }
+ }
+ return columnsWithFacet;
+ }
+
+ /**
+ *
+ * @param parentPredefined
+ * @param predefined
+ * @param parent
+ * @param custom
+ * @return
+ */
+ public static String encodeStyleClass(Object parentPredefined,
+ Object predefined, Object parent, Object custom) {
+ StringBuffer styleClass = new StringBuffer();
+ // Construct predefined classes
+ if (null != parentPredefined) {
+ styleClass.append(parentPredefined).append(SPACE);
+ } else if (null != predefined) {
+ styleClass.append(predefined).append(SPACE);
+ }
+ // Append class from parent component.
+ if (null != parent) {
+ styleClass.append(parent).append(SPACE);
+ }
+ if (null != custom) {
+ styleClass.append(custom);
+ }
+ if (styleClass.length() > 0) {
+ return styleClass.toString();
+ }
+ return null;
+ }
+
+ /**
+ *
+ * @param sourceElement
+ * @param columns
+ * @return
+ */
+ protected int getColumnsCount(Element sourceElement,
+ ArrayList<Element> columns) {
+ int count = 0;
+ // check for exact value in component
+ try {
+ int span = Integer.parseInt(sourceElement.getAttribute("columns"));
+ count = count > 0 ? span : calculateRowColumns(sourceElement,
+ columns);
+ } catch (NumberFormatException e) {
+ count = calculateRowColumns(sourceElement, columns);
+ }
+ return count;
+ }
+
+ /*
+ * Calculate max number of columns per row. For rows, recursive calculate
+ * max length.
+ */
+ private int calculateRowColumns(Element sourceElement,
+ ArrayList<Element> columns) {
+ int count = 0;
+ int currentLength = 0;
+ for (Element column : columns) {
+ if (ComponentUtil.isRendered(column)) {
+ if (column.getNodeName().endsWith(":columnGroup")) {
+ // Store max calculated value of previsous rows.
+ if (currentLength > count) {
+ count = currentLength;
+ }
+ // Calculate number of columns in row.
+ currentLength = calculateRowColumns(sourceElement,
+ getColumns(column));
+ // Store max calculated value
+ if (currentLength > count) {
+ count = currentLength;
+ }
+ currentLength = 0;
+ } else if (column.getNodeName().equals(
+ sourceElement.getPrefix() + ":column")) {
+ String breakBeforeStr = column.getAttribute("breakBefore");
+ // For new row, save length of previsous.
+ if (Boolean.getBoolean(breakBeforeStr)) {
+ if (currentLength > count) {
+ count = currentLength;
+ }
+ currentLength = 0;
+ }
+ String colspanStr = column.getAttribute(HTML.ATTR_COLSPAN);
+ try {
+ int colspan = Integer.parseInt(colspanStr);
+ currentLength += colspan > 0 ? colspan : 1;
+ } catch (NumberFormatException e) {
+ currentLength++;
+ }
+ } else if (column.getNodeName().endsWith(":column")) {
+ // UIColumn always have colspan == 1.
+ currentLength++;
+ }
+
+ }
+ }
+ if (currentLength > count) {
+ count = currentLength;
+ }
+ return count;
+ }
+
+ /**
+ * Checks, whether it is necessary to re-create an element at change of
+ * attribute
+ *
+ * @param pageContext
+ * Contains the information on edited page.
+ * @param sourceElement
+ * The current element of the source tree.
+ * @param visualDocument
+ * The document of the visual tree.
+ * @param visualNode
+ * The current node of the visual tree.
+ * @param data
+ * The arbitrary data, built by a method <code>create</code>
+ * @param name
+ * Attribute name
+ * @param value
+ * Attribute value
+ * @return <code>true</code> if it is required to re-create an element at
a
+ * modification of attribute, <code>false</code> otherwise.
+ */
+ public boolean isRecreateAtAttrChange(VpePageContext pageContext,
+ Element sourceElement, nsIDOMDocument visualDocument,
+ nsIDOMElement visualNode, Object data, String name, String value) {
+ return true;
+ }
+}
Modified:
trunk/jsf/plugins/org.jboss.tools.jsf.vpe.richfaces/templates/vpe-templates-richfaces.xml
===================================================================
---
trunk/jsf/plugins/org.jboss.tools.jsf.vpe.richfaces/templates/vpe-templates-richfaces.xml 2008-10-10
13:58:48 UTC (rev 10775)
+++
trunk/jsf/plugins/org.jboss.tools.jsf.vpe.richfaces/templates/vpe-templates-richfaces.xml 2008-10-10
14:37:12 UTC (rev 10776)
@@ -358,6 +358,25 @@
</vpe:textFormatting>
<vpe:pseudoContent defaultText="yes"/>
</vpe:template>
+ </vpe:tag>
+
+ <vpe:tag name="rich:extendedDataTable"
case-sensitive="yes">
+ <vpe:template children="yes" modify="no"
class="org.jboss.tools.jsf.vpe.richfaces.template.RichFacesExtendedDataTableTemplate">
+ <vpe:resize>
+ <vpe:width width-attr="width" />
+ <vpe:height height-attr="height" />
+ </vpe:resize>
+ <vpe:dnd>
+ <vpe:drag start-enable="yes" />
+ <vpe:drop container="yes">
+ <vpe:container-child tag-name="column"/>
+ </vpe:drop>
+ </vpe:dnd>
+ <vpe:textFormatting use-default-formats="yes">
+ <vpe:format type="BlockFormat" addChildren="deny"/>
+ </vpe:textFormatting>
+ <vpe:pseudoContent defaultText="yes"/>
+ </vpe:template>
</vpe:tag>
<vpe:tag name="rich:orderingList" case-sensitive="yes">