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