001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (https://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software GmbH & Co. KG, please see the 018 * company website: https://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: https://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.workplace.help; 029 030import org.opencms.configuration.CmsParameterConfiguration; 031import org.opencms.file.CmsProject; 032import org.opencms.file.CmsProperty; 033import org.opencms.file.CmsPropertyDefinition; 034import org.opencms.file.CmsResource; 035import org.opencms.file.CmsResourceFilter; 036import org.opencms.file.CmsVfsResourceNotFoundException; 037import org.opencms.file.types.CmsResourceTypeXmlPage; 038import org.opencms.i18n.CmsEncoder; 039import org.opencms.i18n.CmsLocaleManager; 040import org.opencms.jsp.CmsJspActionElement; 041import org.opencms.jsp.CmsJspNavElement; 042import org.opencms.loader.CmsLoaderException; 043import org.opencms.main.CmsException; 044import org.opencms.main.CmsLog; 045import org.opencms.main.OpenCms; 046import org.opencms.security.CmsRole; 047import org.opencms.security.CmsRoleViolationException; 048import org.opencms.staticexport.CmsLinkManager; 049import org.opencms.util.CmsMacroResolver; 050import org.opencms.util.CmsStringUtil; 051import org.opencms.workplace.CmsDialog; 052import org.opencms.workplace.CmsWorkplace; 053import org.opencms.workplace.CmsWorkplaceSettings; 054 055import java.io.IOException; 056import java.util.Iterator; 057import java.util.List; 058import java.util.Locale; 059import java.util.Map; 060 061import org.apache.commons.logging.Log; 062 063import jakarta.servlet.http.HttpServletRequest; 064import jakarta.servlet.http.HttpServletResponse; 065import jakarta.servlet.jsp.PageContext; 066 067/** 068 * The bean that provides methods to build the HTML for the single online help frames.<p> 069 * 070 * <h4>Things to know</h4> 071 * <ul> 072 * <li> 073 * Online help will only work with resources of type xmlpage. 074 * <li> 075 * Content pages with a property <em>"template-elements"</em> set to a path of a ressource (jsp, page,...) 076 * will get the content produced by <code>{@link org.opencms.jsp.CmsJspActionElement#getContent(String)}</code> 077 * appended after their own output. This allows to use jsp's in the online help template. 078 * </ul> 079 * 080 * @since 6.0.0 081 */ 082public class CmsHelpTemplateBean extends CmsDialog { 083 084 /** File name of the default help file to load. */ 085 public static final String DEFAULT_HELPFILE = "index.html"; 086 087 /** File name of the help mappings properties file(s). */ 088 public static final String HELPMAPPINGS_FILENAME = "mappings_" 089 + "${" 090 + CmsMacroResolver.KEY_REQUEST_LOCALE 091 + "}.properties"; 092 093 /** The name of the help module. */ 094 public static final String MODULE_NAME = "org.opencms.workplace.help"; 095 096 /** Request parameter name for the buildframe flag parameter. */ 097 public static final String PARAM_BUILDFRAME = "buildframe"; 098 099 /** Request parameter name for the helpresource uri. */ 100 public static final String PARAM_HELPRESOURCE = "helpresource"; 101 102 /** Request parameter name for the homelink in head frame. */ 103 public static final String PARAM_HOMELINK = "homelink"; 104 105 /** Request parameter name for the workplaceresource uri. */ 106 public static final String PARAM_WORKPLACERESOURCE = "workplaceresource"; 107 108 /** VFS path to the help folder, contains a macro for the Locale which has to be resolved. */ 109 public static final String PATH_HELP = CmsWorkplace.VFS_PATH_LOCALES 110 + "${" 111 + CmsMacroResolver.KEY_REQUEST_LOCALE 112 + "}/help/"; 113 114 /** Value of the NavInfo property indicating the start folder of the help. */ 115 public static final String PROPERTY_VALUE_HELPSTART = "help.start"; 116 117 /** Relative RFS path of the help mappings property file(s). */ 118 public static final String RFS_HELPMAPPINGS = "classes/" 119 + MODULE_NAME.replace('.', '/') 120 + "/" 121 + HELPMAPPINGS_FILENAME; 122 123 /** Absolute path to used JSP templates. */ 124 public static final String TEMPLATEPATH = CmsWorkplace.VFS_PATH_MODULES + MODULE_NAME + "/jsptemplates/"; 125 126 /** The log object for this class. */ 127 private static final Log LOG = CmsLog.getLog(CmsHelpTemplateBean.class); 128 129 /** The online project that is switched to whenever body content is processed that should not be exported. */ 130 private CmsProject m_offlineProject; 131 132 /** The online project that is switched to whenever body content is processed that shall be exported. */ 133 private CmsProject m_onlineProject; 134 135 /** Request parameter for the help build frameset flag. */ 136 private String m_paramBuildframe; 137 138 /** Request parameter for the help resource to display. */ 139 private String m_paramHelpresource; 140 141 /** Request parameter for the home link to use in the head frame. */ 142 private String m_paramHomelink; 143 144 /** Request parameter for the current workplace resource. */ 145 private String m_paramWorkplaceresource; 146 147 /** 148 * Public constructor with JSP action element.<p> 149 * 150 * @param jsp an initialized JSP action element 151 */ 152 public CmsHelpTemplateBean(CmsJspActionElement jsp) { 153 154 super(jsp); 155 156 try { 157 m_onlineProject = getCms().readProject(CmsProject.ONLINE_PROJECT_ID); 158 m_offlineProject = jsp.getRequestContext().getCurrentProject(); 159 } catch (CmsException e) { 160 // failed to get online project 161 m_onlineProject = getCms().getRequestContext().getCurrentProject(); 162 } 163 } 164 165 /** 166 * Public constructor with JSP variables.<p> 167 * 168 * @param context the JSP page context 169 * @param req the JSP request 170 * @param res the JSP response 171 */ 172 public CmsHelpTemplateBean(PageContext context, HttpServletRequest req, HttpServletResponse res) { 173 174 this(new CmsJspActionElement(context, req, res)); 175 } 176 177 /** 178 * Returns the java script method to open the online help window.<p> 179 * 180 * @param locale the current users workplace Locale 181 * @return the java script method to open the online help window 182 */ 183 public static String buildOnlineHelpJavaScript(Locale locale) { 184 185 StringBuffer result = new StringBuffer(16); 186 187 // the online help invoker: opens documentation central in a new window. 188 result.append("function openOnlineHelp() {\n"); 189 result.append("\twindow.open('http://documentation.opencms.org/central/','_blank');\n"); 190 result.append("}\n"); 191 192 String s = result.toString(); 193 return s; 194 } 195 196 /** 197 * Returns the HTML for the end of the page.<p> 198 * 199 * @return the HTML for the end of the page 200 */ 201 public String buildHtmlHelpEnd() { 202 203 StringBuffer result = new StringBuffer(4); 204 result.append("</body>\n"); 205 result.append("</html>"); 206 return result.toString(); 207 } 208 209 /** 210 * Returns the HTML for the start of the page.<p> 211 * 212 * @param cssFile the CSS file name to use 213 * @param transitional if true, transitional doctype is used 214 * @return the HTML for the start of the page 215 */ 216 public String buildHtmlHelpStart(String cssFile, boolean transitional) { 217 218 StringBuffer result = new StringBuffer(8); 219 if (transitional) { 220 result.append("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n"); 221 } else { 222 result.append("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\">\n"); 223 } 224 result.append("<html>\n"); 225 result.append("<head>\n"); 226 result.append("\t<meta HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=utf-8"); 227 result.append("\">\n"); 228 result.append("\t<title>"); 229 if (CmsStringUtil.isNotEmpty(getParamHelpresource())) { 230 result.append( 231 getJsp().property( 232 CmsPropertyDefinition.PROPERTY_TITLE, 233 getParamHelpresource(), 234 key(Messages.GUI_HELP_FRAMESET_TITLE_0))); 235 } else { 236 result.append(key(Messages.GUI_HELP_FRAMESET_TITLE_0)); 237 } 238 result.append("</title>\n"); 239 result.append("\t<link rel=\"stylesheet\" type=\"text/css\" href=\""); 240 result.append(getStyleUri(getJsp(), cssFile)).append("\">\n"); 241 result.append("</head>\n"); 242 return result.toString(); 243 } 244 245 /** 246 * Returns the HTML for the body frame of the online help.<p> 247 * 248 * @return the HTML for the body frame of the online help 249 */ 250 public String displayBody() { 251 252 StringBuffer result = new StringBuffer(256); 253 254 // change to online project to allow static export 255 try { 256 getJsp().getRequestContext().setCurrentProject(m_onlineProject); 257 result.append(buildHtmlHelpStart("onlinehelp.css", true)); 258 result.append("<body>\n"); 259 result.append("<a name=\"top\"></a>\n"); 260 result.append("<table class=\"helpcontent\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n"); 261 result.append("<tr>\n"); 262 result.append("\t<td class=\"helpnav\">\n"); 263 result.append( 264 "\t\t<a class=\"navhelphead\" href=\"javascript:top.body.location.href=top.head.homeLink;\">"); 265 result.append(key(Messages.GUI_HELP_NAVIGATION_HEAD_0)); 266 result.append("</a>\n"); 267 result.append(buildHtmlHelpNavigation()); 268 result.append("</td>\n"); 269 result.append("\t<td class=\"helpcontent\">\n"); 270 result.append("\t\t<h1>"); 271 result.append( 272 getJsp().property( 273 CmsPropertyDefinition.PROPERTY_TITLE, 274 getParamHelpresource(), 275 key(Messages.GUI_HELP_FRAMESET_TITLE_0))); 276 result.append("</h1>\n"); 277 // print navigation if property template-elements is set to sitemap 278 result.append(getJsp().getContent(getParamHelpresource(), "body", getLocale())); 279 try { 280 // additionally allow appending content of dynamic pages whose path may be specified 281 // as value of property PROPERTY_TEMPLATE_ELEMENTS (currently sitemap.jsp and search.jsp are used) 282 CmsProperty elements = getCms().readPropertyObject( 283 getParamHelpresource(), 284 CmsPropertyDefinition.PROPERTY_TEMPLATE_ELEMENTS, 285 false); 286 if (!elements.isNullProperty()) { 287 try { 288 // trigger an exception here as getContent won't throw anything! 289 getJsp().getCmsObject().readFile(elements.getValue()); 290 // Ok, ressource exists: switsch from the online project to turn of static export links. 291 String elementName = elements.getValue(); 292 // check, wether the "dynamic resource" wants to be exported or not: 293 boolean export = false; 294 CmsProperty exportProp = getCms().readPropertyObject( 295 elementName, 296 CmsPropertyDefinition.PROPERTY_EXPORT, 297 true); 298 299 if (!exportProp.isNullProperty()) { 300 export = Boolean.valueOf(exportProp.getValue(CmsStringUtil.FALSE)).booleanValue(); 301 } 302 if (!export) { 303 // switch back from online project to avoid export: 304 getJsp().getRequestContext().setCurrentProject(m_offlineProject); 305 } 306 result.append(getJsp().getContent(elements.getValue())); 307 308 } catch (Throwable t) { 309 CmsVfsResourceNotFoundException e2 = new CmsVfsResourceNotFoundException( 310 Messages.get().container( 311 Messages.GUI_HELP_ERR_CONTENT_APPEND_2, 312 getParamHelpresource(), 313 elements.getValue(), 314 CmsPropertyDefinition.PROPERTY_TEMPLATE_ELEMENTS), 315 t); 316 throw e2; 317 } 318 } 319 } catch (CmsException e1) { 320 321 if (LOG.isErrorEnabled()) { 322 LOG.error(e1); 323 } 324 result.append("<br>\n<div class=\"dialogerror\">"); 325 // getLocale() does not work in this context!?! 326 result.append(e1.getMessageContainer().key(Locale.GERMAN)); 327 result.append("</div>"); 328 } 329 result.append("\t</td>\n"); 330 result.append("</tr>\n"); 331 result.append("</table>\n"); 332 result.append(buildHtmlHelpEnd()); 333 return result.toString(); 334 } finally { 335 getJsp().getRequestContext().setCurrentProject(m_offlineProject); 336 } 337 } 338 339 /** 340 * Returns the HTML for the head frame of the online help.<p> 341 * 342 * @return the HTML for the head frame of the online help 343 */ 344 public String displayHead() { 345 346 StringBuffer result = new StringBuffer(2048); 347 348 int buttonStyle = getSettings().getUserSettings().getWorkplaceButtonStyle(); 349 350 // change to online project to allow exporting 351 try { 352 getJsp().getRequestContext().setCurrentProject(m_onlineProject); 353 String resourcePath = getJsp().link("/system/modules/" + MODULE_NAME + "/resources/"); 354 355 result.append(buildHtmlHelpStart("workplace.css", false)); 356 result.append("<body class=\"buttons-head\" unselectable=\"on\">\n"); 357 result.append("<script src=\""); 358 result.append(getJsp().link("/system/modules/org.opencms.workplace.help/resources/search.js")); 359 result.append("\"></script>\n"); 360 361 // store home link in JS variable to use it in body frame 362 result.append("<script >\n<!--\n"); 363 result.append("\tvar homeLink = \""); 364 result.append(CmsEncoder.escapeXml(getParamHomelink())); 365 result.append("\";\n\n"); 366 result.append("//-->\n</script>\n"); 367 368 // search form with invisible elements 369 370 // search index may be attached to resource /system/modules/org.opencms.workplace.help/elements/search.jsp, 371 // property search.index. 372 String index = getJsp().property( 373 "search.index", 374 "/system/modules/org.opencms.workplace.help/elements/search.jsp", 375 "German online help", 376 false); 377 StringBuffer submitAction = new StringBuffer(); 378 submitAction.append("parseSearchQuery(document.forms[\'searchform\'],\'"); 379 submitAction.append( 380 Messages.get().getBundle(getLocale()).key( 381 Messages.GUI_HELP_ERR_SEARCH_WORD_LENGTH_1, 382 Integer.valueOf(3))).append("\');"); 383 384 result.append("<form style=\"margin: 0;\" name=\"searchform\" method=\"post\" action=\""); 385 String searchLink = getJsp().link( 386 new StringBuffer("/system/modules/org.opencms.workplace.help/elements/search.jsp?").append( 387 CmsLocaleManager.PARAMETER_LOCALE).append("=").append(getLocale()).toString()); 388 result.append(searchLink); 389 result.append("\" target=\"body\""); 390 result.append(" onsubmit=\""); 391 result.append(submitAction.toString()); 392 result.append("\">\n"); 393 result.append(" <input type=\"hidden\" name=\"action\" value=\"search\" />\n"); 394 result.append(" <input type=\"hidden\" name=\"query\" value=\"\" />\n"); 395 result.append(" <input type=\"hidden\" name=\"index\" value=\"" + index + "\" />\n"); 396 result.append(" <input type=\"hidden\" name=\"searchPage\" value=\"1\" />\n"); 397 398 result.append("<table width=\"100%\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n"); 399 result.append("<tr>\n"); 400 result.append("\t<td align=\"left\">\n"); 401 402 // display navigation buttons 403 result.append(buttonBar(HTML_START)); 404 result.append(buttonBarStartTab(0, 5)); 405 result.append( 406 button( 407 "javascript:history.back();", 408 null, 409 "back.png", 410 org.opencms.search.Messages.GUI_HELP_BUTTON_BACK_0, 411 buttonStyle, 412 resourcePath)); 413 result.append( 414 button( 415 "javascript:history.forward();", 416 null, 417 "next.png", 418 org.opencms.search.Messages.GUI_HELP_BUTTON_NEXT_0, 419 buttonStyle, 420 resourcePath)); 421 422 result.append( 423 button( 424 "javascript:top.body.location.href='" + CmsEncoder.escapeXml(getParamHomelink()) + "';", 425 null, 426 "contents.png", 427 org.opencms.search.Messages.GUI_HELP_BUTTON_CONTENTS_0, 428 buttonStyle, 429 resourcePath)); 430 //search 431 result.append("<td style=\"vertical-align: top;\">"); 432 result.append("<input type=\"text\" name=\"query2\" class=\"onlineform\" style=\"width: 120px\" value=\""); 433 result.append(""); 434 result.append(" \">"); 435 result.append("</td>\n"); 436 437 result.append( 438 button( 439 new StringBuffer("javascript:").append(submitAction.toString()).toString(), 440 null, 441 null, 442 org.opencms.search.Messages.GUI_HELP_BUTTON_SEARCH_0, 443 2, 444 null)); 445 446 result.append(buttonBar(HTML_END)); 447 448 result.append("</td>\n"); 449 result.append("\t<td align=\"right\" width=\"100%\">\n"); 450 451 // display close button 452 result.append(buttonBar(HTML_START)); 453 result.append(buttonBarSeparator(5, 0)); 454 result.append( 455 button( 456 "javascript:top.close();", 457 null, 458 "close", 459 org.opencms.search.Messages.GUI_HELP_BUTTON_CLOSE_0, 460 buttonStyle, 461 resourcePath)); 462 result.append(buttonBar(HTML_END)); 463 464 result.append("\t</td>\n"); 465 result.append("\t<td> </td>\n"); 466 result.append("<td>"); 467 468 // display logo 469 result.append("<span style=\"display: block; width: 80px; height: 22px; background-image: url(\'"); 470 result.append(getSkinUri()); 471 result.append("commons/workplace.png"); 472 result.append("\'); \"></span>"); 473 result.append("</td>"); 474 result.append("</tr>\n"); 475 result.append("</table>\n"); 476 result.append("</form>\n"); 477 result.append(buildHtmlHelpEnd()); 478 479 return result.toString(); 480 } finally { 481 // set back to offline project 482 getJsp().getRequestContext().setCurrentProject(m_offlineProject); 483 } 484 } 485 486 /** 487 * Generates the HTML for the online help frameset or redirects to the help body, depending on the build frameset flag.<p> 488 * 489 * @return the HTML for the online help frameset or an empty String (redirect) 490 * @throws IOException if redirection fails 491 */ 492 public String displayHelp() throws IOException { 493 494 String result = ""; 495 // change to online project to allow static export / export links 496 try { 497 getJsp().getRequestContext().setCurrentProject(m_onlineProject); 498 499 if (isBuildFrameset()) { 500 // build the online help frameset 501 result = displayFrameset(); 502 } else { 503 // redirect to the help body 504 StringBuffer bodyLink = new StringBuffer(8); 505 bodyLink.append(TEMPLATEPATH); 506 bodyLink.append("help_body.jsp?"); 507 bodyLink.append(CmsHelpTemplateBean.PARAM_HELPRESOURCE); 508 bodyLink.append("="); 509 bodyLink.append(getJsp().getRequestContext().getUri()); 510 bodyLink.append("&"); 511 bodyLink.append(CmsLocaleManager.PARAMETER_LOCALE); 512 bodyLink.append("="); 513 bodyLink.append(getLocale()); 514 // add the other parameters too! 515 String bodyLinkWithParams = attachRequestString(bodyLink.toString()); 516 String redirectLink = getJsp().link(bodyLinkWithParams); 517 // set back to current project 518 getJsp().getResponse().sendRedirect(redirectLink); 519 } 520 return result; 521 } finally { 522 getJsp().getRequestContext().setCurrentProject(m_onlineProject); 523 } 524 } 525 526 /** 527 * Returns the buildframe parameter indicating if the frameset should be generated.<p> 528 * 529 * @return the buildframe parameter indicating if the frameset should be generated 530 */ 531 public String getParamBuildframe() { 532 533 return m_paramBuildframe; 534 } 535 536 /** 537 * Returns the helpresource parameter value.<p> 538 * 539 * @return the helpresource parameter value 540 */ 541 public String getParamHelpresource() { 542 543 if (m_paramHelpresource == null) { 544 m_paramHelpresource = resolveMacros(PATH_HELP) + DEFAULT_HELPFILE; 545 } 546 547 return m_paramHelpresource; 548 } 549 550 /** 551 * Returns the homelink parameter value.<p> 552 * 553 * @return the homelink parameter value 554 */ 555 public String getParamHomelink() { 556 557 return m_paramHomelink; 558 } 559 560 /** 561 * Returns the workplaceresource parameter value.<p> 562 * 563 * @return the workplaceresource parameter value 564 */ 565 public String getParamWorkplaceresource() { 566 567 return m_paramWorkplaceresource; 568 } 569 570 /** 571 * Sets the buildframe parameter indicating if the frameset should be generated.<p> 572 * 573 * @param buildframe the buildframe parameter indicating if the frameset should be generated 574 */ 575 public void setParamBuildframe(String buildframe) { 576 577 m_paramBuildframe = buildframe; 578 } 579 580 /** 581 * Sets the helpresource parameter value.<p> 582 * 583 * @param helpresource the helpresource parameter value 584 */ 585 public void setParamHelpresource(String helpresource) { 586 587 m_paramHelpresource = helpresource; 588 } 589 590 /** 591 * Sets the homelink parameter value.<p> 592 * 593 * @param homelink the homelink parameter value 594 */ 595 public void setParamHomelink(String homelink) { 596 597 m_paramHomelink = homelink; 598 } 599 600 /** 601 * Sets the workplaceresource parameter value.<p> 602 * 603 * @param workplaceresource the workplaceresource parameter value 604 */ 605 public void setParamWorkplaceresource(String workplaceresource) { 606 607 m_paramWorkplaceresource = workplaceresource; 608 } 609 610 /** 611 * Returns the HTML to build the navigation of the online help folder.<p> 612 * 613 * @return the HTML to build the navigation of the online help folder 614 */ 615 protected String buildHtmlHelpNavigation() { 616 617 StringBuffer result = new StringBuffer(512); 618 // determine current URI 619 String currentUri = getParamHelpresource(); 620 // ignore ressources outside content folder: e.g. the search.html which 621 // is in the general help module and not the german or english online help folder. 622 if ((currentUri == null) || (currentUri.indexOf("/workplace/locales/") == -1)) { 623 // BUG!: getLocale().getLanguage() -> getCms().getRequestContext().getLocale() returns "en"! 624 //currentUri = "/system/workplace/locales/" + getLocale().getLanguage() + "/help/"; 625 currentUri = resolveMacros(PATH_HELP) + DEFAULT_HELPFILE; 626 } 627 // determine level of help start folder 628 int helpLevel = CmsResource.getPathLevel(PATH_HELP); 629 630 // get a list of all pages / subfolders in the help folder 631 List<CmsJspNavElement> navList = getJsp().getNavigation().getNavigationTreeForFolder(currentUri, helpLevel, 99); 632 Iterator<CmsJspNavElement> i = navList.iterator(); 633 634 while (i.hasNext()) { 635 CmsJspNavElement nav = i.next(); 636 // calculate level to display 637 int level = nav.getNavTreeLevel() - (helpLevel - 1); 638 if (nav.getResourceName().equals(currentUri) 639 || (nav.isFolderLink() && currentUri.equals(nav.getResourceName() + "index.html"))) { 640 result.append("\t\t<span class=\"navhelpcurrent\" style=\"padding-left: "); 641 result.append(level * 10); 642 result.append("px; background-position: "); 643 result.append((level - 1) * 10); 644 result.append("px 1px;\">"); 645 result.append(nav.getNavText()); 646 result.append("</span><br style=\"clear:left\">\n"); 647 } else { 648 result.append("\t\t<a class=\"navhelp\" style=\"padding-left: "); 649 result.append(level * 10); 650 result.append("px; background-position: "); 651 result.append((level - 1) * 10); 652 result.append("px 1px;\" href=\""); 653 if (nav.isFolderLink()) { 654 // append file name to folder links to avoid static export issues 655 result.append( 656 getJsp().link( 657 "/system/modules/org.opencms.workplace.help/jsptemplates/help_body.jsp?helpresource=" 658 + nav.getResourceName() 659 + "index.html&" 660 + CmsLocaleManager.PARAMETER_LOCALE 661 + "=" 662 + getLocale())); 663 } else { 664 result.append( 665 getJsp().link( 666 "/system/modules/org.opencms.workplace.help/jsptemplates/help_body.jsp?helpresource=" 667 + nav.getResourceName() 668 + "&" 669 + CmsLocaleManager.PARAMETER_LOCALE 670 + "=" 671 + getLocale())); 672 // result.append(getJsp().link(nav.getResourceName())); 673 } 674 result.append("\">"); 675 result.append(nav.getNavText()); 676 result.append("</a><br style=\"clear:left\">\n"); 677 } 678 } 679 return result.toString(); 680 } 681 682 /** 683 * @see org.opencms.workplace.CmsWorkplace#checkRole() 684 */ 685 @Override 686 protected void checkRole() throws CmsRoleViolationException { 687 688 // needed since these pages are static exported 689 if (!OpenCms.getDefaultUsers().isUserExport(getCms().getRequestContext().getCurrentUser().getName())) { 690 // only for users that are not the export user 691 OpenCms.getRoleManager().checkRole(getCms(), CmsRole.WORKPLACE_USER); 692 } 693 } 694 695 /** 696 * Returns the HTML to build the frameset for the online help popup window.<p> 697 * 698 * @return the HTML to build the frameset for the online help popup window 699 */ 700 protected String displayFrameset() { 701 702 StringBuffer result = new StringBuffer(8); 703 result.append("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\">\n"); 704 result.append("<html>\n"); 705 result.append("<head>\n"); 706 result.append("\t<title>"); 707 result.append(key(Messages.GUI_HELP_FRAMESET_TITLE_0)); 708 result.append("</title>\n"); 709 710 // script to avoid frameset display errors 711 result.append("<script >\n<!--\n"); 712 result.append("\t if (window.name == \"body\") {\n"); 713 result.append("\t\ttop.location.href = \"" + getJsp().link(getJsp().getRequestContext().getUri()) + "\";\n"); 714 result.append("\t}\n"); 715 result.append("//-->\n</script>\n"); 716 result.append("<meta HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=utf-8\">\n"); 717 718 result.append("</head>\n\n"); 719 result.append("<frameset rows=\"24,*\" border=\"0\" frameborder=\"0\" framespacing=\"0\">\n"); 720 result.append("\t<frame name=\"head\" src=\""); 721 722 StringBuffer headLink = new StringBuffer(8); 723 headLink.append(TEMPLATEPATH); 724 headLink.append("help_head.jsp?"); 725 headLink.append(CmsLocaleManager.PARAMETER_LOCALE); 726 headLink.append("="); 727 headLink.append(getLocale()); 728 headLink.append("&"); 729 headLink.append(PARAM_HOMELINK); 730 headLink.append("="); 731 headLink.append(getParamHomelink()); 732 result.append(CmsEncoder.escapeXml(getJsp().link(attachRequestString(headLink.toString())))); 733 result.append("\" scrolling=\"no\" noresize>\n"); 734 result.append("\t<frame name=\"body\" src=\""); 735 StringBuffer bodyLink = new StringBuffer(8); 736 bodyLink.append(TEMPLATEPATH); 737 bodyLink.append("help_body.jsp?"); 738 bodyLink.append(CmsHelpTemplateBean.PARAM_HELPRESOURCE); 739 bodyLink.append("="); 740 bodyLink.append(getJsp().getRequestContext().getUri()); 741 bodyLink.append("&"); 742 bodyLink.append(CmsLocaleManager.PARAMETER_LOCALE); 743 bodyLink.append("="); 744 bodyLink.append(getLocale()); 745 result.append(getJsp().link(bodyLink.toString())); 746 result.append("\" scrolling=\"auto\" noresize>\n"); 747 result.append("</frameset>\n\n"); 748 result.append("<body></body>\n"); 749 result.append("</html>"); 750 751 return result.toString(); 752 } 753 754 /** 755 * Determines the mapped help page for a given workplace resource URI.<p> 756 * 757 * If a mapping information is found, the requested URI is set to the found value.<p> 758 * 759 * If no workplace resource URI is given, nothing is changed.<p> 760 */ 761 protected void getMappedHelpUri() { 762 763 try { 764 getJsp().getRequestContext().setCurrentProject(m_onlineProject); 765 if (CmsStringUtil.isNotEmpty(getParamWorkplaceresource())) { 766 // found a workplace resource parameter, try to get a mapping for it 767 String helpResource = null; 768 String wpResource = getParamWorkplaceresource(); 769 int xmlPageId; 770 try { 771 xmlPageId = OpenCms.getResourceManager().getResourceType( 772 CmsResourceTypeXmlPage.getStaticTypeName()).getTypeId(); 773 } catch (CmsLoaderException e1) { 774 xmlPageId = CmsResourceTypeXmlPage.getStaticTypeId(); 775 } 776 if (getCms().existsResource( 777 resolveMacros(getParamWorkplaceresource()), 778 CmsResourceFilter.requireType(xmlPageId))) { 779 // given workplace resource is a page in VFS, use it as start point 780 helpResource = resolveMacros(getParamWorkplaceresource()); 781 setParamHomelink(getJsp().link(helpResource)); 782 } else { 783 // given workplace resource does not exist, resolve mapping 784 try { 785 786 // try to read the mappings from the current module 787 String absolutePath = OpenCms.getSystemInfo().getAbsoluteRfsPathRelativeToWebInf( 788 resolveMacros(RFS_HELPMAPPINGS)); 789 CmsParameterConfiguration props = new CmsParameterConfiguration(absolutePath); 790 791 // remove context from workplace path 792 wpResource = CmsLinkManager.removeOpenCmsContext(wpResource); 793 794 // determine mapping for workplace resource 795 while ((wpResource != null) && CmsStringUtil.isEmpty(helpResource)) { 796 helpResource = props.getString(wpResource, null); 797 wpResource = CmsResource.getParentFolder(wpResource); 798 } 799 } catch (IOException e) { 800 // no mappings found in module, ignore 801 } 802 803 if (CmsStringUtil.isEmpty(helpResource)) { 804 // no mapping found, use default help URI 805 helpResource = DEFAULT_HELPFILE; 806 } 807 // create path to the help resource 808 helpResource = resolveMacros(PATH_HELP) + helpResource; 809 if (!getCms().existsResource(helpResource, CmsResourceFilter.IGNORE_EXPIRATION)) { 810 helpResource = resolveMacros(PATH_HELP) + DEFAULT_HELPFILE; 811 } 812 setParamHomelink(getJsp().link(resolveMacros(PATH_HELP) + DEFAULT_HELPFILE)); 813 } 814 // set URI to found help page URI 815 getJsp().getRequestContext().setUri(helpResource); 816 } 817 818 } finally { 819 getJsp().getRequestContext().setCurrentProject(m_offlineProject); 820 } 821 } 822 823 /** 824 * @see org.opencms.workplace.CmsWorkplace#initWorkplaceRequestValues(org.opencms.workplace.CmsWorkplaceSettings, jakarta.servlet.http.HttpServletRequest) 825 */ 826 @Override 827 protected void initWorkplaceRequestValues(CmsWorkplaceSettings settings, HttpServletRequest request) { 828 829 // fill the parameter values in the get/set methods 830 fillParamValues(request); 831 832 // determine initial page to show on frameset generation 833 if (isBuildFrameset()) { 834 // get the mapped URI 835 getMappedHelpUri(); 836 } 837 } 838 839 /** 840 * Returns true if the online help frameset has to be generated.<p> 841 * 842 * @return true if the online help frameset has to be generated, otherwise false 843 */ 844 protected boolean isBuildFrameset() { 845 846 return Boolean.valueOf(getParamBuildframe()).booleanValue(); 847 } 848 849 /** 850 * Attaches the resource name to the request as parameter.<p> 851 * 852 * @param resourceName a name of a resource 853 * 854 * @return The given resource name with additional request parameter concatenations of the 855 * current request on this <code>CmsDialog</code> 856 */ 857 private String attachRequestString(String resourceName) { 858 859 StringBuffer result = new StringBuffer(resourceName); 860 boolean firstParam = true; 861 if (resourceName.indexOf('?') == -1) { 862 // no params in uri yet? 863 result.append('?'); 864 } else { 865 firstParam = false; 866 } 867 868 @SuppressWarnings("unchecked") 869 Map<String, String[]> params = getJsp().getRequest().getParameterMap(); 870 Iterator<Map.Entry<String, String[]>> it = params.entrySet().iterator(); 871 String[] values = null; 872 while (it.hasNext()) { 873 if (values == null) { 874 // first iteration: check if params before so an & has to be used. 875 if (!firstParam) { 876 result.append('&'); 877 } 878 } else { 879 result.append("&"); 880 } 881 Map.Entry<String, String[]> entry = it.next(); 882 result.append(entry.getKey().toString()).append('='); 883 values = entry.getValue(); 884 for (int i = 0; i < values.length; i++) { 885 result.append(values[i]); 886 if ((i + 1) < values.length) { 887 result.append(','); 888 } 889 } 890 } 891 return result.toString(); 892 } 893 894}