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.tools; 029 030import org.opencms.file.CmsObject; 031import org.opencms.file.CmsProperty; 032import org.opencms.file.CmsPropertyDefinition; 033import org.opencms.file.CmsResource; 034import org.opencms.i18n.CmsEncoder; 035import org.opencms.i18n.CmsMessages; 036import org.opencms.jsp.CmsJspNavBuilder; 037import org.opencms.jsp.CmsJspNavElement; 038import org.opencms.main.CmsException; 039import org.opencms.main.CmsLog; 040import org.opencms.util.CmsStringUtil; 041import org.opencms.workplace.CmsWorkplace; 042 043import java.util.HashMap; 044import java.util.Iterator; 045import java.util.Map; 046 047import org.apache.commons.logging.Log; 048 049/** 050 * Helper class to build easily other admin tool handlers.<p> 051 * 052 * @since 6.0.0 053 */ 054public abstract class A_CmsToolHandler implements I_CmsToolHandler { 055 056 /** Property for the parameters argument.<p> */ 057 public static final String ARG_PARAM_NAME = "params"; 058 059 /** Property for the path argument.<p> */ 060 public static final String ARG_PATH_NAME = "path"; 061 062 /** Property definition for the arguments.<p> */ 063 public static final String ARGS_PROPERTY_DEFINITION = "admintoolhandler-args"; 064 065 /** Argument separator.<p> */ 066 public static final String ARGUMENT_SEPARATOR = "|"; 067 068 /** Default disabled help text constant.<p> */ 069 public static final String DEFAULT_DISABLED_HELPTEXT = "${key." + Messages.GUI_TOOLS_DISABLED_HELP_0 + "}"; 070 071 /** Argument name and value separator.<p> */ 072 public static final String VALUE_SEPARATOR = ":"; 073 074 /** Property for the confirmation message argument.<p> */ 075 private static final String ARG_CONFIRMATION_NAME = "confirmation"; 076 077 /** The static log object for this class. */ 078 private static final Log LOG = CmsLog.getLog(A_CmsToolHandler.class); 079 080 /** Confirmation message. */ 081 private String m_confirmationMessage; 082 083 /** Help text or description if disabled. */ 084 private String m_disabledHelpText; 085 086 /** Group to be included in. */ 087 private String m_group; 088 089 /** Help text or description. */ 090 private String m_helpText; 091 092 /** Icon path (32x32). */ 093 private String m_iconPath; 094 095 /** Link pointer. */ 096 private String m_link; 097 098 /** Display name. */ 099 private String m_name; 100 101 /** Needed parameters. */ 102 private String m_parameters; 103 104 /** Tool path to install in. */ 105 private String m_path; 106 107 /** Relative position in group. */ 108 private float m_position; 109 110 /** Menu item name. */ 111 private String m_shortName; 112 113 /** Small icon path (16x16). */ 114 private String m_smallIconPath; 115 116 /** 117 * Returns the confirmation Message.<p> 118 * 119 * @return the confirmation Message 120 */ 121 public String getConfirmationMessage() { 122 123 return m_confirmationMessage; 124 } 125 126 /** 127 * @see org.opencms.workplace.tools.I_CmsToolHandler#getDisabledHelpText() 128 */ 129 public String getDisabledHelpText() { 130 131 return m_disabledHelpText; 132 } 133 134 /** 135 * @see org.opencms.workplace.tools.I_CmsToolHandler#getGroup() 136 */ 137 public String getGroup() { 138 139 return m_group; 140 } 141 142 /** 143 * @see org.opencms.workplace.tools.I_CmsToolHandler#getHelpText() 144 */ 145 public String getHelpText() { 146 147 return m_helpText; 148 } 149 150 /** 151 * @see org.opencms.workplace.tools.I_CmsToolHandler#getIconPath() 152 */ 153 public String getIconPath() { 154 155 return m_iconPath; 156 } 157 158 /** 159 * @see org.opencms.workplace.tools.I_CmsToolHandler#getLink() 160 */ 161 public String getLink() { 162 163 return m_link; 164 } 165 166 /** 167 * @see org.opencms.workplace.tools.I_CmsToolHandler#getName() 168 */ 169 public String getName() { 170 171 return m_name; 172 } 173 174 /** 175 * @see org.opencms.workplace.tools.I_CmsToolHandler#getParameters(org.opencms.workplace.CmsWorkplace) 176 */ 177 public Map<String, String[]> getParameters(CmsWorkplace wp) { 178 179 Map<String, String[]> argMap = new HashMap<String, String[]>(); 180 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(m_parameters)) { 181 String toolParams = CmsEncoder.decode(wp.resolveMacros(m_parameters)); 182 Iterator<String> itArgs = CmsStringUtil.splitAsList(toolParams, "&").iterator(); 183 while (itArgs.hasNext()) { 184 String arg = itArgs.next(); 185 int pos = arg.indexOf("="); 186 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(arg.substring(pos + 1))) { 187 argMap.put(arg.substring(0, pos), new String[] {arg.substring(pos + 1)}); 188 } 189 } 190 } 191 return argMap; 192 } 193 194 /** 195 * @see org.opencms.workplace.tools.I_CmsToolHandler#getPath() 196 */ 197 public String getPath() { 198 199 return m_path; 200 } 201 202 /** 203 * @see org.opencms.workplace.tools.I_CmsToolHandler#getPosition() 204 */ 205 public float getPosition() { 206 207 return m_position; 208 } 209 210 /** 211 * @see org.opencms.workplace.tools.I_CmsToolHandler#getShortName() 212 */ 213 public String getShortName() { 214 215 return m_shortName; 216 } 217 218 /** 219 * @see org.opencms.workplace.tools.I_CmsToolHandler#getSmallIconPath() 220 */ 221 public String getSmallIconPath() { 222 223 return m_smallIconPath; 224 } 225 226 /** 227 * @see org.opencms.workplace.tools.I_CmsToolHandler#isEnabled(org.opencms.workplace.CmsWorkplace) 228 */ 229 public boolean isEnabled(CmsWorkplace wp) { 230 231 return isEnabled(wp.getCms()); 232 } 233 234 /** 235 * @see org.opencms.workplace.tools.I_CmsToolHandler#isVisible(org.opencms.workplace.CmsWorkplace) 236 */ 237 public boolean isVisible(CmsWorkplace wp) { 238 239 return isVisible(wp.getCms()); 240 } 241 242 /** 243 * Sets the confirmation Message.<p> 244 * 245 * @param confirmationMessage the confirmation Message to set 246 */ 247 public void setConfirmationMessage(String confirmationMessage) { 248 249 m_confirmationMessage = confirmationMessage; 250 } 251 252 /** 253 * Sets the help text if disabled.<p> 254 * 255 * @param disabledHelpText the help text to set 256 */ 257 public void setDisabledHelpText(String disabledHelpText) { 258 259 m_disabledHelpText = disabledHelpText; 260 } 261 262 /** 263 * Sets the group.<p> 264 * 265 * @param group the group to set 266 */ 267 public void setGroup(String group) { 268 269 m_group = group; 270 } 271 272 /** 273 * Sets the help text.<p> 274 * 275 * @param helpText the help text to set 276 */ 277 public void setHelpText(String helpText) { 278 279 m_helpText = helpText; 280 } 281 282 /** 283 * Sets the icon path.<p> 284 * 285 * @param iconPath the icon path to set 286 */ 287 public void setIconPath(String iconPath) { 288 289 m_iconPath = iconPath; 290 } 291 292 /** 293 * Sets the link.<p> 294 * 295 * @param link the link to set 296 */ 297 public void setLink(String link) { 298 299 m_link = link; 300 } 301 302 /** 303 * Sets the name.<p> 304 * 305 * @param name the name to set 306 */ 307 public void setName(String name) { 308 309 m_name = name; 310 } 311 312 /** 313 * Sets the parameter string.<p> 314 * 315 * @param paramString the parameter string to set 316 */ 317 public void setParameterString(String paramString) { 318 319 m_parameters = paramString; 320 } 321 322 /** 323 * Sets the path.<p> 324 * 325 * @param path the path to set 326 */ 327 public void setPath(String path) { 328 329 m_path = path; 330 } 331 332 /** 333 * Sets the position.<p> 334 * 335 * @param position the position to set 336 */ 337 public void setPosition(float position) { 338 339 m_position = position; 340 } 341 342 /** 343 * Sets the short name.<p> 344 * 345 * @param shortName the short name to set 346 */ 347 public void setShortName(String shortName) { 348 349 m_shortName = shortName; 350 } 351 352 /** 353 * Sets the small icon path.<p> 354 * 355 * @param smallIconPath the samll icon path to set 356 */ 357 public void setSmallIconPath(String smallIconPath) { 358 359 m_smallIconPath = smallIconPath; 360 } 361 362 /** 363 * Default implementation.<p> 364 * 365 * It takes the icon path from <code>{@link org.opencms.file.CmsPropertyDefinition#PROPERTY_NAVIMAGE}</code> property, 366 * or uses a default icon if undefined, the name is taken from the 367 * <code>{@link org.opencms.file.CmsPropertyDefinition#PROPERTY_NAVTEXT}</code> property, 368 * or uses the <code>{@link org.opencms.file.CmsPropertyDefinition#PROPERTY_TITLE}</code> property if undefined, 369 * or an default text, if still undefined. if you want 2 different names, one for the big icon tools and one for 370 * the menu/navbar entries, use a <code>{@link A_CmsToolHandler#VALUE_SEPARATOR}</code> to separate them in the property. 371 * (if you do so, the first one is for big icons and the second one for menu/navbar entries). the help text is taken from the 372 * <code>{@link org.opencms.file.CmsPropertyDefinition#PROPERTY_DESCRIPTION}</code> property or a 373 * default text if undefined, if you want to customize a help text while disabled, use a 374 * <code>{@link A_CmsToolHandler#VALUE_SEPARATOR}</code> as a separator in the same property.<p> 375 * 376 * The group is taken from the <code>{@link org.opencms.file.CmsPropertyDefinition#PROPERTY_NAVINFO}</code> property, 377 * the position from the <code>{@link org.opencms.file.CmsPropertyDefinition#PROPERTY_NAVPOS}</code> 378 * and the install path is given by the folder structure if the <code>{@link #ARGS_PROPERTY_DEFINITION}</code> 379 * property does not include path information.<p> 380 * 381 * For the icon path you can specify 2 paths separated by a <code>{@link A_CmsToolHandler#VALUE_SEPARATOR}</code>, 382 * the first one will be used as a group icon (32x32), and the second as an menu icon (16x16). The paths are relative 383 * to the /system/workplace/resources/ folder. If the tool is disabled, the names of the icons are composed as 384 * ${name}_disabled.${ext}<p> 385 * 386 * The confirmation message is taken from the <code>{@link #ARGS_PROPERTY_DEFINITION}</code> with key 387 * <code>#ARG_CONFIRMATION_NAME</code> 388 * 389 * @see org.opencms.workplace.tools.I_CmsToolHandler#setup(org.opencms.file.CmsObject, CmsToolRootHandler, java.lang.String) 390 */ 391 public boolean setup(CmsObject cms, CmsToolRootHandler root, String resourcePath) { 392 393 try { 394 resourcePath = cms.getSitePath(cms.readResource(resourcePath)); 395 } catch (CmsException e) { 396 // should not happen 397 if (LOG.isErrorEnabled()) { 398 LOG.error(e.getLocalizedMessage(), e); 399 } 400 } 401 CmsJspNavElement navElem = new CmsJspNavBuilder(cms).getNavigationForResource(resourcePath); 402 403 String name = navElem.getNavText(); 404 if (CmsMessages.isUnknownKey(name)) { 405 name = navElem.getTitle(); 406 } 407 if (CmsStringUtil.isEmptyOrWhitespaceOnly(name)) { 408 name = "${key." + Messages.GUI_TOOLS_DEFAULT_NAME_0 + "}"; 409 } 410 String shortName = name; 411 if (name.indexOf(VALUE_SEPARATOR) >= 0) { 412 shortName = name.substring(0, name.indexOf(VALUE_SEPARATOR)); 413 name = name.substring(name.indexOf(VALUE_SEPARATOR) + 1); 414 } 415 setName(name); 416 setShortName(shortName); 417 418 String iconPath = navElem.getNavImage(); 419 if (CmsStringUtil.isEmptyOrWhitespaceOnly(iconPath)) { 420 iconPath = "admin/images/default_tool_big.png:admin/images/default_tool_small.png"; 421 } 422 String smallIconPath = iconPath; 423 if (iconPath.indexOf(VALUE_SEPARATOR) >= 0) { 424 smallIconPath = iconPath.substring(iconPath.indexOf(VALUE_SEPARATOR) + 1); 425 iconPath = iconPath.substring(0, iconPath.indexOf(VALUE_SEPARATOR)); 426 } 427 setIconPath(iconPath); 428 setSmallIconPath(smallIconPath); 429 430 String helpText = navElem.getDescription(); 431 if (CmsStringUtil.isEmptyOrWhitespaceOnly(helpText)) { 432 helpText = "${key." + Messages.GUI_TOOLS_DEFAULT_HELP_0 + "}"; 433 } 434 String disabledHelpText = DEFAULT_DISABLED_HELPTEXT; 435 if (helpText.indexOf(VALUE_SEPARATOR) >= 0) { 436 disabledHelpText = helpText.substring(helpText.indexOf(VALUE_SEPARATOR) + 1); 437 helpText = helpText.substring(0, helpText.indexOf(VALUE_SEPARATOR)); 438 } 439 setHelpText(helpText); 440 setDisabledHelpText(disabledHelpText); 441 442 String group = navElem.getInfo(); 443 if (CmsStringUtil.isEmptyOrWhitespaceOnly(group)) { 444 group = "${key." + Messages.GUI_TOOLS_DEFAULT_GROUP_0 + "}"; 445 } 446 447 String path = resourcePath; 448 setLink(cms, resourcePath); 449 if (CmsResource.isFolder(path)) { 450 path = CmsToolManager.TOOLPATH_SEPARATOR 451 + resourcePath.substring( 452 root.getUri().length(), 453 resourcePath.lastIndexOf(CmsToolManager.TOOLPATH_SEPARATOR)); 454 } else { 455 if (resourcePath.lastIndexOf('.') > -1) { 456 path = CmsToolManager.TOOLPATH_SEPARATOR 457 + resourcePath.substring(root.getUri().length(), resourcePath.lastIndexOf('.')); 458 } else { 459 path = CmsToolManager.TOOLPATH_SEPARATOR + resourcePath.substring(root.getUri().length()); 460 } 461 } 462 // install point 463 setPath(path); 464 setGroup(group); 465 setPosition(navElem.getNavPosition()); 466 467 // parameters 468 setParameters(cms, resourcePath); 469 470 return !path.equals(resourcePath); 471 } 472 473 /** 474 * @see java.lang.Object#toString() 475 */ 476 @Override 477 public String toString() { 478 479 return m_path + " - " + m_group + " - " + m_position; 480 } 481 482 /** 483 * Sets the link for the given resource.<p> 484 * 485 * Use the <code>resourcePath</code> as link if it is not a folder. 486 * 487 * If it is a folder, try to use the folder default file property value as link. 488 * if not use the {@link CmsToolManager#VIEW_JSPPAGE_LOCATION}. 489 * 490 * @param cms the cms context 491 * @param resourcePath the path to the resource to set the link for 492 */ 493 protected void setLink(CmsObject cms, String resourcePath) { 494 495 String link = resourcePath; 496 try { 497 // make sure the res is a folder 498 cms.readFolder(resourcePath); 499 500 // adjust the path 501 if (resourcePath.endsWith(CmsToolManager.TOOLPATH_SEPARATOR)) { 502 resourcePath = resourcePath.substring(0, resourcePath.lastIndexOf(CmsToolManager.TOOLPATH_SEPARATOR)); 503 } 504 505 // set admin page as link 506 link = CmsToolManager.VIEW_JSPPAGE_LOCATION; 507 508 // try to use the folder default file as link 509 CmsProperty prop = cms.readPropertyObject(resourcePath, CmsPropertyDefinition.PROPERTY_DEFAULT_FILE, false); 510 String defFile = "index.jsp"; 511 if (!prop.isNullProperty()) { 512 defFile = prop.getValue(); 513 } 514 if (!defFile.startsWith(CmsToolManager.TOOLPATH_SEPARATOR)) { 515 // try to use this relative link 516 defFile = resourcePath + CmsToolManager.TOOLPATH_SEPARATOR + defFile; 517 } 518 if (defFile.indexOf("?") > 0) { 519 if (cms.existsResource(defFile.substring(0, defFile.indexOf("?")))) { 520 link = defFile; 521 } 522 } else if (cms.existsResource(defFile)) { 523 link = defFile; 524 } 525 } catch (CmsException e) { 526 // not a folder or no default file, ignore 527 } 528 529 setLink(link); 530 } 531 532 /** 533 * Sets the needed properties from the {@link #ARGS_PROPERTY_DEFINITION} property of the given resource.<p> 534 * 535 * @param cms the cms context 536 * @param resourcePath the path to the resource to read the property from 537 */ 538 protected void setParameters(CmsObject cms, String resourcePath) { 539 540 try { 541 CmsProperty prop = cms.readPropertyObject(resourcePath, ARGS_PROPERTY_DEFINITION, false); 542 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(prop.getValue())) { 543 Map<String, String> argsMap = new HashMap<String, String>(); 544 Iterator<String> itArgs = CmsStringUtil.splitAsList(prop.getValue(), ARGUMENT_SEPARATOR).iterator(); 545 while (itArgs.hasNext()) { 546 String arg = ""; 547 try { 548 arg = itArgs.next(); 549 int pos = arg.indexOf(VALUE_SEPARATOR); 550 argsMap.put(arg.substring(0, pos), arg.substring(pos + 1)); 551 } catch (StringIndexOutOfBoundsException e) { 552 LOG.error("sep: " + VALUE_SEPARATOR + "arg: " + arg); 553 throw e; 554 } 555 } 556 if (argsMap.get(ARG_PATH_NAME) != null) { 557 setPath(argsMap.get(ARG_PATH_NAME)); 558 } 559 if (argsMap.get(ARG_CONFIRMATION_NAME) != null) { 560 setConfirmationMessage(argsMap.get(ARG_CONFIRMATION_NAME)); 561 } 562 if (argsMap.get(ARG_PARAM_NAME) != null) { 563 setParameterString(argsMap.get(ARG_PARAM_NAME)); 564 } 565 } 566 } catch (CmsException e) { 567 // should never happen 568 if (LOG.isErrorEnabled()) { 569 LOG.error(e.getLocalizedMessage(), e); 570 } 571 } 572 } 573}