/*******************************************************************************
* Copyright (c) 2007-2008 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
*
* Contributor:
* Red Hat, Inc. - initial API and implementation
******************************************************************************/
package org.jboss.tools.jsf.vpe.richfaces.template;
import java.util.HashMap;
import java.util.Map;
import org.jboss.tools.jsf.vpe.richfaces.ComponentUtil;
import org.jboss.tools.jst.web.ui.internal.editor.util.Constants;
import org.jboss.tools.vpe.editor.VpeVisualDomBuilder;
import org.jboss.tools.vpe.editor.context.VpePageContext;
import org.jboss.tools.vpe.editor.template.VpeChildrenInfo;
import org.jboss.tools.vpe.editor.template.VpeCreationData;
import org.jboss.tools.vpe.editor.template.VpeToggableTemplate;
import org.jboss.tools.vpe.editor.util.HTML;
import org.jboss.tools.vpe.editor.util.VpeStyleUtil;
import org.mozilla.interfaces.nsIDOMDocument;
import org.mozilla.interfaces.nsIDOMElement;
import org.mozilla.interfaces.nsIDOMText;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
/**
* Base class for both {@link RichFacesInplaceInputTemplate} and {@link
* RichFacesInplaceSelectTemplate}.
*
* @author Eugene Stherbin
* @see RichFacesInplaceInputTemplate
* @see RichFacesInplaceSelectTemplate
*/
public abstract class RichFacesAbstractInplaceTemplate extends AbstractRichFacesTemplate implements VpeToggableTemplate {
/** The Constant APPLY_BUTTON_GIF. */
protected static final String APPLY_BUTTON_GIF = "/applyButton.gif"; //$NON-NLS-1$
/** The Constant CANCEL_BUTTON_GIF. */
protected static final String CANCEL_BUTTON_GIF = "/cancelButton.gif"; //$NON-NLS-1$
/** The Constant controlsVerticalPositions. */
protected final Map<String, String> controlsVerticalPositions = new HashMap<String, String>();
/** The Constant DEFAULT_INPUT_WIDTH_VALUE. */
protected static final String DEFAULT_INPUT_WIDTH_VALUE = "66px"; //$NON-NLS-1$
/** The Constant DEFAULT_VERTICAL_POSITION. */
protected static final String DEFAULT_VERTICAL_POSITION = null;
/** The Constant defaultButtonImages. */
protected static final Map<String, String> defaultButtonImages = new HashMap<String, String>();
/** The default style classes. */
protected static final Map<String, String> defaultStyleClasses = new HashMap<String, String>();
/** The Constant RICH_INPLACE_VIEW_DEFAULT_STYLE_CLASS. */
protected static final String RICH_INPLACE_VIEW_DEFAULT_STYLE_CLASS = "rich-inplace-view"; //$NON-NLS-1$
/** The button images. */
protected final Map<String, String> buttonImages = new HashMap<String, String>();
/** The controls horizontal positions. */
protected final Map<String, String> controlsHorizontalPositions = new HashMap<String, String>();
/** The is show input. */
protected boolean isToggle = false;
/** The Constant SPACER_GIF. */
protected final String SPACER_GIF = getCssExtension() + "/spacer.gif"; //$NON-NLS-1$
protected final String DEFAULT_LABEL_VALUE = "\u00A0\u00A0\u00A0"; //$NON-NLS-1$
protected String sourceCancelButtonIcon;
protected String sourceApplyButtonIcon;
/**
* The Constructor.
*/
public RichFacesAbstractInplaceTemplate() {
super();
initDefaultStyleClasses();
initDefaultButtonImages();
initPositions();
}
/**
* Creates the root span template method.
*
* @param visualDocument the visual document
* @param source the source
* @return the ns IDOM element
*/
protected nsIDOMElement createRootSpanTemplateMethod(Element source, nsIDOMDocument visualDocument, Attributes attrs) {
final nsIDOMElement rootSpan = visualDocument.createElement(HTML.TAG_SPAN);
rootSpan.setAttribute(VpeVisualDomBuilder.VPE_USER_TOGGLE_ID, String.valueOf(this.isToggle));
String rootStyleClass = "rich-inplace" + getCssStylesSuffix(); //$NON-NLS-1$
for (String sc : getRootSpanClasses(attrs)) {
if (ComponentUtil.isNotBlank(sc)) {
rootStyleClass += Constants.WHITE_SPACE + sc;
}
}
rootSpan.setAttribute(HTML.ATTR_CLASS, rootStyleClass);
String style = Constants.EMPTY;
if (this.isToggle) {
style = "position: relative;"; //$NON-NLS-1$
}
rootSpan.setAttribute(HTML.ATTR_STYLE, style + "; display: " + attrs.getLayout() + Constants.SEMICOLON); //$NON-NLS-1$
return rootSpan;
}
/**
* Gets the css extension.
*
* @return the css extension
*/
protected abstract String getCssExtension();
/**
* Gets the css style.
*
* @return the css style
*/
protected abstract String getCssStyle();
/**
* Gets the css styles suffix.
*
* @return the css styles suffix
*/
protected abstract String getCssStylesSuffix();
/**
* Gets the root span classes.
*
* @return the root span classes
*/
protected abstract String[] getRootSpanClasses(Attributes attrs);
/**
* Gets the value.
*
* @return the value
*/
protected String getValue(Attributes attrs) {
String rst = Constants.EMPTY;
if (ComponentUtil.isNotBlank(attrs.getDefaultLabel())) {
rst = attrs.getDefaultLabel();
} else if (ComponentUtil.isBlank(attrs.getDefaultLabel())
&& ComponentUtil.isNotBlank(attrs.getValue())) {
rst = attrs.getValue();
} else if (isToggle) {
rst = Constants.WHITE_SPACE;
} else {
rst = DEFAULT_LABEL_VALUE;
}
return rst;
}
/**
* Initialize the default button images.
*/
protected void initDefaultButtonImages() {
if (defaultButtonImages.isEmpty()) {
defaultButtonImages.put("cancelControlIcon", getCssExtension() + CANCEL_BUTTON_GIF); //$NON-NLS-1$
defaultButtonImages.put("saveControlIcon", getCssExtension() + APPLY_BUTTON_GIF); //$NON-NLS-1$
}
}
/**
* Initialize the default style classes.
*/
protected void initDefaultStyleClasses() {
if (defaultStyleClasses.isEmpty()) {
defaultStyleClasses.put("rootSpan", "rich-inplace" + getCssStylesSuffix() + " {0} {1}"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
}
/**
* Initialize the positions.
*/
protected void initPositions() {
if (controlsVerticalPositions.isEmpty()) {
controlsVerticalPositions.put(HTML.VALUE_ALIGN_BOTTOM, "18px"); //$NON-NLS-1$
controlsVerticalPositions.put(HTML.VALUE_ALIGN_TOP, "-12px"); //$NON-NLS-1$
controlsVerticalPositions.put(HTML.VALUE_ALIGN_CENTER, "0px"); //$NON-NLS-1$
}
if (controlsHorizontalPositions.isEmpty()) {
controlsHorizontalPositions.put(HTML.VALUE_ALIGN_LEFT, "0px"); //$NON-NLS-1$
controlsHorizontalPositions.put(HTML.VALUE_ALIGN_CENTER, "53px"); //$NON-NLS-1$
}
}
/**
* Prepare data.
*
* @param source the source
*/
protected void prepareData(VpePageContext pageContext, Element source) {
prepareImages(source);
}
/**
* Prepare images.
*
* @param source the source
*/
protected void prepareImages(Element source) {
for (String key : defaultButtonImages.keySet()) {
String value = ComponentUtil.getAttribute(source, key);
if(ComponentUtil.isNotBlank(value)) {
this.buttonImages.put(key, value);
} else {
this.buttonImages.put(key, defaultButtonImages.get(key));
}
}
}
/**
* Sets the up image.
*
* @param img the img
* @param width the width
* @param height the height
* @param border the border
* @param image the image
*/
protected void setUpImg(nsIDOMElement img, int width, int height, int border, String image) {
ComponentUtil.setImg(img, image);
img.setAttribute(HTML.ATTR_WIDTH, String.valueOf(width));
img.setAttribute(HTML.ATTR_HEIGHT, String.valueOf(height));
img.setAttribute(HTML.ATTR_BORDER, String.valueOf(border));
}
/**
* Sets the up span root.
*
* @param visualDocument the visual document
* @param spanRoot the span root
* @param source the source
*/
protected void setUpSpanRoot(nsIDOMElement spanRoot, Element source, nsIDOMDocument visualDocument, Attributes attrs) {
if (attrs.getStyleClass().length() > 0) {
spanRoot.setAttribute(HTML.ATTR_CLASS, attrs.getStyleClass());
} else {
spanRoot.setAttribute(HTML.ATTR_CLASS, RICH_INPLACE_VIEW_DEFAULT_STYLE_CLASS);
}
String value = Constants.WHITE_SPACE;
if (attrs.getValue().length() > 0) {
value = attrs.getValue();
}
final nsIDOMText text = visualDocument.createTextNode(value);
spanRoot.appendChild(text);
}
/**
* Stop toggling.
*
* @param sourceNode the source node
* @see org.jboss.tools.vpe.editor.template.VpeToggableTemplate#stopToggling(org.w3c.dom.Node)
*/
public void stopToggling(Node sourceNode) {
this.isToggle = false;
}
/**
* Toggle.
*
* @param builder the builder
* @param sourceNode the source node
* @param toggleId the toggle id
*
* @see org.jboss.tools.vpe.editor.template.VpeToggableTemplate#toggle(
* org.jboss.tools.vpe.editor.VpeVisualDomBuilder, org.w3c.dom.Node, java.lang.String)
*/
public void toggle(VpeVisualDomBuilder builder, Node sourceNode, String toggleId) {
isToggle = !isToggle;
}
protected abstract String getCssStylesControlSuffix();
protected abstract String getControlPositionsSubStyles(Attributes attrs);
protected abstract String getMainControlsDivCssClass();
/**
* Creates the controls div.
*
* @param visualDocument the visual document
* @param sourceNode the source node
* @param pageContext the page context
* @param creationData the VpeCreationData object
* @return the ns IDOM element
*/
protected nsIDOMElement createControlsDiv(VpePageContext pageContext,
Node sourceNode, nsIDOMDocument visualDocument,
VpeCreationData creationData, Attributes attrs) {
final nsIDOMElement element = visualDocument.createElement(HTML.TAG_DIV);
element.setAttribute(HTML.ATTR_CLASS, getMainControlsDivCssClass());
element.setAttribute(HTML.ATTR_STYLE, "position: absolute; " + getControlPositionsSubStyles(attrs)); //$NON-NLS-1$
final nsIDOMElement divShadov = visualDocument.createElement(HTML.TAG_DIV);
divShadov.setAttribute(HTML.ATTR_CLASS, "rich-inplace" + getCssStylesSuffix() + "-shadow"); //$NON-NLS-1$ //$NON-NLS-2$
final nsIDOMElement divShadovTable = visualDocument.createElement(HTML.TAG_TABLE);
divShadovTable.setAttribute(HTML.ATTR_CELLPADDING, "0"); //$NON-NLS-1$
divShadovTable.setAttribute(HTML.ATTR_CELLSPACING, "0"); //$NON-NLS-1$
divShadovTable.setAttribute(HTML.ATTR_BORDER, "0"); //$NON-NLS-1$
final nsIDOMElement divShadovTBody = visualDocument.createElement(HTML.TAG_TBODY);
final nsIDOMElement divShadovTr1 = visualDocument.createElement(HTML.TAG_TR);
final nsIDOMElement divShadovTr2 = visualDocument.createElement(HTML.TAG_TR);
final nsIDOMElement divShadovTd1 = visualDocument.createElement(HTML.TAG_TD);
final nsIDOMElement divShadovTd2 = visualDocument.createElement(HTML.TAG_TD);
final nsIDOMElement divShadovTd1Tr2 = visualDocument.createElement(HTML.TAG_TD);
final nsIDOMElement divShadovTd2Tr2 = visualDocument.createElement(HTML.TAG_TD);
final nsIDOMElement td1Img = visualDocument.createElement(HTML.TAG_IMG);
final nsIDOMElement td2Img = visualDocument.createElement(HTML.TAG_IMG);
final nsIDOMElement td3Img = visualDocument.createElement(HTML.TAG_IMG);
final nsIDOMElement td4Img = visualDocument.createElement(HTML.TAG_IMG);
setUpImg(td1Img, 10, 1, 0, SPACER_GIF);
setUpImg(td2Img, 1, 10, 0, SPACER_GIF);
setUpImg(td3Img, 1, 10, 0, SPACER_GIF);
setUpImg(td4Img, 10, 1, 0, SPACER_GIF);
divShadovTd1.setAttribute(HTML.ATTR_CLASS, "rich-inplace" + getCssStylesSuffix() + "-shadow-tl"); //$NON-NLS-1$ //$NON-NLS-2$
divShadovTd2.setAttribute(HTML.ATTR_CLASS, "rich-inplace" + getCssStylesSuffix() + "-shadow-tr"); //$NON-NLS-1$ //$NON-NLS-2$
divShadovTd1Tr2.setAttribute(HTML.ATTR_CLASS, "rich-inplace" + getCssStylesSuffix() + "-shadow-bl"); //$NON-NLS-1$ //$NON-NLS-2$
divShadovTd2Tr2.setAttribute(HTML.ATTR_CLASS, "rich-inplace" + getCssStylesSuffix() + "-shadow-br"); //$NON-NLS-1$ //$NON-NLS-2$
final nsIDOMElement divButtons = visualDocument.createElement(HTML.TAG_DIV);
divButtons.setAttribute(HTML.ATTR_STYLE, "position: relative; height: 18px;"); //$NON-NLS-1$
/*
* Encoding controls facet
*/
Element controlFacet = ComponentUtil.getFacetElement(
(Element) sourceNode, RichFaces.NAME_FACET_CONTROLS, false);
if (controlFacet != null) {
VpeChildrenInfo childrenInfo = new VpeChildrenInfo(divButtons);
childrenInfo.addSourceChild(controlFacet);
creationData.addChildrenInfo(childrenInfo);
} else {
// Create "Apply" button
final nsIDOMElement applyButtonImg = visualDocument.createElement(HTML.TAG_INPUT);
applyButtonImg.setAttribute(HTML.ATTR_TYPE, HTML.VALUE_TYPE_IMAGE);
String applyButtonClass = "rich-inplace" + getCssStylesSuffix() + "-control"; //$NON-NLS-1$ //$NON-NLS-2$
if (ComponentUtil.isNotBlank(attrs.getControlClass())) {
applyButtonClass += Constants.EMPTY + attrs.getControlClass();
}
applyButtonImg.setAttribute(HTML.ATTR_CLASS, applyButtonClass);
final String saveControlIconImg = buttonImages.get("saveControlIcon"); //$NON-NLS-1$
if (defaultButtonImages.containsValue(saveControlIconImg)) {
// Set default icon from resources
ComponentUtil.setImg(applyButtonImg, saveControlIconImg);
} else {
// Set custom user icon
String imgFullPath = VpeStyleUtil.addFullPathToImgSrc(saveControlIconImg, pageContext, true);
applyButtonImg.setAttribute(HTML.ATTR_SRC, imgFullPath);
}
applyButtonImg.setAttribute(VpeVisualDomBuilder.VPE_USER_TOGGLE_ID, String.valueOf(0));
// Create "Cancel" button
final nsIDOMElement cancelButtonImg = visualDocument.createElement(HTML.TAG_INPUT);
cancelButtonImg.setAttribute(HTML.ATTR_TYPE, HTML.VALUE_TYPE_IMAGE);
String cancelButtonClass = "rich-inplace" + getCssStylesSuffix() + "-control"; //$NON-NLS-1$ //$NON-NLS-2$
if (ComponentUtil.isNotBlank(attrs.getControlClass())) {
cancelButtonClass += Constants.EMPTY + attrs.getControlClass();
}
cancelButtonImg.setAttribute(HTML.ATTR_CLASS, cancelButtonClass);
final String cancelControlIconImg = buttonImages.get("cancelControlIcon"); //$NON-NLS-1$
if (defaultButtonImages.containsValue(cancelControlIconImg)) {
// Set default icon from resources
ComponentUtil.setImg(cancelButtonImg, cancelControlIconImg);
} else {
// Set custom user icon
String imgFullPath = VpeStyleUtil.addFullPathToImgSrc(cancelControlIconImg, pageContext, true);
cancelButtonImg.setAttribute(HTML.ATTR_SRC, imgFullPath);
}
cancelButtonImg.setAttribute(VpeVisualDomBuilder.VPE_USER_TOGGLE_ID, String.valueOf(0));
divButtons.appendChild(applyButtonImg);
divButtons.appendChild(cancelButtonImg);
/*
* Adding shadow to controls
*/
element.appendChild(divShadov);
divShadov.appendChild(divShadovTable);
divShadovTable.appendChild(divShadovTBody);
divShadovTBody.appendChild(divShadovTr1);
divShadovTr1.appendChild(divShadovTd1);
divShadovTd1.appendChild(td1Img);
divShadovTr1.appendChild(divShadovTd2);
divShadovTd2.appendChild(td2Img);
divShadovTBody.appendChild(divShadovTr2);
divShadovTr2.appendChild(divShadovTd1Tr2);
divShadovTd1Tr2.appendChild(td3Img);
divShadovTr2.appendChild(divShadovTd2Tr2);
divShadovTd2Tr2.appendChild(td4Img);
}
// Adding controls
element.appendChild(divButtons);
return element;
}
class Attributes {
/*
* Attributes names
*/
private final String EDIT_CLASS = "editClass"; //$NON-NLS-1$
private final String VIEW_CLASS = "viewClass"; //$NON-NLS-1$
private final String CONTROL_CLASS = "controlClass"; //$NON-NLS-1$
private final String SHOW_CONTROLS = "showControls"; //$NON-NLS-1$
private final String LAYOUT = "layout"; //$NON-NLS-1$
private final String CONTROLS_HORIZONTAL_POSOSITION = "controlsHorizontalPosition"; //$NON-NLS-1$
private final String CONTROLS_VERTICAL_POSITION = "controlsVerticalPosition"; //$NON-NLS-1$
private final String DEFAULT_LABEL = "defaultLabel"; //$NON-NLS-1$
private final String DEFAULT_VALUE = Constants.WHITE_SPACE;
/*
* Attributes
*/
private String editClass;
private String viewClass;
private String controlClass;
private boolean showControls;
private String layout;
private String value;
private String controlsHorizontalPosition;
private String controlsVerticalPosition;
private String defaultLabel;
private String styleClass;
public Attributes(final Element sourceElement) {
if (null == sourceElement) {
return;
}
editClass = sourceElement.getAttribute(EDIT_CLASS);
viewClass = sourceElement.getAttribute(VIEW_CLASS);
controlClass = sourceElement.getAttribute(CONTROL_CLASS);
showControls = Boolean.parseBoolean(sourceElement.getAttribute(SHOW_CONTROLS));
layout = sourceElement.getAttribute(LAYOUT);
value = sourceElement.getAttribute(HTML.ATTR_VALUE);
controlsHorizontalPosition = sourceElement.getAttribute(CONTROLS_HORIZONTAL_POSOSITION);
controlsVerticalPosition = sourceElement.getAttribute(CONTROLS_VERTICAL_POSITION);
defaultLabel = sourceElement.getAttribute(DEFAULT_LABEL);
styleClass = sourceElement.getAttribute(RichFaces.ATTR_STYLE_CLASS);
/*
* Setting default value when needed.
*/
if (ComponentUtil.isBlank(value)) {
value = DEFAULT_VALUE;
}
if (ComponentUtil.isBlank(layout)
|| (!(layout.equalsIgnoreCase(HTML.VALUE_INLINE))
&& !(layout.equalsIgnoreCase(HTML.VALUE_BLOCK)))) {
layout = HTML.VALUE_INLINE;
}
if (ComponentUtil.isBlank(controlsVerticalPosition)
|| !isInKeySet(controlsVerticalPositions,
controlsVerticalPosition)) {
this.controlsVerticalPosition = HTML.VALUE_ALIGN_CENTER;
}
if (ComponentUtil.isBlank(controlsHorizontalPosition)
|| !isInKeySet(controlsHorizontalPositions,
controlsHorizontalPosition)) {
this.controlsHorizontalPosition = HTML.VALUE_ALIGN_RIGHT;
}
}
/**
* Checks if the value is in the map's key set.
*
* @param map the map
* @param value the value
* @return true, if the value is in
*/
protected boolean isInKeySet(Map<String, String> map, String value) {
boolean rst = false;
for (String key : map.keySet()) {
if (key.equalsIgnoreCase(value)) {
rst = true;
break;
}
}
return rst;
}
public String getEditClass() {
return editClass;
}
public String getViewClass() {
return viewClass;
}
public String getLayout() {
return layout;
}
public String getControlClass() {
return controlClass;
}
public boolean isShowControls() {
return showControls;
}
public String getValue() {
return value;
}
public String getControlsHorizontalPosition() {
return controlsHorizontalPosition;
}
public String getControlsVerticalPosition() {
return controlsVerticalPosition;
}
public String getDefaultLabel() {
return defaultLabel;
}
public String getStyleClass() {
return styleClass;
}
}
}