| /** |
| * Copyright (c) 2008 Oracle Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are 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: |
| * Oracle Corporation - initial API and implementation |
| */ |
| package org.eclipse.jst.jsf.apache.trinidad.tagsupport.converter.operations; |
| |
| import java.util.Iterator; |
| import java.util.List; |
| |
| import org.eclipse.jst.jsf.apache.trinidad.tagsupport.ITrinidadConstants; |
| import org.eclipse.jst.jsf.common.dom.TagIdentifier; |
| import org.eclipse.jst.jsf.core.internal.tld.TagIdentifierFactory; |
| import org.eclipse.jst.pagedesigner.converter.ConvertPosition; |
| import org.w3c.dom.Element; |
| |
| /** |
| * ITransformOperation implementation specifically for the "panelFormLayout" |
| * JSF Element. |
| * |
| * <br><b>Note:</b> requires ITransformOperation.setTagConverterContext(...) to |
| * have been called to provide a valid ITagConverterContext instance prior to |
| * a call to the transform(...) method. |
| * |
| * @author Ian Trimble - Oracle |
| */ |
| public class PanelFormLayoutOperation extends AbstractTrinidadTransformOperation { |
| |
| private static final String STYLECLASS_REQUIREDSPAN = "AFRequiredIconStyle"; //$NON-NLS-1$ |
| private static final String STYLECLASS_GROUPSEPARATOR = "af_panelFormLayout_separator"; //$NON-NLS-1$ |
| private static final String STYLECLASS_LABELCELL = "af_inputText_label af_panelFormLayout_label-cell"; //$NON-NLS-1$ |
| private static final String STYLECLASS_FIELDCELL = "af_panelFormLayout_content-cell"; //$NON-NLS-1$ |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jst.pagedesigner.dtmanager.converter.operations.AbstractTransformOperation#transform(org.w3c.dom.Element, org.w3c.dom.Element) |
| */ |
| @Override |
| public Element transform(Element srcElement, Element curElement) { |
| //calculate required values |
| int columnCount = calculateColumnCount(srcElement); |
| int rowCount = calculateRowCount(srcElement); |
| String fieldWidth = calculateFieldWidth(srcElement); |
| String labelWidth = calculateLabelWidth(srcElement); |
| |
| //initialize current column/row variables |
| int currentColumn = 1; |
| int currentRow = 1; |
| |
| //build outer table |
| Element outerTableElement = createElement("table"); //$NON-NLS-1$ |
| String styleClass = srcElement.getAttribute("styleClass"); //$NON-NLS-1$ |
| if (styleClass != null && styleClass.length() > 0) { |
| appendAttribute(outerTableElement, "class", styleClass); //$NON-NLS-1$ |
| } |
| String inlineStyle = srcElement.getAttribute("inlineStyle"); //$NON-NLS-1$ |
| if (inlineStyle != null && inlineStyle.length() > 0) { |
| appendAttribute(outerTableElement, "style", inlineStyle + ";width:100%;"); //$NON-NLS-1$ //$NON-NLS-2$ |
| } else { |
| appendAttribute(outerTableElement, "style", "width:100%;"); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| appendAttribute(outerTableElement, "cellpadding", "0"); //$NON-NLS-1$ //$NON-NLS-2$ |
| appendAttribute(outerTableElement, "cellspacing", "0"); //$NON-NLS-1$ //$NON-NLS-2$ |
| appendAttribute(outerTableElement, "border", "0"); //$NON-NLS-1$ //$NON-NLS-2$ |
| Element outerTBodyElement = appendChildElement("tbody", outerTableElement); //$NON-NLS-1$ |
| Element outerTopTRElement = appendChildElement("tr", outerTBodyElement); //$NON-NLS-1$ |
| |
| //build start of column |
| Element currentTBodyElement = buildColumnStart(outerTopTRElement, columnCount, currentColumn, labelWidth, fieldWidth); |
| |
| //build controls |
| List<Element> childElements = getChildElementsSkipFacets(srcElement); |
| Iterator<Element> itChildElements = childElements.iterator(); |
| while (itChildElements.hasNext()) { |
| Element childElement = itChildElements.next(); |
| if (ITrinidadConstants.TAG_IDENTIFIER_GROUP.isSameTagType( |
| TagIdentifierFactory.createDocumentTagWrapper(childElement))) { |
| if (currentRow > 1) { |
| buildGroupSeparatorRow(currentTBodyElement); |
| } |
| List<Element> groupChildElements = getChildElementsSkipFacets(childElement); |
| Iterator<Element> itGroupChildElements = groupChildElements.iterator(); |
| while (itGroupChildElements.hasNext()) { |
| Element groupChildElement = itGroupChildElements.next(); |
| buildControlRow(groupChildElement, currentTBodyElement); |
| } |
| currentRow += groupChildElements.size(); |
| if (currentRow <= rowCount) { |
| buildGroupSeparatorRow(currentTBodyElement); |
| } |
| if (currentRow > rowCount && currentColumn < columnCount) { |
| currentRow = 1; |
| currentColumn++; |
| currentTBodyElement = buildColumnStart( |
| outerTopTRElement, columnCount, currentColumn, labelWidth, fieldWidth); |
| } |
| } else { |
| buildControlRow(childElement, currentTBodyElement); |
| currentRow++; |
| if (currentRow > rowCount && currentColumn < columnCount) { |
| currentRow = 1; |
| currentColumn++; |
| currentTBodyElement = buildColumnStart( |
| outerTopTRElement, columnCount, currentColumn, labelWidth, fieldWidth); |
| } |
| } |
| } |
| |
| //handle "footer" facet |
| Element footerElement = getChildFacetByName(srcElement, "footer"); //$NON-NLS-1$ |
| if (footerElement != null) { |
| List<Element> footerChildElements = getChildElementsSkipFacets(footerElement); |
| if (footerChildElements.size() > 0) { |
| Element outerBottomTRElement = appendChildElement("tr", outerTBodyElement); //$NON-NLS-1$ |
| currentTBodyElement = buildFooterStart( |
| outerBottomTRElement, columnCount, labelWidth); |
| rowCount = countChildElements(footerElement); |
| currentRow = 1; |
| Iterator<Element> itFooterChildElements = footerChildElements.iterator(); |
| while (itFooterChildElements.hasNext()) { |
| Element footerChildElement = itFooterChildElements.next(); |
| if (ITrinidadConstants.TAG_IDENTIFIER_GROUP.isSameTagType( |
| TagIdentifierFactory.createDocumentTagWrapper(footerChildElement))) { |
| if (currentRow > 1) { |
| buildGroupSeparatorRow(currentTBodyElement); |
| } |
| List<Element> groupFooterChildElements = getChildElementsSkipFacets(footerChildElement); |
| Iterator<Element> itGroupFooterChildElements = groupFooterChildElements.iterator(); |
| while (itGroupFooterChildElements.hasNext()) { |
| Element groupFooterChildElement = itGroupFooterChildElements.next(); |
| if (ITrinidadConstants.TAG_IDENTIFIER_GROUP.isSameTagType( |
| TagIdentifierFactory.createDocumentTagWrapper(groupFooterChildElement))) { |
| if (currentRow > 1) { |
| buildGroupSeparatorRow(currentTBodyElement); |
| } |
| List<Element> subGroupFooterChildElements = getChildElementsSkipFacets(groupFooterChildElement); |
| Iterator<Element> itSubGroupFooterChildElements = subGroupFooterChildElements.iterator(); |
| while (itSubGroupFooterChildElements.hasNext()) { |
| Element subGroupFooterChildElement = itSubGroupFooterChildElements.next(); |
| buildControlRow(subGroupFooterChildElement, currentTBodyElement, true); |
| currentRow++; |
| } |
| if (currentRow <= rowCount) { |
| buildGroupSeparatorRow(currentTBodyElement); |
| } |
| } else { |
| buildControlRow(groupFooterChildElement, currentTBodyElement, true); |
| currentRow++; |
| } |
| } |
| if (currentRow <= rowCount) { |
| buildGroupSeparatorRow(currentTBodyElement); |
| } |
| } else { |
| buildControlRow(footerChildElement, currentTBodyElement, true); |
| currentRow++; |
| } |
| } |
| } |
| } |
| |
| return outerTableElement; |
| } |
| |
| private int calculateRowCount(Element srcElement) { |
| int rowCount = Integer.MAX_VALUE; |
| int specifiedRows = Integer.MAX_VALUE; |
| String rows = srcElement.getAttribute("rows"); //$NON-NLS-1$ |
| if (rows != null && rows.length() > 0) { |
| try { |
| //not spec'ed, but observed that setting rows < 5 is ignored |
| specifiedRows = Math.max(5, Integer.parseInt(rows)); |
| } catch(NumberFormatException nfe) { |
| //ignore - specifiedRows will default to Integer.MAX_VALUE |
| } |
| } |
| int specifiedMaxColumns = Integer.MAX_VALUE; |
| String maxColumns = srcElement.getAttribute("maxColumns"); //$NON-NLS-1$ |
| if (maxColumns != null && maxColumns.length() > 0) { |
| try { |
| specifiedMaxColumns = Integer.parseInt(maxColumns); |
| } catch(NumberFormatException nfe) { |
| //ignore - specifiedMaxColumns will default to Integer.MAX_VALUE |
| } |
| } |
| int childElementCount = countChildElements(srcElement); |
| int calculatedColumns = childElementCount / specifiedRows; |
| if (childElementCount % specifiedRows > 0) { |
| calculatedColumns++; |
| } |
| if (calculatedColumns > specifiedMaxColumns) { |
| rowCount = childElementCount / specifiedMaxColumns; |
| } else { |
| rowCount = specifiedRows; |
| } |
| return rowCount; |
| } |
| |
| private int calculateColumnCount(Element srcElement) { |
| int columnCount = Integer.MAX_VALUE; |
| int specifiedRows = Integer.MAX_VALUE; |
| String rows = srcElement.getAttribute("rows"); //$NON-NLS-1$ |
| if (rows != null && rows.length() > 0) { |
| try { |
| //not spec'ed, but observed that setting rows < 5 is ignored |
| specifiedRows = Math.max(5, Integer.parseInt(rows)); |
| } catch(NumberFormatException nfe) { |
| //ignore - specifiedRows will default to Integer.MAX_VALUE |
| } |
| } |
| int specifiedMaxColumns = Integer.MAX_VALUE; |
| String maxColumns = srcElement.getAttribute("maxColumns"); //$NON-NLS-1$ |
| if (maxColumns != null && maxColumns.length() > 0) { |
| try { |
| specifiedMaxColumns = Integer.parseInt(maxColumns); |
| } catch(NumberFormatException nfe) { |
| //ignore - specifiedMaxColumns will default to Integer.MAX_VALUE |
| } |
| } |
| int childElementCount = countChildElements(srcElement); |
| int calculatedColumns = childElementCount / specifiedRows; |
| if (childElementCount % specifiedRows > 0) { |
| calculatedColumns++; |
| } |
| columnCount = Math.min(specifiedMaxColumns, calculatedColumns); |
| return columnCount; |
| } |
| |
| private int countChildElements(Element srcElement) { |
| int count = 0; |
| List<Element> childElements = getChildElementsSkipFacets(srcElement); |
| Iterator<Element> itChildElements = childElements.iterator(); |
| while (itChildElements.hasNext()) { |
| Element childElement = itChildElements.next(); |
| if (ITrinidadConstants.TAG_IDENTIFIER_GROUP.isSameTagType( |
| TagIdentifierFactory.createDocumentTagWrapper(childElement))) { |
| count += countChildElements(childElement); |
| } else { |
| count++; |
| } |
| } |
| return count; |
| } |
| |
| private String calculateFieldWidth(Element srcElement) { |
| String width = null; |
| String fieldWidth = srcElement.getAttribute("fieldWidth"); //$NON-NLS-1$ |
| if (fieldWidth != null && fieldWidth.length() > 0) { |
| width = fieldWidth; |
| } else { |
| String labelWidth = srcElement.getAttribute("labelWidth"); //$NON-NLS-1$ |
| if (labelWidth != null && labelWidth.length() > 1) { |
| if (labelWidth.endsWith("%")) { //$NON-NLS-1$ |
| try { |
| int iLabelWidth = Integer.parseInt(labelWidth.substring(0, labelWidth.length() - 1)); |
| if (iLabelWidth <= 100) { |
| width = String.valueOf(100 - iLabelWidth) + "%"; //$NON-NLS-1$ |
| } |
| } catch(NumberFormatException nfe) { |
| //ignore - cannot calculate and so will return null |
| } |
| } |
| } |
| } |
| return width; |
| } |
| |
| private String calculateLabelWidth(Element srcElement) { |
| String width = null; |
| String labelWidth = srcElement.getAttribute("labelWidth"); //$NON-NLS-1$ |
| if (labelWidth != null && labelWidth.length() > 0) { |
| width = labelWidth; |
| } else { |
| String fieldWidth = srcElement.getAttribute("fieldWidth"); //$NON-NLS-1$ |
| if (fieldWidth != null && fieldWidth.length() > 1) { |
| if (fieldWidth.endsWith("%")) { //$NON-NLS-1$ |
| try { |
| int iFieldWidth = Integer.parseInt(fieldWidth.substring(0, fieldWidth.length() - 1)); |
| if (iFieldWidth <= 100) { |
| width = String.valueOf(100 - iFieldWidth) + "%"; //$NON-NLS-1$ |
| } |
| } catch(NumberFormatException nfe) { |
| //ignore - cannot calculate and so will return null |
| } |
| } |
| } |
| } |
| return width; |
| } |
| |
| private Element buildColumnStart( |
| Element parentElement, int columnCount, int currentColumn, |
| String labelWidth, String fieldWidth) { |
| Element tdElement = appendChildElement("td", parentElement); //$NON-NLS-1$ |
| appendAttribute(tdElement, "style", "vertical-align:top;"); //$NON-NLS-1$ //$NON-NLS-2$ |
| if (currentColumn < columnCount) { |
| String width = String.valueOf(100 / columnCount) + "%"; //$NON-NLS-1$ |
| appendAttribute(tdElement, "width", width); //$NON-NLS-1$ |
| } |
| Element tableElement = appendChildElement("table", tdElement); //$NON-NLS-1$ |
| appendAttribute(tableElement, "cellpadding", "0"); //$NON-NLS-1$ //$NON-NLS-2$ |
| appendAttribute(tableElement, "cellspacing", "0"); //$NON-NLS-1$ //$NON-NLS-2$ |
| appendAttribute(tableElement, "border", "0"); //$NON-NLS-1$ //$NON-NLS-2$ |
| appendAttribute(tableElement, "width", "100%"); //$NON-NLS-1$ //$NON-NLS-2$ |
| Element tBodyElement = appendChildElement("tbody", tableElement); //$NON-NLS-1$ |
| Element trElement = appendChildElement("tr", tBodyElement); //$NON-NLS-1$ |
| Element tdLabelElement = appendChildElement("td", trElement); //$NON-NLS-1$ |
| if (labelWidth != null && labelWidth.length() > 0) { |
| appendAttribute(tdLabelElement, "style", "width:" + labelWidth); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| Element tdFieldElement = appendChildElement("td", trElement); //$NON-NLS-1$ |
| if (fieldWidth != null && fieldWidth.length() > 0) { |
| appendAttribute(tdFieldElement, "style", "width:" + fieldWidth); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| return tBodyElement; |
| } |
| |
| private void buildControlRow(Element srcElement, Element parentElement, boolean alignLabelsTop) { |
| Element trElement = appendChildElement("tr", parentElement); //$NON-NLS-1$ |
| Element tdLabelElement = appendChildElement("td", trElement); //$NON-NLS-1$ |
| appendAttribute(tdLabelElement, "class", STYLECLASS_LABELCELL); //$NON-NLS-1$ |
| if (alignLabelsTop) { |
| appendAttribute(tdLabelElement, "valign", "top"); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| appendAttribute(tdLabelElement, "nowrap", ""); //$NON-NLS-1$ //$NON-NLS-2$ |
| buildLabel(srcElement, tdLabelElement); |
| Element tdFieldElement = appendChildElement("td", trElement); //$NON-NLS-1$ |
| appendAttribute(tdFieldElement, "class", STYLECLASS_FIELDCELL); //$NON-NLS-1$ |
| appendAttribute(tdFieldElement, "valign", "top"); //$NON-NLS-1$ //$NON-NLS-2$ |
| appendAttribute(tdFieldElement, "nowrap", ""); //$NON-NLS-1$ //$NON-NLS-2$ |
| tagConverterContext.addChild(srcElement, new ConvertPosition(tdFieldElement, 0)); |
| } |
| |
| private void buildControlRow(Element srcElement, Element parentElement) { |
| buildControlRow(srcElement, parentElement, false); |
| } |
| |
| private void buildLabel(Element srcElement, Element parentElement) { |
| TagIdentifier tagID = TagIdentifierFactory.createDocumentTagWrapper(srcElement); |
| if ( |
| tagID.isSameTagType(ITrinidadConstants.TAG_IDENTIFIER_INPUTCOLOR) || |
| tagID.isSameTagType(ITrinidadConstants.TAG_IDENTIFIER_INPUTDATE) || |
| tagID.isSameTagType(ITrinidadConstants.TAG_IDENTIFIER_INPUTFILE) || |
| tagID.isSameTagType(ITrinidadConstants.TAG_IDENTIFIER_INPUTLISTOFVALUES) || |
| tagID.isSameTagType(ITrinidadConstants.TAG_IDENTIFIER_INPUTNUMBERSPINBOX) || |
| tagID.isSameTagType(ITrinidadConstants.TAG_IDENTIFIER_INPUTTEXT) || |
| tagID.isSameTagType(ITrinidadConstants.TAG_IDENTIFIER_SELECTBOOLEANCHECKBOX) || |
| tagID.isSameTagType(ITrinidadConstants.TAG_IDENTIFIER_SELECTBOOLEANRADIO) || |
| tagID.isSameTagType(ITrinidadConstants.TAG_IDENTIFIER_SELECTMANYCHECKBOX) || |
| tagID.isSameTagType(ITrinidadConstants.TAG_IDENTIFIER_SELECTMANYLISTBOX) || |
| tagID.isSameTagType(ITrinidadConstants.TAG_IDENTIFIER_SELECTONECHOICE) || |
| tagID.isSameTagType(ITrinidadConstants.TAG_IDENTIFIER_SELECTONELISTBOX) || |
| tagID.isSameTagType(ITrinidadConstants.TAG_IDENTIFIER_SELECTONERADIO) || |
| tagID.isSameTagType(ITrinidadConstants.TAG_IDENTIFIER_PANELLABELANDMESSAGE)) { |
| String required = srcElement.getAttribute("required"); //$NON-NLS-1$ |
| String showRequired = srcElement.getAttribute("showRequired"); //$NON-NLS-1$ |
| if (Boolean.parseBoolean(required) || Boolean.parseBoolean(showRequired)) { |
| Element spanElement = appendChildElement("span", parentElement); //$NON-NLS-1$ |
| appendAttribute(spanElement, "title", "Required"); //$NON-NLS-1$ //$NON-NLS-2$ |
| appendAttribute(spanElement, "class", STYLECLASS_REQUIREDSPAN); //$NON-NLS-1$ |
| appendChildText("* ", spanElement); //$NON-NLS-1$ |
| } |
| String label = srcElement.getAttribute("labelAndAccessKey"); //$NON-NLS-1$ |
| if (label == null || label.length() < 1) { |
| label = srcElement.getAttribute("label"); //$NON-NLS-1$ |
| } |
| if (label != null && label.length() > 0) { |
| Element labelElement = appendChildElement("label", parentElement); //$NON-NLS-1$ |
| appendChildText(label, labelElement); |
| } |
| } |
| } |
| |
| private void buildGroupSeparatorRow(Element parentElement) { |
| Element trElement = appendChildElement("tr", parentElement); //$NON-NLS-1$ |
| Element tdElement = appendChildElement("td", trElement); //$NON-NLS-1$ |
| appendAttribute(tdElement, "colspan", "2"); //$NON-NLS-1$ //$NON-NLS-2$ |
| Element divElement = appendChildElement("div", tdElement); //$NON-NLS-1$ |
| appendAttribute(divElement, "class", STYLECLASS_GROUPSEPARATOR); //$NON-NLS-1$ |
| } |
| |
| private Element buildFooterStart( |
| Element parentElement, int columnCount, String labelWidth) { |
| Element tdElement = appendChildElement("td", parentElement); //$NON-NLS-1$ |
| appendAttribute(tdElement, "style", "vertical-align:top;"); //$NON-NLS-1$ //$NON-NLS-2$ |
| appendAttribute(tdElement, "colspan", String.valueOf(columnCount)); //$NON-NLS-1$ |
| Element tableElement = appendChildElement("table", tdElement); //$NON-NLS-1$ |
| appendAttribute(tableElement, "cellpadding", "0"); //$NON-NLS-1$ //$NON-NLS-2$ |
| appendAttribute(tableElement, "cellspacing", "0"); //$NON-NLS-1$ //$NON-NLS-2$ |
| appendAttribute(tableElement, "border", "0"); //$NON-NLS-1$ //$NON-NLS-2$ |
| appendAttribute(tableElement, "width", "100%"); //$NON-NLS-1$ //$NON-NLS-2$ |
| Element tBodyElement = appendChildElement("tbody", tableElement); //$NON-NLS-1$ |
| Element trElement = appendChildElement("tr", tBodyElement); //$NON-NLS-1$ |
| String footerLabelWidth = null; |
| String footerFieldWidth = null; |
| if (labelWidth != null && labelWidth.length() > 0) { |
| if (labelWidth.endsWith("%")) { //$NON-NLS-1$ |
| try { |
| int iLabelWidth = Integer.parseInt(labelWidth.substring(0, labelWidth.length() - 1)); |
| iLabelWidth = iLabelWidth / columnCount; |
| footerLabelWidth = String.valueOf(iLabelWidth) + "%"; //$NON-NLS-1$ |
| footerFieldWidth = String.valueOf(100 - iLabelWidth) + "%"; //$NON-NLS-1$ |
| } catch(NumberFormatException nfe) { |
| //ignore - cannot calculate, widths remain null |
| } |
| } else { |
| footerLabelWidth = labelWidth; |
| } |
| } |
| Element tdLabelElement = appendChildElement("td", trElement); //$NON-NLS-1$ |
| if (footerLabelWidth != null && footerLabelWidth.length() > 0) { |
| //appendAttribute(tdLabelElement, "style", "width:" + footerLabelWidth); //$NON-NLS-1$ //$NON-NLS-2$ |
| appendAttribute(tdLabelElement, "width", footerLabelWidth); //$NON-NLS-1$ |
| } |
| Element tdFieldElement = appendChildElement("td", trElement); //$NON-NLS-1$ |
| if (footerFieldWidth != null && footerFieldWidth.length() > 0) { |
| //appendAttribute(tdFieldElement, "style", "width:" + footerFieldWidth); //$NON-NLS-1$ //$NON-NLS-2$ |
| appendAttribute(tdFieldElement, "width", footerFieldWidth); //$NON-NLS-1$ |
| } |
| return tBodyElement; |
| } |
| |
| } |