001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com) 005 * 006 * This library is free software; you can redistribute it and/or 007 * modify it under the terms of the GNU Lesser General Public 008 * License as published by the Free Software Foundation; either 009 * version 2.1 of the License, or (at your option) any later version. 010 * 011 * This library is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 * Lesser General Public License for more details. 015 * 016 * For further information about Alkacon Software GmbH & Co. KG, please see the 017 * company website: http://www.alkacon.com 018 * 019 * For further information about OpenCms, please see the 020 * project website: http://www.opencms.org 021 * 022 * You should have received a copy of the GNU Lesser General Public 023 * License along with this library; if not, write to the Free Software 024 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 025 * 026 */ 027 028package org.opencms.workplace; 029 030import org.opencms.file.CmsResource; 031import org.opencms.file.CmsResourceFilter; 032import org.opencms.i18n.CmsEncoder; 033import org.opencms.i18n.CmsMessageContainer; 034import org.opencms.jsp.CmsJspActionElement; 035import org.opencms.main.CmsException; 036import org.opencms.main.CmsLog; 037import org.opencms.main.OpenCms; 038import org.opencms.security.CmsPermissionSet; 039import org.opencms.staticexport.CmsLinkManager; 040import org.opencms.ui.CmsVaadinUtils; 041import org.opencms.ui.apps.CmsAppHierarchyConfiguration; 042import org.opencms.util.CmsRequestUtil; 043import org.opencms.util.CmsStringUtil; 044import org.opencms.workplace.editors.CmsPreEditorAction; 045import org.opencms.workplace.tools.CmsToolDialog; 046import org.opencms.workplace.tools.CmsToolManager; 047 048import java.io.IOException; 049import java.util.HashMap; 050import java.util.Map; 051 052import javax.servlet.http.HttpServletRequest; 053import javax.servlet.http.HttpServletResponse; 054import javax.servlet.jsp.JspException; 055import javax.servlet.jsp.JspWriter; 056import javax.servlet.jsp.PageContext; 057 058import org.apache.commons.logging.Log; 059 060/** 061 * Provides methods for building the dialog windows of OpenCms.<p> 062 * 063 * @since 6.0.0 064 */ 065public class CmsDialog extends CmsToolDialog { 066 067 /** Value for the action: cancel. */ 068 public static final int ACTION_CANCEL = 4; 069 070 /** Value for the action: close popup window. */ 071 public static final int ACTION_CLOSEPOPUP = 6; 072 073 /** Value for the action: save & close popup window. */ 074 public static final int ACTION_CLOSEPOPUP_SAVE = 7; 075 076 /** Value for the action: confirmed. */ 077 public static final int ACTION_CONFIRMED = 1; 078 079 /** Value for the action: continue. */ 080 public static final int ACTION_CONTINUE = 8; 081 082 /** Value for the action: default (show initial dialog form). */ 083 public static final int ACTION_DEFAULT = 0; 084 085 /** Value for the action: locks confirmed. */ 086 public static final int ACTION_LOCKS_CONFIRMED = 99; 087 088 /** Value for the action: ok. */ 089 public static final int ACTION_OK = 3; 090 091 // note: action values 90 - 99 are reserved for reports 092 /** Value for the action: begin the report. */ 093 public static final int ACTION_REPORT_BEGIN = 90; 094 095 /** Value for the action: end the report. */ 096 public static final int ACTION_REPORT_END = 92; 097 098 /** Value for the action: update the report. */ 099 public static final int ACTION_REPORT_UPDATE = 91; 100 101 /** Value for the action: button "set" clicked. */ 102 public static final int ACTION_SET = 5; 103 104 /** Value for the action: wait (show please wait screen). */ 105 public static final int ACTION_WAIT = 2; 106 107 /** Constant for the "Advanced" button in the build button methods. */ 108 public static final int BUTTON_ADVANCED = 3; 109 110 /** Constant for the "Back" button in the build button methods. */ 111 public static final int BUTTON_BACK = 9; 112 113 /** Constant for the "Cancel" button in the build button methods. */ 114 public static final int BUTTON_CANCEL = 1; 115 116 /** Constant for the "Close" button in the build button methods. */ 117 public static final int BUTTON_CLOSE = 2; 118 119 /** Constant for the "Continue" button in the build button methods. */ 120 public static final int BUTTON_CONTINUE = 10; 121 122 /** Constant for the "Details" button in the build button methods. */ 123 public static final int BUTTON_DETAILS = 5; 124 125 /** Constant for the "Discard" button in the build button methods (same function as "Cancel" button but different text on button. */ 126 public static final int BUTTON_DISCARD = 8; 127 128 /** Constant for the "Edit" button in the build button methods (same function as "Ok" button but different text on button. */ 129 public static final int BUTTON_EDIT = 7; 130 131 /** Constant for the "OK" button in the build button methods. */ 132 public static final int BUTTON_OK = 0; 133 134 /** Constant for the "OK" button in the build button methods (without form submission). */ 135 public static final int BUTTON_OK_NO_SUBMIT = 6; 136 137 /** Constant for the "Set" button in the build button methods. */ 138 public static final int BUTTON_SET = 4; 139 140 /** Request parameter value for the action: back. */ 141 public static final String DIALOG_BACK = "back"; 142 143 /** Request parameter value for the action: cancel. */ 144 public static final String DIALOG_CANCEL = "cancel"; 145 146 /** Request parameter value for the action: dialog confirmed. */ 147 public static final String DIALOG_CONFIRMED = "confirmed"; 148 149 /** Request parameter value for the action: continue. */ 150 public static final String DIALOG_CONTINUE = "continue"; 151 152 /** Request parameter value for the action: initial call. */ 153 public static final String DIALOG_INITIAL = "initial"; 154 155 /** Request parameter value for the action: dialog locks confirmed. */ 156 public static final String DIALOG_LOCKS_CONFIRMED = "locksconfirmed"; 157 158 /** Request parameter value for the action: ok. */ 159 public static final String DIALOG_OK = "ok"; 160 161 /** Request parameter value for the action: set. */ 162 public static final String DIALOG_SET = "set"; 163 164 /** Request parameter value for the action: show please wait screen. */ 165 public static final String DIALOG_WAIT = "wait"; 166 167 /** Request parameter name for the action. */ 168 public static final String PARAM_ACTION = "action"; 169 170 /** Request parameter name for the action. */ 171 public static final String PARAM_ACTION_VALUE_FOR_CHANGED_INDEX = "index"; 172 173 /** Request parameter name for the closelink. */ 174 public static final String PARAM_CLOSELINK = "closelink"; 175 176 /** Request parameter name for the dialog type. */ 177 public static final String PARAM_DIALOGTYPE = "dialogtype"; 178 179 /** Request parameter name for the error stack. */ 180 public static final String PARAM_ERRORSTACK = "errorstack"; 181 182 /** Request parameter name for the file. */ 183 public static final String PARAM_FILE = "file"; 184 185 /** Request parameter name for the frame name. */ 186 public static final String PARAM_FRAMENAME = "framename"; 187 188 /** Request parameter name for the "is popup" flag. */ 189 public static final String PARAM_ISPOPUP = "ispopup"; 190 191 /** Request parameter name for the lock. */ 192 public static final String PARAM_LOCK = "lock"; 193 194 /** Request parameter name for the error message. */ 195 public static final String PARAM_MESSAGE = "message"; 196 197 /** Request parameter name for the originalparams. */ 198 public static final String PARAM_ORIGINALPARAMS = "originalparams"; 199 200 /** Request parameter name for the preactiondone. */ 201 public static final String PARAM_PREACTIONDONE = "preactiondone"; 202 203 /** Request parameter name for the redirect flag. */ 204 public static final String PARAM_REDIRECT = "redirect"; 205 206 /** Request parameter name for the resource. */ 207 public static final String PARAM_RESOURCE = "resource"; 208 209 /** Request parameter name for the target. */ 210 public static final String PARAM_TARGET = "target"; 211 212 /** Request parameter name for the thread id. */ 213 public static final String PARAM_THREAD = "thread"; 214 215 /** Request parameter name for indicating if another thread is following the current one. */ 216 public static final String PARAM_THREAD_HASNEXT = "threadhasnext"; 217 218 /** Request parameter name for the dialog title. */ 219 public static final String PARAM_TITLE = "title"; 220 221 /** Request parameter value for the action: begin the report. */ 222 public static final String REPORT_BEGIN = "reportbegin"; 223 224 /** Request parameter value for the action: end the report. */ 225 public static final String REPORT_END = "reportend"; 226 227 /** Request parameter value for the action: update the report. */ 228 public static final String REPORT_UPDATE = "reportupdate"; 229 230 /** Key name for the throwable attribute. */ 231 protected static final String ATTRIBUTE_THROWABLE = "throwable"; 232 233 /** The log object for this class. */ 234 private static final Log LOG = CmsLog.getLog(CmsDialog.class); 235 236 /** The dialog action. */ 237 private int m_action; 238 239 /** 240 * The custom mapping for online help.<p> 241 * 242 * It will be translated to a javascript variable called onlineHelpUriCustom. 243 * If it is set, the top.head javascript for the online help will use this value. <p> 244 */ 245 private String m_onlineHelpUriCustom; 246 247 /** The dialog action parameter. */ 248 private String m_paramAction; 249 250 /** The close link parameter. */ 251 private String m_paramCloseLink; 252 253 /** The dialog type. */ 254 private String m_paramDialogtype; 255 256 /** The frame name parameter. */ 257 private String m_paramFrameName; 258 259 /** The is popup parameter. */ 260 private String m_paramIsPopup; 261 262 /** The messages parameter. */ 263 private String m_paramMessage; 264 265 /** The original parameters. */ 266 private String m_paramOriginalParams; 267 268 /** The pre action done parameter. */ 269 private String m_paramPreActionDone; 270 271 /** The redirect parameter. */ 272 private String m_paramRedirect; 273 274 /** The resource parameter. */ 275 private String m_paramResource; 276 277 /** The title parameter. */ 278 private String m_paramTitle; 279 280 /** 281 * Public constructor with JSP action element.<p> 282 * 283 * @param jsp an initialized JSP action element 284 */ 285 public CmsDialog(CmsJspActionElement jsp) { 286 287 super(jsp); 288 } 289 290 /** 291 * Public constructor with JSP variables.<p> 292 * 293 * @param context the JSP page context 294 * @param req the JSP request 295 * @param res the JSP response 296 */ 297 public CmsDialog(PageContext context, HttpServletRequest req, HttpServletResponse res) { 298 299 this(new CmsJspActionElement(context, req, res)); 300 } 301 302 /** 303 * Returns an initialized CmsDialog instance that is read from the request attributes.<p> 304 * 305 * This method is used by dialog elements. 306 * The dialog elements do not initialize their own workplace class, 307 * but use the initialized instance of the "master" class. 308 * This is required to ensure that parameters of the "master" class 309 * can properly be kept on the dialog elements.<p> 310 * 311 * To prevent null pointer exceptions, an empty dialog is returned if 312 * nothing is found in the request attributes.<p> 313 * 314 * @param context the JSP page context 315 * @param req the JSP request 316 * @param res the JSP response 317 * 318 * @return an initialized CmsDialog instance that is read from the request attributes 319 */ 320 public static CmsDialog initCmsDialog(PageContext context, HttpServletRequest req, HttpServletResponse res) { 321 322 CmsDialog wp = (CmsDialog)req.getAttribute(CmsWorkplace.SESSION_WORKPLACE_CLASS); 323 if (wp == null) { 324 // ensure that we don't get null pointers if the page is directly called 325 wp = new CmsDialog(new CmsJspActionElement(context, req, res)); 326 wp.fillParamValues(req); 327 } 328 return wp; 329 } 330 331 /** 332 * Used to close the current JSP dialog.<p> 333 * 334 * This method tries to include the URI stored in the workplace settings. 335 * This URI is determined by the frame name, which has to be set 336 * in the frame name parameter.<p> 337 * 338 * @throws JspException if including an element fails 339 */ 340 public void actionCloseDialog() throws JspException { 341 342 // create a map with empty "resource" parameter to avoid changing the folder when returning to explorer file list 343 Map<String, String> params = new HashMap<String, String>(); 344 params.put(PARAM_RESOURCE, ""); 345 if (isPopup()) { 346 JspWriter out = getJsp().getJspContext().getOut(); 347 try { 348 // try to close the popup 349 350 out.write("<html><head></head>\n"); 351 out.write("<body onload=\"top.close();\">\n"); 352 out.write("</body>\n"); 353 out.write("</html>\n"); 354 } catch (IOException e) { 355 // error redirecting, include explorer file list 356 getJsp().include(FILE_EXPLORER_FILELIST, null, params); 357 } finally { 358 try { 359 out.close(); 360 } catch (IOException e) { 361 throw new JspException(e.getMessage(), e); 362 } 363 } 364 } else if (getParamCloseLink() != null) { 365 // close link parameter present 366 try { 367 if (CmsLinkManager.isWorkplaceLink(getParamCloseLink())) { 368 // in case the close link points to the new workplace, make sure to set the new location on the top frame 369 openWorkplaceLink(getParamCloseLink()); 370 } else if (Boolean.valueOf(getParamRedirect()).booleanValue()) { 371 // redirect parameter is true, redirect to given close link 372 getJsp().getResponse().sendRedirect(getParamCloseLink()); 373 } else { 374 // forward JSP 375 if (!isForwarded()) { 376 setForwarded(true); 377 CmsRequestUtil.forwardRequest( 378 getParamCloseLink(), 379 getJsp().getRequest(), 380 getJsp().getResponse()); 381 } 382 } 383 } catch (Exception e) { 384 // forward failed 385 throw new JspException(e.getMessage(), e); 386 } 387 } else if (getParamFramename() != null) { 388 // no workplace frame mode (currently used for galleries) 389 // frame name parameter found, get URI 390 String frameUri = getSettings().getFrameUris().get(getParamFramename()); 391 // resetting the action parameter 392 params.put(PARAM_ACTION, ""); 393 if (frameUri != null) { 394 // URI found, include it 395 // remove context path from URI before inclusion 396 frameUri = CmsLinkManager.removeOpenCmsContext(frameUri); 397 // include the found frame URI 398 getJsp().include(frameUri, null, params); 399 } else { 400 // no URI found, include the explorer file list 401 openLaunchpad(); 402 } 403 } else { 404 // no frame name parameter found, include the explorer file list 405 openLaunchpad(); 406 } 407 } 408 409 /** 410 * Returns the html code to build the ajax report container.<p> 411 * 412 * @param title the title of the report box 413 * 414 * @return html code 415 */ 416 public String buildAjaxResultContainer(String title) { 417 418 StringBuffer html = new StringBuffer(512); 419 html.append(dialogBlockStart(title)); 420 html.append(dialogWhiteBoxStart()); 421 html.append("<div id='ajaxreport' >"); 422 html.append(buildAjaxWaitMessage()); 423 html.append("</div>\n"); 424 html.append(dialogWhiteBoxEnd()); 425 html.append(dialogBlockEnd()); 426 html.append(" <br>\n"); 427 return html.toString(); 428 } 429 430 /** 431 * Override to display additional options in the lock dialog.<p> 432 * 433 * @return html code to display additional options 434 */ 435 public String buildLockAdditionalOptions() { 436 437 return ""; 438 } 439 440 /** 441 * Returns the html code to build the confirmation messages.<p> 442 * 443 * @return html code 444 */ 445 public String buildLockConfirmationMessageJS() { 446 447 StringBuffer html = new StringBuffer(512); 448 html.append("<script ><!--\n"); 449 html.append("function setConfirmationMessage(locks, blockinglocks) {\n"); 450 html.append("\tvar confMsg = document.getElementById('conf-msg');\n"); 451 html.append("\tif (locks > -1) {\n"); 452 html.append("\t\tif (blockinglocks > '0') {\n"); 453 html.append("\t\t\tshowAjaxReportContent();\n"); 454 html.append("\t\t\tdocument.getElementById('lock-body-id').className = '';\n"); 455 html.append("\t\t\tdocument.getElementById('butClose').className = '';\n"); 456 html.append("\t\t\tdocument.getElementById('butContinue').className = 'hide';\n"); 457 html.append("\t\t\tconfMsg.innerHTML = '"); 458 html.append(key(org.opencms.workplace.commons.Messages.GUI_OPERATION_BLOCKING_LOCKS_0)); 459 html.append("';\n"); 460 html.append("\t\t} else {\n"); 461 html.append("\t\t\tsubmitAction('"); 462 html.append(CmsDialog.DIALOG_OK); 463 html.append("', null, 'main');\n"); 464 html.append("\t\t\tdocument.forms['main'].submit();\n"); 465 html.append("\t\t}\n"); 466 html.append("\t} else {\n"); 467 html.append("\t\tdocument.getElementById('butClose').className = '';\n"); 468 html.append("\t\tdocument.getElementById('butContinue').className = 'hide';\n"); 469 html.append("\t\tconfMsg.innerHTML = '"); 470 html.append(key(Messages.GUI_AJAX_REPORT_WAIT_0)); 471 html.append("';\n"); 472 html.append("\t}\n"); 473 html.append("}\n"); 474 html.append("// -->\n"); 475 html.append("</script>\n"); 476 return html.toString(); 477 } 478 479 /** 480 * Returns the html code to build the header box.<p> 481 * 482 * @return html code 483 * 484 * @throws CmsException if something goes wrong 485 */ 486 public String buildLockHeaderBox() throws CmsException { 487 488 StringBuffer html = new StringBuffer(512); 489 // include resource info 490 html.append(dialogBlockStart(null)); 491 html.append(key(org.opencms.workplace.commons.Messages.GUI_LABEL_TITLE_0)); 492 html.append(": "); 493 html.append(getJsp().property("Title", getParamResource(), "")); 494 html.append("<br>\n"); 495 html.append(key(org.opencms.workplace.commons.Messages.GUI_LABEL_STATE_0)); 496 html.append(": "); 497 html.append(getState()); 498 html.append("<br>\n"); 499 html.append(key(org.opencms.workplace.commons.Messages.GUI_LABEL_PERMALINK_0)); 500 html.append(": "); 501 html.append(OpenCms.getLinkManager().getPermalink(getCms(), getParamResource())); 502 html.append(dialogBlockEnd()); 503 return html.toString(); 504 } 505 506 /** 507 * Builds the outer dialog window border.<p> 508 * 509 * @param segment the HTML segment (START / END) 510 * @param attributes optional additional attributes for the opening dialog table 511 * 512 * @return a dialog window start / end segment 513 */ 514 public String dialog(int segment, String attributes) { 515 516 if (segment == HTML_START) { 517 StringBuffer html = new StringBuffer(512); 518 if (useNewStyle()) { 519 html.append(dialogTitle()); 520 } 521 html.append("<table class=\"dialog\" cellpadding=\"0\" cellspacing=\"0\""); 522 if (attributes != null) { 523 html.append(" "); 524 html.append(attributes); 525 } 526 html.append("><tr><td>\n<table class=\"dialogbox\" cellpadding=\"0\" cellspacing=\"0\">\n"); 527 html.append("<tr><td>\n"); 528 if (useNewStyle() && getToolManager().hasToolPathForUrl(getJsp().getRequestContext().getUri())) { 529 html.append(getAdminTool().groupHtml(this)); 530 } 531 return html.toString(); 532 } else { 533 return "</td></tr></table>\n</td></tr></table>\n<p> </p>\n"; 534 } 535 } 536 537 /** 538 * Builds a block with 3D border and optional subheadline in the dialog content area.<p> 539 * 540 * @param segment the HTML segment (START / END) 541 * @param headline the headline String for the block 542 * @param error if true, an error block will be created 543 * 544 * @return 3D block start / end segment 545 */ 546 public String dialogBlock(int segment, String headline, boolean error) { 547 548 if (segment == HTML_START) { 549 StringBuffer result = new StringBuffer(512); 550 String errorStyle = ""; 551 if (error) { 552 errorStyle = " dialogerror"; 553 } 554 result.append("<!-- 3D block start -->\n"); 555 result.append("<fieldset class=\"dialogblock\">\n"); 556 if (CmsStringUtil.isNotEmpty(headline)) { 557 result.append("<legend>"); 558 result.append("<span class=\"textbold"); 559 result.append(errorStyle); 560 result.append("\" unselectable=\"on\">"); 561 result.append(headline); 562 result.append("</span></legend>\n"); 563 } 564 return result.toString(); 565 } else { 566 return "</fieldset>\n<!-- 3D block end -->\n"; 567 } 568 } 569 570 /** 571 * Builds the end HTML for a block with 3D border in the dialog content area.<p> 572 * 573 * @return 3D block start / end segment 574 */ 575 public String dialogBlockEnd() { 576 577 return dialogBlock(HTML_END, null, false); 578 } 579 580 /** 581 * Builds the start HTML for a block with 3D border and optional subheadline in the dialog content area.<p> 582 * 583 * @param headline the headline String for the block 584 * 585 * @return 3D block start / end segment 586 */ 587 public String dialogBlockStart(String headline) { 588 589 return dialogBlock(HTML_START, headline, false); 590 } 591 592 /** 593 * Builds the button row under the dialog content area without the buttons.<p> 594 * 595 * @param segment the HTML segment (START / END) 596 * 597 * @return the button row start / end segment 598 */ 599 public String dialogButtonRow(int segment) { 600 601 if (segment == HTML_START) { 602 return "<!-- button row start -->\n<div class=\"dialogbuttons\" unselectable=\"on\">\n"; 603 } else { 604 return "</div>\n<!-- button row end -->\n"; 605 } 606 } 607 608 /** 609 * Builds the end of the button row under the dialog content area without the buttons.<p> 610 * 611 * @return the button row end segment 612 */ 613 public String dialogButtonRowEnd() { 614 615 return dialogButtonRow(HTML_END); 616 } 617 618 /** 619 * Builds the start of the button row under the dialog content area without the buttons.<p> 620 * 621 * @return the button row start segment 622 */ 623 public String dialogButtonRowStart() { 624 625 return dialogButtonRow(HTML_START); 626 } 627 628 /** 629 * Builds the html for the button row under the dialog content area, including buttons.<p> 630 * 631 * @param buttons array of constants of which buttons to include in the row 632 * @param attributes array of Strings for additional button attributes 633 * 634 * @return the html for the button row under the dialog content area, including buttons 635 */ 636 public String dialogButtons(int[] buttons, String[] attributes) { 637 638 StringBuffer result = new StringBuffer(256); 639 result.append(dialogButtonRow(HTML_START)); 640 for (int i = 0; i < buttons.length; i++) { 641 dialogButtonsHtml(result, buttons[i], attributes[i]); 642 } 643 result.append(dialogButtonRow(HTML_END)); 644 return result.toString(); 645 } 646 647 /** 648 * Builds a button row with a single "close" button.<p> 649 * 650 * @return the button row 651 */ 652 public String dialogButtonsClose() { 653 654 return dialogButtons(new int[] {BUTTON_CLOSE}, new String[1]); 655 } 656 657 /** 658 * Builds a button row with a single "close" button.<p> 659 * 660 * @param closeAttribute additional attributes for the "close" button 661 * 662 * @return the button row 663 */ 664 public String dialogButtonsClose(String closeAttribute) { 665 666 return dialogButtons(new int[] {BUTTON_CLOSE}, new String[] {closeAttribute}); 667 } 668 669 /** 670 * Builds a button row with a "close" and a "details" button.<p> 671 * 672 * @param closeAttribute additional attributes for the "close" button 673 * @param detailsAttribute additional attributes for the "details" button 674 * 675 * @return the button row 676 */ 677 public String dialogButtonsCloseDetails(String closeAttribute, String detailsAttribute) { 678 679 return dialogButtons(new int[] {BUTTON_CLOSE, BUTTON_DETAILS}, new String[] {closeAttribute, detailsAttribute}); 680 } 681 682 /** 683 * Builds a button row with a single "ok" button.<p> 684 * 685 * @return the button row 686 */ 687 public String dialogButtonsOk() { 688 689 return dialogButtons(new int[] {BUTTON_OK}, new String[1]); 690 } 691 692 /** 693 * Builds a button row with a single "ok" button.<p> 694 * 695 * @param okAttribute additional attributes for the "ok" button 696 * 697 * @return the button row 698 */ 699 public String dialogButtonsOk(String okAttribute) { 700 701 return dialogButtons(new int[] {BUTTON_OK}, new String[] {okAttribute}); 702 } 703 704 /** 705 * Builds a button row with an "ok" and a "cancel" button.<p> 706 * 707 * @return the button row 708 */ 709 public String dialogButtonsOkCancel() { 710 711 return dialogButtons(new int[] {BUTTON_OK, BUTTON_CANCEL}, new String[2]); 712 } 713 714 /** 715 * Builds a button row with an "ok" and a "cancel" button.<p> 716 * 717 * @param okAttributes additional attributes for the "ok" button 718 * @param cancelAttributes additional attributes for the "cancel" button 719 * 720 * @return the button row 721 */ 722 public String dialogButtonsOkCancel(String okAttributes, String cancelAttributes) { 723 724 return dialogButtons(new int[] {BUTTON_OK, BUTTON_CANCEL}, new String[] {okAttributes, cancelAttributes}); 725 } 726 727 /** 728 * Builds a button row with an "ok", a "cancel" and an "advanced" button.<p> 729 * 730 * @param okAttributes additional attributes for the "ok" button 731 * @param cancelAttributes additional attributes for the "cancel" button 732 * @param advancedAttributes additional attributes for the "advanced" button 733 * 734 * @return the button row 735 */ 736 public String dialogButtonsOkCancelAdvanced( 737 String okAttributes, 738 String cancelAttributes, 739 String advancedAttributes) { 740 741 return dialogButtons( 742 new int[] {BUTTON_OK, BUTTON_CANCEL, BUTTON_ADVANCED}, 743 new String[] {okAttributes, cancelAttributes, advancedAttributes}); 744 } 745 746 /** 747 * Builds a button row with a "set", an "ok", and a "cancel" button.<p> 748 * 749 * @param setAttributes additional attributes for the "set" button 750 * @param okAttributes additional attributes for the "ok" button 751 * @param cancelAttributes additional attributes for the "cancel" button 752 * 753 * @return the button row 754 */ 755 public String dialogButtonsSetOkCancel(String setAttributes, String okAttributes, String cancelAttributes) { 756 757 return dialogButtons( 758 new int[] {BUTTON_SET, BUTTON_OK, BUTTON_CANCEL}, 759 new String[] {setAttributes, okAttributes, cancelAttributes}); 760 } 761 762 /** 763 * Builds the content area of the dialog window.<p> 764 * 765 * @param segment the HTML segment (START / END) 766 * @param title the title String for the dialog window 767 * 768 * @return a content area start / end segment 769 */ 770 public String dialogContent(int segment, String title) { 771 772 if (segment == HTML_START) { 773 StringBuffer result = new StringBuffer(512); 774 // null title is ok, we always want the title headline 775 result.append(dialogHead(title)); 776 result.append("<div class=\"dialogcontent\" unselectable=\"on\">\n"); 777 result.append("<!-- dialogcontent start -->\n"); 778 return result.toString(); 779 } else { 780 return "<!-- dialogcontent end -->\n</div>\n"; 781 } 782 } 783 784 /** 785 * Returns the end html for the content area of the dialog window.<p> 786 * 787 * @return the end html for the content area of the dialog window 788 */ 789 public String dialogContentEnd() { 790 791 return dialogContent(HTML_END, null); 792 } 793 794 /** 795 * Returns the start html for the content area of the dialog window.<p> 796 * 797 * @param title the title for the dialog 798 * 799 * @return the start html for the content area of the dialog window 800 */ 801 public String dialogContentStart(String title) { 802 803 return dialogContent(HTML_START, title); 804 } 805 806 /** 807 * Returns the end html for the outer dialog window border.<p> 808 * 809 * @return the end html for the outer dialog window border 810 */ 811 public String dialogEnd() { 812 813 return dialog(HTML_END, null); 814 } 815 816 /** 817 * Builds the title of the dialog window.<p> 818 * 819 * @param title the title String for the dialog window 820 * 821 * @return the HTML title String for the dialog window 822 */ 823 public String dialogHead(String title) { 824 825 String escapedTitle; 826 if (title == null) { 827 escapedTitle = ""; 828 } else { 829 escapedTitle = CmsEncoder.escapeHtml(title); 830 } 831 832 return "<div class=\"dialoghead\" unselectable=\"on\">" + escapedTitle + "</div>"; 833 } 834 835 /** 836 * Builds an invisible horizontal spacer with the specified width.<p> 837 * 838 * @param width the width of the spacer in pixels 839 * 840 * @return an invisible horizontal spacer with the specified width 841 */ 842 public String dialogHorizontalSpacer(int width) { 843 844 return "<td><span style=\"display:block; height: 1px; width: " + width + "px;\"></span></td>"; 845 } 846 847 /** 848 * Builds the necessary button row.<p> 849 * 850 * @return the button row 851 */ 852 public String dialogLockButtons() { 853 854 StringBuffer html = new StringBuffer(512); 855 html.append("<div id='butClose' >\n"); 856 html.append(dialogButtonsClose()); 857 html.append("</div>\n"); 858 html.append("<div id='butContinue' class='hide' >\n"); 859 html.append( 860 dialogButtons( 861 new int[] {BUTTON_CONTINUE, BUTTON_CANCEL}, 862 new String[] {" onclick=\"submitAction('" + DIALOG_OK + "', form); form.submit();\"", ""})); 863 html.append("</div>\n"); 864 return html.toString(); 865 } 866 867 /** 868 * Builds a dialog line without break (display: block).<p> 869 * 870 * @param segment the HTML segment (START / END) 871 * 872 * @return a row start / end segment 873 */ 874 public String dialogRow(int segment) { 875 876 if (segment == HTML_START) { 877 return "<div class=\"dialogrow\">"; 878 } else { 879 return "</div>\n"; 880 } 881 } 882 883 /** 884 * Builds the end of a dialog line without break (display: block).<p> 885 * 886 * @return the row end segment 887 */ 888 public String dialogRowEnd() { 889 890 return dialogRow(HTML_END); 891 } 892 893 /** 894 * Builds the start of a dialog line without break (display: block).<p> 895 * 896 * @return the row start segment 897 */ 898 public String dialogRowStart() { 899 900 return dialogRow(HTML_START); 901 } 902 903 /** 904 * Builds the standard javascript for submitting the dialog.<p> 905 * 906 * @return the standard javascript for submitting the dialog 907 */ 908 @Override 909 public String dialogScriptSubmit() { 910 911 if (useNewStyle()) { 912 return super.dialogScriptSubmit(); 913 } 914 StringBuffer result = new StringBuffer(512); 915 result.append("function submitAction(actionValue, theForm, formName) {\n"); 916 result.append("\tif (theForm == null) {\n"); 917 result.append("\t\ttheForm = document.forms[formName];\n"); 918 result.append("\t}\n"); 919 result.append("\ttheForm." + PARAM_FRAMENAME + ".value = window.name;\n"); 920 result.append("\tif (actionValue == \"" + DIALOG_OK + "\") {\n"); 921 result.append("\t\treturn true;\n"); 922 result.append("\t}\n"); 923 result.append("\ttheForm." + PARAM_ACTION + ".value = actionValue;\n"); 924 result.append("\ttheForm.submit();\n"); 925 result.append("\treturn false;\n"); 926 result.append("}\n"); 927 928 return result.toString(); 929 } 930 931 /** 932 * Builds a horizontal separator line in the dialog content area.<p> 933 * 934 * @return a separator element 935 */ 936 public String dialogSeparator() { 937 938 return "<div class=\"dialogseparator\" unselectable=\"on\"></div>"; 939 } 940 941 /** 942 * Builds a space between two elements in the dialog content area.<p> 943 * 944 * @return a space element 945 */ 946 public String dialogSpacer() { 947 948 return "<div class=\"dialogspacer\" unselectable=\"on\"> </div>"; 949 } 950 951 /** 952 * Returns the start html for the outer dialog window border.<p> 953 * 954 * @return the start html for the outer dialog window border 955 */ 956 public String dialogStart() { 957 958 return dialog(HTML_START, null); 959 } 960 961 /** 962 * Returns the start html for the outer dialog window border.<p> 963 * 964 * @param attributes optional html attributes to insert 965 * 966 * @return the start html for the outer dialog window border 967 */ 968 public String dialogStart(String attributes) { 969 970 return dialog(HTML_START, attributes); 971 } 972 973 /** 974 * Builds a subheadline in the dialog content area.<p> 975 * 976 * @param headline the desired headline string 977 * 978 * @return a subheadline element 979 */ 980 public String dialogSubheadline(String headline) { 981 982 StringBuffer retValue = new StringBuffer(128); 983 retValue.append("<div class=\"dialogsubheader\" unselectable=\"on\">"); 984 retValue.append(headline); 985 retValue.append("</div>\n"); 986 return retValue.toString(); 987 } 988 989 /** 990 * Builds the HTML code to fold and unfold a white-box.<p> 991 * 992 * @param headline the heading to display 993 * @param id the id of the toggle 994 * @param show true if the white box is open at the beginning 995 * 996 * @return HTML code to fold and unfold a white-box 997 */ 998 public String dialogToggleStart(String headline, String id, boolean show) { 999 1000 StringBuffer result = new StringBuffer(512); 1001 // set icon and style class to use: hide user permissions 1002 String image = "plus.png"; 1003 String styleClass = "hide"; 1004 if (show) { 1005 // show user permissions 1006 image = "minus.png"; 1007 styleClass = "show"; 1008 } 1009 1010 result.append("<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n"); 1011 result.append("<tr>\n"); 1012 result.append( 1013 "\t<td style=\"vertical-align: bottom; padding-bottom: 2px;\"><a href=\"javascript:toggleDetail('"); 1014 result.append(id); 1015 result.append("');\"><img src=\""); 1016 result.append(getSkinUri()); 1017 result.append("commons/"); 1018 result.append(image); 1019 result.append("\" class=\"noborder\" id=\"ic-"); 1020 result.append(id); 1021 result.append("\"></a></td>\n"); 1022 result.append("\t<td>"); 1023 result.append(dialogSubheadline(headline)); 1024 result.append("</td>\n"); 1025 result.append("</tr>\n"); 1026 result.append("</table>\n"); 1027 1028 result.append("<div class=\""); 1029 result.append(styleClass); 1030 result.append("\" id=\""); 1031 result.append(id); 1032 result.append("\">\n"); 1033 return result.toString(); 1034 } 1035 1036 /** 1037 * Builds a white box in the dialog content area.<p> 1038 * 1039 * @param segment the HTML segment (START / END) 1040 * 1041 * @return the white box start / end segment 1042 */ 1043 public String dialogWhiteBox(int segment) { 1044 1045 if (segment == HTML_START) { 1046 return "<!-- white box start -->\n" 1047 + "<div class=\"dialoginnerboxborder\">\n" 1048 + "<div class=\"dialoginnerbox\" unselectable=\"off\">\n"; 1049 } else { 1050 return "</div>\n</div>\n<!-- white box end -->\n"; 1051 } 1052 } 1053 1054 /** 1055 * Builds the end of a white box in the dialog content area.<p> 1056 * 1057 * @return the white box end segment 1058 */ 1059 public String dialogWhiteBoxEnd() { 1060 1061 return dialogWhiteBox(HTML_END); 1062 } 1063 1064 /** 1065 * Builds the start of a white box in the dialog content area.<p> 1066 * 1067 * @return the white box start segment 1068 */ 1069 public String dialogWhiteBoxStart() { 1070 1071 return dialogWhiteBox(HTML_START); 1072 } 1073 1074 /** 1075 * Returns the action value.<p> 1076 * 1077 * The action value is used on JSP pages to select the proper action 1078 * in a large "switch" statement.<p> 1079 * 1080 * @return the action value 1081 */ 1082 public int getAction() { 1083 1084 return m_action; 1085 } 1086 1087 /** 1088 * Returns the action to be carried out after a click on the cancel button..<p> 1089 * 1090 * @return the action to be carried out after a click on the cancel button. 1091 */ 1092 public String getCancelAction() { 1093 1094 return DIALOG_CANCEL; 1095 } 1096 1097 /** 1098 * Returns the http URI of the current dialog, to be used 1099 * as value for the "action" attribute of a html form.<p> 1100 * 1101 * This URI is the real one.<p> 1102 * 1103 * @return the http URI of the current dialog 1104 */ 1105 public String getDialogRealUri() { 1106 1107 return getJsp().link(getJsp().getRequestContext().getUri()); 1108 } 1109 1110 /** 1111 * Returns the http URI of the current dialog, to be used 1112 * as value for the "action" attribute of a html form.<p> 1113 * 1114 * This URI could not be really the real one... <p> 1115 * 1116 * @return the http URI of the current dialog 1117 */ 1118 public String getDialogUri() { 1119 1120 if (!useNewStyle()) { 1121 return getDialogRealUri(); 1122 } else { 1123 return CmsToolManager.linkForToolPath(getJsp(), getCurrentToolPath()); 1124 } 1125 } 1126 1127 /** 1128 * Returns the custom mapping for the online help.<p> 1129 * 1130 * @return the custom mapping for the online help 1131 */ 1132 public String getOnlineHelpUriCustom() { 1133 1134 if (m_onlineHelpUriCustom == null) { 1135 return null; 1136 } 1137 StringBuffer result = new StringBuffer(m_onlineHelpUriCustom.length() + 4); 1138 result.append("\""); 1139 result.append(m_onlineHelpUriCustom); 1140 result.append("\""); 1141 return result.toString(); 1142 } 1143 1144 /** 1145 * Returns the value of the action parameter, 1146 * or null if this parameter was not provided.<p> 1147 * 1148 * The action parameter is very important, 1149 * it will select the dialog action to perform. 1150 * The value of the {@link #getAction()} method will be 1151 * initialized from the action parameter.<p> 1152 * 1153 * @return the value of the action parameter 1154 */ 1155 public String getParamAction() { 1156 1157 return m_paramAction; 1158 } 1159 1160 /** 1161 * Returns the value of the close link parameter, 1162 * or null if this parameter was not provided.<p> 1163 * 1164 * @return the value of the close link parameter 1165 */ 1166 public String getParamCloseLink() { 1167 1168 if ((m_paramCloseLink == null) || "null".equals(m_paramCloseLink)) { 1169 return null; 1170 } 1171 return m_paramCloseLink; 1172 } 1173 1174 /** 1175 * Returns the value of the dialog type parameter, 1176 * or null if this parameter was not provided.<p> 1177 * 1178 * This parameter is very important. 1179 * It must match to the localization keys, 1180 * e.g. "copy" for the copy dialog.<p> 1181 * 1182 * This parameter must be set manually by the subclass during 1183 * first initialization.<p> 1184 * 1185 * @return the value of the dialog type parameter 1186 */ 1187 public String getParamDialogtype() { 1188 1189 return m_paramDialogtype; 1190 } 1191 1192 /** 1193 * Returns the value of the frame name parameter.<p> 1194 * 1195 * @return the value of the frame name parameter 1196 */ 1197 public String getParamFramename() { 1198 1199 if ((m_paramFrameName != null) && !"null".equals(m_paramFrameName)) { 1200 return m_paramFrameName; 1201 } else { 1202 return null; 1203 } 1204 } 1205 1206 /** 1207 * Returns the is popup parameter.<p> 1208 * 1209 * Use this parameter to indicate that the dialog is shown in a popup window.<p> 1210 * 1211 * @return the is popup parameter 1212 */ 1213 public String getParamIsPopup() { 1214 1215 return m_paramIsPopup; 1216 } 1217 1218 /** 1219 * Returns the value of the message parameter, 1220 * or null if this parameter was not provided.<p> 1221 * 1222 * The message parameter is used on dialogs to 1223 * show any text message.<p> 1224 * 1225 * @return the value of the message parameter 1226 */ 1227 public String getParamMessage() { 1228 1229 return m_paramMessage; 1230 } 1231 1232 /** 1233 * Returns the value of the original parameters parameter.<p> 1234 * 1235 * This stores the request parameter values from a previous dialog, if necessary.<p> 1236 * 1237 * @return the value of the original parameters parameter 1238 */ 1239 public String getParamOriginalParams() { 1240 1241 return m_paramOriginalParams; 1242 } 1243 1244 /** 1245 * Returns the value of the preaction done parameter.<p> 1246 * 1247 * @return the value of the preaction done parameter 1248 */ 1249 public String getParamPreActionDone() { 1250 1251 return m_paramPreActionDone; 1252 } 1253 1254 /** 1255 * Returns the value of the redirect flag parameter.<p> 1256 * 1257 * @return the value of the redirect flag parameter 1258 */ 1259 public String getParamRedirect() { 1260 1261 return m_paramRedirect; 1262 } 1263 1264 /** 1265 * Returns the value of the file parameter, 1266 * or null if this parameter was not provided.<p> 1267 * 1268 * The file parameter selects the file on which the dialog action 1269 * is to be performed.<p> 1270 * 1271 * @return the value of the file parameter 1272 */ 1273 public String getParamResource() { 1274 1275 if ((m_paramResource != null) && !"null".equals(m_paramResource)) { 1276 return m_paramResource; 1277 } else { 1278 return null; 1279 } 1280 } 1281 1282 /** 1283 * Returns the value of the title parameter, 1284 * or null if this parameter was not provided.<p> 1285 * 1286 * This parameter is used to build the title 1287 * of the dialog. It is a parameter so that the title 1288 * can be passed to included elements.<p> 1289 * 1290 * @return the value of the title parameter 1291 */ 1292 public String getParamTitle() { 1293 1294 return m_paramTitle; 1295 } 1296 1297 /** 1298 * Gets a formatted file state string.<p> 1299 * 1300 * @return formatted state string 1301 * 1302 * @throws CmsException if something goes wrong 1303 */ 1304 public String getState() throws CmsException { 1305 1306 if (CmsStringUtil.isNotEmpty(getParamResource())) { 1307 CmsResource file = getCms().readResource(getParamResource(), CmsResourceFilter.ALL); 1308 if (getCms().isInsideCurrentProject(getParamResource())) { 1309 return key(Messages.getStateKey(file.getState())); 1310 } else { 1311 return key(Messages.GUI_EXPLORER_STATENIP_0); 1312 } 1313 } 1314 return "+++ resource parameter not found +++"; 1315 } 1316 1317 /** 1318 * Checks if the current resource has lock state exclusive or inherited.<p> 1319 * 1320 * This is used to determine whether the dialog shows the option to delete all 1321 * siblings of the resource or not. 1322 * 1323 * @return true if lock state is exclusive or inherited, otherwise false 1324 */ 1325 public boolean hasCorrectLockstate() { 1326 1327 org.opencms.lock.CmsLock lock = null; 1328 try { 1329 // get the lock state for the current resource 1330 lock = getCms().getLock(getParamResource()); 1331 } catch (CmsException e) { 1332 // error getting lock state, log the error and return false 1333 LOG.error(e.getLocalizedMessage(getLocale()), e); 1334 return false; 1335 } 1336 // check if auto lock feature is enabled 1337 boolean autoLockFeature = lock.isNullLock() && OpenCms.getWorkplaceManager().autoLockResources(); 1338 return autoLockFeature || lock.isExclusive() || lock.isInherited(); 1339 } 1340 1341 /** 1342 * Checks if this resource has siblings.<p> 1343 * 1344 * @return true if this resource has siblings 1345 */ 1346 public boolean hasSiblings() { 1347 1348 try { 1349 return getCms().readResource(getParamResource(), CmsResourceFilter.ALL).getSiblingCount() > 1; 1350 } catch (CmsException e) { 1351 LOG.error(e.getLocalizedMessage(getLocale()), e); 1352 return false; 1353 } 1354 1355 } 1356 1357 /** 1358 * Builds the start html of the page, including setting of DOCTYPE and 1359 * inserting a header with the content-type.<p> 1360 * 1361 * @return the start html of the page 1362 */ 1363 public String htmlStart() { 1364 1365 return pageHtml(HTML_START, null); 1366 } 1367 1368 /** 1369 * Builds the start html of the page, including setting of DOCTYPE and 1370 * inserting a header with the content-type.<p> 1371 * 1372 * This overloads the default method of the parent class.<p> 1373 * 1374 * @param helpUrl the key for the online help to include on the page 1375 * 1376 * @return the start html of the page 1377 */ 1378 @Override 1379 public String htmlStart(String helpUrl) { 1380 1381 return pageHtml(HTML_START, helpUrl); 1382 } 1383 1384 /** 1385 * Builds the start html of the page, including setting of DOCTYPE and 1386 * inserting a header with the content-type.<p> 1387 * 1388 * @param helpUrl the key for the online help to include on the page 1389 * @param title the title for the page 1390 * 1391 * @return the start html of the page 1392 */ 1393 public String htmlStart(String helpUrl, String title) { 1394 1395 return pageHtml(HTML_START, helpUrl, title); 1396 } 1397 1398 /** 1399 * Builds the start html of the page, including setting of DOCTYPE, 1400 * inserting a header with the content-type and choosing an individual style sheet.<p> 1401 * 1402 * @param title the title for the page 1403 * @param stylesheet the style sheet to include 1404 * 1405 * @return the start html of the page 1406 */ 1407 public String htmlStartStyle(String title, String stylesheet) { 1408 1409 return pageHtmlStyle(HTML_START, title, stylesheet); 1410 } 1411 1412 /** 1413 * Displays the throwable on the error page and logs the error.<p> 1414 * 1415 * @param wp the workplace class 1416 * @param t the throwable to be displayed on the error page 1417 * 1418 * @throws JspException if the include of the error page jsp fails 1419 */ 1420 public void includeErrorpage(CmsWorkplace wp, Throwable t) throws JspException { 1421 1422 CmsLog.getLog(wp).error(Messages.get().getBundle().key(Messages.ERR_WORKPLACE_DIALOG_0), t); 1423 getJsp().getRequest().setAttribute(SESSION_WORKPLACE_CLASS, wp); 1424 getJsp().getRequest().setAttribute(ATTRIBUTE_THROWABLE, t); 1425 getJsp().include(FILE_DIALOG_SCREEN_ERRORPAGE); 1426 } 1427 1428 /** 1429 * Returns the "isPopup" flag.<p> 1430 * 1431 * @return the "isPopup" flag 1432 */ 1433 public boolean isPopup() { 1434 1435 return Boolean.valueOf(getParamIsPopup()).booleanValue(); 1436 } 1437 1438 /** 1439 * Returns if the dialog is called in direct edit mode before the editor is opened.<p> 1440 * 1441 * @return true if the dialog is called in direct edit mode before the editor is opened 1442 */ 1443 public boolean isPreEditor() { 1444 1445 return CmsPreEditorAction.isPreEditorMode(this); 1446 } 1447 1448 /** 1449 * Builds the start html of the page, including setting of DOCTYPE and 1450 * inserting a header with the content-type.<p> 1451 * 1452 * This overloads the default method of the parent class.<p> 1453 * 1454 * @param segment the HTML segment (START / END) 1455 * @param helpUrl the url for the online help to include on the page 1456 * 1457 * @return the start html of the page 1458 */ 1459 @Override 1460 public String pageHtml(int segment, String helpUrl) { 1461 1462 return pageHtml(segment, helpUrl, null); 1463 } 1464 1465 /** 1466 * Builds the start html of the page, including setting of DOCTYPE and 1467 * inserting a header with the content-type.<p> 1468 * 1469 * This overloads the default method of the parent class.<p> 1470 * 1471 * @param segment the HTML segment (START / END) 1472 * @param helpUrl the url for the online help to include on the page 1473 * @param title the title for the page 1474 * 1475 * @return the start html of the page 1476 */ 1477 public String pageHtml(int segment, String helpUrl, String title) { 1478 1479 if (segment == HTML_START) { 1480 String stylesheet = null; 1481 if (isPopup() && !useNewStyle()) { 1482 stylesheet = "popup.css"; 1483 } 1484 StringBuffer result = new StringBuffer(pageHtmlStyle(segment, title, stylesheet)); 1485 if (getSettings().isViewExplorer()) { 1486 result.append("<script src=\""); 1487 result.append(getSkinUri()); 1488 result.append("commons/explorer.js\"></script>\n"); 1489 } 1490 result.append("<script >\n"); 1491 result.append(dialogScriptSubmit()); 1492 if (helpUrl != null) { 1493 result.append("if (top.head && top.head.helpUrl) {\n"); 1494 result.append("\ttop.head.helpUrl=\""); 1495 result.append(helpUrl + "\";\n"); 1496 result.append("}\n\n"); 1497 } 1498 // the variable that may be set as path: if non-null this will be 1499 // used as path for the online help window. This is needed because there are pages 1500 // e.g. /administration/accounts/users/new that perform a jsp - forward while leaving the 1501 // path parameter on the old page: no correct online help possible. 1502 result.append("var onlineHelpUriCustom = "); 1503 result.append(getOnlineHelpUriCustom()); 1504 result.append(";\n"); 1505 1506 result.append("</script>\n"); 1507 return result.toString(); 1508 } else { 1509 return super.pageHtml(segment, null); 1510 } 1511 } 1512 1513 /** 1514 * Set the custom mapping for the online help. <p> 1515 * 1516 * This value will be set to a javascript variable called onlineHelpUriCustom. 1517 * If it is set, the top.head javascript for the online help will use this value. <p> 1518 * 1519 * This method should be called from <code>{@link #initWorkplaceRequestValues(CmsWorkplaceSettings, HttpServletRequest)}</code>, 1520 * <code>{@link CmsWorkplace#initWorkplaceMembers(CmsJspActionElement)}</code> 1521 * or from the jsp if the dialog class is used for several actions. 1522 * It should be used whenever the online help mapping does not work (due to jsp - forwards).<p> 1523 * 1524 * @param uri the left hand value in mapping.properties for the online help pages 1525 */ 1526 public void setOnlineHelpUriCustom(String uri) { 1527 1528 m_onlineHelpUriCustom = uri; 1529 } 1530 1531 /** 1532 * Sets the value of the action parameter.<p> 1533 * 1534 * @param value the value to set 1535 */ 1536 public void setParamAction(String value) { 1537 1538 m_paramAction = value; 1539 } 1540 1541 /** 1542 * Sets the value of the close link parameter.<p> 1543 * 1544 * @param value the value to set 1545 */ 1546 public void setParamCloseLink(String value) { 1547 1548 // ensure decoded chars are re-encoded again properly 1549 1550 m_paramCloseLink = value; 1551 } 1552 1553 /** 1554 * Sets the value of the dialog type parameter.<p> 1555 * 1556 * @param value the value to set 1557 */ 1558 public void setParamDialogtype(String value) { 1559 1560 m_paramDialogtype = value; 1561 } 1562 1563 /** 1564 * Sets the value of the frame name parameter.<p> 1565 * 1566 * @param value the value to set 1567 */ 1568 public void setParamFramename(String value) { 1569 1570 m_paramFrameName = value; 1571 } 1572 1573 /** 1574 * Sets the is popup parameter.<p> 1575 * 1576 * @param value the is popup parameter value 1577 */ 1578 public void setParamIsPopup(String value) { 1579 1580 m_paramIsPopup = value; 1581 } 1582 1583 /** 1584 * Sets the value of the message parameter.<p> 1585 * 1586 * @param value the value to set 1587 */ 1588 public void setParamMessage(String value) { 1589 1590 m_paramMessage = value; 1591 } 1592 1593 /** 1594 * Sets the value of the original parameters parameter.<p> 1595 * 1596 * @param paramOriginalParams the value of the original parameters parameter 1597 */ 1598 public void setParamOriginalParams(String paramOriginalParams) { 1599 1600 m_paramOriginalParams = paramOriginalParams; 1601 } 1602 1603 /** 1604 * Sets the value of the preaction done parameter.<p> 1605 * 1606 * @param paramPreActionDone the value of the preaction done parameter 1607 */ 1608 public void setParamPreActionDone(String paramPreActionDone) { 1609 1610 m_paramPreActionDone = paramPreActionDone; 1611 } 1612 1613 /** 1614 * Sets the value of the redirect flag parameter.<p> 1615 * 1616 * @param redirect the value of the redirect flag parameter 1617 */ 1618 public void setParamRedirect(String redirect) { 1619 1620 m_paramRedirect = redirect; 1621 } 1622 1623 /** 1624 * Sets the value of the file parameter.<p> 1625 * 1626 * @param value the value to set 1627 */ 1628 public void setParamResource(String value) { 1629 1630 m_paramResource = value; 1631 } 1632 1633 /** 1634 * Sets the value of the title parameter.<p> 1635 * 1636 * @param value the value to set 1637 */ 1638 public void setParamTitle(String value) { 1639 1640 m_paramTitle = value; 1641 } 1642 1643 /** 1644 * Appends a space char. between tag attributes.<p> 1645 * 1646 * @param attribute a tag attribute 1647 * 1648 * @return the tag attribute with a leading space char 1649 */ 1650 protected String appendDelimiter(String attribute) { 1651 1652 if (CmsStringUtil.isNotEmpty(attribute)) { 1653 if (!attribute.startsWith(" ")) { 1654 // add a delimiter space between the beginning button HTML and the button tag attributes 1655 return " " + attribute; 1656 } else { 1657 return attribute; 1658 } 1659 } 1660 1661 return ""; 1662 } 1663 1664 /** 1665 * Returns ajax wait message.<p> 1666 * 1667 * @return html code 1668 */ 1669 protected String buildAjaxWaitMessage() { 1670 1671 StringBuffer html = new StringBuffer(512); 1672 html.append("<table border='0' style='vertical-align:middle; height: 150px;'>\n"); 1673 html.append("<tr><td width='40' align='center' valign='middle'><img src='"); 1674 html.append(CmsWorkplace.getSkinUri()); 1675 html.append("commons/wait.gif' id='ajaxreport-img' width='32' height='32' alt=''></td>\n"); 1676 html.append("<td valign='middle'><span id='ajaxreport-txt' style='color: #000099; font-weight: bold;'>\n"); 1677 html.append(key(org.opencms.workplace.Messages.GUI_AJAX_REPORT_WAIT_0)); 1678 html.append("</span><br></td></tr></table>\n"); 1679 return html.toString(); 1680 } 1681 1682 /** 1683 * Checks if the permissions of the current user on the resource to use in the dialog are sufficient.<p> 1684 * 1685 * Automatically generates a CmsMessageContainer object with an error message and stores it in the users session.<p> 1686 * 1687 * @param required the required permissions for the dialog 1688 * @param neededForFolder if true, the permissions are required for the parent folder of the resource (e.g. for editors) 1689 * 1690 * @return true if the permissions are sufficient, otherwise false 1691 */ 1692 protected boolean checkResourcePermissions(CmsPermissionSet required, boolean neededForFolder) { 1693 1694 return checkResourcePermissions( 1695 required, 1696 neededForFolder, 1697 Messages.get().container( 1698 Messages.GUI_ERR_RESOURCE_PERMISSIONS_2, 1699 getParamResource(), 1700 required.getPermissionString())); 1701 } 1702 1703 /** 1704 * Checks if the permissions of the current user on the resource to use in the dialog are sufficient.<p> 1705 * 1706 * Automatically generates a CmsMessageContainer object with an error message and stores it in the users session.<p> 1707 * 1708 * @param required the required permissions for the dialog 1709 * @param neededForFolder if true, the permissions are required for the parent folder of the resource (e.g. for editors) 1710 * @param errorMessage the message container that is stored in the session in case the permissions are not sufficient 1711 * 1712 * @return true if the permissions are sufficient, otherwise false 1713 */ 1714 protected boolean checkResourcePermissions( 1715 CmsPermissionSet required, 1716 boolean neededForFolder, 1717 CmsMessageContainer errorMessage) { 1718 1719 boolean hasPermissions = false; 1720 try { 1721 CmsResource res; 1722 if (neededForFolder) { 1723 // check permissions for the folder the resource is in 1724 res = getCms().readResource(CmsResource.getParentFolder(getParamResource()), CmsResourceFilter.ALL); 1725 } else { 1726 res = getCms().readResource(getParamResource(), CmsResourceFilter.ALL); 1727 } 1728 hasPermissions = getCms().hasPermissions(res, required, false, CmsResourceFilter.ALL); 1729 } catch (CmsException e) { 1730 // should usually never happen 1731 if (LOG.isInfoEnabled()) { 1732 LOG.info(e.getLocalizedMessage(), e); 1733 } 1734 } 1735 1736 if (!hasPermissions) { 1737 // store the error message in the users session 1738 getSettings().setErrorMessage(errorMessage); 1739 } 1740 1741 return hasPermissions; 1742 } 1743 1744 /** 1745 * Returns the full path of the current workplace folder.<p> 1746 * 1747 * @return the full path of the current workplace folder 1748 */ 1749 protected String computeCurrentFolder() { 1750 1751 String currentFolder = getSettings().getExplorerResource(); 1752 if (currentFolder == null) { 1753 // set current folder to root folder 1754 try { 1755 currentFolder = getCms().getSitePath(getCms().readFolder("/", CmsResourceFilter.IGNORE_EXPIRATION)); 1756 } catch (CmsException e) { 1757 // can usually be ignored 1758 if (LOG.isInfoEnabled()) { 1759 LOG.info(e.getLocalizedMessage(), e); 1760 } 1761 currentFolder = "/"; 1762 } 1763 } 1764 if (!currentFolder.endsWith("/")) { 1765 // add folder separator to currentFolder 1766 currentFolder += "/"; 1767 } 1768 return currentFolder; 1769 } 1770 1771 /** 1772 * Renders the HTML for a single input button of a specified type.<p> 1773 * 1774 * @param result a string buffer where the rendered HTML gets appended to 1775 * @param button a integer key to identify the button 1776 * @param attribute an optional string with possible tag attributes, or null 1777 */ 1778 protected void dialogButtonsHtml(StringBuffer result, int button, String attribute) { 1779 1780 attribute = appendDelimiter(attribute); 1781 1782 switch (button) { 1783 case BUTTON_OK: 1784 result.append("<input name=\"ok\" value=\""); 1785 result.append(key(Messages.GUI_DIALOG_BUTTON_OK_0) + "\""); 1786 if (attribute.toLowerCase().indexOf("onclick") == -1) { 1787 result.append(" type=\"submit\""); 1788 } else { 1789 result.append(" type=\"button\""); 1790 } 1791 result.append(" class=\"dialogbutton\""); 1792 result.append(attribute); 1793 result.append(">\n"); 1794 break; 1795 case BUTTON_CANCEL: 1796 result.append("<input name=\"cancel\" type=\"button\" value=\""); 1797 result.append(key(Messages.GUI_DIALOG_BUTTON_CANCEL_0) + "\""); 1798 if (attribute.toLowerCase().indexOf("onclick") == -1) { 1799 result.append(" onclick=\"submitAction('" + DIALOG_CANCEL + "', form);\""); 1800 } 1801 result.append(" class=\"dialogbutton\""); 1802 result.append(attribute); 1803 result.append(">\n"); 1804 break; 1805 case BUTTON_EDIT: 1806 result.append("<input name=\"ok\" value=\""); 1807 result.append(key(Messages.GUI_DIALOG_BUTTON_EDIT_0) + "\""); 1808 if (attribute.toLowerCase().indexOf("onclick") == -1) { 1809 result.append(" type=\"submit\""); 1810 } else { 1811 result.append(" type=\"button\""); 1812 } 1813 result.append(" class=\"dialogbutton\""); 1814 result.append(attribute); 1815 result.append(">\n"); 1816 break; 1817 case BUTTON_DISCARD: 1818 result.append("<input name=\"cancel\" type=\"button\" value=\""); 1819 result.append(key(Messages.GUI_DIALOG_BUTTON_DISCARD_0) + "\""); 1820 if (attribute.toLowerCase().indexOf("onclick") == -1) { 1821 result.append(" onclick=\"submitAction('" + DIALOG_CANCEL + "', form);\""); 1822 } 1823 result.append(" class=\"dialogbutton\""); 1824 result.append(attribute); 1825 result.append(">\n"); 1826 break; 1827 case BUTTON_CLOSE: 1828 result.append("<input name=\"close\" type=\"button\" value=\""); 1829 result.append(key(Messages.GUI_DIALOG_BUTTON_CLOSE_0) + "\""); 1830 if (attribute.toLowerCase().indexOf("onclick") == -1) { 1831 result.append(" onclick=\"submitAction('" + DIALOG_CANCEL + "', form);\""); 1832 } 1833 result.append(" class=\"dialogbutton\""); 1834 result.append(attribute); 1835 result.append(">\n"); 1836 break; 1837 case BUTTON_ADVANCED: 1838 result.append("<input name=\"advanced\" type=\"button\" value=\""); 1839 result.append(key(Messages.GUI_DIALOG_BUTTON_ADVANCED_0) + "\""); 1840 result.append(" class=\"dialogbutton\""); 1841 result.append(attribute); 1842 result.append(">\n"); 1843 break; 1844 case BUTTON_SET: 1845 result.append("<input name=\"set\" type=\"button\" value=\""); 1846 result.append(key(Messages.GUI_DIALOG_BUTTON_SET_0) + "\""); 1847 if (attribute.toLowerCase().indexOf("onclick") == -1) { 1848 result.append(" onclick=\"submitAction('" + DIALOG_SET + "', form);\""); 1849 } 1850 result.append(" class=\"dialogbutton\""); 1851 result.append(attribute); 1852 result.append(">\n"); 1853 break; 1854 case BUTTON_BACK: 1855 result.append("<input name=\"set\" type=\"button\" value=\""); 1856 result.append(key(Messages.GUI_DIALOG_BUTTON_BACK_0) + "\""); 1857 if (attribute.toLowerCase().indexOf("onclick") == -1) { 1858 result.append(" onclick=\"submitAction('" + DIALOG_BACK + "', form);\""); 1859 } 1860 result.append(" class=\"dialogbutton\""); 1861 result.append(attribute); 1862 result.append(">\n"); 1863 break; 1864 case BUTTON_CONTINUE: 1865 result.append("<input name=\"set\" type=\"button\" value=\""); 1866 result.append(key(Messages.GUI_DIALOG_BUTTON_CONTINUE_0) + "\""); 1867 if (attribute.toLowerCase().indexOf("onclick") == -1) { 1868 result.append(" onclick=\"submitAction('" + DIALOG_CONTINUE + "', form);\""); 1869 } 1870 result.append(" class=\"dialogbutton\""); 1871 result.append(attribute); 1872 result.append(">\n"); 1873 break; 1874 case BUTTON_DETAILS: 1875 result.append("<input name=\"details\" type=\"button\" value=\""); 1876 result.append(key(Messages.GUI_DIALOG_BUTTON_DETAIL_0) + "\""); 1877 result.append(" class=\"dialogbutton\""); 1878 result.append(attribute); 1879 result.append(">\n"); 1880 break; 1881 default: 1882 // not a valid button code, just insert a warning in the HTML 1883 result.append("<!-- invalid button code: "); 1884 result.append(button); 1885 result.append(" -->\n"); 1886 } 1887 } 1888 1889 /** 1890 * Returns the link URL to get back one folder in the administration view.<p> 1891 * 1892 * @return the link URL to get back one folder in the administration view 1893 */ 1894 protected String getAdministrationBackLink() { 1895 1896 return CmsWorkplace.VFS_PATH_WORKPLACE 1897 + "action/administration_content_top.html" 1898 + "?sender=" 1899 + CmsResource.getParentFolder(getJsp().getRequestContext().getFolderUri()); 1900 } 1901 1902 /** 1903 * @see org.opencms.workplace.CmsWorkplace#initWorkplaceRequestValues(org.opencms.workplace.CmsWorkplaceSettings, javax.servlet.http.HttpServletRequest) 1904 */ 1905 @Override 1906 protected void initWorkplaceRequestValues(CmsWorkplaceSettings settings, HttpServletRequest request) { 1907 1908 fillParamValues(request); 1909 if (DIALOG_CANCEL.equals(getParamAction())) { 1910 setAction(ACTION_CANCEL); 1911 } 1912 } 1913 1914 /** 1915 * Opens the launch pad view.<p> 1916 * 1917 * @throws JspException in case writing to the JSP output stream fails 1918 */ 1919 protected void openLaunchpad() throws JspException { 1920 1921 try { 1922 openWorkplaceLink(CmsVaadinUtils.getWorkplaceLink(CmsAppHierarchyConfiguration.APP_ID)); 1923 } catch (Exception e) { 1924 // forward failed 1925 throw new JspException(e.getMessage(), e); 1926 } 1927 } 1928 1929 /** 1930 * Opens a workplace UI link in the top frame.<p> 1931 * 1932 * @param workplaceLink the workplace link to open 1933 * 1934 * @throws IOException in case writing to the JSP output stream fails 1935 */ 1936 protected void openWorkplaceLink(String workplaceLink) throws IOException { 1937 1938 // in case the close link points to the new workplace, make sure to set the new location on the top frame 1939 JspWriter out = getJsp().getJspContext().getOut(); 1940 try { 1941 out.write( 1942 "<html><head><script >top.location.href=\"" 1943 + workplaceLink 1944 + "\";</script></head>\n"); 1945 out.write("</html>\n"); 1946 } finally { 1947 out.close(); 1948 } 1949 } 1950 1951 /** 1952 * Sets the action value.<p> 1953 * 1954 * @param value the action value 1955 */ 1956 protected void setAction(int value) { 1957 1958 m_action = value; 1959 } 1960}