All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opencms.workplace.CmsWidgetDialog Maven / Gradle / Ivy

Go to download

OpenCms is an enterprise-ready, easy to use website content management system based on Java and XML technology. Offering a complete set of features, OpenCms helps content managers worldwide to create and maintain beautiful websites fast and efficiently.

There is a newer version: 18.0
Show newest version
/*
 * This library is part of OpenCms -
 * the Open Source Content Management System
 *
 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * For further information about Alkacon Software GmbH & Co. KG, please see the
 * company website: http://www.alkacon.com
 *
 * For further information about OpenCms, please see the
 * project website: http://www.opencms.org
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package org.opencms.workplace;

import org.opencms.i18n.CmsEncoder;
import org.opencms.jsp.CmsJspActionElement;
import org.opencms.main.CmsLog;
import org.opencms.main.I_CmsThrowable;
import org.opencms.main.OpenCms;
import org.opencms.util.CmsRequestUtil;
import org.opencms.util.CmsStringUtil;
import org.opencms.widgets.A_CmsWidget;
import org.opencms.widgets.CmsDisplayWidget;
import org.opencms.widgets.I_CmsWidget;
import org.opencms.widgets.I_CmsWidgetDialog;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;

import org.apache.commons.logging.Log;

/**
 * Base class for dialogs that use the OpenCms widgets without XML content.

* * @since 6.0.0 */ public abstract class CmsWidgetDialog extends CmsDialog implements I_CmsWidgetDialog { /** Action for optional element creation. */ public static final int ACTION_ELEMENT_ADD = 152; /** Action for optional element removal. */ public static final int ACTION_ELEMENT_REMOVE = 153; /** Value for the action: error in the form validation. */ public static final int ACTION_ERROR = 303; /** Value for the action: save the dialog. */ public static final int ACTION_SAVE = 300; /** Request parameter value for the action: save the dialog. */ public static final String DIALOG_SAVE = "save"; /** Indicates an optional element should be created. */ public static final String EDITOR_ACTION_ELEMENT_ADD = "addelement"; /** Indicates an optional element should be removed. */ public static final String EDITOR_ACTION_ELEMENT_REMOVE = "removeelement"; /** Prefix for "hidden" parameters, required since these must be unescaped later. */ public static final String HIDDEN_PARAM_PREFIX = "hidden."; /** The log object for this class. */ private static final Log LOG = CmsLog.getLog(CmsWidgetDialog.class); /** The errors thrown by commit actions. */ protected List m_commitErrors; /** The object edited with this widget dialog. */ protected Object m_dialogObject; /** The allowed pages for this dialog in a List. */ protected List m_pages; /** Controls which page is currently displayed in the dialog. */ protected String m_paramPage; /** The validation errors for the input form. */ protected List m_validationErrorList; /** Contains all parameter value of this dialog. */ protected Map> m_widgetParamValues; /** The list of widgets used on the dialog. */ protected List m_widgets; /** The set of help message ids that have already been used. */ private Set m_helpMessageIds; /** * Parameter stores the index of the element to add or remove.

* * This must not be null, because it must be available * when calling {@link org.opencms.workplace.CmsWorkplace#paramsAsHidden()}.

*/ private String m_paramElementIndex = "0"; /** * Parameter stores the name of the element to add or remove.

* * This must not be null, because it must be available * when calling {@link org.opencms.workplace.CmsWorkplace#paramsAsHidden()}.

*/ private String m_paramElementName = "undefined"; /** Optional localized key prefix identificator. */ private String m_prefix; /** * Public constructor with JSP action element.

* * @param jsp an initialized JSP action element */ public CmsWidgetDialog(CmsJspActionElement jsp) { super(jsp); } /** * Public constructor with JSP variables.

* * @param context the JSP page context * @param req the JSP request * @param res the JSP response */ public CmsWidgetDialog(PageContext context, HttpServletRequest req, HttpServletResponse res) { this(new CmsJspActionElement(context, req, res)); } /** * Deletes the edited dialog object from the session.

*/ public void actionCancel() { clearDialogObject(); } /** * Commits the edited object after pressing the "OK" button.

* * @throws IOException in case of errors forwarding to the required result page * @throws ServletException in case of errors forwarding to the required result page */ public abstract void actionCommit() throws IOException, ServletException; /** * Adds or removes an optional element.

* * Depends on the value stored in the {@link CmsDialog#getAction()} method.

*/ public void actionToggleElement() { // get the necessary parameters to add/remove the element int index = 0; try { index = Integer.parseInt(getParamElementIndex()); } catch (Exception e) { // ignore, should not happen } String name = getParamElementName(); // get the base parameter definition CmsWidgetDialogParameter base = getParameterDefinition(name); if (base != null) { // the requested parameter is valid for this dialog List params = getParameters().get(name); if (getAction() == ACTION_ELEMENT_REMOVE) { // remove the value params.remove(index); } else { List sequence = getParameters().get(base.getName()); if (sequence.size() > 0) { // add the new value after the clicked element index = index + 1; } CmsWidgetDialogParameter newParam = new CmsWidgetDialogParameter(base, index); params.add(index, newParam); } // reset all index value in the parameter list for (int i = 0; i < params.size(); i++) { CmsWidgetDialogParameter param = params.get(i); param.setindex(i); } } } /** * Returns the html for a button to add an optional element.

* * @param elementName name of the element * @param insertAfter the index of the element after which the new element should be created * @param enabled if true, the button to add an element is shown, otherwise a spacer is returned * @return the html for a button to add an optional element */ public String buildAddElement(String elementName, int insertAfter, boolean enabled) { if (enabled) { StringBuffer href = new StringBuffer(4); href.append("javascript:addElement('"); href.append(elementName); href.append("', "); href.append(insertAfter); href.append(");"); return button(href.toString(), null, "new.png", Messages.GUI_DIALOG_BUTTON_ADDNEW_0, 0); } else { return ""; } } /** * Builds the HTML for the dialog form.

* * @return the HTML for the dialog form */ public String buildDialogForm() { // create the dialog HTML return createDialogHtml(getParamPage()); } /** * Returns the html for a button to remove an optional element.

* * @param elementName name of the element * @param index the element index of the element to remove * @param enabled if true, the button to remove an element is shown, otherwise a spacer is returned * @return the html for a button to remove an optional element */ public String buildRemoveElement(String elementName, int index, boolean enabled) { if (enabled) { StringBuffer href = new StringBuffer(4); href.append("javascript:removeElement('"); href.append(elementName); href.append("', "); href.append(index); href.append(");"); return button(href.toString(), null, "deletecontent.png", Messages.GUI_DIALOG_BUTTON_DELETE_0, 0); } else { return ""; } } /** * Clears the "dialog object" for this widget dialog by removing it from the current users session.

*/ public void clearDialogObject() { setDialogObject(null); } /** * Builds the end HTML for a block with 3D border in the dialog content area.

* * @return 3D block start / end segment */ @Override public String dialogBlockEnd() { StringBuffer result = new StringBuffer(8); result.append(super.dialogBlockEnd()); result.append(dialogSpacer()); result.append("\n"); return result.toString(); } /** * Builds the start HTML for a block with 3D border and optional subheadline in the dialog content area.

* * @param headline the headline String for the block * @return 3D block start / end segment */ @Override public String dialogBlockStart(String headline) { StringBuffer result = new StringBuffer(8); result.append("\n"); result.append(super.dialogBlockStart(headline)); return result.toString(); } /** * Creates the HTML for the buttons on the dialog.

* * @return the HTML for the buttons on the dialog.

*/ public String dialogButtonsCustom() { if (getPages().size() > 1) { // this is a multi page dialog, create buttons according to current page int pageIndex = getPages().indexOf(getParamPage()); if (pageIndex == (getPages().size() - 1)) { // this is the last dialog page return dialogButtons(new int[] {BUTTON_OK, BUTTON_BACK, BUTTON_CANCEL}, new String[3]); } else if (pageIndex > 0) { // this is a dialog page between first and last page return dialogButtons(new int[] {BUTTON_BACK, BUTTON_CONTINUE, BUTTON_CANCEL}, new String[3]); } else { // this is the first dialog page return dialogButtons(new int[] {BUTTON_CONTINUE, BUTTON_CANCEL}, new String[2]); } } boolean onlyDisplay = true; Iterator it = getWidgets().iterator(); while (it.hasNext()) { CmsWidgetDialogParameter wdp = it.next(); if (!(wdp.getWidget() instanceof CmsDisplayWidget)) { onlyDisplay = false; break; } } if (!onlyDisplay) { // this is a single page dialog, create common buttons return dialogButtons(new int[] {BUTTON_OK, BUTTON_CANCEL}, new String[2]); } // this is a display only dialog return ""; } /** * Performs the dialog actions depending on the initialized action and displays the dialog form.

* * @throws JspException if dialog actions fail * @throws IOException if writing to the JSP out fails, or in case of errors forwarding to the required result page * @throws ServletException in case of errors forwarding to the required result page */ public void displayDialog() throws JspException, IOException, ServletException { displayDialog(false); } /** * Performs the dialog actions depending on the initialized action and displays the dialog form if needed.

* * @param writeLater if true no output is written, * you have to call manually the {@link #defaultActionHtml()} method. * * @throws JspException if dialog actions fail * @throws IOException if writing to the JSP out fails, or in case of errors forwarding to the required result page * @throws ServletException in case of errors forwarding to the required result page */ public void displayDialog(boolean writeLater) throws JspException, IOException, ServletException { if (isForwarded()) { return; } switch (getAction()) { case ACTION_CANCEL: // ACTION: cancel button pressed actionCancel(); actionCloseDialog(); break; case ACTION_ERROR: // ACTION: an error occurred (display nothing) break; case ACTION_SAVE: // ACTION: save edited values setParamAction(DIALOG_OK); actionCommit(); if (closeDialogOnCommit()) { setAction(ACTION_CANCEL); actionCloseDialog(); break; } setAction(ACTION_DEFAULT); //$FALL-THROUGH$ case ACTION_DEFAULT: default: // ACTION: show dialog (default) if (!writeLater) { writeDialog(); } } } /** * @see org.opencms.widgets.I_CmsWidgetDialog#getButtonStyle() */ public int getButtonStyle() { return getSettings().getUserSettings().getEditorButtonStyle(); } /** * Returns the errors that are thrown by save actions or form generation.

* * @return the errors that are thrown by save actions or form generation */ public List getCommitErrors() { return m_commitErrors; } /** * Returns the dialog object for this widget dialog, or null * if no dialog object has been set.

* * @return the dialog object for this widget dialog, or null */ public Object getDialogObject() { if (m_dialogObject == null) { m_dialogObject = getDialogObjectMap().get(getClass().getName()); } return m_dialogObject; } /** * @see org.opencms.widgets.I_CmsWidgetDialog#getHelpMessageIds() */ public Set getHelpMessageIds() { if (m_helpMessageIds == null) { m_helpMessageIds = new HashSet(); } return m_helpMessageIds; } /** * Returns the index of the element to add or remove.

* * @return the index of the element to add or remove */ public String getParamElementIndex() { return m_paramElementIndex; } /** * Returns the name of the element to add or remove.

* * @return the name of the element to add or remove */ public String getParamElementName() { return m_paramElementName; } /** * Returns the page parameter.

* * @return the page parameter */ public String getParamPage() { return m_paramPage; } /** * Returns the value of the widget parameter with the given name, or null * if no such widget parameter is available.

* * @param name the widget parameter name to get the value for * * @return the value of the widget parameter with the given name */ public String getParamValue(String name) { return getParamValue(name, 0); } /** * Returns the value of the widget parameter with the given name and index, or null * if no such widget parameter is available.

* * @param name the widget parameter name to get the value for * @param index the widget parameter index * * @return the value of the widget parameter with the given name and index */ public String getParamValue(String name, int index) { List params = m_widgetParamValues.get(name); if (params != null) { if ((index >= 0) && (index < params.size())) { CmsWidgetDialogParameter param = params.get(index); if (param.getId().equals(CmsWidgetDialogParameter.createId(name, index))) { return param.getStringValue(getCms()); } } } return null; } /** * @see org.opencms.widgets.I_CmsWidgetDialog#getUserAgent() */ public String getUserAgent() { return getJsp().getRequest().getHeader(CmsRequestUtil.HEADER_USER_AGENT); } /** * Generates the HTML for the end of the widget dialog.

* * This HTML includes additional components, for example the <div> * tags containing the help texts.

* * @return the HTML for the end of the widget dialog */ public String getWidgetHtmlEnd() { StringBuffer result = new StringBuffer(32); // iterate over unique widgets from collector Iterator i = getWidgets().iterator(); while (i.hasNext()) { CmsWidgetDialogParameter param = i.next(); result.append(param.getWidget().getDialogHtmlEnd(getCms(), this, param)); } return result.toString(); } /** * Generates the HTML include tags for external JavaScripts files of the used widgets.

* * @return the HTML include tags for external JavaScripts files of the used widgets * * @throws JspException if an error occurs during JavaScript generation */ public String getWidgetIncludes() throws JspException { StringBuffer result = new StringBuffer(32); try { // iterate over unique widgets from collector Iterator i = getWidgets().iterator(); Set set = new HashSet(); while (i.hasNext()) { I_CmsWidget widget = i.next().getWidget(); if (!set.contains(widget)) { result.append(widget.getDialogIncludes(getCms(), this)); result.append('\n'); set.add(widget); } } } catch (Throwable e) { includeErrorpage(this, e); } return result.toString(); } /** * Generates the JavaScript init calls for the used widgets.

* * @return the JavaScript init calls for the used widgets * * @throws JspException the JavaScript init calls for the used widgets */ public String getWidgetInitCalls() throws JspException { StringBuffer result = new StringBuffer(32); try { // iterate over unique widgets from collector Iterator i = getWidgets().iterator(); Set set = new HashSet(); while (i.hasNext()) { I_CmsWidget widget = i.next().getWidget(); if (!set.contains(widget)) { result.append(widget.getDialogInitCall(getCms(), this)); set.add(widget); } } } catch (Throwable e) { includeErrorpage(this, e); } return result.toString(); } /** * Generates the JavaScript initialization methods for the used widgets.

* * @return the JavaScript initialization methods for the used widgets * * @throws JspException if an error occurs during JavaScript generation */ public String getWidgetInitMethods() throws JspException { StringBuffer result = new StringBuffer(32); try { // iterate over unique widgets from collector Iterator i = getWidgets().iterator(); Set set = new HashSet(); while (i.hasNext()) { I_CmsWidget widget = i.next().getWidget(); if (!set.contains(widget)) { result.append(widget.getDialogInitMethod(getCms(), this)); set.add(widget); } } } catch (Throwable e) { includeErrorpage(this, e); } return result.toString(); } /** * @see org.opencms.workplace.CmsWorkplace#paramsAsHidden() */ @Override public String paramsAsHidden() { if (getAction() != ACTION_ERROR) { return super.paramsAsHidden(); } // on an error page, also output the widget parameters StringBuffer result = new StringBuffer(); result.append(super.paramsAsHidden()); result.append('\n'); result.append(widgetParamsAsHidden()); return result.toString(); } /** * Stores the given object as "dialog object" for this widget dialog in the current users session.

* * @param dialogObject the object to store */ public void setDialogObject(Object dialogObject) { m_dialogObject = dialogObject; if (dialogObject == null) { // null object: remove the entry from the map getDialogObjectMap().remove(getClass().getName()); } else { getDialogObjectMap().put(getClass().getName(), dialogObject); } } /** * Sets the index of the element to add or remove.

* * @param elementIndex the index of the element to add or remove */ public void setParamElementIndex(String elementIndex) { m_paramElementIndex = elementIndex; } /** * Sets the name of the element to add or remove.

* * @param elementName the name of the element to add or remove */ public void setParamElementName(String elementName) { m_paramElementName = elementName; } /** * Sets the page parameter.

* * @param paramPage the page parameter to set */ public void setParamPage(String paramPage) { m_paramPage = paramPage; } /** * Returns the values of all widget parameters of this dialog as HTML hidden fields.

* * @return the values of all widget parameters of this dialog as HTML hidden fields * * @see org.opencms.workplace.CmsWorkplace#paramsAsHidden() */ public String widgetParamsAsHidden() { return widgetParamsAsHidden(null); } /** * Returns the values of all widget parameters of this dialog as HTML hidden fields, * excluding the widget values that are on the given dialog page.

* * This can be used to create multi-page dialogs where the values are passed from * one page to another before everything is submitted. If a widget A is used on page X, * there should be no "hidden" HTML field for A since otherwise A would have 2 values when * submitting the dialog page: The one from the widget itself and the one from the hidden * field. This may lead to undefined results when processing the submitted values.

* * @param excludeDialogPage the dialog page to exclude the values for * * @return the values of all widget parameters of this dialog as HTML hidden fields, * excluding the widget values that are on the given dialog page * * @see org.opencms.workplace.CmsWorkplace#paramsAsHidden() */ public String widgetParamsAsHidden(String excludeDialogPage) { StringBuffer result = new StringBuffer(); Iterator i = m_widgetParamValues.keySet().iterator(); while (i.hasNext()) { List params = m_widgetParamValues.get(i.next()); Iterator j = params.iterator(); while (j.hasNext()) { CmsWidgetDialogParameter param = j.next(); String value = param.getStringValue(getCms()); if (CmsStringUtil.isNotEmpty(value) && ((excludeDialogPage == null) || (!param.getDialogPage().equals(excludeDialogPage)))) { result.append("\n"); } } } return result.toString(); } /** * Writes the dialog html code, only if the {@link #ACTION_DEFAULT} is set.

* * @throws JspException if dialog actions fail * @throws IOException if writing to the JSP out fails, or in case of errors forwarding to the required result page */ public void writeDialog() throws IOException, JspException { if (isForwarded()) { return; } switch (getAction()) { case ACTION_CANCEL: case ACTION_ERROR: case ACTION_SAVE: break; case ACTION_DEFAULT: default: // ACTION: show dialog (default) setParamAction(DIALOG_SAVE); JspWriter out = getJsp().getJspContext().getOut(); out.print(defaultActionHtml()); } } /** * Adds the given error to the list of errors that are thrown by save actions or form generation.

* * If the error list has not been initialized yet, this is done automatically.

* * @param error the errors to add */ protected void addCommitError(Exception error) { if (m_commitErrors == null) { m_commitErrors = new ArrayList(); } m_commitErrors.add(error); } /** * Adds a new widget parameter definition to the list of all widgets of this dialog.

* * @param param the widget parameter definition to add */ protected void addWidget(CmsWidgetDialogParameter param) { if (m_widgets == null) { m_widgets = new ArrayList(); } param.setKeyPrefix(m_prefix); m_widgets.add(param); } /** * Returns true if the dialog should be closed after the values have been committed.

* * The default implementation returns true in case there are no * commit errors.

* * @return true if the dialog should be closed after the values have been committed */ protected boolean closeDialogOnCommit() { return !hasCommitErrors(); } /** * Commits all values on the dialog.

* * @return a List of all Exceptions that occurred when comitting the dialog.

*/ protected List commitWidgetValues() { return commitWidgetValues(null); } /** * Commits all values on the given dialog page.

* * @param dialogPage the dialog (page) to commit * * @return a List of all Exceptions that occurred when committing the dialog page.

*/ protected List commitWidgetValues(String dialogPage) { List result = new ArrayList(); Iterator i = getWidgets().iterator(); while (i.hasNext()) { // check for all widget parameters CmsWidgetDialogParameter base = i.next(); if ((dialogPage == null) || (base.getDialogPage() == null) || dialogPage.equals(base.getDialogPage())) { // the parameter is located on the requested dialog base.prepareCommit(); List params = m_widgetParamValues.get(base.getName()); Iterator j = params.iterator(); while (j.hasNext()) { CmsWidgetDialogParameter param = j.next(); try { param.commitValue(this); } catch (Exception e) { result.add(e); } } } } setValidationErrorList(result); return result; } /** * Creates the dialog HTML for all defined widgets of this dialog.

* * @return the dialog HTML for all defined widgets of this dialog */ protected String createDialogHtml() { return createDialogHtml(null); } /** * Creates the dialog HTML for all defined widgets of the named dialog (page).

* * To get a more complex layout variation, you have to overwrite this method in your dialog class.

* * @param dialog the dialog (page) to get the HTML for * @return the dialog HTML for all defined widgets of the named dialog (page) */ protected String createDialogHtml(String dialog) { StringBuffer result = new StringBuffer(1024); // create table result.append(createWidgetTableStart()); // show error header once if there were validation errors result.append(createWidgetErrorHeader()); Iterator i = getWidgets().iterator(); // iterate the type sequence while (i.hasNext()) { // get the current widget base definition CmsWidgetDialogParameter base = i.next(); // check if the element is on the requested dialog page if ((dialog == null) || dialog.equals(base.getDialogPage())) { // add the HTML for the dialog element result.append(createDialogRowHtml(base)); } } // close table result.append(createWidgetTableEnd()); return result.toString(); } /** * Creates the dialog HTML for all occurrences of one widget parameter.

* * @param base the widget parameter base * @return the dialog HTML for one widget parameter */ protected String createDialogRowHtml(CmsWidgetDialogParameter base) { StringBuffer result = new StringBuffer(256); List sequence = getParameters().get(base.getName()); int count = sequence.size(); // check if value is optional or multiple boolean addValue = false; if (count < base.getMaxOccurs()) { addValue = true; } boolean removeValue = false; if (count > base.getMinOccurs()) { removeValue = true; } // check if value is present boolean disabledElement = false; if (count < 1) { // no parameter with the value present, but also not optional: use base as parameter sequence = new ArrayList(); sequence.add(base); count = 1; if (base.getMinOccurs() == 0) { disabledElement = true; } } // loop through multiple elements for (int j = 0; j < count; j++) { // get the parameter and the widget CmsWidgetDialogParameter p = sequence.get(j); I_CmsWidget widget = p.getWidget(); // check for an error in this row if (p.hasError()) { // show error message result.append("\"\""); Throwable t = p.getError(); while (t != null) { if (t instanceof I_CmsThrowable) { result.append(CmsEncoder.escapeXml(((I_CmsThrowable)t).getLocalizedMessage(getLocale()))); } else { result.append(CmsEncoder.escapeXml(t.getLocalizedMessage())); } t = t.getCause(); if (t != null) { result.append("
"); } } result.append("\n"); } // create label and help bubble cells result.append(""); result.append(""); result.append(keyDefault(A_CmsWidget.getLabelKey(p), p.getName())); if (count > 1) { result.append(" [").append(p.getIndex() + 1).append("]"); } result.append(": "); if (p.getIndex() == 0) { // show help bubble only on first element of each content definition result.append(p.getWidget().getHelpBubble(getCms(), this, p)); } else { // create empty cell for all following elements result.append(dialogHorizontalSpacer(16)); } // append individual widget html cell if element is enabled if (!disabledElement) { // this is a simple type, display widget result.append(widget.getDialogWidget(getCms(), this, p)); } else { // disabled element, show message for optional element result.append(""); result.append(key(Messages.GUI_EDITOR_WIDGET_OPTIONALELEMENT_0)); result.append(""); } // append add and remove element buttons if required result.append(dialogHorizontalSpacer(5)); result.append(""); if (addValue || removeValue) { result.append("

"); if (!addValue) { result.append(dialogHorizontalSpacer(25)); } else { result.append( ""); // close row result.append("\n"); } return result.toString(); } /** * Creates the dialog widget rows HTML for the specified widget indices.

* * @param startIndex the widget index to start with * @param endIndex the widget index to stop at * * @return the dialog widget rows HTML for the specified widget indices */ protected String createDialogRowsHtml(int startIndex, int endIndex) { StringBuffer result = new StringBuffer((endIndex - startIndex) * 8); for (int i = startIndex; i <= endIndex; i++) { CmsWidgetDialogParameter base = getWidgets().get(i); result.append(createDialogRowHtml(base)); } return result.toString(); } /** * Creates the complete widget dialog end block HTML that finishes a widget block.

* * @return the complete widget dialog end block HTML that finishes a widget block */ protected String createWidgetBlockEnd() { StringBuffer result = new StringBuffer(8); result.append(createWidgetTableEnd()); result.append(dialogBlockEnd()); return result.toString(); } /** * Create the complete widget dialog start block HTML that begins a widget block with optional headline.

* * @param headline the headline String for the block * * @return the complete widget dialog start block HTML that begins a widget block with optional headline */ protected String createWidgetBlockStart(String headline) { StringBuffer result = new StringBuffer(16); result.append(dialogBlockStart(headline)); result.append(createWidgetTableStart()); return result.toString(); } /** * Creates the HTML for the error message if validation errors were found.

* * @return the HTML for the error message if validation errors were found */ protected String createWidgetErrorHeader() { StringBuffer result = new StringBuffer(8); if (hasValidationErrors() || hasCommitErrors()) { result.append("

\n"); result.append(""); result.append("\n"); result.append("\n"); if (hasCommitErrors()) { result.append(dialogBlockStart("")); result.append(createWidgetTableStart()); Iterator i = getCommitErrors().iterator(); while (i.hasNext()) { Throwable t = i.next(); result.append("\n"); } result.append(createWidgetTableEnd()); result.append(dialogBlockEnd()); } if (hasValidationErrors()) { result.append(dialogBlockStart("")); result.append(createWidgetTableStart()); Iterator i = getValidationErrorList().iterator(); while (i.hasNext()) { Throwable t = i.next(); result.append("\n"); } result.append(createWidgetTableEnd()); result.append(dialogBlockEnd()); } } return result.toString(); } /** * Creates the HTML for the table around the dialog widgets.

* * @return the HTML for the table around the dialog widgets */ protected String createWidgetTableEnd() { return "

"); result.append(buildAddElement(base.getName(), p.getIndex(), addValue)); } if (removeValue) { if (!addValue) { result.append( ""); result.append("
"); } result.append(buildRemoveElement(base.getName(), p.getIndex(), removeValue)); } result.append("
"); } result.append("
 
 "); result.append(key(Messages.GUI_EDITOR_WIDGET_VALIDATION_ERROR_TITLE_0)); result.append(" "); result.append("
 
\"\""); while (t != null) { String message = ""; if (t instanceof I_CmsThrowable) { message = ((I_CmsThrowable)t).getLocalizedMessage(getLocale()); } else { message = t.getLocalizedMessage(); } if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(message)) { result.append(CmsStringUtil.escapeHtml(message)); } t = t.getCause(); if (t != null) { result.append("
"); } } result.append("
\"\""); while (t != null) { String message = ""; if (t instanceof I_CmsThrowable) { message = ((I_CmsThrowable)t).getLocalizedMessage(getLocale()); } else { message = t.getLocalizedMessage(); } result.append(CmsStringUtil.escapeHtml(message)); t = t.getCause(); if (t != null) { result.append("
"); } } result.append("
\n"; } /** * Creates the HTML to close the table around the dialog widgets.

* * @return the HTML to close the table around the dialog widgets */ protected String createWidgetTableStart() { return "

\n"; } /** * Generates the dialog starting html code.

* * @return html code * * @throws JspException if something goes wrong */ protected String defaultActionHtml() throws JspException { StringBuffer result = new StringBuffer(2048); result.append(defaultActionHtmlStart()); result.append(defaultActionHtmlContent()); result.append(defaultActionHtmlEnd()); return result.toString(); } /** * Returns the html code for the default action content.

* * @return html code */ protected String defaultActionHtmlContent() { StringBuffer result = new StringBuffer(2048); result.append("
\n"); result.append(dialogContentStart(getDialogTitle())); result.append(buildDialogForm()); result.append(dialogContentEnd()); result.append(dialogButtonsCustom()); result.append(paramsAsHidden()); if (getParamFramename() == null) { result.append("\n\n"); } result.append("\n"); result.append(getWidgetHtmlEnd()); return result.toString(); } /** * Generates the dialog ending html code.

* * @return html code */ protected String defaultActionHtmlEnd() { StringBuffer result = new StringBuffer(2048); result.append(dialogEnd()); result.append(bodyEnd()); result.append(htmlEnd()); return result.toString(); } /** * Generates the dialog starting html code.

* * @return html code * * @throws JspException if something goes wrong */ protected String defaultActionHtmlStart() throws JspException { StringBuffer result = new StringBuffer(2048); result.append(htmlStart("administration/index.html")); result.append("\n"); result.append("\n"); result.append(getWidgetIncludes()); result.append("\n"); result.append(bodyStart(null, "onload='init();' onunload='exitEditor();'")); result.append(dialogStart()); return result.toString(); } /** * Defines the list of parameters for this dialog.

*/ protected abstract void defineWidgets(); /** * Fills all widgets of this widget dialog with the values from the request parameters.

* * @param request the current HTTP servlet request */ protected void fillWidgetValues(HttpServletRequest request) { Map parameters = request.getParameterMap(); Map processedParameters = new HashMap(); Iterator p = parameters.entrySet().iterator(); // make sure all "hidden" widget parameters are decoded while (p.hasNext()) { Map.Entry entry = (Map.Entry)p.next(); String key = (String)entry.getKey(); String[] values = (String[])entry.getValue(); if (key.startsWith(HIDDEN_PARAM_PREFIX)) { // this is an encoded hidden parameter key = key.substring(HIDDEN_PARAM_PREFIX.length()); String[] newValues = new String[values.length]; for (int l = 0; l < values.length; l++) { newValues[l] = CmsEncoder.decode(values[l], getCms().getRequestContext().getEncoding()); } values = newValues; } processedParameters.put(key, values); } // now process the parameters m_widgetParamValues = new HashMap>(); Iterator i = getWidgets().iterator(); while (i.hasNext()) { // check for all widget base parameters CmsWidgetDialogParameter base = i.next(); List params = new ArrayList(); int maxOccurs = base.getMaxOccurs(); boolean onPage = false; if (base.isCollectionBase()) { // for a collection base, check if we are on the page where the collection base is shown if (CmsStringUtil.isNotEmpty(getParamAction()) && !DIALOG_INITIAL.equals(getParamAction())) { // if no action set (usually for first display of dialog) make sure all values are shown // DIALOG_INITIAL is a special value for the first display and must be handled the same way String page = getParamPage(); // keep in mind that since the paramPage will be set AFTER the widget values are filled, // so the first time this page is called from another page the following will result to "false", // but for every "submit" on the page this will be "true" onPage = CmsStringUtil.isEmpty(page) || CmsStringUtil.isEmpty(base.getDialogPage()) || base.getDialogPage().equals(page); } } for (int j = 0; j < maxOccurs; j++) { // check for all possible values in the request parameters String id = CmsWidgetDialogParameter.createId(base.getName(), j); boolean required = (params.size() < base.getMinOccurs()) || (processedParameters.get(id) != null) || (!onPage && base.hasValue(j)); if (required) { CmsWidgetDialogParameter param = new CmsWidgetDialogParameter(base, params.size(), j); param.setKeyPrefix(m_prefix); base.getWidget().setEditorValue(getCms(), processedParameters, this, param); params.add(param); } } m_widgetParamValues.put(base.getName(), params); } } /** * Returns the title for this Dialog.

* * In the default implementation this method returns null. * Override this if needed.

* * @return the title for this Dialog, or null if this dialog has no title */ protected String getDialogTitle() { return null; } /** * Returns the allowed pages for this dialog.

* * @return the allowed pages for this dialog */ protected abstract String[] getPageArray(); /** * Returns the allowed pages for this dialog.

* * @return the allowed pages for this dialog */ protected List getPages() { if (m_pages == null) { m_pages = Arrays.asList(getPageArray()); } return m_pages; } /** * Returns the parameter widget definition for the given parameter name.

* * @param name the parameter name to get the definition for * * @return the parameter widget definition for the given parameter name */ protected CmsWidgetDialogParameter getParameterDefinition(String name) { Iterator i = getWidgets().iterator(); while (i.hasNext()) { // check for all widget parameters CmsWidgetDialogParameter base = i.next(); if (base.getName().equals(name)) { return base; } } return null; } /** * Returns the map with the widget parameter values.

* * @return the map with the widget parameter values */ protected Map> getParameters() { return m_widgetParamValues; } /** * Returns the validation errors for the dialog.

* * The method (@link CmsWidgetDialog#commitWidgetValues(String)) has to set this list.

* * @return the validation errors for the dialog */ protected List getValidationErrorList() { return m_validationErrorList; } /** * Returns the widget HTML code for the given parameter.

* * @param param the name (id) of the parameter to get the widget HTML for * * @return the widget HTML code for the given parameter */ protected String getWidget(CmsWidgetDialogParameter param) { if (param != null) { return param.getWidget().getDialogWidget(getCms(), this, param); } return null; } /** * Returns the list of all widgets used on this widget dialog, the * List must contain Objects of type {@link CmsWidgetDialogParameter}.

* * @return the list of all widgets used on this widget dialog */ protected List getWidgets() { if (m_widgets == null) { m_widgets = new ArrayList(); } return m_widgets; } /** * Returns true if the current dialog (page) has commit errors.

* * @return true if the current dialog (page) has commit errors */ protected boolean hasCommitErrors() { return (m_commitErrors != null) && (m_commitErrors.size() > 0); } /** * Returns true if the current dialog (page) has validation errors.

* * @return true if the current dialog (page) has validation errors */ protected boolean hasValidationErrors() { return (m_validationErrorList != null) && (m_validationErrorList.size() > 0); } /** * @see org.opencms.workplace.CmsWorkplace#initWorkplaceRequestValues(org.opencms.workplace.CmsWorkplaceSettings, javax.servlet.http.HttpServletRequest) */ @Override protected void initWorkplaceRequestValues(CmsWorkplaceSettings settings, HttpServletRequest request) { // set the dialog type setParamDialogtype(getClass().getName()); // fill the parameter values in the get/set methods fillParamValues(request); if (CmsStringUtil.isEmptyOrWhitespaceOnly(getParamPage()) || !getPages().contains(getParamPage())) { // ensure a valid page is set setParamPage(getPages().get(0)); } // test the needed parameters try { validateParamaters(); } catch (Exception e) { if (LOG.isInfoEnabled()) { LOG.info(Messages.get().container(Messages.ERR_WORKPLACE_DIALOG_PARAMS_1, getCurrentToolPath()), e); } // close if parameters not available setAction(ACTION_CANCEL); try { actionCloseDialog(); } catch (JspException e1) { // ignore } return; } // fill the widget map defineWidgets(); fillWidgetValues(request); // set the action for the JSP switch if (DIALOG_SAVE.equals(getParamAction())) { // ok button pressed, save List errors = commitWidgetValues(null); if (errors.size() > 0) { setAction(ACTION_DEFAULT); // found validation errors, redisplay page return; } setAction(ACTION_SAVE); } else if (DIALOG_OK.equals(getParamAction())) { // ok button pressed setAction(ACTION_CANCEL); } else if (DIALOG_CANCEL.equals(getParamAction())) { // cancel button pressed setAction(ACTION_CANCEL); } else if (EDITOR_ACTION_ELEMENT_ADD.equals(getParamAction())) { // add optional input element setAction(ACTION_ELEMENT_ADD); actionToggleElement(); setAction(ACTION_DEFAULT); } else if (EDITOR_ACTION_ELEMENT_REMOVE.equals(getParamAction())) { // remove optional input element setAction(ACTION_ELEMENT_REMOVE); actionToggleElement(); setAction(ACTION_DEFAULT); } else if (DIALOG_BACK.equals(getParamAction())) { // go back one page setAction(ACTION_DEFAULT); List errors = commitWidgetValues(getParamPage()); if (errors.size() > 0) { // found validation errors, redisplay page return; } int pageIndex = getPages().indexOf(getParamPage()) - 1; setParamPage(getPages().get(pageIndex)); } else if (DIALOG_CONTINUE.equals(getParamAction())) { // go to next page setAction(ACTION_DEFAULT); List errors = commitWidgetValues(getParamPage()); if (errors.size() > 0) { // found validation errors, redisplay page return; } int pageIndex = getPages().indexOf(getParamPage()) + 1; setParamPage(getPages().get(pageIndex)); } else { // first dialog call, set the default action setAction(ACTION_DEFAULT); } } /** * Sets the errors that are thrown by save actions or form generation.

* * @param errors the errors that are thrown by save actions or form generation */ protected void setCommitErrors(List errors) { m_commitErrors = errors; } /** * Sets an optional localized key prefix identificator for all widgets.

* * @param prefix the optional localized key prefix identificator for all widgets * * @see org.opencms.widgets.I_CmsWidgetParameter#setKeyPrefix(java.lang.String) */ protected void setKeyPrefix(String prefix) { m_prefix = prefix; } /** * Sets the allowed pages for this dialog.

* * @param pages the allowed pages for this dialog */ protected void setPages(List pages) { m_pages = pages; } /** * Sets the validation errors for the dialog.

* * Use this in the method (@link CmsWidgetDialog#commitWidgetValues(String)) to set the list.

* * @param errors the validation errors */ protected void setValidationErrorList(List errors) { m_validationErrorList = errors; } /** * Should be overridden for parameter validation.

* * The exception is never seen by the user, so it can be just a new {@link Exception}().

* * @throws Exception if the parameters are not valid */ protected void validateParamaters() throws Exception { // valid by default } /** * Returns the (internal use only) map of dialog objects.

* * @return the (internal use only) map of dialog objects */ private Map getDialogObjectMap() { @SuppressWarnings("unchecked") Map objects = (Map)getSettings().getDialogObject(); if (objects == null) { // using hash table as most efficient version of a synchronized map objects = new Hashtable(); getSettings().setDialogObject(objects); } return objects; } }