0001: /*
0002: * File : $Source: /usr/local/cvs/opencms/src/org/opencms/workplace/CmsWidgetDialog.java,v $
0003: * Date : $Date: 2008-03-17 08:55:33 $
0004: * Version: $Revision: 1.67 $
0005: *
0006: * This library is part of OpenCms -
0007: * the Open Source Content Management System
0008: *
0009: * Copyright (c) 2002 - 2008 Alkacon Software GmbH (http://www.alkacon.com)
0010: *
0011: * This library is free software; you can redistribute it and/or
0012: * modify it under the terms of the GNU Lesser General Public
0013: * License as published by the Free Software Foundation; either
0014: * version 2.1 of the License, or (at your option) any later version.
0015: *
0016: * This library is distributed in the hope that it will be useful,
0017: * but WITHOUT ANY WARRANTY; without even the implied warranty of
0018: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0019: * Lesser General Public License for more details.
0020: *
0021: * For further information about Alkacon Software GmbH, please see the
0022: * company website: http://www.alkacon.com
0023: *
0024: * For further information about OpenCms, please see the
0025: * project website: http://www.opencms.org
0026: *
0027: * You should have received a copy of the GNU Lesser General Public
0028: * License along with this library; if not, write to the Free Software
0029: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0030: */
0031:
0032: package org.opencms.workplace;
0033:
0034: import org.opencms.i18n.CmsEncoder;
0035: import org.opencms.jsp.CmsJspActionElement;
0036: import org.opencms.main.CmsLog;
0037: import org.opencms.main.I_CmsThrowable;
0038: import org.opencms.main.OpenCms;
0039: import org.opencms.util.CmsRequestUtil;
0040: import org.opencms.util.CmsStringUtil;
0041: import org.opencms.widgets.A_CmsWidget;
0042: import org.opencms.widgets.CmsDisplayWidget;
0043: import org.opencms.widgets.I_CmsWidget;
0044: import org.opencms.widgets.I_CmsWidgetDialog;
0045:
0046: import java.io.IOException;
0047: import java.util.ArrayList;
0048: import java.util.Arrays;
0049: import java.util.HashMap;
0050: import java.util.HashSet;
0051: import java.util.Hashtable;
0052: import java.util.Iterator;
0053: import java.util.List;
0054: import java.util.Map;
0055: import java.util.Set;
0056:
0057: import javax.servlet.ServletException;
0058: import javax.servlet.http.HttpServletRequest;
0059: import javax.servlet.http.HttpServletResponse;
0060: import javax.servlet.jsp.JspException;
0061: import javax.servlet.jsp.JspWriter;
0062: import javax.servlet.jsp.PageContext;
0063:
0064: import org.apache.commons.logging.Log;
0065:
0066: /**
0067: * Base class for dialogs that use the OpenCms widgets without XML content.<p>
0068: *
0069: * @author Alexander Kandzior
0070: *
0071: * @version $Revision: 1.67 $
0072: *
0073: * @since 6.0.0
0074: */
0075: public abstract class CmsWidgetDialog extends CmsDialog implements
0076: I_CmsWidgetDialog {
0077:
0078: /** Action for optional element creation. */
0079: public static final int ACTION_ELEMENT_ADD = 152;
0080:
0081: /** Action for optional element removal. */
0082: public static final int ACTION_ELEMENT_REMOVE = 153;
0083:
0084: /** Value for the action: error in the form validation. */
0085: public static final int ACTION_ERROR = 303;
0086:
0087: /** Value for the action: save the dialog. */
0088: public static final int ACTION_SAVE = 300;
0089:
0090: /** Request parameter value for the action: save the dialog. */
0091: public static final String DIALOG_SAVE = "save";
0092:
0093: /** Indicates an optional element should be created. */
0094: public static final String EDITOR_ACTION_ELEMENT_ADD = "addelement";
0095:
0096: /** Indicates an optional element should be removed. */
0097: public static final String EDITOR_ACTION_ELEMENT_REMOVE = "removeelement";
0098:
0099: /** Prefix for "hidden" parameters, required since these must be unescaped later. */
0100: public static final String HIDDEN_PARAM_PREFIX = "hidden.";
0101:
0102: /** The log object for this class. */
0103: private static final Log LOG = CmsLog.getLog(CmsWidgetDialog.class);
0104:
0105: /** The errors thrown by commit actions. */
0106: protected List m_commitErrors;
0107:
0108: /** The object edited with this widget dialog. */
0109: protected Object m_dialogObject;
0110:
0111: /** The allowed pages for this dialog in a List. */
0112: protected List m_pages;
0113:
0114: /** Controls which page is currently displayed in the dialog. */
0115: protected String m_paramPage;
0116:
0117: /** The validation errors for the input form. */
0118: protected List m_validationErrorList;
0119:
0120: /** Contains all parameter value of this dialog. */
0121: protected Map m_widgetParamValues;
0122:
0123: /** The list of widgets used on the dialog. */
0124: protected List m_widgets;
0125:
0126: /** The set of help message ids that have already been used. */
0127: private Set m_helpMessageIds;
0128:
0129: /**
0130: * Parameter stores the index of the element to add or remove.<p>
0131: *
0132: * This must not be <code>null</code>, because it must be available
0133: * when calling <code>{@link org.opencms.workplace.CmsWorkplace#paramsAsHidden()}</code>.<p>
0134: */
0135: private String m_paramElementIndex = "0";
0136:
0137: /**
0138: * Parameter stores the name of the element to add or remove.<p>
0139: *
0140: * This must not be <code>null</code>, because it must be available
0141: * when calling <code>{@link org.opencms.workplace.CmsWorkplace#paramsAsHidden()}</code>.<p>
0142: */
0143: private String m_paramElementName = "undefined";
0144:
0145: /** Optional localized key prefix identificator. */
0146: private String m_prefix;
0147:
0148: /**
0149: * Public constructor with JSP action element.<p>
0150: *
0151: * @param jsp an initialized JSP action element
0152: */
0153: public CmsWidgetDialog(CmsJspActionElement jsp) {
0154:
0155: super (jsp);
0156: }
0157:
0158: /**
0159: * Public constructor with JSP variables.<p>
0160: *
0161: * @param context the JSP page context
0162: * @param req the JSP request
0163: * @param res the JSP response
0164: */
0165: public CmsWidgetDialog(PageContext context, HttpServletRequest req,
0166: HttpServletResponse res) {
0167:
0168: this (new CmsJspActionElement(context, req, res));
0169: }
0170:
0171: /**
0172: * Deletes the edited dialog object from the session.<p>
0173: */
0174: public void actionCancel() {
0175:
0176: clearDialogObject();
0177: }
0178:
0179: /**
0180: * Commits the edited object after pressing the "OK" button.<p>
0181: *
0182: * @throws IOException in case of errors forwarding to the required result page
0183: * @throws ServletException in case of errors forwarding to the required result page
0184: */
0185: public abstract void actionCommit() throws IOException,
0186: ServletException;
0187:
0188: /**
0189: * Adds or removes an optional element.<p>
0190: *
0191: * Depends on the value stored in the <code>{@link CmsDialog#getAction()}</code> method.<p>
0192: */
0193: public void actionToggleElement() {
0194:
0195: // get the necessary parameters to add/remove the element
0196: int index = 0;
0197: try {
0198: index = Integer.parseInt(getParamElementIndex());
0199: } catch (Exception e) {
0200: // ignore, should not happen
0201: }
0202: String name = getParamElementName();
0203: // get the base parameter definition
0204: CmsWidgetDialogParameter base = getParameterDefinition(name);
0205: if (base != null) {
0206: // the requested parameter is valid for this dialog
0207: List params = (List) getParameters().get(name);
0208: if (getAction() == ACTION_ELEMENT_REMOVE) {
0209: // remove the value
0210: params.remove(index);
0211: } else {
0212: List sequence = (List) getParameters().get(
0213: base.getName());
0214: if (sequence.size() > 0) {
0215: // add the new value after the clicked element
0216: index = index + 1;
0217: }
0218: CmsWidgetDialogParameter newParam = new CmsWidgetDialogParameter(
0219: base, index);
0220: params.add(index, newParam);
0221: }
0222: // reset all index value in the parameter list
0223: for (int i = 0; i < params.size(); i++) {
0224: CmsWidgetDialogParameter param = (CmsWidgetDialogParameter) params
0225: .get(i);
0226: param.setindex(i);
0227: }
0228: }
0229: }
0230:
0231: /**
0232: * Returns the html for a button to add an optional element.<p>
0233: *
0234: * @param elementName name of the element
0235: * @param insertAfter the index of the element after which the new element should be created
0236: * @param enabled if true, the button to add an element is shown, otherwise a spacer is returned
0237: * @return the html for a button to add an optional element
0238: */
0239: public String buildAddElement(String elementName, int insertAfter,
0240: boolean enabled) {
0241:
0242: if (enabled) {
0243: StringBuffer href = new StringBuffer(4);
0244: href.append("javascript:addElement('");
0245: href.append(elementName);
0246: href.append("', ");
0247: href.append(insertAfter);
0248: href.append(");");
0249: return button(href.toString(), null, "new.png",
0250: Messages.GUI_DIALOG_BUTTON_ADDNEW_0, 0);
0251: } else {
0252: return "";
0253: }
0254: }
0255:
0256: /**
0257: * Builds the HTML for the dialog form.<p>
0258: *
0259: * @return the HTML for the dialog form
0260: */
0261: public String buildDialogForm() {
0262:
0263: // create the dialog HTML
0264: return createDialogHtml(getParamPage());
0265: }
0266:
0267: /**
0268: * Returns the html for a button to remove an optional element.<p>
0269: *
0270: * @param elementName name of the element
0271: * @param index the element index of the element to remove
0272: * @param enabled if true, the button to remove an element is shown, otherwise a spacer is returned
0273: * @return the html for a button to remove an optional element
0274: */
0275: public String buildRemoveElement(String elementName, int index,
0276: boolean enabled) {
0277:
0278: if (enabled) {
0279: StringBuffer href = new StringBuffer(4);
0280: href.append("javascript:removeElement('");
0281: href.append(elementName);
0282: href.append("', ");
0283: href.append(index);
0284: href.append(");");
0285: return button(href.toString(), null, "deletecontent.png",
0286: Messages.GUI_DIALOG_BUTTON_DELETE_0, 0);
0287: } else {
0288: return "";
0289: }
0290: }
0291:
0292: /**
0293: * Clears the "dialog object" for this widget dialog by removing it from the current users session.<p>
0294: */
0295: public void clearDialogObject() {
0296:
0297: setDialogObject(null);
0298: }
0299:
0300: /**
0301: * Builds the end HTML for a block with 3D border in the dialog content area.<p>
0302: *
0303: * @return 3D block start / end segment
0304: */
0305: public String dialogBlockEnd() {
0306:
0307: StringBuffer result = new StringBuffer(8);
0308: result.append(super .dialogBlockEnd());
0309: result.append(dialogSpacer());
0310: result.append("</td></tr>\n");
0311: return result.toString();
0312: }
0313:
0314: /**
0315: * Builds the start HTML for a block with 3D border and optional subheadline in the dialog content area.<p>
0316: *
0317: * @param headline the headline String for the block
0318: * @return 3D block start / end segment
0319: */
0320: public String dialogBlockStart(String headline) {
0321:
0322: StringBuffer result = new StringBuffer(8);
0323: result.append("<tr><td colspan=\"5\">\n");
0324: result.append(super .dialogBlockStart(headline));
0325: return result.toString();
0326: }
0327:
0328: /**
0329: * Creates the HTML for the buttons on the dialog.<p>
0330: *
0331: * @return the HTML for the buttons on the dialog.<p>
0332: */
0333: public String dialogButtonsCustom() {
0334:
0335: if (getPages().size() > 1) {
0336: // this is a multi page dialog, create buttons according to current page
0337: int pageIndex = getPages().indexOf(getParamPage());
0338: if (pageIndex == getPages().size() - 1) {
0339: // this is the last dialog page
0340: return dialogButtons(new int[] { BUTTON_OK,
0341: BUTTON_BACK, BUTTON_CANCEL }, new String[3]);
0342: } else if (pageIndex > 0) {
0343: // this is a dialog page between first and last page
0344: return dialogButtons(new int[] { BUTTON_BACK,
0345: BUTTON_CONTINUE, BUTTON_CANCEL }, new String[3]);
0346: } else {
0347: // this is the first dialog page
0348: return dialogButtons(new int[] { BUTTON_CONTINUE,
0349: BUTTON_CANCEL }, new String[2]);
0350: }
0351: }
0352: boolean onlyDisplay = true;
0353: Iterator it = getWidgets().iterator();
0354: while (it.hasNext()) {
0355: CmsWidgetDialogParameter wdp = (CmsWidgetDialogParameter) it
0356: .next();
0357: if (!(wdp.getWidget() instanceof CmsDisplayWidget)) {
0358: onlyDisplay = false;
0359: break;
0360: }
0361: }
0362: if (!onlyDisplay) {
0363: // this is a single page dialog, create common buttons
0364: return dialogButtons(
0365: new int[] { BUTTON_OK, BUTTON_CANCEL },
0366: new String[2]);
0367: }
0368: // this is a display only dialog
0369: return "";
0370: }
0371:
0372: /**
0373: * Performs the dialog actions depending on the initialized action and displays the dialog form.<p>
0374: *
0375: * @throws JspException if dialog actions fail
0376: * @throws IOException if writing to the JSP out fails, or in case of errors forwarding to the required result page
0377: * @throws ServletException in case of errors forwarding to the required result page
0378: */
0379: public void displayDialog() throws JspException, IOException,
0380: ServletException {
0381:
0382: displayDialog(false);
0383: }
0384:
0385: /**
0386: * Performs the dialog actions depending on the initialized action and displays the dialog form if needed.<p>
0387: *
0388: * @param writeLater if <code>true</code> no output is written,
0389: * you have to call manually the <code>{@link #defaultActionHtml()}</code> method.
0390: *
0391: * @throws JspException if dialog actions fail
0392: * @throws IOException if writing to the JSP out fails, or in case of errors forwarding to the required result page
0393: * @throws ServletException in case of errors forwarding to the required result page
0394: */
0395: public void displayDialog(boolean writeLater) throws JspException,
0396: IOException, ServletException {
0397:
0398: if (isForwarded()) {
0399: return;
0400: }
0401: switch (getAction()) {
0402:
0403: case ACTION_CANCEL:
0404: // ACTION: cancel button pressed
0405: actionCancel();
0406: actionCloseDialog();
0407: break;
0408:
0409: case ACTION_ERROR:
0410: // ACTION: an error occurred (display nothing)
0411: break;
0412:
0413: case ACTION_SAVE:
0414: // ACTION: save edited values
0415: setParamAction(DIALOG_OK);
0416: actionCommit();
0417: if (closeDialogOnCommit()) {
0418: setAction(ACTION_CANCEL);
0419: actionCloseDialog();
0420: break;
0421: }
0422: setAction(ACTION_DEFAULT);
0423:
0424: case ACTION_DEFAULT:
0425: default:
0426: // ACTION: show dialog (default)
0427: if (!writeLater) {
0428: writeDialog();
0429: }
0430: }
0431: }
0432:
0433: /**
0434: * @see org.opencms.widgets.I_CmsWidgetDialog#getButtonStyle()
0435: */
0436: public int getButtonStyle() {
0437:
0438: return getSettings().getUserSettings().getEditorButtonStyle();
0439: }
0440:
0441: /**
0442: * Returns the errors that are thrown by save actions or form generation.<p>
0443: *
0444: * @return the errors that are thrown by save actions or form generation
0445: */
0446: public List getCommitErrors() {
0447:
0448: return m_commitErrors;
0449: }
0450:
0451: /**
0452: * Returns the dialog object for this widget dialog, or <code>null</code>
0453: * if no dialog object has been set.<p>
0454: *
0455: * @return the dialog object for this widget dialog, or <code>null</code>
0456: */
0457: public Object getDialogObject() {
0458:
0459: if (m_dialogObject == null) {
0460: m_dialogObject = getDialogObjectMap().get(
0461: getClass().getName());
0462: }
0463: return m_dialogObject;
0464: }
0465:
0466: /**
0467: * @see org.opencms.widgets.I_CmsWidgetDialog#getHelpMessageIds()
0468: */
0469: public Set getHelpMessageIds() {
0470:
0471: if (m_helpMessageIds == null) {
0472: m_helpMessageIds = new HashSet();
0473: }
0474: return m_helpMessageIds;
0475: }
0476:
0477: /**
0478: * Returns the index of the element to add or remove.<p>
0479: *
0480: * @return the index of the element to add or remove
0481: */
0482: public String getParamElementIndex() {
0483:
0484: return m_paramElementIndex;
0485: }
0486:
0487: /**
0488: * Returns the name of the element to add or remove.<p>
0489: *
0490: * @return the name of the element to add or remove
0491: */
0492: public String getParamElementName() {
0493:
0494: return m_paramElementName;
0495: }
0496:
0497: /**
0498: * Returns the page parameter.<p>
0499: *
0500: * @return the page parameter
0501: */
0502: public String getParamPage() {
0503:
0504: return m_paramPage;
0505: }
0506:
0507: /**
0508: * Returns the value of the widget parameter with the given name, or <code>null</code>
0509: * if no such widget parameter is available.<p>
0510: *
0511: * @param name the widget parameter name to get the value for
0512: *
0513: * @return the value of the widget parameter with the given name
0514: */
0515: public String getParamValue(String name) {
0516:
0517: return getParamValue(name, 0);
0518: }
0519:
0520: /**
0521: * Returns the value of the widget parameter with the given name and index, or <code>null</code>
0522: * if no such widget parameter is available.<p>
0523: *
0524: * @param name the widget parameter name to get the value for
0525: * @param index the widget parameter index
0526: *
0527: * @return the value of the widget parameter with the given name and index
0528: */
0529: public String getParamValue(String name, int index) {
0530:
0531: List params = (List) m_widgetParamValues.get(name);
0532: if (params != null) {
0533: if ((index >= 0) && (index < params.size())) {
0534: CmsWidgetDialogParameter param = (CmsWidgetDialogParameter) params
0535: .get(index);
0536: if (param.getId().equals(
0537: CmsWidgetDialogParameter.createId(name, index))) {
0538: return param.getStringValue(getCms());
0539: }
0540: }
0541: }
0542:
0543: return null;
0544: }
0545:
0546: /**
0547: * @see org.opencms.widgets.I_CmsWidgetDialog#getUserAgent()
0548: */
0549: public String getUserAgent() {
0550:
0551: return getJsp().getRequest().getHeader(
0552: CmsRequestUtil.HEADER_USER_AGENT);
0553: }
0554:
0555: /**
0556: * Generates the HTML for the end of the widget dialog.<p>
0557: *
0558: * This HTML includes additional components, for example the <div>
0559: * tags containing the help texts.<p>
0560: *
0561: * @return the HTML for the end of the widget dialog
0562: */
0563: public String getWidgetHtmlEnd() {
0564:
0565: StringBuffer result = new StringBuffer(32);
0566: // iterate over unique widgets from collector
0567: Iterator i = getWidgets().iterator();
0568: while (i.hasNext()) {
0569: CmsWidgetDialogParameter param = (CmsWidgetDialogParameter) i
0570: .next();
0571: result.append(param.getWidget().getDialogHtmlEnd(getCms(),
0572: this , param));
0573: }
0574: return result.toString();
0575: }
0576:
0577: /**
0578: * Generates the HTML include tags for external JavaScripts files of the used widgets.<p>
0579: *
0580: * @return the HTML include tags for external JavaScripts files of the used widgets
0581: *
0582: * @throws JspException if an error occurs during JavaScript generation
0583: */
0584: public String getWidgetIncludes() throws JspException {
0585:
0586: StringBuffer result = new StringBuffer(32);
0587: try {
0588: // iterate over unique widgets from collector
0589: Iterator i = getWidgets().iterator();
0590: Set set = new HashSet();
0591: while (i.hasNext()) {
0592: I_CmsWidget widget = ((CmsWidgetDialogParameter) i
0593: .next()).getWidget();
0594: if (!set.contains(widget)) {
0595: result.append(widget.getDialogIncludes(getCms(),
0596: this ));
0597: result.append('\n');
0598: set.add(widget);
0599: }
0600: }
0601: } catch (Throwable e) {
0602:
0603: includeErrorpage(this , e);
0604: }
0605: return result.toString();
0606: }
0607:
0608: /**
0609: * Generates the JavaScript init calls for the used widgets.<p>
0610: *
0611: * @return the JavaScript init calls for the used widgets
0612: *
0613: * @throws JspException the JavaScript init calls for the used widgets
0614: */
0615: public String getWidgetInitCalls() throws JspException {
0616:
0617: StringBuffer result = new StringBuffer(32);
0618: try {
0619: // iterate over unique widgets from collector
0620: Iterator i = getWidgets().iterator();
0621: Set set = new HashSet();
0622: while (i.hasNext()) {
0623: I_CmsWidget widget = ((CmsWidgetDialogParameter) i
0624: .next()).getWidget();
0625: if (!set.contains(widget)) {
0626: result.append(widget.getDialogInitCall(getCms(),
0627: this ));
0628: set.add(widget);
0629: }
0630: }
0631: } catch (Throwable e) {
0632: includeErrorpage(this , e);
0633: }
0634: return result.toString();
0635: }
0636:
0637: /**
0638: * Generates the JavaScript initialization methods for the used widgets.<p>
0639: *
0640: * @return the JavaScript initialization methods for the used widgets
0641: *
0642: * @throws JspException if an error occurs during JavaScript generation
0643: */
0644: public String getWidgetInitMethods() throws JspException {
0645:
0646: StringBuffer result = new StringBuffer(32);
0647: try {
0648: // iterate over unique widgets from collector
0649: Iterator i = getWidgets().iterator();
0650: Set set = new HashSet();
0651: while (i.hasNext()) {
0652: I_CmsWidget widget = ((CmsWidgetDialogParameter) i
0653: .next()).getWidget();
0654: if (!set.contains(widget)) {
0655: result.append(widget.getDialogInitMethod(getCms(),
0656: this ));
0657: set.add(widget);
0658: }
0659: }
0660: } catch (Throwable e) {
0661: includeErrorpage(this , e);
0662: }
0663: return result.toString();
0664: }
0665:
0666: /**
0667: * @see org.opencms.workplace.CmsWorkplace#paramsAsHidden()
0668: */
0669: public String paramsAsHidden() {
0670:
0671: if (getAction() != ACTION_ERROR) {
0672: return super .paramsAsHidden();
0673: }
0674: // on an error page, also output the widget parameters
0675: StringBuffer result = new StringBuffer();
0676: result.append(super .paramsAsHidden());
0677: result.append('\n');
0678: result.append(widgetParamsAsHidden());
0679: return result.toString();
0680: }
0681:
0682: /**
0683: * Stores the given object as "dialog object" for this widget dialog in the current users session.<p>
0684: *
0685: * @param dialogObject the object to store
0686: */
0687: public void setDialogObject(Object dialogObject) {
0688:
0689: m_dialogObject = dialogObject;
0690: if (dialogObject == null) {
0691: // null object: remove the entry from the map
0692: getDialogObjectMap().remove(getClass().getName());
0693: } else {
0694: getDialogObjectMap()
0695: .put(getClass().getName(), dialogObject);
0696: }
0697: }
0698:
0699: /**
0700: * Sets the index of the element to add or remove.<p>
0701: *
0702: * @param elementIndex the index of the element to add or remove
0703: */
0704: public void setParamElementIndex(String elementIndex) {
0705:
0706: m_paramElementIndex = elementIndex;
0707: }
0708:
0709: /**
0710: * Sets the name of the element to add or remove.<p>
0711: *
0712: * @param elementName the name of the element to add or remove
0713: */
0714: public void setParamElementName(String elementName) {
0715:
0716: m_paramElementName = elementName;
0717: }
0718:
0719: /**
0720: * Sets the page parameter.<p>
0721: *
0722: * @param paramPage the page parameter to set
0723: */
0724: public void setParamPage(String paramPage) {
0725:
0726: m_paramPage = paramPage;
0727: }
0728:
0729: /**
0730: * Returns the values of all widget parameters of this dialog as HTML hidden fields.<p>
0731: *
0732: * @return the values of all widget parameters of this dialog as HTML hidden fields
0733: *
0734: * @see org.opencms.workplace.CmsWorkplace#paramsAsHidden()
0735: */
0736: public String widgetParamsAsHidden() {
0737:
0738: return widgetParamsAsHidden(null);
0739: }
0740:
0741: /**
0742: * Returns the values of all widget parameters of this dialog as HTML hidden fields,
0743: * excluding the widget values that are on the given dialog page.<p>
0744: *
0745: * This can be used to create multi-page dialogs where the values are passed from
0746: * one page to another before everything is submitted. If a widget A is used on page X,
0747: * there should be no "hidden" HTML field for A since otherwise A would have 2 values when
0748: * submitting the dialog page: The one from the widget itself and the one from the hidden
0749: * field. This may lead to undefined results when processing the submitted values.<p>
0750: *
0751: * @param excludeDialogPage the dialog page to exclude the values for
0752: *
0753: * @return the values of all widget parameters of this dialog as HTML hidden fields,
0754: * excluding the widget values that are on the given dialog page
0755: *
0756: * @see org.opencms.workplace.CmsWorkplace#paramsAsHidden()
0757: */
0758: public String widgetParamsAsHidden(String excludeDialogPage) {
0759:
0760: StringBuffer result = new StringBuffer();
0761: Iterator i = m_widgetParamValues.keySet().iterator();
0762: while (i.hasNext()) {
0763: List params = (List) m_widgetParamValues.get(i.next());
0764: Iterator j = params.iterator();
0765: while (j.hasNext()) {
0766: CmsWidgetDialogParameter param = (CmsWidgetDialogParameter) j
0767: .next();
0768: String value = param.getStringValue(getCms());
0769: if (CmsStringUtil.isNotEmpty(value)
0770: && ((excludeDialogPage == null) || (!param
0771: .getDialogPage().equals(
0772: excludeDialogPage)))) {
0773: result.append("<input type=\"hidden\" name=\"");
0774: result.append(HIDDEN_PARAM_PREFIX);
0775: result.append(param.getId());
0776: result.append("\" value=\"");
0777: String encoded = CmsEncoder.encode(value, getCms()
0778: .getRequestContext().getEncoding());
0779: result.append(encoded);
0780: result.append("\">\n");
0781: }
0782: }
0783: }
0784: return result.toString();
0785: }
0786:
0787: /**
0788: * Writes the dialog html code, only if the <code>{@link #ACTION_DEFAULT}</code> is set.<p>
0789: *
0790: * @throws JspException if dialog actions fail
0791: * @throws IOException if writing to the JSP out fails, or in case of errors forwarding to the required result page
0792: */
0793: public void writeDialog() throws IOException, JspException {
0794:
0795: if (isForwarded()) {
0796: return;
0797: }
0798: switch (getAction()) {
0799: case ACTION_CANCEL:
0800: case ACTION_ERROR:
0801: case ACTION_SAVE:
0802: break;
0803:
0804: case ACTION_DEFAULT:
0805: default:
0806: // ACTION: show dialog (default)
0807: setParamAction(DIALOG_SAVE);
0808: JspWriter out = getJsp().getJspContext().getOut();
0809: out.print(defaultActionHtml());
0810: }
0811: }
0812:
0813: /**
0814: * Adds the given error to the list of errors that are thrown by save actions or form generation.<p>
0815: *
0816: * If the error list has not been initialized yet, this is done automatically.<p>
0817: *
0818: * @param error the errors to add
0819: */
0820: protected void addCommitError(Exception error) {
0821:
0822: if (m_commitErrors == null) {
0823: m_commitErrors = new ArrayList();
0824: }
0825: m_commitErrors.add(error);
0826: }
0827:
0828: /**
0829: * Adds a new widget parameter definition to the list of all widgets of this dialog.<p>
0830: *
0831: * @param param the widget parameter definition to add
0832: */
0833: protected void addWidget(CmsWidgetDialogParameter param) {
0834:
0835: if (m_widgets == null) {
0836: m_widgets = new ArrayList();
0837: }
0838: param.setKeyPrefix(m_prefix);
0839: m_widgets.add(param);
0840: }
0841:
0842: /**
0843: * Returns <code>true</code> if the dialog should be closed after the values have been committed.<p>
0844: *
0845: * The default implementation returns <code>true</code> in case there are no
0846: * commit errors.<p>
0847: *
0848: * @return <code>true</code> if the dialog should be closed after the values have been committed
0849: */
0850: protected boolean closeDialogOnCommit() {
0851:
0852: return !hasCommitErrors();
0853: }
0854:
0855: /**
0856: * Commits all values on the dialog.<p>
0857: *
0858: * @return a List of all Exceptions that occured when comitting the dialog.<p>
0859: */
0860: protected List commitWidgetValues() {
0861:
0862: return commitWidgetValues(null);
0863: }
0864:
0865: /**
0866: * Commits all values on the given dialog page.<p>
0867: *
0868: * @param dialogPage the dialog (page) to commit
0869: *
0870: * @return a List of all Exceptions that occurred when committing the dialog page.<p>
0871: */
0872: protected List commitWidgetValues(String dialogPage) {
0873:
0874: List result = new ArrayList();
0875: Iterator i = getWidgets().iterator();
0876: while (i.hasNext()) {
0877: // check for all widget parameters
0878: CmsWidgetDialogParameter base = (CmsWidgetDialogParameter) i
0879: .next();
0880: if ((dialogPage == null) || (base.getDialogPage() == null)
0881: || dialogPage.equals(base.getDialogPage())) {
0882: // the parameter is located on the requested dialog
0883: base.prepareCommit();
0884: List params = (List) m_widgetParamValues.get(base
0885: .getName());
0886: Iterator j = params.iterator();
0887: while (j.hasNext()) {
0888: CmsWidgetDialogParameter param = (CmsWidgetDialogParameter) j
0889: .next();
0890: try {
0891: param.commitValue(this );
0892: } catch (Exception e) {
0893: result.add(e);
0894: }
0895: }
0896: }
0897: }
0898: setValidationErrorList(result);
0899: return result;
0900: }
0901:
0902: /**
0903: * Creates the dialog HTML for all defined widgets of this dialog.<p>
0904: *
0905: * @return the dialog HTML for all defined widgets of this dialog
0906: */
0907: protected String createDialogHtml() {
0908:
0909: return createDialogHtml(null);
0910: }
0911:
0912: /**
0913: * Creates the dialog HTML for all defined widgets of the named dialog (page).<p>
0914: *
0915: * To get a more complex layout variation, you have to overwrite this method in your dialog class.<p>
0916: *
0917: * @param dialog the dialog (page) to get the HTML for
0918: * @return the dialog HTML for all defined widgets of the named dialog (page)
0919: */
0920: protected String createDialogHtml(String dialog) {
0921:
0922: StringBuffer result = new StringBuffer(1024);
0923:
0924: // create table
0925: result.append(createWidgetTableStart());
0926:
0927: // show error header once if there were validation errors
0928: result.append(createWidgetErrorHeader());
0929:
0930: Iterator i = getWidgets().iterator();
0931: // iterate the type sequence
0932: while (i.hasNext()) {
0933: // get the current widget base definition
0934: CmsWidgetDialogParameter base = (CmsWidgetDialogParameter) i
0935: .next();
0936: // check if the element is on the requested dialog page
0937: if ((dialog == null) || dialog.equals(base.getDialogPage())) {
0938: // add the HTML for the dialog element
0939: result.append(createDialogRowHtml(base));
0940: }
0941: }
0942: // close table
0943: result.append(createWidgetTableEnd());
0944:
0945: return result.toString();
0946: }
0947:
0948: /**
0949: * Creates the dialog HTML for all occurrences of one widget parameter.<p>
0950: *
0951: * @param base the widget parameter base
0952: * @return the dialog HTML for one widget parameter
0953: */
0954: protected String createDialogRowHtml(CmsWidgetDialogParameter base) {
0955:
0956: StringBuffer result = new StringBuffer(256);
0957:
0958: List sequence = (List) getParameters().get(base.getName());
0959: int count = sequence.size();
0960:
0961: // check if value is optional or multiple
0962: boolean addValue = false;
0963: if (count < base.getMaxOccurs()) {
0964: addValue = true;
0965: }
0966: boolean removeValue = false;
0967: if (count > base.getMinOccurs()) {
0968: removeValue = true;
0969: }
0970:
0971: // check if value is present
0972: boolean disabledElement = false;
0973: if (count < 1) {
0974: // no parameter with the value present, but also not optional: use base as parameter
0975: sequence = new ArrayList();
0976: sequence.add(base);
0977: count = 1;
0978: if (base.getMinOccurs() == 0) {
0979: disabledElement = true;
0980: }
0981: }
0982:
0983: // loop through multiple elements
0984: for (int j = 0; j < count; j++) {
0985:
0986: // get the parameter and the widget
0987: CmsWidgetDialogParameter p = (CmsWidgetDialogParameter) sequence
0988: .get(j);
0989: I_CmsWidget widget = p.getWidget();
0990:
0991: // check for an error in this row
0992: if (p.hasError()) {
0993: // show error message
0994: result.append("<tr><td></td><td><img src=\"");
0995: result.append(getSkinUri()).append(
0996: "editors/xmlcontent/");
0997: result.append("error.png");
0998: result
0999: .append("\" border=\"0\" alt=\"\"></td><td class=\"xmlTdError\">");
1000: Throwable t = p.getError();
1001: while (t != null) {
1002: if (t instanceof I_CmsThrowable) {
1003: result
1004: .append(CmsEncoder
1005: .escapeXml(((I_CmsThrowable) t)
1006: .getLocalizedMessage(getLocale())));
1007: } else {
1008: result.append(CmsEncoder.escapeXml(t
1009: .getLocalizedMessage()));
1010: }
1011: t = t.getCause();
1012: if (t != null) {
1013: result.append("<br>");
1014: }
1015: }
1016: result.append("</td><td colspan=\"2\"></td></tr>\n");
1017: }
1018:
1019: // create label and help bubble cells
1020: result.append("<tr>");
1021: result.append("<td class=\"xmlLabel");
1022: if (disabledElement) {
1023: // element is disabled, mark it with css
1024: result.append("Disabled");
1025: }
1026:
1027: result.append("\">");
1028: result.append(keyDefault(A_CmsWidget.getLabelKey(p), p
1029: .getName()));
1030: if (count > 1) {
1031: result.append(" [").append(p.getIndex() + 1)
1032: .append("]");
1033: }
1034: result.append(": </td>");
1035: if (p.getIndex() == 0) {
1036: // show help bubble only on first element of each content definition
1037: result.append(p.getWidget().getHelpBubble(getCms(),
1038: this , p));
1039: } else {
1040: // create empty cell for all following elements
1041: result.append(dialogHorizontalSpacer(16));
1042: }
1043:
1044: // append individual widget html cell if element is enabled
1045: if (!disabledElement) {
1046: // this is a simple type, display widget
1047: result
1048: .append(widget.getDialogWidget(getCms(), this ,
1049: p));
1050: } else {
1051: // disabled element, show message for optional element
1052: result.append("<td class=\"xmlTdDisabled maxwidth\">");
1053: result
1054: .append(key(Messages.GUI_EDITOR_WIDGET_OPTIONALELEMENT_0));
1055: result.append("</td>");
1056: }
1057:
1058: // append add and remove element buttons if required
1059: result.append(dialogHorizontalSpacer(5));
1060: result.append("<td>");
1061: if (addValue || removeValue) {
1062: result
1063: .append("<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><tr>");
1064:
1065: if (!addValue) {
1066: result.append(dialogHorizontalSpacer(25));
1067: } else {
1068: result
1069: .append("<td><table class=\"editorbuttonbackground\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><tr>");
1070: result.append(buildAddElement(base.getName(), p
1071: .getIndex(), addValue));
1072: }
1073:
1074: if (removeValue) {
1075: if (!addValue) {
1076: result
1077: .append("<td><table class=\"editorbuttonbackground\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><tr>");
1078: }
1079: result.append(buildRemoveElement(base.getName(), p
1080: .getIndex(), removeValue));
1081: }
1082:
1083: result.append("</tr></table></td>");
1084: result.append("</tr></table>");
1085: }
1086: result.append("</td>");
1087: // close row
1088: result.append("</tr>\n");
1089: }
1090:
1091: return result.toString();
1092: }
1093:
1094: /**
1095: * Creates the dialog widget rows HTML for the specified widget indices.<p>
1096: *
1097: * @param startIndex the widget index to start with
1098: * @param endIndex the widget index to stop at
1099: *
1100: * @return the dialog widget rows HTML for the specified widget indices
1101: */
1102: protected String createDialogRowsHtml(int startIndex, int endIndex) {
1103:
1104: StringBuffer result = new StringBuffer(
1105: (endIndex - startIndex) * 8);
1106: for (int i = startIndex; i <= endIndex; i++) {
1107: CmsWidgetDialogParameter base = (CmsWidgetDialogParameter) getWidgets()
1108: .get(i);
1109: result.append(createDialogRowHtml(base));
1110: }
1111: return result.toString();
1112: }
1113:
1114: /**
1115: * Creates the complete widget dialog end block HTML that finishes a widget block.<p>
1116: *
1117: * @return the complete widget dialog end block HTML that finishes a widget block
1118: */
1119: protected String createWidgetBlockEnd() {
1120:
1121: StringBuffer result = new StringBuffer(8);
1122: result.append(createWidgetTableEnd());
1123: result.append(dialogBlockEnd());
1124: return result.toString();
1125: }
1126:
1127: /**
1128: * Create the complete widget dialog start block HTML that begins a widget block with optional headline.<p>
1129: *
1130: * @param headline the headline String for the block
1131: *
1132: * @return the complete widget dialog start block HTML that begins a widget block with optional headline
1133: */
1134: protected String createWidgetBlockStart(String headline) {
1135:
1136: StringBuffer result = new StringBuffer(16);
1137: result.append(dialogBlockStart(headline));
1138: result.append(createWidgetTableStart());
1139: return result.toString();
1140: }
1141:
1142: /**
1143: * Creates the HTML for the error message if validation errors were found.<p>
1144: *
1145: * @return the HTML for the error message if validation errors were found
1146: */
1147: protected String createWidgetErrorHeader() {
1148:
1149: StringBuffer result = new StringBuffer(8);
1150: if (hasValidationErrors() || hasCommitErrors()) {
1151: result.append("<tr><td colspan=\"5\"> </td></tr>\n");
1152: result.append("<tr><td colspan=\"2\"> </td>");
1153: result.append("<td class=\"xmlTdErrorHeader\">");
1154: result
1155: .append(key(Messages.GUI_EDITOR_WIDGET_VALIDATION_ERROR_TITLE_0));
1156: result.append("</td><td colspan=\"2\"> ");
1157: result.append("</td></tr>\n");
1158: result.append("<tr><td colspan=\"5\"> </td></tr>\n");
1159: if (hasCommitErrors()) {
1160: result.append(dialogBlockStart(""));
1161: result.append(createWidgetTableStart());
1162: Iterator i = getCommitErrors().iterator();
1163: while (i.hasNext()) {
1164: Throwable t = (Throwable) i.next();
1165: result.append("<tr><td><img src=\"");
1166: result.append(getSkinUri()).append(
1167: "editors/xmlcontent/");
1168: result.append("error.png");
1169: result
1170: .append("\" border=\"0\" alt=\"\"></td><td class=\"xmlTdError maxwidth\">");
1171: while (t != null) {
1172: String message = "";
1173: if (t instanceof I_CmsThrowable) {
1174: message = ((I_CmsThrowable) t)
1175: .getLocalizedMessage(getLocale());
1176: } else {
1177: message = t.getLocalizedMessage();
1178: }
1179: result
1180: .append(CmsStringUtil
1181: .escapeHtml(message));
1182: t = t.getCause();
1183: if (t != null) {
1184: result.append("<br>");
1185: }
1186: }
1187: result.append("</td></tr>\n");
1188: }
1189: result.append(createWidgetTableEnd());
1190: result.append(dialogBlockEnd());
1191: }
1192: if (hasValidationErrors()) {
1193: result.append(dialogBlockStart(""));
1194: result.append(createWidgetTableStart());
1195: Iterator i = getValidationErrorList().iterator();
1196: while (i.hasNext()) {
1197: Throwable t = (Throwable) i.next();
1198: result.append("<tr><td><img src=\"");
1199: result.append(getSkinUri()).append(
1200: "editors/xmlcontent/");
1201: result.append("error.png");
1202: result
1203: .append("\" border=\"0\" alt=\"\"></td><td class=\"xmlTdError maxwidth\">");
1204: while (t != null) {
1205: String message = "";
1206: if (t instanceof I_CmsThrowable) {
1207: message = ((I_CmsThrowable) t)
1208: .getLocalizedMessage(getLocale());
1209: } else {
1210: message = t.getLocalizedMessage();
1211: }
1212: result
1213: .append(CmsStringUtil
1214: .escapeHtml(message));
1215: t = t.getCause();
1216: if (t != null) {
1217: result.append("<br>");
1218: }
1219: }
1220: result.append("</td></tr>\n");
1221: }
1222: result.append(createWidgetTableEnd());
1223: result.append(dialogBlockEnd());
1224: }
1225: }
1226: return result.toString();
1227: }
1228:
1229: /**
1230: * Creates the HTML for the table around the dialog widgets.<p>
1231: *
1232: * @return the HTML for the table around the dialog widgets
1233: */
1234: protected String createWidgetTableEnd() {
1235:
1236: return "</table>\n";
1237: }
1238:
1239: /**
1240: * Creates the HTML to close the table around the dialog widgets.<p>
1241: *
1242: * @return the HTML to close the table around the dialog widgets
1243: */
1244: protected String createWidgetTableStart() {
1245:
1246: return "<table cellspacing='0' cellpadding='0' class='xmlTable'>\n";
1247: }
1248:
1249: /**
1250: * Generates the dialog starting html code.<p>
1251: *
1252: * @return html code
1253: *
1254: * @throws JspException if something goes wrong
1255: */
1256: protected String defaultActionHtml() throws JspException {
1257:
1258: StringBuffer result = new StringBuffer(2048);
1259: result.append(defaultActionHtmlStart());
1260: result.append(defaultActionHtmlContent());
1261: result.append(defaultActionHtmlEnd());
1262: return result.toString();
1263: }
1264:
1265: /**
1266: * Returns the html code for the default action content.<p>
1267: *
1268: * @return html code
1269: */
1270: protected String defaultActionHtmlContent() {
1271:
1272: StringBuffer result = new StringBuffer(2048);
1273: result
1274: .append(
1275: "<form name=\"EDITOR\" id=\"EDITOR\" method=\"post\" action=\"")
1276: .append(getDialogRealUri());
1277: result
1278: .append(
1279: "\" class=\"nomargin\" onsubmit=\"return submitAction('")
1280: .append(DIALOG_OK).append("', null, 'EDITOR');\">\n");
1281: result.append(dialogContentStart(getDialogTitle()));
1282: result.append(buildDialogForm());
1283: result.append(dialogContentEnd());
1284: result.append(dialogButtonsCustom());
1285: result.append(paramsAsHidden());
1286: if (getParamFramename() == null) {
1287: result.append("\n<input type=\"hidden\" name=\"").append(
1288: PARAM_FRAMENAME).append("\" value=\"\">\n");
1289: }
1290: result.append("</form>\n");
1291: result.append(getWidgetHtmlEnd());
1292: return result.toString();
1293: }
1294:
1295: /**
1296: * Generates the dialog ending html code.<p>
1297: *
1298: * @return html code
1299: */
1300: protected String defaultActionHtmlEnd() {
1301:
1302: StringBuffer result = new StringBuffer(2048);
1303: result.append(dialogEnd());
1304: result.append(bodyEnd());
1305: result.append(htmlEnd());
1306: return result.toString();
1307: }
1308:
1309: /**
1310: * Generates the dialog starting html code.<p>
1311: *
1312: * @return html code
1313: *
1314: * @throws JspException if something goes wrong
1315: */
1316: protected String defaultActionHtmlStart() throws JspException {
1317:
1318: StringBuffer result = new StringBuffer(2048);
1319: result.append(htmlStart("administration/index.html"));
1320: result.append("<script type=\"text/javascript\" src=\"")
1321: .append(getResourceUri()).append(
1322: "editors/xmlcontent/edit.js\"></script>\n");
1323: result.append("<script type=\"text/javascript\" src=\"")
1324: .append(getResourceUri()).append(
1325: "editors/xmlcontent/help.js\"></script>\n");
1326: result.append(getWidgetIncludes());
1327: result.append("<script type=\"text/javascript\">\n<!--\n");
1328: result
1329: .append("// flag indicating if form initialization is finished\n");
1330: result.append("var initialized = false;\n");
1331: result.append("// the OpenCms context path\n");
1332: result.append("var contextPath = \"").append(
1333: OpenCms.getSystemInfo().getOpenCmsContext()).append(
1334: "\";\n\n");
1335: result.append("// action parameters of the form\n");
1336: result.append("var actionAddElement = \"").append(
1337: EDITOR_ACTION_ELEMENT_ADD).append("\";\n");
1338: result.append("var actionRemoveElement = \"").append(
1339: EDITOR_ACTION_ELEMENT_REMOVE).append("\";\n");
1340: result.append("function init() {\n");
1341: result.append(getWidgetInitCalls());
1342: result.append("\tsetTimeout(\"scrollForm();\", 200);\n");
1343: result.append("\tinitialized = true;\n");
1344: result.append("}\n\n");
1345: result.append("function exitEditor() {\n");
1346: result.append("\ttry {\n");
1347: result.append("\t\t// close file selector popup if present\n");
1348: result.append("\t\tcloseTreeWin();\n");
1349: result.append("\t} catch (e) {}\n");
1350: result.append("}\n");
1351: result.append(getWidgetInitMethods());
1352: result.append("\n// -->\n</script>\n");
1353: result.append(bodyStart(null,
1354: "onload='init();' onunload='exitEditor();'"));
1355: result.append(dialogStart());
1356: return result.toString();
1357: }
1358:
1359: /**
1360: * Defines the list of parameters for this dialog.<p>
1361: */
1362: protected abstract void defineWidgets();
1363:
1364: /**
1365: * Fills all widgets of this widget dialog with the values from the request parameters.<p>
1366: *
1367: * @param request the current HTTP servlet request
1368: */
1369: protected void fillWidgetValues(HttpServletRequest request) {
1370:
1371: Map parameters = request.getParameterMap();
1372: Map processedParameters = new HashMap();
1373: Iterator p = parameters.entrySet().iterator();
1374: // make sure all "hidden" widget parameters are decoded
1375: while (p.hasNext()) {
1376: Map.Entry entry = (Map.Entry) p.next();
1377: String key = (String) entry.getKey();
1378: String[] values = (String[]) entry.getValue();
1379: if (key.startsWith(HIDDEN_PARAM_PREFIX)) {
1380: // this is an encoded hidden parameter
1381: key = key.substring(HIDDEN_PARAM_PREFIX.length());
1382: String[] newValues = new String[values.length];
1383: for (int l = 0; l < values.length; l++) {
1384: newValues[l] = CmsEncoder.decode(values[l],
1385: getCms().getRequestContext().getEncoding());
1386: }
1387: values = newValues;
1388: }
1389: processedParameters.put(key, values);
1390: }
1391:
1392: // now process the parameters
1393: m_widgetParamValues = new HashMap();
1394: Iterator i = getWidgets().iterator();
1395:
1396: while (i.hasNext()) {
1397: // check for all widget base parameters
1398: CmsWidgetDialogParameter base = (CmsWidgetDialogParameter) i
1399: .next();
1400:
1401: List params = new ArrayList();
1402: int maxOccurs = base.getMaxOccurs();
1403:
1404: boolean onPage = false;
1405: if (base.isCollectionBase()) {
1406: // for a collection base, check if we are on the page where the collection base is shown
1407: if (CmsStringUtil.isNotEmpty(getParamAction())
1408: && !DIALOG_INITIAL.equals(getParamAction())) {
1409: // if no action set (usually for first display of dialog) make sure all values are shown
1410: // DIALOG_INITIAL is a special value for the first display and must be handled the same way
1411: String page = getParamPage();
1412: // keep in mind that since the paramPage will be set AFTER the widget values are filled,
1413: // so the first time this page is called from another page the following will result to "false",
1414: // but for every "submit" on the page this will be "true"
1415: onPage = CmsStringUtil.isEmpty(page)
1416: || CmsStringUtil.isEmpty(base
1417: .getDialogPage())
1418: || base.getDialogPage().equals(page);
1419: }
1420: }
1421:
1422: for (int j = 0; j < maxOccurs; j++) {
1423: // check for all possible values in the request parameters
1424: String id = CmsWidgetDialogParameter.createId(base
1425: .getName(), j);
1426:
1427: boolean required = (params.size() < base.getMinOccurs())
1428: || (processedParameters.get(id) != null)
1429: || (!onPage && base.hasValue(j));
1430:
1431: if (required) {
1432: CmsWidgetDialogParameter param = new CmsWidgetDialogParameter(
1433: base, params.size(), j);
1434: param.setKeyPrefix(m_prefix);
1435: base.getWidget().setEditorValue(getCms(),
1436: processedParameters, this , param);
1437: params.add(param);
1438: }
1439: }
1440: m_widgetParamValues.put(base.getName(), params);
1441: }
1442: }
1443:
1444: /**
1445: * Returns the title for this Dialog.<p>
1446: *
1447: * In the default implementation this method returns <code>null</code>.
1448: * Override this if needed.<p>
1449: *
1450: * @return the title for this Dialog, or <code>null</code> if this dialog has no title
1451: */
1452: protected String getDialogTitle() {
1453:
1454: return null;
1455: }
1456:
1457: /**
1458: * Returns the allowed pages for this dialog.<p>
1459: *
1460: * @return the allowed pages for this dialog
1461: */
1462: protected abstract String[] getPageArray();
1463:
1464: /**
1465: * Returns the allowed pages for this dialog.<p>
1466: *
1467: * @return the allowed pages for this dialog
1468: */
1469: protected List getPages() {
1470:
1471: if (m_pages == null) {
1472: m_pages = Arrays.asList(getPageArray());
1473: }
1474: return m_pages;
1475: }
1476:
1477: /**
1478: * Returns the parameter widget definition for the given parameter name.<p>
1479: *
1480: * @param name the parameter name to get the definition for
1481: *
1482: * @return the parameter widget definition for the given parameter name
1483: */
1484: protected CmsWidgetDialogParameter getParameterDefinition(
1485: String name) {
1486:
1487: Iterator i = getWidgets().iterator();
1488: while (i.hasNext()) {
1489: // check for all widget parameters
1490: CmsWidgetDialogParameter base = (CmsWidgetDialogParameter) i
1491: .next();
1492: if (base.getName().equals(name)) {
1493: return base;
1494: }
1495: }
1496: return null;
1497: }
1498:
1499: /**
1500: * Returns the map with the widget parameter values.<p>
1501: *
1502: * @return the map with the widget parameter values
1503: */
1504: protected Map getParameters() {
1505:
1506: return m_widgetParamValues;
1507: }
1508:
1509: /**
1510: * Returns the validation errors for the dialog.<p>
1511: *
1512: * The method (@link CmsWidgetDialog#commitWidgetValues(String)) has to set this list.<p>
1513: *
1514: * @return the validation errors for the dialog
1515: */
1516: protected List getValidationErrorList() {
1517:
1518: return m_validationErrorList;
1519: }
1520:
1521: /**
1522: * Returns the widget HTML code for the given parameter.<p>
1523: *
1524: * @param param the name (id) of the parameter to get the widget HTML for
1525: *
1526: * @return the widget HTML code for the given parameter
1527: */
1528: protected String getWidget(CmsWidgetDialogParameter param) {
1529:
1530: if (param != null) {
1531: return param.getWidget().getDialogWidget(getCms(), this ,
1532: param);
1533: }
1534: return null;
1535: }
1536:
1537: /**
1538: * Returns the list of all widgets used on this widget dialog, the
1539: * List must contain Objects of type <code>{@link CmsWidgetDialogParameter}</code>.<p>
1540: *
1541: * @return the list of all widgets used on this widget dialog
1542: */
1543: protected List getWidgets() {
1544:
1545: if (m_widgets == null) {
1546: m_widgets = new ArrayList();
1547: }
1548: return m_widgets;
1549: }
1550:
1551: /**
1552: * Returns <code>true</code> if the current dialog (page) has commit errors.<p>
1553: *
1554: * @return <code>true</code> if the current dialog (page) has commit errors
1555: */
1556: protected boolean hasCommitErrors() {
1557:
1558: return (m_commitErrors != null) && (m_commitErrors.size() > 0);
1559: }
1560:
1561: /**
1562: * Returns <code>true</code> if the current dialog (page) has validation errors.<p>
1563: *
1564: * @return <code>true</code> if the current dialog (page) has validation errors
1565: */
1566: protected boolean hasValidationErrors() {
1567:
1568: return (m_validationErrorList != null)
1569: && (m_validationErrorList.size() > 0);
1570: }
1571:
1572: /**
1573: * @see org.opencms.workplace.CmsWorkplace#initWorkplaceRequestValues(org.opencms.workplace.CmsWorkplaceSettings, javax.servlet.http.HttpServletRequest)
1574: */
1575: protected void initWorkplaceRequestValues(
1576: CmsWorkplaceSettings settings, HttpServletRequest request) {
1577:
1578: // set the dialog type
1579: setParamDialogtype(getClass().getName());
1580:
1581: // fill the parameter values in the get/set methods
1582: fillParamValues(request);
1583:
1584: if (CmsStringUtil.isEmptyOrWhitespaceOnly(getParamPage())
1585: || !getPages().contains(getParamPage())) {
1586: // ensure a valid page is set
1587: setParamPage((String) getPages().get(0));
1588: }
1589:
1590: // test the needed parameters
1591: try {
1592: validateParamaters();
1593: } catch (Exception e) {
1594: if (LOG.isInfoEnabled()) {
1595: LOG.info(Messages.get().container(
1596: Messages.ERR_WORKPLACE_DIALOG_PARAMS_1,
1597: getCurrentToolPath()), e);
1598: }
1599: // close if parameters not available
1600: setAction(ACTION_CANCEL);
1601: try {
1602: actionCloseDialog();
1603: } catch (JspException e1) {
1604: // ignore
1605: }
1606: return;
1607: }
1608:
1609: // fill the widget map
1610: defineWidgets();
1611: fillWidgetValues(request);
1612:
1613: // set the action for the JSP switch
1614: if (DIALOG_SAVE.equals(getParamAction())) {
1615: // ok button pressed, save
1616: List errors = commitWidgetValues(null);
1617: if (errors.size() > 0) {
1618: setAction(ACTION_DEFAULT);
1619: // found validation errors, redisplay page
1620: return;
1621: }
1622: setAction(ACTION_SAVE);
1623: } else if (DIALOG_OK.equals(getParamAction())) {
1624: // ok button pressed
1625: setAction(ACTION_CANCEL);
1626: } else if (DIALOG_CANCEL.equals(getParamAction())) {
1627: // cancel button pressed
1628: setAction(ACTION_CANCEL);
1629: } else if (EDITOR_ACTION_ELEMENT_ADD.equals(getParamAction())) {
1630: // add optional input element
1631: setAction(ACTION_ELEMENT_ADD);
1632: actionToggleElement();
1633: setAction(ACTION_DEFAULT);
1634: } else if (EDITOR_ACTION_ELEMENT_REMOVE
1635: .equals(getParamAction())) {
1636: // remove optional input element
1637: setAction(ACTION_ELEMENT_REMOVE);
1638: actionToggleElement();
1639: setAction(ACTION_DEFAULT);
1640: } else if (DIALOG_BACK.equals(getParamAction())) {
1641: // go back one page
1642: setAction(ACTION_DEFAULT);
1643: List errors = commitWidgetValues(getParamPage());
1644: if (errors.size() > 0) {
1645: // found validation errors, redisplay page
1646: return;
1647: }
1648: int pageIndex = getPages().indexOf(getParamPage()) - 1;
1649: setParamPage((String) getPages().get(pageIndex));
1650:
1651: } else if (DIALOG_CONTINUE.equals(getParamAction())) {
1652: // go to next page
1653: setAction(ACTION_DEFAULT);
1654: List errors = commitWidgetValues(getParamPage());
1655: if (errors.size() > 0) {
1656: // found validation errors, redisplay page
1657: return;
1658: }
1659: int pageIndex = getPages().indexOf(getParamPage()) + 1;
1660: setParamPage((String) getPages().get(pageIndex));
1661:
1662: } else {
1663: // first dialog call, set the default action
1664: setAction(ACTION_DEFAULT);
1665: }
1666: }
1667:
1668: /**
1669: * Sets the errors that are thrown by save actions or form generation.<p>
1670: *
1671: * @param errors the errors that are thrown by save actions or form generation
1672: */
1673: protected void setCommitErrors(List errors) {
1674:
1675: m_commitErrors = errors;
1676: }
1677:
1678: /**
1679: * Sets an optional localized key prefix identificator for all widgets.<p>
1680: *
1681: * @param prefix the optional localized key prefix identificator for all widgets
1682: *
1683: * @see org.opencms.widgets.I_CmsWidgetParameter#setKeyPrefix(java.lang.String)
1684: */
1685: protected void setKeyPrefix(String prefix) {
1686:
1687: m_prefix = prefix;
1688: }
1689:
1690: /**
1691: * Sets the allowed pages for this dialog.<p>
1692: *
1693: * @param pages the allowed pages for this dialog
1694: */
1695: protected void setPages(List pages) {
1696:
1697: m_pages = pages;
1698: }
1699:
1700: /**
1701: * Sets the validation errors for the dialog.<p>
1702: *
1703: * Use this in the method (@link CmsWidgetDialog#commitWidgetValues(String)) to set the list.<p>
1704: *
1705: * @param errors the validation errors
1706: */
1707: protected void setValidationErrorList(List errors) {
1708:
1709: m_validationErrorList = errors;
1710: }
1711:
1712: /**
1713: * Should be overridden for parameter validation.<p>
1714: *
1715: * The exception is never seen by the user, so it can be just a <code>new {@link Exception}()</code>.<p>
1716: *
1717: * @throws Exception if the parameters are not valid
1718: */
1719: protected void validateParamaters() throws Exception {
1720:
1721: // valid by default
1722: }
1723:
1724: /**
1725: * Returns the (internal use only) map of dialog objects.<p>
1726: *
1727: * @return the (internal use only) map of dialog objects
1728: */
1729: private Map getDialogObjectMap() {
1730:
1731: Map objects = (Map) getSettings().getDialogObject();
1732: if (objects == null) {
1733: // using hash table as most efficient version of a synchronized map
1734: objects = new Hashtable();
1735: getSettings().setDialogObject(objects);
1736: }
1737: return objects;
1738: }
1739: }
|