001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://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: http://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: http://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 javax.servlet.http.HttpServletRequest; 062import javax.servlet.http.HttpServletResponse; 063import javax.servlet.jsp.PageContext; 064 065import org.apache.commons.logging.Log; 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(getJsp().property( 231 CmsPropertyDefinition.PROPERTY_TITLE, 232 getParamHelpresource(), 233 key(Messages.GUI_HELP_FRAMESET_TITLE_0))); 234 } else { 235 result.append(key(Messages.GUI_HELP_FRAMESET_TITLE_0)); 236 } 237 result.append("</title>\n"); 238 result.append("\t<link rel=\"stylesheet\" type=\"text/css\" href=\""); 239 result.append(getStyleUri(getJsp(), cssFile)).append("\">\n"); 240 result.append("</head>\n"); 241 return result.toString(); 242 } 243 244 /** 245 * Returns the HTML for the body frame of the online help.<p> 246 * 247 * @return the HTML for the body frame of the online help 248 */ 249 public String displayBody() { 250 251 StringBuffer result = new StringBuffer(256); 252 253 // change to online project to allow static export 254 try { 255 getJsp().getRequestContext().setCurrentProject(m_onlineProject); 256 result.append(buildHtmlHelpStart("onlinehelp.css", true)); 257 result.append("<body>\n"); 258 result.append("<a name=\"top\"></a>\n"); 259 result.append("<table class=\"helpcontent\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n"); 260 result.append("<tr>\n"); 261 result.append("\t<td class=\"helpnav\">\n"); 262 result.append( 263 "\t\t<a class=\"navhelphead\" href=\"javascript:top.body.location.href=top.head.homeLink;\">"); 264 result.append(key(Messages.GUI_HELP_NAVIGATION_HEAD_0)); 265 result.append("</a>\n"); 266 result.append(buildHtmlHelpNavigation()); 267 result.append("</td>\n"); 268 result.append("\t<td class=\"helpcontent\">\n"); 269 result.append("\t\t<h1>"); 270 result.append( 271 getJsp().property( 272 CmsPropertyDefinition.PROPERTY_TITLE, 273 getParamHelpresource(), 274 key(Messages.GUI_HELP_FRAMESET_TITLE_0))); 275 result.append("</h1>\n"); 276 // print navigation if property template-elements is set to sitemap 277 result.append(getJsp().getContent(getParamHelpresource(), "body", getLocale())); 278 try { 279 // additionally allow appending content of dynamic pages whose path may be specified 280 // as value of property PROPERTY_TEMPLATE_ELEMENTS (currently sitemap.jsp and search.jsp are used) 281 CmsProperty elements = getCms().readPropertyObject( 282 getParamHelpresource(), 283 CmsPropertyDefinition.PROPERTY_TEMPLATE_ELEMENTS, 284 false); 285 if (!elements.isNullProperty()) { 286 try { 287 // trigger an exception here as getContent won't throw anything! 288 getJsp().getCmsObject().readFile(elements.getValue()); 289 // Ok, ressource exists: switsch from the online project to turn of static export links. 290 String elementName = elements.getValue(); 291 // check, wether the "dynamic resource" wants to be exported or not: 292 boolean export = false; 293 CmsProperty exportProp = getCms().readPropertyObject( 294 elementName, 295 CmsPropertyDefinition.PROPERTY_EXPORT, 296 true); 297 298 if (!exportProp.isNullProperty()) { 299 export = Boolean.valueOf(exportProp.getValue(CmsStringUtil.FALSE)).booleanValue(); 300 } 301 if (!export) { 302 // switch back from online project to avoid export: 303 getJsp().getRequestContext().setCurrentProject(m_offlineProject); 304 } 305 result.append(getJsp().getContent(elements.getValue())); 306 307 } catch (Throwable t) { 308 CmsVfsResourceNotFoundException e2 = new CmsVfsResourceNotFoundException( 309 Messages.get().container( 310 Messages.GUI_HELP_ERR_CONTENT_APPEND_2, 311 getParamHelpresource(), 312 elements.getValue(), 313 CmsPropertyDefinition.PROPERTY_TEMPLATE_ELEMENTS), 314 t); 315 throw e2; 316 } 317 } 318 } catch (CmsException e1) { 319 320 if (LOG.isErrorEnabled()) { 321 LOG.error(e1); 322 } 323 result.append("<br>\n<div class=\"dialogerror\">"); 324 // getLocale() does not work in this context!?! 325 result.append(e1.getMessageContainer().key(Locale.GERMAN)); 326 result.append("</div>"); 327 } 328 result.append("\t</td>\n"); 329 result.append("</tr>\n"); 330 result.append("</table>\n"); 331 result.append(buildHtmlHelpEnd()); 332 return result.toString(); 333 } finally { 334 getJsp().getRequestContext().setCurrentProject(m_offlineProject); 335 } 336 } 337 338 /** 339 * Returns the HTML for the head frame of the online help.<p> 340 * 341 * @return the HTML for the head frame of the online help 342 */ 343 public String displayHead() { 344 345 StringBuffer result = new StringBuffer(2048); 346 347 int buttonStyle = getSettings().getUserSettings().getWorkplaceButtonStyle(); 348 349 // change to online project to allow exporting 350 try { 351 getJsp().getRequestContext().setCurrentProject(m_onlineProject); 352 String resourcePath = getJsp().link("/system/modules/" + MODULE_NAME + "/resources/"); 353 354 result.append(buildHtmlHelpStart("workplace.css", false)); 355 result.append("<body class=\"buttons-head\" unselectable=\"on\">\n"); 356 result.append("<script src=\""); 357 result.append(getJsp().link("/system/modules/org.opencms.workplace.help/resources/search.js")); 358 result.append("\"></script>\n"); 359 360 // store home link in JS variable to use it in body frame 361 result.append("<script >\n<!--\n"); 362 result.append("\tvar homeLink = \""); 363 result.append(CmsEncoder.escapeXml(getParamHomelink())); 364 result.append("\";\n\n"); 365 result.append("//-->\n</script>\n"); 366 367 // search form with invisible elements 368 369 // search index may be attached to resource /system/modules/org.opencms.workplace.help/elements/search.jsp, 370 // property search.index. 371 String index = getJsp().property( 372 "search.index", 373 "/system/modules/org.opencms.workplace.help/elements/search.jsp", 374 "German online help", 375 false); 376 StringBuffer submitAction = new StringBuffer(); 377 submitAction.append("parseSearchQuery(document.forms[\'searchform\'],\'"); 378 submitAction.append( 379 Messages.get().getBundle(getLocale()).key( 380 Messages.GUI_HELP_ERR_SEARCH_WORD_LENGTH_1, 381 Integer.valueOf(3))).append("\');"); 382 383 result.append("<form style=\"margin: 0;\" name=\"searchform\" method=\"post\" action=\""); 384 String searchLink = getJsp().link( 385 new StringBuffer("/system/modules/org.opencms.workplace.help/elements/search.jsp?").append( 386 CmsLocaleManager.PARAMETER_LOCALE).append("=").append(getLocale()).toString()); 387 result.append(searchLink); 388 result.append("\" target=\"body\""); 389 result.append(" onsubmit=\""); 390 result.append(submitAction.toString()); 391 result.append("\">\n"); 392 result.append(" <input type=\"hidden\" name=\"action\" value=\"search\" />\n"); 393 result.append(" <input type=\"hidden\" name=\"query\" value=\"\" />\n"); 394 result.append(" <input type=\"hidden\" name=\"index\" value=\"" + index + "\" />\n"); 395 result.append(" <input type=\"hidden\" name=\"searchPage\" value=\"1\" />\n"); 396 397 result.append("<table width=\"100%\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n"); 398 result.append("<tr>\n"); 399 result.append("\t<td align=\"left\">\n"); 400 401 // display navigation buttons 402 result.append(buttonBar(HTML_START)); 403 result.append(buttonBarStartTab(0, 5)); 404 result.append(button( 405 "javascript:history.back();", 406 null, 407 "back.png", 408 org.opencms.search.Messages.GUI_HELP_BUTTON_BACK_0, 409 buttonStyle, 410 resourcePath)); 411 result.append(button( 412 "javascript:history.forward();", 413 null, 414 "next.png", 415 org.opencms.search.Messages.GUI_HELP_BUTTON_NEXT_0, 416 buttonStyle, 417 resourcePath)); 418 419 result.append(button( 420 "javascript:top.body.location.href='" + CmsEncoder.escapeXml(getParamHomelink()) + "';", 421 null, 422 "contents.png", 423 org.opencms.search.Messages.GUI_HELP_BUTTON_CONTENTS_0, 424 buttonStyle, 425 resourcePath)); 426 //search 427 result.append("<td style=\"vertical-align: top;\">"); 428 result.append("<input type=\"text\" name=\"query2\" class=\"onlineform\" style=\"width: 120px\" value=\""); 429 result.append(""); 430 result.append(" \">"); 431 result.append("</td>\n"); 432 433 result.append( 434 button( 435 new StringBuffer("javascript:").append(submitAction.toString()).toString(), 436 null, 437 null, 438 org.opencms.search.Messages.GUI_HELP_BUTTON_SEARCH_0, 439 2, 440 null)); 441 442 result.append(buttonBar(HTML_END)); 443 444 result.append("</td>\n"); 445 result.append("\t<td align=\"right\" width=\"100%\">\n"); 446 447 // display close button 448 result.append(buttonBar(HTML_START)); 449 result.append(buttonBarSeparator(5, 0)); 450 result.append(button( 451 "javascript:top.close();", 452 null, 453 "close", 454 org.opencms.search.Messages.GUI_HELP_BUTTON_CLOSE_0, 455 buttonStyle, 456 resourcePath)); 457 result.append(buttonBar(HTML_END)); 458 459 result.append("\t</td>\n"); 460 result.append("\t<td> </td>\n"); 461 result.append("<td>"); 462 463 // display logo 464 result.append("<span style=\"display: block; width: 80px; height: 22px; background-image: url(\'"); 465 result.append(getSkinUri()); 466 result.append("commons/workplace.png"); 467 result.append("\'); \"></span>"); 468 result.append("</td>"); 469 result.append("</tr>\n"); 470 result.append("</table>\n"); 471 result.append("</form>\n"); 472 result.append(buildHtmlHelpEnd()); 473 474 return result.toString(); 475 } finally { 476 // set back to offline project 477 getJsp().getRequestContext().setCurrentProject(m_offlineProject); 478 } 479 } 480 481 /** 482 * Generates the HTML for the online help frameset or redirects to the help body, depending on the build frameset flag.<p> 483 * 484 * @return the HTML for the online help frameset or an empty String (redirect) 485 * @throws IOException if redirection fails 486 */ 487 public String displayHelp() throws IOException { 488 489 String result = ""; 490 // change to online project to allow static export / export links 491 try { 492 getJsp().getRequestContext().setCurrentProject(m_onlineProject); 493 494 if (isBuildFrameset()) { 495 // build the online help frameset 496 result = displayFrameset(); 497 } else { 498 // redirect to the help body 499 StringBuffer bodyLink = new StringBuffer(8); 500 bodyLink.append(TEMPLATEPATH); 501 bodyLink.append("help_body.jsp?"); 502 bodyLink.append(CmsHelpTemplateBean.PARAM_HELPRESOURCE); 503 bodyLink.append("="); 504 bodyLink.append(getJsp().getRequestContext().getUri()); 505 bodyLink.append("&"); 506 bodyLink.append(CmsLocaleManager.PARAMETER_LOCALE); 507 bodyLink.append("="); 508 bodyLink.append(getLocale()); 509 // add the other parameters too! 510 String bodyLinkWithParams = attachRequestString(bodyLink.toString()); 511 String redirectLink = getJsp().link(bodyLinkWithParams); 512 // set back to current project 513 getJsp().getResponse().sendRedirect(redirectLink); 514 } 515 return result; 516 } finally { 517 getJsp().getRequestContext().setCurrentProject(m_onlineProject); 518 } 519 } 520 521 /** 522 * Returns the buildframe parameter indicating if the frameset should be generated.<p> 523 * 524 * @return the buildframe parameter indicating if the frameset should be generated 525 */ 526 public String getParamBuildframe() { 527 528 return m_paramBuildframe; 529 } 530 531 /** 532 * Returns the helpresource parameter value.<p> 533 * 534 * @return the helpresource parameter value 535 */ 536 public String getParamHelpresource() { 537 538 if (m_paramHelpresource == null) { 539 m_paramHelpresource = resolveMacros(PATH_HELP) + DEFAULT_HELPFILE; 540 } 541 542 return m_paramHelpresource; 543 } 544 545 /** 546 * Returns the homelink parameter value.<p> 547 * 548 * @return the homelink parameter value 549 */ 550 public String getParamHomelink() { 551 552 return m_paramHomelink; 553 } 554 555 /** 556 * Returns the workplaceresource parameter value.<p> 557 * 558 * @return the workplaceresource parameter value 559 */ 560 public String getParamWorkplaceresource() { 561 562 return m_paramWorkplaceresource; 563 } 564 565 /** 566 * Sets the buildframe parameter indicating if the frameset should be generated.<p> 567 * 568 * @param buildframe the buildframe parameter indicating if the frameset should be generated 569 */ 570 public void setParamBuildframe(String buildframe) { 571 572 m_paramBuildframe = buildframe; 573 } 574 575 /** 576 * Sets the helpresource parameter value.<p> 577 * 578 * @param helpresource the helpresource parameter value 579 */ 580 public void setParamHelpresource(String helpresource) { 581 582 m_paramHelpresource = helpresource; 583 } 584 585 /** 586 * Sets the homelink parameter value.<p> 587 * 588 * @param homelink the homelink parameter value 589 */ 590 public void setParamHomelink(String homelink) { 591 592 m_paramHomelink = homelink; 593 } 594 595 /** 596 * Sets the workplaceresource parameter value.<p> 597 * 598 * @param workplaceresource the workplaceresource parameter value 599 */ 600 public void setParamWorkplaceresource(String workplaceresource) { 601 602 m_paramWorkplaceresource = workplaceresource; 603 } 604 605 /** 606 * Returns the HTML to build the navigation of the online help folder.<p> 607 * 608 * @return the HTML to build the navigation of the online help folder 609 */ 610 protected String buildHtmlHelpNavigation() { 611 612 StringBuffer result = new StringBuffer(512); 613 // determine current URI 614 String currentUri = getParamHelpresource(); 615 // ignore ressources outside content folder: e.g. the search.html which 616 // is in the general help module and not the german or english online help folder. 617 if ((currentUri == null) || (currentUri.indexOf("/workplace/locales/") == -1)) { 618 // BUG!: getLocale().getLanguage() -> getCms().getRequestContext().getLocale() returns "en"! 619 //currentUri = "/system/workplace/locales/" + getLocale().getLanguage() + "/help/"; 620 currentUri = resolveMacros(PATH_HELP) + DEFAULT_HELPFILE; 621 } 622 // determine level of help start folder 623 int helpLevel = CmsResource.getPathLevel(PATH_HELP); 624 625 // get a list of all pages / subfolders in the help folder 626 List<CmsJspNavElement> navList = getJsp().getNavigation().getNavigationTreeForFolder(currentUri, helpLevel, 99); 627 Iterator<CmsJspNavElement> i = navList.iterator(); 628 629 while (i.hasNext()) { 630 CmsJspNavElement nav = i.next(); 631 // calculate level to display 632 int level = nav.getNavTreeLevel() - (helpLevel - 1); 633 if (nav.getResourceName().equals(currentUri) 634 || (nav.isFolderLink() && currentUri.equals(nav.getResourceName() + "index.html"))) { 635 result.append("\t\t<span class=\"navhelpcurrent\" style=\"padding-left: "); 636 result.append(level * 10); 637 result.append("px; background-position: "); 638 result.append((level - 1) * 10); 639 result.append("px 1px;\">"); 640 result.append(nav.getNavText()); 641 result.append("</span><br style=\"clear:left\">\n"); 642 } else { 643 result.append("\t\t<a class=\"navhelp\" style=\"padding-left: "); 644 result.append(level * 10); 645 result.append("px; background-position: "); 646 result.append((level - 1) * 10); 647 result.append("px 1px;\" href=\""); 648 if (nav.isFolderLink()) { 649 // append file name to folder links to avoid static export issues 650 result.append( 651 getJsp().link( 652 "/system/modules/org.opencms.workplace.help/jsptemplates/help_body.jsp?helpresource=" 653 + nav.getResourceName() 654 + "index.html&" 655 + CmsLocaleManager.PARAMETER_LOCALE 656 + "=" 657 + getLocale())); 658 } else { 659 result.append(getJsp().link( 660 "/system/modules/org.opencms.workplace.help/jsptemplates/help_body.jsp?helpresource=" 661 + nav.getResourceName() 662 + "&" 663 + CmsLocaleManager.PARAMETER_LOCALE 664 + "=" 665 + getLocale())); 666 // result.append(getJsp().link(nav.getResourceName())); 667 } 668 result.append("\">"); 669 result.append(nav.getNavText()); 670 result.append("</a><br style=\"clear:left\">\n"); 671 } 672 } 673 return result.toString(); 674 } 675 676 /** 677 * @see org.opencms.workplace.CmsWorkplace#checkRole() 678 */ 679 @Override 680 protected void checkRole() throws CmsRoleViolationException { 681 682 // needed since these pages are static exported 683 if (!OpenCms.getDefaultUsers().isUserExport(getCms().getRequestContext().getCurrentUser().getName())) { 684 // only for users that are not the export user 685 OpenCms.getRoleManager().checkRole(getCms(), CmsRole.WORKPLACE_USER); 686 } 687 } 688 689 /** 690 * Returns the HTML to build the frameset for the online help popup window.<p> 691 * 692 * @return the HTML to build the frameset for the online help popup window 693 */ 694 protected String displayFrameset() { 695 696 StringBuffer result = new StringBuffer(8); 697 result.append("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\">\n"); 698 result.append("<html>\n"); 699 result.append("<head>\n"); 700 result.append("\t<title>"); 701 result.append(key(Messages.GUI_HELP_FRAMESET_TITLE_0)); 702 result.append("</title>\n"); 703 704 // script to avoid frameset display errors 705 result.append("<script >\n<!--\n"); 706 result.append("\t if (window.name == \"body\") {\n"); 707 result.append("\t\ttop.location.href = \"" + getJsp().link(getJsp().getRequestContext().getUri()) + "\";\n"); 708 result.append("\t}\n"); 709 result.append("//-->\n</script>\n"); 710 result.append("<meta HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=utf-8\">\n"); 711 712 result.append("</head>\n\n"); 713 result.append("<frameset rows=\"24,*\" border=\"0\" frameborder=\"0\" framespacing=\"0\">\n"); 714 result.append("\t<frame name=\"head\" src=\""); 715 716 StringBuffer headLink = new StringBuffer(8); 717 headLink.append(TEMPLATEPATH); 718 headLink.append("help_head.jsp?"); 719 headLink.append(CmsLocaleManager.PARAMETER_LOCALE); 720 headLink.append("="); 721 headLink.append(getLocale()); 722 headLink.append("&"); 723 headLink.append(PARAM_HOMELINK); 724 headLink.append("="); 725 headLink.append(getParamHomelink()); 726 result.append(CmsEncoder.escapeXml(getJsp().link(attachRequestString(headLink.toString())))); 727 result.append("\" scrolling=\"no\" noresize>\n"); 728 result.append("\t<frame name=\"body\" src=\""); 729 StringBuffer bodyLink = new StringBuffer(8); 730 bodyLink.append(TEMPLATEPATH); 731 bodyLink.append("help_body.jsp?"); 732 bodyLink.append(CmsHelpTemplateBean.PARAM_HELPRESOURCE); 733 bodyLink.append("="); 734 bodyLink.append(getJsp().getRequestContext().getUri()); 735 bodyLink.append("&"); 736 bodyLink.append(CmsLocaleManager.PARAMETER_LOCALE); 737 bodyLink.append("="); 738 bodyLink.append(getLocale()); 739 result.append(getJsp().link(bodyLink.toString())); 740 result.append("\" scrolling=\"auto\" noresize>\n"); 741 result.append("</frameset>\n\n"); 742 result.append("<body></body>\n"); 743 result.append("</html>"); 744 745 return result.toString(); 746 } 747 748 /** 749 * Determines the mapped help page for a given workplace resource URI.<p> 750 * 751 * If a mapping information is found, the requested URI is set to the found value.<p> 752 * 753 * If no workplace resource URI is given, nothing is changed.<p> 754 */ 755 protected void getMappedHelpUri() { 756 757 try { 758 getJsp().getRequestContext().setCurrentProject(m_onlineProject); 759 if (CmsStringUtil.isNotEmpty(getParamWorkplaceresource())) { 760 // found a workplace resource parameter, try to get a mapping for it 761 String helpResource = null; 762 String wpResource = getParamWorkplaceresource(); 763 int xmlPageId; 764 try { 765 xmlPageId = OpenCms.getResourceManager().getResourceType( 766 CmsResourceTypeXmlPage.getStaticTypeName()).getTypeId(); 767 } catch (CmsLoaderException e1) { 768 xmlPageId = CmsResourceTypeXmlPage.getStaticTypeId(); 769 } 770 if (getCms().existsResource( 771 resolveMacros(getParamWorkplaceresource()), 772 CmsResourceFilter.requireType(xmlPageId))) { 773 // given workplace resource is a page in VFS, use it as start point 774 helpResource = resolveMacros(getParamWorkplaceresource()); 775 setParamHomelink(getJsp().link(helpResource)); 776 } else { 777 // given workplace resource does not exist, resolve mapping 778 try { 779 780 // try to read the mappings from the current module 781 String absolutePath = OpenCms.getSystemInfo().getAbsoluteRfsPathRelativeToWebInf( 782 resolveMacros(RFS_HELPMAPPINGS)); 783 CmsParameterConfiguration props = new CmsParameterConfiguration(absolutePath); 784 785 // remove context from workplace path 786 wpResource = CmsLinkManager.removeOpenCmsContext(wpResource); 787 788 // determine mapping for workplace resource 789 while ((wpResource != null) && CmsStringUtil.isEmpty(helpResource)) { 790 helpResource = props.getString(wpResource, null); 791 wpResource = CmsResource.getParentFolder(wpResource); 792 } 793 } catch (IOException e) { 794 // no mappings found in module, ignore 795 } 796 797 if (CmsStringUtil.isEmpty(helpResource)) { 798 // no mapping found, use default help URI 799 helpResource = DEFAULT_HELPFILE; 800 } 801 // create path to the help resource 802 helpResource = resolveMacros(PATH_HELP) + helpResource; 803 if (!getCms().existsResource(helpResource, CmsResourceFilter.IGNORE_EXPIRATION)) { 804 helpResource = resolveMacros(PATH_HELP) + DEFAULT_HELPFILE; 805 } 806 setParamHomelink(getJsp().link(resolveMacros(PATH_HELP) + DEFAULT_HELPFILE)); 807 } 808 // set URI to found help page URI 809 getJsp().getRequestContext().setUri(helpResource); 810 } 811 812 } finally { 813 getJsp().getRequestContext().setCurrentProject(m_offlineProject); 814 } 815 } 816 817 /** 818 * @see org.opencms.workplace.CmsWorkplace#initWorkplaceRequestValues(org.opencms.workplace.CmsWorkplaceSettings, javax.servlet.http.HttpServletRequest) 819 */ 820 @Override 821 protected void initWorkplaceRequestValues(CmsWorkplaceSettings settings, HttpServletRequest request) { 822 823 // fill the parameter values in the get/set methods 824 fillParamValues(request); 825 826 // determine initial page to show on frameset generation 827 if (isBuildFrameset()) { 828 // get the mapped URI 829 getMappedHelpUri(); 830 } 831 } 832 833 /** 834 * Returns true if the online help frameset has to be generated.<p> 835 * 836 * @return true if the online help frameset has to be generated, otherwise false 837 */ 838 protected boolean isBuildFrameset() { 839 840 return Boolean.valueOf(getParamBuildframe()).booleanValue(); 841 } 842 843 /** 844 * Attaches the resource name to the request as parameter.<p> 845 * 846 * @param resourceName a name of a resource 847 * 848 * @return The given resource name with additional request parameter concatenations of the 849 * current request on this <code>CmsDialog</code> 850 */ 851 private String attachRequestString(String resourceName) { 852 853 StringBuffer result = new StringBuffer(resourceName); 854 boolean firstParam = true; 855 if (resourceName.indexOf('?') == -1) { 856 // no params in uri yet? 857 result.append('?'); 858 } else { 859 firstParam = false; 860 } 861 862 @SuppressWarnings("unchecked") 863 Map<String, String[]> params = getJsp().getRequest().getParameterMap(); 864 Iterator<Map.Entry<String, String[]>> it = params.entrySet().iterator(); 865 String[] values = null; 866 while (it.hasNext()) { 867 if (values == null) { 868 // first iteration: check if params before so an & has to be used. 869 if (!firstParam) { 870 result.append('&'); 871 } 872 } else { 873 result.append("&"); 874 } 875 Map.Entry<String, String[]> entry = it.next(); 876 result.append(entry.getKey().toString()).append('='); 877 values = entry.getValue(); 878 for (int i = 0; i < values.length; i++) { 879 result.append(values[i]); 880 if ((i + 1) < values.length) { 881 result.append(','); 882 } 883 } 884 } 885 return result.toString(); 886 } 887 888}