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; 029 030import org.opencms.ade.configuration.CmsElementView; 031import org.opencms.ade.containerpage.shared.CmsCntPageData.ElementDeleteMode; 032import org.opencms.ade.galleries.shared.CmsGallerySearchScope; 033import org.opencms.ade.upload.CmsDefaultUploadRestriction; 034import org.opencms.ade.upload.I_CmsUploadRestriction; 035import org.opencms.configuration.CmsAdditionalLogFolderConfig; 036import org.opencms.configuration.CmsDefaultUserSettings; 037import org.opencms.db.CmsExportPoint; 038import org.opencms.db.CmsUserSettings; 039import org.opencms.db.I_CmsProjectDriver; 040import org.opencms.file.CmsFolder; 041import org.opencms.file.CmsObject; 042import org.opencms.file.CmsProject; 043import org.opencms.file.CmsPropertyDefinition; 044import org.opencms.file.CmsRequestContext; 045import org.opencms.file.CmsResource; 046import org.opencms.file.CmsResourceFilter; 047import org.opencms.file.CmsUser; 048import org.opencms.file.CmsVfsResourceNotFoundException; 049import org.opencms.file.types.CmsResourceTypeFolder; 050import org.opencms.file.types.CmsResourceTypeFolderExtended; 051import org.opencms.file.types.I_CmsResourceType; 052import org.opencms.i18n.CmsAcceptLanguageHeaderParser; 053import org.opencms.i18n.CmsEncoder; 054import org.opencms.i18n.CmsI18nInfo; 055import org.opencms.i18n.CmsLocaleComparator; 056import org.opencms.i18n.CmsLocaleManager; 057import org.opencms.i18n.I_CmsLocaleHandler; 058import org.opencms.loader.CmsLoaderException; 059import org.opencms.main.CmsBroadcast.ContentMode; 060import org.opencms.main.CmsEvent; 061import org.opencms.main.CmsException; 062import org.opencms.main.CmsLog; 063import org.opencms.main.I_CmsEventListener; 064import org.opencms.main.OpenCms; 065import org.opencms.module.CmsModule; 066import org.opencms.module.CmsModuleManager; 067import org.opencms.relations.CmsCategoryService; 068import org.opencms.security.CmsOrganizationalUnit; 069import org.opencms.security.CmsPermissionSet; 070import org.opencms.security.CmsPermissionViolationException; 071import org.opencms.security.CmsRole; 072import org.opencms.security.CmsRoleViolationException; 073import org.opencms.security.I_CmsPrincipal; 074import org.opencms.util.CmsRfsFileViewer; 075import org.opencms.util.CmsStringUtil; 076import org.opencms.util.CmsUUID; 077import org.opencms.workplace.CmsAccountInfo.Field; 078import org.opencms.workplace.editors.CmsEditorDisplayOptions; 079import org.opencms.workplace.editors.CmsEditorHandler; 080import org.opencms.workplace.editors.CmsWorkplaceEditorManager; 081import org.opencms.workplace.editors.I_CmsEditorActionHandler; 082import org.opencms.workplace.editors.I_CmsEditorCssHandler; 083import org.opencms.workplace.editors.I_CmsEditorHandler; 084import org.opencms.workplace.editors.I_CmsPreEditorActionDefinition; 085import org.opencms.workplace.editors.directedit.CmsDirectEditDefaultProvider; 086import org.opencms.workplace.editors.directedit.I_CmsDirectEditProvider; 087import org.opencms.workplace.explorer.CmsExplorerTypeAccess; 088import org.opencms.workplace.explorer.CmsExplorerTypeSettings; 089import org.opencms.workplace.galleries.A_CmsAjaxGallery; 090import org.opencms.workplace.tools.CmsToolManager; 091 092import java.io.IOException; 093import java.io.UnsupportedEncodingException; 094import java.net.URL; 095import java.util.ArrayList; 096import java.util.Arrays; 097import java.util.Collections; 098import java.util.Enumeration; 099import java.util.HashMap; 100import java.util.HashSet; 101import java.util.Iterator; 102import java.util.List; 103import java.util.Locale; 104import java.util.Map; 105import java.util.Set; 106import java.util.concurrent.TimeUnit; 107import java.util.jar.Manifest; 108import java.util.regex.Pattern; 109import java.util.regex.PatternSyntaxException; 110 111import javax.servlet.http.HttpServletRequest; 112import javax.servlet.http.HttpSession; 113 114import org.apache.commons.logging.Log; 115 116import com.google.common.cache.Cache; 117import com.google.common.cache.CacheBuilder; 118import com.google.common.collect.Lists; 119import com.google.common.collect.Maps; 120import com.google.common.collect.Sets; 121 122/** 123 * Manages the global OpenCms workplace settings for all users.<p> 124 * 125 * This class reads the settings from the "opencms.properties" and stores them in member variables. 126 * For each setting one or more get methods are provided.<p> 127 * 128 * @since 6.0.0 129 */ 130public final class CmsWorkplaceManager implements I_CmsLocaleHandler, I_CmsEventListener { 131 132 /** 133 * Helper class used to easily define default view mappings for standard resource types.<p> 134 */ 135 static class ViewRules { 136 137 /** 138 * Internal view map.<p> 139 */ 140 private Map<String, String> m_viewMap = Maps.newHashMap(); 141 142 /** 143 * Creates a new instance.<p> 144 * 145 * @param rules an array of strings of the form 'foo,bar,baz:view1', where foo, ... are type names and view1 is a view name (explorertype) 146 */ 147 public ViewRules(String... rules) { 148 149 for (String rule : rules) { 150 int colIndex = rule.indexOf(':'); 151 if (colIndex != -1) { 152 String before = rule.substring(0, colIndex); 153 String after = rule.substring(colIndex + 1); 154 for (String token : CmsStringUtil.splitAsList(before, ",")) { 155 m_viewMap.put(token.trim(), after); 156 } 157 } 158 159 } 160 } 161 162 /** 163 * Gets the view configured for the given type.<p> 164 * 165 * @param type a resource type name 166 * @return the view explorer type for the given resource type 167 */ 168 public String getViewForType(String type) { 169 170 return m_viewMap.get(type); 171 172 } 173 } 174 175 /** The default encoding for the workplace (UTF-8). */ 176 public static final String DEFAULT_WORKPLACE_ENCODING = CmsEncoder.ENCODING_UTF_8; 177 178 /** The workplace localization manifest attribute name. */ 179 public static final String LOCALIZATION_ATTRIBUTE_NAME = "OpenCms-Localization"; 180 181 /** The manifest file resource name. */ 182 public static final String MANIFEST_RESOURCE_NAME = "META-INF/MANIFEST.MF"; 183 184 /** The id of the "requestedResource" parameter for the OpenCms login form. */ 185 public static final String PARAM_LOGIN_REQUESTED_RESOURCE = "requestedResource"; 186 187 /** Key name for the session workplace settings. */ 188 public static final String SESSION_WORKPLACE_SETTINGS = "__CmsWorkplace.WORKPLACE_SETTINGS"; 189 190 /** Default view configuration. */ 191 static ViewRules m_defaultViewRules = new ViewRules( 192 "folder,plain,jsp,htmlredirect,containerpage:view_basic", 193 "imagegallery,downloadgallery,linkgallery,subsitemap,content_folder:view_folders", 194 "formatter_config,xmlvfsbundle,propertyvfsbundle,bundledescriptor,sitemap_config,sitemap_master_config,site_plugin,attr_editor_config,module_config,elementview,seo_file,containerpage_template,inheritance_config,macro_formatter,flex_formatter,settings_config:view_configs", 195 "xmlcontent,pointer:view_other"); 196 197 /** The default account infos. */ 198 private static final CmsAccountInfo[] DEFAULT_ACCOUNT_INFOS = new CmsAccountInfo[] { 199 new CmsAccountInfo(Field.firstname, null, false), 200 new CmsAccountInfo(Field.lastname, null, false), 201 new CmsAccountInfo(Field.email, null, false), 202 new CmsAccountInfo(Field.institution, null, false)}; 203 204 /** The logger for this class. */ 205 private static final Log LOG = CmsLog.getLog(CmsWorkplaceManager.class); 206 207 /** Value of the acacia-unlock configuration option (may be null if not set). */ 208 private String m_acaciaUnlock; 209 210 /** The configured account infos. */ 211 private List<CmsAccountInfo> m_accountInfos; 212 213 /** The admin cms context. */ 214 private CmsObject m_adminCms; 215 216 /** Indicates if auto-locking of resources is enabled or disabled. */ 217 private boolean m_autoLockResources; 218 219 /** The name of the local category folder(s). */ 220 private String m_categoryFolder; 221 222 /** The default access for explorer types. */ 223 private CmsExplorerTypeAccess m_defaultAccess; 224 225 /** The configured default locale of the workplace. */ 226 private Locale m_defaultLocale; 227 228 /** The default property setting for setting new property values. */ 229 private boolean m_defaultPropertiesOnStructure; 230 231 /** The default user settings. */ 232 private CmsDefaultUserSettings m_defaultUserSettings; 233 234 /** The configured dialog handlers. */ 235 private Map<String, I_CmsDialogHandler> m_dialogHandler; 236 237 /** The configured direct edit provider. */ 238 private I_CmsDirectEditProvider m_directEditProvider; 239 240 /** A flag, indicating if the categories should be displayed separated by repository in the category selection dialog. */ 241 private boolean m_displayCategoriesByRepository; 242 243 /** A flag, indicating if the categories should be displayed separated by repository in the category selection dialog. */ 244 private boolean m_displayCategorySelectionCollapsed; 245 246 /** The edit action handler. */ 247 private I_CmsEditorActionHandler m_editorAction; 248 249 /** The editor CSS handlers. */ 250 private List<I_CmsEditorCssHandler> m_editorCssHandlers; 251 252 /** The workplace editor display options. */ 253 private CmsEditorDisplayOptions m_editorDisplayOptions; 254 255 /** The editor handler. */ 256 private I_CmsEditorHandler m_editorHandler; 257 258 /** The editor manager. */ 259 private CmsWorkplaceEditorManager m_editorManager; 260 261 /** The element delete mode. */ 262 private ElementDeleteMode m_elementDeleteMode; 263 264 /** The flag if switching tabs in the advanced property dialog is enabled. */ 265 private boolean m_enableAdvancedPropertyTabs; 266 267 /** The configured encoding of the workplace. */ 268 private String m_encoding; 269 270 /** The explorer type settings. */ 271 private List<CmsExplorerTypeSettings> m_explorerTypeSettings; 272 273 /** The explorer type settings from the configured modules. */ 274 private List<CmsExplorerTypeSettings> m_explorerTypeSettingsFromModules; 275 276 /** The explorer type settings from the XML configuration. */ 277 private List<CmsExplorerTypeSettings> m_explorerTypeSettingsFromXml; 278 279 /** The explorer type settings as Map with resource type name as key. */ 280 private Map<String, CmsExplorerTypeSettings> m_explorerTypeSettingsMap; 281 282 /** The element views generated from explorer types. */ 283 private Map<CmsUUID, CmsElementView> m_explorerTypeViews = Maps.newHashMap(); 284 285 /** The workplace export points. */ 286 private Set<CmsExportPoint> m_exportPoints; 287 288 /** Maximum size of an upload file. */ 289 private int m_fileMaxUploadSize; 290 291 /** The instance used for reading portions of lines of a file to choose. */ 292 private CmsRfsFileViewer m_fileViewSettings; 293 294 /** The configured workplace galleries. */ 295 private Map<String, A_CmsAjaxGallery> m_galleries; 296 297 /** The configured gallery default scope. */ 298 private String m_galleryDefaultScope; 299 300 /** The group translation. */ 301 private I_CmsGroupNameTranslation m_groupNameTranslation; 302 303 /** The configured group translation class name. */ 304 private String m_groupTranslationClass; 305 306 /** Keep-alive flag. */ 307 private Boolean m_keepAlive; 308 309 /** Contains all folders that should be labeled if siblings exist. */ 310 private List<String> m_labelSiteFolders; 311 312 /** List of installed workplace locales, sorted ascending. */ 313 private List<Locale> m_locales; 314 315 /** The configured list of localized workplace folders. */ 316 private List<String> m_localizedFolders; 317 318 /** The additional log folder configuration. */ 319 private CmsAdditionalLogFolderConfig m_logFolderConfig = new CmsAdditionalLogFolderConfig(); 320 321 /** The workplace localized messages (mapped to the locales). */ 322 private Map<Locale, CmsWorkplaceMessages> m_messages; 323 324 /** The post upload handler. */ 325 private I_CmsPostUploadDialogHandler m_postUploadHandler; 326 327 /** The condition definitions for the resource types which are triggered before opening the editor. */ 328 private List<I_CmsPreEditorActionDefinition> m_preEditorConditionDefinitions; 329 330 /** The repository folder handler. */ 331 private I_CmsRepositoryFolderHandler m_repositoryFolderHandler; 332 333 /** Indicates if the user management icon should be displayed in the workplace. */ 334 private boolean m_showUserGroupIcon; 335 336 /** Exclude patterns for synchronization. */ 337 private ArrayList<Pattern> m_synchronizeExcludePatterns; 338 339 /** The temporary file project used by the editors. */ 340 private CmsProject m_tempFileProject; 341 342 /** The tool manager. */ 343 private CmsToolManager m_toolManager; 344 345 /** The upload restriction. */ 346 private I_CmsUploadRestriction m_uploadRestriction = CmsDefaultUploadRestriction.unrestricted(); 347 348 /** Keeps track of whether the upload restriction has been set. */ 349 private boolean m_uploadRestrictionSet; 350 351 /** The user additional information configuration. */ 352 private CmsWorkplaceUserInfoManager m_userInfoManager; 353 354 /** The user list mode. */ 355 private String m_userListMode; 356 357 /** The configured workplace views. */ 358 private List<CmsWorkplaceView> m_views; 359 360 /** Expiring cache used to limit the number of notifications sent because of invalid workplace server names. */ 361 private Cache<String, String> m_workplaceServerUserChecks; 362 363 /** The XML content auto correction flag. */ 364 private boolean m_xmlContentAutoCorrect; 365 366 /** The role required for editing the sitemap configuration. */ 367 private String m_sitemapConfigEditRole; 368 369 /** 370 * Creates a new instance for the workplace manager, will be called by the workplace configuration manager.<p> 371 */ 372 public CmsWorkplaceManager() { 373 374 if (CmsLog.INIT.isInfoEnabled()) { 375 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_WORKPLACE_INITIALIZE_START_0)); 376 } 377 378 m_locales = new ArrayList<Locale>(); 379 m_labelSiteFolders = new ArrayList<String>(); 380 m_localizedFolders = new ArrayList<String>(); 381 m_autoLockResources = true; 382 m_categoryFolder = CmsCategoryService.REPOSITORY_BASE_FOLDER; 383 m_xmlContentAutoCorrect = true; 384 m_showUserGroupIcon = true; 385 m_dialogHandler = new HashMap<String, I_CmsDialogHandler>(); 386 m_views = new ArrayList<CmsWorkplaceView>(); 387 m_exportPoints = new HashSet<CmsExportPoint>(); 388 m_editorHandler = new CmsEditorHandler(); 389 m_fileMaxUploadSize = -1; 390 m_fileViewSettings = new CmsRfsFileViewer(); 391 m_explorerTypeSettingsFromXml = new ArrayList<CmsExplorerTypeSettings>(); 392 m_explorerTypeSettingsFromModules = new ArrayList<CmsExplorerTypeSettings>(); 393 m_defaultPropertiesOnStructure = true; 394 m_enableAdvancedPropertyTabs = true; 395 m_defaultUserSettings = new CmsDefaultUserSettings(); 396 m_defaultAccess = new CmsExplorerTypeAccess(); 397 m_galleries = new HashMap<String, A_CmsAjaxGallery>(); 398 flushMessageCache(); 399 m_preEditorConditionDefinitions = new ArrayList<I_CmsPreEditorActionDefinition>(); 400 m_editorCssHandlers = new ArrayList<I_CmsEditorCssHandler>(); 401 m_synchronizeExcludePatterns = new ArrayList<Pattern>(); 402 403 // important to set this to null to avoid unnecessary overhead during configuration phase 404 m_explorerTypeSettings = null; 405 CacheBuilder<Object, Object> cb = CacheBuilder.newBuilder().expireAfterWrite( 406 2, 407 TimeUnit.MINUTES).concurrencyLevel(3); 408 m_workplaceServerUserChecks = cb.build(); 409 } 410 411 /** 412 * Returns true if the provided request was done by a Workplace user.<p> 413 * 414 * @param req the request to check 415 * 416 * @return true if the provided request was done by a Workplace user 417 */ 418 public static boolean isWorkplaceUser(HttpServletRequest req) { 419 420 HttpSession session = req.getSession(false); 421 if (session != null) { 422 // if a session is available, check for a workplace configuration 423 CmsWorkplaceSettings workplaceSettings = (CmsWorkplaceSettings)session.getAttribute( 424 CmsWorkplaceManager.SESSION_WORKPLACE_SETTINGS); 425 return ((null != workplaceSettings) && !workplaceSettings.getUser().isGuestUser()); 426 } 427 // no session means no workplace use 428 return false; 429 } 430 431 /** 432 * Adds an account info.<p> 433 * 434 * @param info the account info to add 435 */ 436 public void addAccountInfo(CmsAccountInfo info) { 437 438 if (m_accountInfos == null) { 439 m_accountInfos = new ArrayList<CmsAccountInfo>(); 440 } 441 m_accountInfos.add(info); 442 } 443 444 /** 445 * Adds an account info.<p> 446 * 447 * @param field the field 448 * @param addInfoKey the additional info key 449 * @param editable the editable flag 450 */ 451 public void addAccountInfo(String field, String addInfoKey, String editable) { 452 453 addAccountInfo(new CmsAccountInfo(field, addInfoKey, editable)); 454 } 455 456 /** 457 * Adds a dialog handler instance to the list of configured dialog handlers.<p> 458 * 459 * @param clazz the instantiated dialog handler to add 460 */ 461 public void addDialogHandler(I_CmsDialogHandler clazz) { 462 463 m_dialogHandler.put(clazz.getDialogHandler(), clazz); 464 if (CmsLog.INIT.isInfoEnabled()) { 465 CmsLog.INIT.info( 466 Messages.get().getBundle().key( 467 Messages.INIT_ADD_DIALOG_HANDLER_2, 468 clazz.getDialogHandler(), 469 clazz.getClass().getName())); 470 } 471 } 472 473 /** 474 * Adds an editor CSS handler class to the list of handlers.<p> 475 * 476 * @param editorCssHandlerClassName full class name of the css handler class 477 */ 478 public void addEditorCssHandler(String editorCssHandlerClassName) { 479 480 try { 481 I_CmsEditorCssHandler editorCssHandler = (I_CmsEditorCssHandler)Class.forName( 482 editorCssHandlerClassName).newInstance(); 483 m_editorCssHandlers.add(editorCssHandler); 484 if (CmsLog.INIT.isInfoEnabled()) { 485 CmsLog.INIT.info( 486 Messages.get().getBundle().key(Messages.INIT_EDITOR_CSSHANDLER_CLASS_1, editorCssHandlerClassName)); 487 } 488 } catch (Exception e) { 489 LOG.error( 490 Messages.get().getBundle().key(Messages.LOG_INVALID_EDITOR_CSSHANDLER_1, editorCssHandlerClassName), 491 e); 492 } 493 } 494 495 /** 496 * Adds an editor CSS handler class at the first position of the list of handlers.<p> 497 * 498 * @param editorCssHandlerClassName full class name of the css handler class 499 */ 500 public void addEditorCssHandlerToHead(String editorCssHandlerClassName) { 501 502 try { 503 I_CmsEditorCssHandler editorCssHandler = (I_CmsEditorCssHandler)Class.forName( 504 editorCssHandlerClassName).newInstance(); 505 506 List<I_CmsEditorCssHandler> editorCssHandlers = new ArrayList<I_CmsEditorCssHandler>(); 507 editorCssHandlers.add(editorCssHandler); 508 editorCssHandlers.addAll(m_editorCssHandlers); 509 510 m_editorCssHandlers = editorCssHandlers; 511 512 if (CmsLog.INIT.isInfoEnabled()) { 513 CmsLog.INIT.info( 514 Messages.get().getBundle().key(Messages.INIT_EDITOR_CSSHANDLER_CLASS_1, editorCssHandlerClassName)); 515 } 516 } catch (Exception e) { 517 LOG.error( 518 Messages.get().getBundle().key(Messages.LOG_INVALID_EDITOR_CSSHANDLER_1, editorCssHandlerClassName), 519 e); 520 } 521 } 522 523 /** 524 * Adds an explorer type setting object to the list of type settings.<p> 525 * 526 * @param settings the explorer type settings 527 */ 528 public void addExplorerTypeSetting(CmsExplorerTypeSettings settings) { 529 530 m_explorerTypeSettingsFromXml.add(settings); 531 if (CmsLog.INIT.isInfoEnabled()) { 532 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_ADD_TYPE_SETTING_1, settings.getName())); 533 } 534 if (m_explorerTypeSettings != null) { 535 // reset the list of all explorer type settings, but not during startup 536 initExplorerTypeSettings(); 537 } 538 } 539 540 /** 541 * Adds the list of explorer type settings from the given module.<p> 542 * 543 * @param module the module witch contains the explorer type settings to add 544 */ 545 public void addExplorerTypeSettings(CmsModule module) { 546 547 List<CmsExplorerTypeSettings> explorerTypes = module.getExplorerTypes(); 548 if ((explorerTypes != null) && (explorerTypes.size() > 0)) { 549 Iterator<CmsExplorerTypeSettings> i = explorerTypes.iterator(); 550 while (i.hasNext()) { 551 CmsExplorerTypeSettings settings = i.next(); 552 if (m_explorerTypeSettingsFromModules.contains(settings)) { 553 m_explorerTypeSettingsFromModules.remove(settings); 554 } 555 m_explorerTypeSettingsFromModules.add(settings); 556 if (CmsLog.INIT.isInfoEnabled()) { 557 CmsLog.INIT.info( 558 Messages.get().getBundle().key(Messages.INIT_ADD_TYPE_SETTING_1, settings.getName())); 559 } 560 } 561 // reset the list of all explorer type settings 562 initExplorerTypeSettings(); 563 } 564 } 565 566 /** 567 * Adds newly created export point to the workplace configuration.<p> 568 * 569 * @param uri the export point uri 570 * @param destination the export point destination 571 */ 572 public void addExportPoint(String uri, String destination) { 573 574 CmsExportPoint point = new CmsExportPoint(uri, destination); 575 m_exportPoints.add(point); 576 if (CmsLog.INIT.isInfoEnabled() && (point.getDestinationPath() != null)) { 577 CmsLog.INIT.info( 578 Messages.get().getBundle().key( 579 Messages.INIT_ADD_EXPORT_POINT_2, 580 point.getUri(), 581 point.getDestinationPath())); 582 } 583 } 584 585 /** 586 * Adds a folder to the list of labeled folders.<p> 587 * 588 * @param uri the folder uri to add 589 */ 590 public void addLabeledFolder(String uri) { 591 592 m_labelSiteFolders.add(uri); 593 if (CmsLog.INIT.isInfoEnabled()) { 594 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_LABEL_LINKS_IN_FOLDER_1, uri)); 595 } 596 } 597 598 /** 599 * Adds a new folder to the list of localized workplace folders.<p> 600 * 601 * @param uri a new folder to add to the list of localized workplace folders 602 */ 603 public void addLocalizedFolder(String uri) { 604 605 m_localizedFolders.add(uri); 606 if (CmsLog.INIT.isInfoEnabled()) { 607 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_WORKPLACE_LOCALIZED_1, uri)); 608 } 609 } 610 611 /** 612 * Adds an initialized condition definition class that is triggered before opening the editor.<p> 613 * 614 * @param preEditorCondition the initialized condition definition class 615 */ 616 public void addPreEditorConditionDefinition(I_CmsPreEditorActionDefinition preEditorCondition) { 617 618 m_preEditorConditionDefinitions.add(preEditorCondition); 619 if (CmsLog.INIT.isInfoEnabled()) { 620 CmsLog.INIT.info( 621 Messages.get().getBundle().key( 622 Messages.INIT_EDITOR_PRE_ACTION_2, 623 preEditorCondition.getClass().getName(), 624 preEditorCondition.getResourceTypeName())); 625 } 626 } 627 628 /** 629 * Adds a condition definition class for a given resource type name that is triggered before opening the editor.<p> 630 * 631 * @param resourceTypeName the name of the resource type 632 * @param preEditorConditionDefinitionClassName full class name of the condition definition class 633 */ 634 public void addPreEditorConditionDefinition(String resourceTypeName, String preEditorConditionDefinitionClassName) { 635 636 try { 637 I_CmsPreEditorActionDefinition preEditorCondition = (I_CmsPreEditorActionDefinition)Class.forName( 638 preEditorConditionDefinitionClassName).newInstance(); 639 preEditorCondition.setResourceTypeName(resourceTypeName); 640 m_preEditorConditionDefinitions.add(preEditorCondition); 641 if (CmsLog.INIT.isInfoEnabled()) { 642 CmsLog.INIT.info( 643 Messages.get().getBundle().key( 644 Messages.INIT_EDITOR_PRE_ACTION_2, 645 preEditorConditionDefinitionClassName, 646 resourceTypeName)); 647 } 648 } catch (Exception e) { 649 LOG.error( 650 Messages.get().getBundle().key( 651 Messages.LOG_INVALID_EDITOR_PRE_ACTION_1, 652 preEditorConditionDefinitionClassName), 653 e); 654 } 655 } 656 657 /** 658 * Adds a pattern to be excluded in VFS synchronization.<p> 659 * 660 * @param pattern a java regex to applied on the file name 661 */ 662 public void addSynchronizeExcludePattern(String pattern) { 663 664 try { 665 m_synchronizeExcludePatterns.add(Pattern.compile(pattern)); 666 } catch (PatternSyntaxException e) { 667 LOG.error(Messages.get().getBundle().key(Messages.LOG_INVALID_SYNCHRONIZE_EXCLUDE_PATTERN_1, pattern), e); 668 } 669 } 670 671 /** 672 * Returns if the autolock resources feature is enabled.<p> 673 * 674 * @return true if the autolock resources feature is enabled, otherwise false 675 */ 676 public boolean autoLockResources() { 677 678 return m_autoLockResources; 679 } 680 681 /** 682 * Checks whether the workplace is accessed through the workplace server, and sends an error message otherwise.<p> 683 * 684 * @param request the request to check 685 * @param cms the CmsObject to use 686 */ 687 public void checkWorkplaceRequest(HttpServletRequest request, CmsObject cms) { 688 689 try { 690 if ((OpenCms.getSiteManager().getSites().size() > 1) 691 && !OpenCms.getSiteManager().isWorkplaceRequest(request)) { 692 // this is a multi site-configuration, but not a request to the configured Workplace site 693 694 CmsUser user = cms.getRequestContext().getCurrentUser(); 695 // to limit the number of times broadcast is called for a user, we use an expiring cache 696 // with the user name as key 697 if (null == m_workplaceServerUserChecks.getIfPresent(user.getName())) { 698 m_workplaceServerUserChecks.put(user.getName(), ""); 699 OpenCms.getSessionManager().sendBroadcast( 700 null, 701 Messages.get().getBundle(getWorkplaceLocale(cms)).key( 702 Messages.ERR_WORKPLACE_SERVER_CHECK_FAILED_0), 703 user, 704 ContentMode.plain); 705 706 } 707 708 } 709 } catch (Exception e) { 710 LOG.error(e.getLocalizedMessage(), e); 711 } 712 } 713 714 /** 715 * Implements the event listener of this class.<p> 716 * 717 * @see org.opencms.main.I_CmsEventListener#cmsEvent(org.opencms.main.CmsEvent) 718 */ 719 public void cmsEvent(CmsEvent event) { 720 721 switch (event.getType()) { 722 case I_CmsEventListener.EVENT_CLEAR_CACHES: 723 flushMessageCache(); 724 m_editorDisplayOptions.clearCache(); 725 if (LOG.isDebugEnabled()) { 726 LOG.debug(Messages.get().getBundle().key(Messages.LOG_EVENT_CLEAR_CACHES_0)); 727 } 728 break; 729 default: // no operation 730 } 731 } 732 733 /** 734 * Creates a temporary file which is needed while working in an editor with preview option.<p> 735 * 736 * <i>Note</i>: This method is synchronized to avoid rare issues that might be caused by 737 * double requests fired by some browser/OS combinations.<p> 738 * 739 * @param cms the cms context 740 * @param resourceName the name of the resource to copy 741 * @param currentProjectId the id of the project to work with 742 * 743 * @return the file name of the temporary file 744 * 745 * @throws CmsException if something goes wrong 746 */ 747 public synchronized String createTempFile(CmsObject cms, String resourceName, CmsUUID currentProjectId) 748 throws CmsException { 749 750 // check that the current user has write permissions 751 if (!cms.hasPermissions(cms.readResource(resourceName, CmsResourceFilter.ALL), CmsPermissionSet.ACCESS_WRITE)) { 752 throw new CmsPermissionViolationException( 753 org.opencms.db.Messages.get().container(org.opencms.db.Messages.ERR_PERM_DENIED_2, resourceName, "w")); 754 } 755 756 // initialize admin cms context 757 CmsObject adminCms = getAdminCms(cms); 758 759 // generate the filename of the temporary file 760 String temporaryFilename = CmsWorkplace.getTemporaryFileName(resourceName); 761 762 // check if the temporary file is already present 763 if (adminCms.existsResource(temporaryFilename, CmsResourceFilter.ALL)) { 764 // delete old temporary file 765 if (!cms.getLock(temporaryFilename).isUnlocked()) { 766 // steal lock 767 cms.changeLock(temporaryFilename); 768 } else { 769 // lock resource to current user 770 cms.lockResource(temporaryFilename); 771 } 772 cms.deleteResource(temporaryFilename, CmsResource.DELETE_PRESERVE_SIBLINGS); 773 } 774 775 try { 776 // switch to the temporary file project 777 adminCms.getRequestContext().setCurrentProject(cms.readProject(getTempFileProjectId())); 778 // copy the file to edit to a temporary file 779 adminCms.copyResource(resourceName, temporaryFilename, CmsResource.COPY_AS_NEW); 780 } finally { 781 // switch back to current project 782 adminCms.getRequestContext().setCurrentProject(cms.readProject(currentProjectId)); 783 } 784 785 try { 786 // switch to the temporary file project 787 cms.getRequestContext().setCurrentProject( 788 cms.readProject(OpenCms.getWorkplaceManager().getTempFileProjectId())); 789 // lock the temporary file 790 cms.changeLock(temporaryFilename); 791 // touch the temporary file 792 cms.setDateLastModified(temporaryFilename, System.currentTimeMillis(), false); 793 // set the temporary file flag 794 CmsResource tempFile = cms.readResource(temporaryFilename, CmsResourceFilter.ALL); 795 int flags = tempFile.getFlags(); 796 if ((flags & CmsResource.FLAG_TEMPFILE) == 0) { 797 flags += CmsResource.FLAG_TEMPFILE; 798 } 799 cms.chflags(temporaryFilename, flags); 800 // remove eventual release & expiration date from temporary file to make preview in editor work 801 cms.setDateReleased(temporaryFilename, CmsResource.DATE_RELEASED_DEFAULT, false); 802 cms.setDateExpired(temporaryFilename, CmsResource.DATE_EXPIRED_DEFAULT, false); 803 // remove visibility permissions for everybody on temporary file if possible 804 if (cms.hasPermissions(tempFile, CmsPermissionSet.ACCESS_CONTROL)) { 805 cms.chacc( 806 temporaryFilename, 807 I_CmsPrincipal.PRINCIPAL_GROUP, 808 OpenCms.getDefaultUsers().getGroupUsers(), 809 "-v"); 810 } 811 } finally { 812 // switch back to current project 813 cms.getRequestContext().setCurrentProject(cms.readProject(currentProjectId)); 814 } 815 816 return temporaryFilename; 817 } 818 819 /** 820 * Flushes the cached workplace messages.<p> 821 */ 822 public void flushMessageCache() { 823 824 // clear the cached message objects 825 m_messages = new HashMap<Locale, CmsWorkplaceMessages>(); 826 if (LOG.isDebugEnabled()) { 827 try { 828 throw new RuntimeException("Tracing exception"); 829 } catch (Exception e) { 830 LOG.info("Tracing call to CmsWorkplaceManager.flushMessageCache method.", e); 831 } 832 } 833 } 834 835 /** 836 * Gets the value of the acacia-unlock configuration option (null if not set explicitly).<p> 837 * 838 * @return the value of the acacia-unlock configuration option 839 */ 840 public String getAcaciaUnlock() { 841 842 return m_acaciaUnlock; 843 } 844 845 /** 846 * Returns the account infos.<p> 847 * 848 * @return the account infos 849 */ 850 public List<CmsAccountInfo> getAccountInfos() { 851 852 if (m_accountInfos == null) { 853 return Collections.unmodifiableList(Arrays.asList(DEFAULT_ACCOUNT_INFOS)); 854 } else { 855 return Collections.unmodifiableList(m_accountInfos); 856 } 857 } 858 859 /** 860 * Gets the additional log folder configuration.<p> 861 * 862 * @return the additional log folder configuration 863 */ 864 public CmsAdditionalLogFolderConfig getAdditionalLogFolderConfiguration() { 865 866 return m_logFolderConfig; 867 } 868 869 /** 870 * Returns the name of the local category folder(s).<p> 871 * 872 * @return the name of the local category folder(s) 873 */ 874 public String getCategoryFolder() { 875 876 return m_categoryFolder; 877 } 878 879 /** 880 * Returns the configured account infos.<p> 881 * 882 * @return the configured account infos 883 */ 884 public List<CmsAccountInfo> getConfiguredAccountInfos() { 885 886 return m_accountInfos; 887 } 888 889 /** 890 * Gets the access object of the type settings.<p> 891 * 892 * @return access object of the type settings 893 */ 894 public CmsExplorerTypeAccess getDefaultAccess() { 895 896 return m_defaultAccess; 897 } 898 899 /** 900 * Returns the Workplace default locale.<p> 901 * 902 * @return the Workplace default locale 903 */ 904 public Locale getDefaultLocale() { 905 906 return m_defaultLocale; 907 } 908 909 /** 910 * Gets the default name pattern for the given type.<p> 911 * 912 * @param type the type name 913 * @return the default name pattern for the type 914 */ 915 public String getDefaultNamePattern(String type) { 916 917 CmsExplorerTypeSettings settings = getExplorerTypeSetting(type); 918 if ((settings != null) && (settings.getNamePattern() != null)) { 919 return settings.getNamePattern(); 920 } 921 if (type.equals("sitemap_config") || type.equals("module_config")) { 922 return ".config%(number)"; 923 } 924 if (type.equals("content_folder")) { 925 return ".content%(number)"; 926 } 927 return "new_" + type + "%(number)"; 928 } 929 930 /** 931 * Returns the Workplace default user settings.<p> 932 * 933 * @return the Workplace default user settings 934 */ 935 public CmsDefaultUserSettings getDefaultUserSettings() { 936 937 return m_defaultUserSettings; 938 } 939 940 /** 941 * Returns all instantiated dialog handlers for the workplace.<p> 942 * 943 * @return all instantiated dialog handlers for the workplace 944 */ 945 public Map<String, I_CmsDialogHandler> getDialogHandler() { 946 947 return m_dialogHandler; 948 } 949 950 /** 951 * Returns the instantiated dialog handler class for the key or null, if there is no mapping for the key.<p> 952 * 953 * @param key the key whose associated value is to be returned 954 * 955 * @return the instantiated dialog handler class for the key 956 */ 957 public I_CmsDialogHandler getDialogHandler(String key) { 958 959 return m_dialogHandler.get(key); 960 } 961 962 /** 963 * Returns a new instance of the configured direct edit provider.<p> 964 * 965 * @return a new instance of the configured direct edit provider 966 */ 967 public I_CmsDirectEditProvider getDirectEditProvider() { 968 969 return m_directEditProvider.newInstance(); 970 } 971 972 /** 973 * Returns the instantiated editor action handler class.<p> 974 * 975 * @return the instantiated editor action handler class 976 */ 977 public I_CmsEditorActionHandler getEditorActionHandler() { 978 979 return m_editorAction; 980 } 981 982 /** 983 * Returns the instantiated editor CSS handler classes.<p> 984 * 985 * @return the instantiated editor CSS handler classes 986 */ 987 public List<I_CmsEditorCssHandler> getEditorCssHandlers() { 988 989 return m_editorCssHandlers; 990 } 991 992 /** 993 * Returns the instantiated editor display option class.<p> 994 * 995 * @return the instantiated editor display option class 996 */ 997 public CmsEditorDisplayOptions getEditorDisplayOptions() { 998 999 return m_editorDisplayOptions; 1000 } 1001 1002 /** 1003 * Returns the instantiated editor handler class.<p> 1004 * 1005 * @return the instantiated editor handler class 1006 */ 1007 public I_CmsEditorHandler getEditorHandler() { 1008 1009 return m_editorHandler; 1010 } 1011 1012 /** 1013 * Returns the element delete mode.<p> 1014 * 1015 * @return the element delete mode 1016 */ 1017 public ElementDeleteMode getElementDeleteMode() { 1018 1019 return m_elementDeleteMode; 1020 } 1021 1022 /** 1023 * Returns the configured workplace encoding.<p> 1024 * 1025 * @return the configured workplace encoding 1026 */ 1027 public String getEncoding() { 1028 1029 return m_encoding; 1030 } 1031 1032 /** 1033 * Returns the explorer type settings for the specified resource type.<p> 1034 * 1035 * @param type the resource type for which the settings are required 1036 * 1037 * @return the explorer type settings for the specified resource type 1038 */ 1039 public CmsExplorerTypeSettings getExplorerTypeSetting(String type) { 1040 1041 return m_explorerTypeSettingsMap.get(type); 1042 } 1043 1044 /** 1045 * Returns the list of explorer type settings.<p> 1046 * 1047 * These settings provide information for the new resource dialog and the context menu appearance.<p> 1048 * 1049 * @return the list of explorer type settings 1050 */ 1051 public List<CmsExplorerTypeSettings> getExplorerTypeSettings() { 1052 1053 if (m_explorerTypeSettings == null) { 1054 // initialize all explorer type settings if not already done 1055 initExplorerTypeSettings(); 1056 } 1057 1058 return m_explorerTypeSettings; 1059 } 1060 1061 /** 1062 * Gets the explorer types for the given view name.<p> 1063 * 1064 * @param viewName the view name 1065 * 1066 * @return the explorer names for the given view names 1067 */ 1068 public List<CmsExplorerTypeSettings> getExplorerTypesForView(String viewName) { 1069 1070 List<CmsExplorerTypeSettings> result = Lists.newArrayList(); 1071 for (CmsExplorerTypeSettings explorerType : getExplorerTypeSettings()) { 1072 1073 String currentViewName = explorerType.getElementView(); 1074 if (currentViewName == null) { 1075 currentViewName = getDefaultView(explorerType.getName()); 1076 } 1077 if ((currentViewName != null) && currentViewName.equals(viewName)) { 1078 if (OpenCms.getResourceManager().hasResourceType(explorerType.getName())) { 1079 result.add(explorerType); 1080 } 1081 } else if (CmsResourceTypeFolder.getStaticTypeName().equals(explorerType.getName()) 1082 && "view_folders|view_basic".contains(viewName)) { 1083 result.add(explorerType); 1084 } 1085 1086 } 1087 return result; 1088 } 1089 1090 /** 1091 * Gets the element views generated from explorer types.<p> 1092 * 1093 * @return the map of element views from the explorer types 1094 */ 1095 public Map<CmsUUID, CmsElementView> getExplorerTypeViews() { 1096 1097 return Collections.unmodifiableMap(m_explorerTypeViews); 1098 1099 } 1100 1101 /** 1102 * Returns the set of configured export points for the workplace.<p> 1103 * 1104 * @return the set of configured export points for the workplace 1105 */ 1106 public Set<CmsExportPoint> getExportPoints() { 1107 1108 return m_exportPoints; 1109 } 1110 1111 /** 1112 * Returns the value (in bytes) for the maximum file upload size of the current user.<p> 1113 * 1114 * @param cms the initialized CmsObject 1115 * 1116 * @return the value (in bytes) for the maximum file upload size 1117 */ 1118 public long getFileBytesMaxUploadSize(CmsObject cms) { 1119 1120 int maxFileSize = getFileMaxUploadSize(); 1121 long maxFileSizeBytes = maxFileSize * 1024; 1122 // check if current user belongs to Admin group, if so no file upload limit 1123 if ((maxFileSize <= 0) || OpenCms.getRoleManager().hasRole(cms, CmsRole.VFS_MANAGER)) { 1124 maxFileSizeBytes = -1; 1125 } 1126 return maxFileSizeBytes; 1127 } 1128 1129 /** 1130 * Returns the value (in kb) for the maximum file upload size.<p> 1131 * 1132 * @return the value (in kb) for the maximum file upload size 1133 */ 1134 public int getFileMaxUploadSize() { 1135 1136 return m_fileMaxUploadSize; 1137 } 1138 1139 /** 1140 * Returns the system-wide file view settings for the workplace.<p> 1141 * 1142 * Note that this instance may not modified (invocation of setters) directly or a 1143 * <code>{@link org.opencms.main.CmsRuntimeException}</code> will be thrown.<p> 1144 * 1145 * It has to be cloned first and then may be written back to the workplace settings using 1146 * method {@link #setFileViewSettings(CmsObject, org.opencms.util.CmsRfsFileViewer)}.<p> 1147 * 1148 * @return the system-wide file view settings for the workplace 1149 */ 1150 public CmsRfsFileViewer getFileViewSettings() { 1151 1152 return m_fileViewSettings; 1153 } 1154 1155 /** 1156 * Returns a collection of all available galleries.<p> 1157 * 1158 * The Map has the gallery type name as key and an instance of the 1159 * gallery class (not completely initialized) as value.<p> 1160 * 1161 * @return a collection of all available galleries 1162 */ 1163 public Map<String, A_CmsAjaxGallery> getGalleries() { 1164 1165 return m_galleries; 1166 } 1167 1168 /** 1169 * Returns the gallery default scope.<p> 1170 * 1171 * @return the gallery default scope 1172 */ 1173 public CmsGallerySearchScope getGalleryDefaultScope() { 1174 1175 CmsGallerySearchScope result = CmsGallerySearchScope.siteShared; 1176 if (m_galleryDefaultScope != null) { 1177 try { 1178 result = CmsGallerySearchScope.valueOf(m_galleryDefaultScope); 1179 } catch (Throwable t) { 1180 // ignore 1181 } 1182 } 1183 return result; 1184 } 1185 1186 /** 1187 * Gets the configured gallery default scope as a string.<p> 1188 * 1189 * @return the gallery default scope as a string 1190 */ 1191 public String getGalleryDefaultScopeString() { 1192 1193 return m_galleryDefaultScope; 1194 } 1195 1196 /** 1197 * Returns the object used for translating group names.<p> 1198 * 1199 * @return the group name translator 1200 */ 1201 public I_CmsGroupNameTranslation getGroupNameTranslation() { 1202 1203 if (m_groupNameTranslation != null) { 1204 return m_groupNameTranslation; 1205 } 1206 if (m_groupTranslationClass != null) { 1207 try { 1208 m_groupNameTranslation = (I_CmsGroupNameTranslation)Class.forName( 1209 m_groupTranslationClass).newInstance(); 1210 return m_groupNameTranslation; 1211 } catch (ClassNotFoundException e) { 1212 LOG.error(e.getLocalizedMessage(), e); 1213 } catch (IllegalAccessException e) { 1214 LOG.error(e.getLocalizedMessage(), e); 1215 } catch (InstantiationException e) { 1216 LOG.error(e.getLocalizedMessage(), e); 1217 } catch (ClassCastException e) { 1218 LOG.error(e.getLocalizedMessage(), e); 1219 } 1220 m_groupNameTranslation = getDefaultGroupNameTranslation(); 1221 return m_groupNameTranslation; 1222 } else { 1223 m_groupNameTranslation = getDefaultGroupNameTranslation(); 1224 return m_groupNameTranslation; 1225 } 1226 } 1227 1228 /** 1229 * Returns the configured class name for translating group names.<p> 1230 * 1231 * @return the group translation class name 1232 */ 1233 public String getGroupTranslationClass() { 1234 1235 return m_groupTranslationClass; 1236 } 1237 1238 /** 1239 * @see org.opencms.i18n.I_CmsLocaleHandler#getI18nInfo(javax.servlet.http.HttpServletRequest, org.opencms.file.CmsUser, org.opencms.file.CmsProject, java.lang.String) 1240 */ 1241 public CmsI18nInfo getI18nInfo(HttpServletRequest req, CmsUser user, CmsProject project, String resource) { 1242 1243 Locale locale = null; 1244 // try to read locale from session 1245 if (req != null) { 1246 // set the request character encoding 1247 try { 1248 req.setCharacterEncoding(m_encoding); 1249 } catch (UnsupportedEncodingException e) { 1250 // should not ever really happen 1251 LOG.error(Messages.get().getBundle().key(Messages.LOG_UNSUPPORTED_ENCODING_SET_1, m_encoding), e); 1252 } 1253 // read workplace settings 1254 HttpSession session = req.getSession(false); 1255 if (session != null) { 1256 CmsWorkplaceSettings settings = (CmsWorkplaceSettings)session.getAttribute( 1257 CmsWorkplaceManager.SESSION_WORKPLACE_SETTINGS); 1258 if (settings != null) { 1259 locale = settings.getUserSettings().getLocale(); 1260 } 1261 } 1262 } 1263 1264 if (locale == null) { 1265 // no session available, try to read the locale form the user additional info 1266 if (!user.isGuestUser()) { 1267 // check user settings only for "real" users 1268 CmsUserSettings settings = new CmsUserSettings(user); 1269 locale = settings.getLocale(); 1270 1271 } 1272 if (req != null) { 1273 List<Locale> acceptedLocales = (new CmsAcceptLanguageHeaderParser( 1274 req, 1275 getDefaultLocale())).getAcceptedLocales(); 1276 if ((locale != null) && (!acceptedLocales.contains(locale))) { 1277 acceptedLocales.add(0, locale); 1278 } 1279 locale = OpenCms.getLocaleManager().getFirstMatchingLocale(acceptedLocales, m_locales); 1280 } 1281 1282 // if no locale was found, use the default 1283 if (locale == null) { 1284 locale = getDefaultLocale(); 1285 } 1286 } 1287 1288 return new CmsI18nInfo(locale, m_encoding); 1289 } 1290 1291 /** 1292 * Returns a list of site folders which generate labeled links.<p> 1293 * 1294 * @return a list of site folders which generate labeled links 1295 */ 1296 public List<String> getLabelSiteFolders() { 1297 1298 return m_labelSiteFolders; 1299 } 1300 1301 /** 1302 * Returns the list of available workplace locales, sorted ascending.<p> 1303 * 1304 * Please note: Be careful not to modify the returned Set as it is not a clone.<p> 1305 * 1306 * @return the set of available workplace locales 1307 */ 1308 public List<Locale> getLocales() { 1309 1310 return m_locales; 1311 } 1312 1313 /** 1314 * Returns the configured list of localized workplace folders.<p> 1315 * 1316 * @return the configured list of localized workplace folders 1317 */ 1318 public List<String> getLocalizedFolders() { 1319 1320 return m_localizedFolders; 1321 } 1322 1323 /** 1324 * Returns the {@link CmsWorkplaceMessages} for the given locale.<p> 1325 * 1326 * The workplace messages are a collection of resource bundles, containing the messages 1327 * for all OpenCms core bundles and of all initialized modules.<p> 1328 * 1329 * Please note that the message objects are cached internally. 1330 * The returned message object should therefore never be modified directly in any way.<p> 1331 * 1332 * @param locale the locale to get the messages for 1333 * 1334 * @return the {@link CmsWorkplaceMessages} for the given locale 1335 */ 1336 public CmsWorkplaceMessages getMessages(Locale locale) { 1337 1338 CmsWorkplaceMessages result = m_messages.get(locale); 1339 if (result != null) { 1340 // messages have already been read 1341 return result; 1342 } 1343 1344 // messages have not been read so far 1345 synchronized (this) { 1346 // check again 1347 result = m_messages.get(locale); 1348 if (result == null) { 1349 result = new CmsWorkplaceMessages(locale); 1350 m_messages.put(locale, result); 1351 } 1352 } 1353 return result; 1354 } 1355 1356 /** 1357 * Returns the post upload handler.<p> 1358 * 1359 * @return the post upload handler 1360 */ 1361 public I_CmsPostUploadDialogHandler getPostUploadHandler() { 1362 1363 return m_postUploadHandler; 1364 } 1365 1366 /** 1367 * Returns the condition definition for the given resource type that is triggered before opening the editor.<p> 1368 * 1369 * @param resourceType the resource type 1370 * 1371 * @return the condition definition for the given resource type class name or null if none is found 1372 */ 1373 public I_CmsPreEditorActionDefinition getPreEditorConditionDefinition(I_CmsResourceType resourceType) { 1374 1375 Iterator<I_CmsPreEditorActionDefinition> i = m_preEditorConditionDefinitions.iterator(); 1376 I_CmsPreEditorActionDefinition result = null; 1377 int matchResult = -1; 1378 while (i.hasNext()) { 1379 I_CmsPreEditorActionDefinition currentDefinition = i.next(); 1380 if (resourceType.getClass().isInstance(currentDefinition.getResourceType())) { 1381 // now determine the match count... 1382 int matchDistance = 0; 1383 Class<?> superClass = resourceType.getClass(); 1384 while (true) { 1385 // check if a super class is present 1386 if (superClass == null) { 1387 break; 1388 } 1389 if (superClass.getName().equals(currentDefinition.getResourceType().getClass().getName())) { 1390 break; 1391 } 1392 matchDistance += 1; 1393 superClass = superClass.getSuperclass(); 1394 } 1395 if (matchResult != -1) { 1396 if (matchDistance < matchResult) { 1397 matchResult = matchDistance; 1398 result = currentDefinition; 1399 } 1400 } else { 1401 matchResult = matchDistance; 1402 result = currentDefinition; 1403 } 1404 } 1405 } 1406 return result; 1407 } 1408 1409 /** 1410 * Returns the condition definitions for the different resource 1411 * types which are triggered before opening the editor.<p> 1412 * 1413 * @return the condition definitions 1414 */ 1415 public List<I_CmsPreEditorActionDefinition> getPreEditorConditionDefinitions() { 1416 1417 return m_preEditorConditionDefinitions; 1418 } 1419 1420 /** 1421 * Returns the repository folder handler.<p> 1422 * 1423 * @return the repository folder handler 1424 */ 1425 public I_CmsRepositoryFolderHandler getRepositoryFolderHandler() { 1426 1427 if (m_repositoryFolderHandler == null) { 1428 // handler has not been configured, use the default one 1429 m_repositoryFolderHandler = new CmsRepositoryFolderHandler(); 1430 } 1431 return m_repositoryFolderHandler; 1432 } 1433 1434 /** 1435 * Gets the name of the role necessary for editing the sitemap configuration. 1436 * 1437 * @return the name of the role necessary for editing the sitemap configuration 1438 */ 1439 public String getSitemapConfigEditRole() { 1440 1441 return m_sitemapConfigEditRole; 1442 } 1443 1444 /** 1445 * Returns Regex patterns that should be excluded from synchronization.<p> 1446 * 1447 * @return the exclude patterns 1448 */ 1449 public ArrayList<Pattern> getSynchronizeExcludePatterns() { 1450 1451 return m_synchronizeExcludePatterns; 1452 } 1453 1454 /** 1455 * Returns the id of the temporary file project required by the editors.<p> 1456 * 1457 * @return the id of the temporary file project required by the editors 1458 */ 1459 public CmsUUID getTempFileProjectId() { 1460 1461 if (m_tempFileProject != null) { 1462 return m_tempFileProject.getUuid(); 1463 } else { 1464 return null; 1465 } 1466 } 1467 1468 /** 1469 * Returns the tool manager.<p> 1470 * 1471 * @return the tool manager 1472 */ 1473 public CmsToolManager getToolManager() { 1474 1475 if (m_toolManager == null) { 1476 m_toolManager = new CmsToolManager(); 1477 } 1478 return m_toolManager; 1479 } 1480 1481 /** 1482 * Gets the upload hook URI which should be opened for an upload to a given folder.<p> 1483 * This method will return null if no upload hook should be used for the given upload folder.<p> 1484 * 1485 * The API for this upload hook is as follows: 1486 * 1487 * The upload hook will be called with the following parameters: 1488 * 1489 * resources (required): a comma separated list of the structure ids of the uploaded resources 1490 * if this is omitted 1491 * closelink (optional): a link which should be opened once the upload hook has finished whatever 1492 * it is doing 1493 * 1494 * @param cms the current CMS context 1495 * @param uploadFolder the folder for which the upload hook should be found 1496 * 1497 * @return the URI of the upload hook or null 1498 */ 1499 public String getUploadHook(CmsObject cms, String uploadFolder) { 1500 1501 if (m_postUploadHandler != null) { 1502 return m_postUploadHandler.getUploadHook(cms, uploadFolder); 1503 } 1504 I_CmsDialogHandler handler = getDialogHandler(CmsDialogSelector.DIALOG_PROPERTY); 1505 if ((handler != null) && (handler instanceof I_CmsPostUploadDialogHandler)) { 1506 return ((I_CmsPostUploadDialogHandler)handler).getUploadHook(cms, uploadFolder); 1507 } else { 1508 return null; 1509 } 1510 } 1511 1512 /** 1513 * Gets the upload restriction. 1514 * 1515 * @return the upload restriction 1516 */ 1517 public I_CmsUploadRestriction getUploadRestriction() { 1518 1519 return m_uploadRestriction; 1520 } 1521 1522 /** 1523 * Returns the user additional information configuration Manager.<p> 1524 * 1525 * @return the user additional information configuration manager 1526 */ 1527 public CmsWorkplaceUserInfoManager getUserInfoManager() { 1528 1529 return m_userInfoManager; 1530 } 1531 1532 /** 1533 * Returns the user list mode as a string.<p> 1534 * 1535 * @return the user list mode as a string 1536 */ 1537 public String getUserListModeString() { 1538 1539 return m_userListMode; 1540 } 1541 1542 /** 1543 * Returns the map of configured workplace views.<p> 1544 * 1545 * @return the map of configured workplace views 1546 */ 1547 public List<CmsWorkplaceView> getViews() { 1548 1549 return m_views; 1550 } 1551 1552 /** 1553 * Returns the instantiated workplace editor manager class.<p> 1554 * 1555 * @return the instantiated workplace editor manager class 1556 */ 1557 public CmsWorkplaceEditorManager getWorkplaceEditorManager() { 1558 1559 return m_editorManager; 1560 } 1561 1562 /** 1563 * Returns the list of explorer type settings configured in the opencms-workplace.xml file.<p> 1564 * 1565 * @return the list of explorer type settings 1566 */ 1567 public List<CmsExplorerTypeSettings> getWorkplaceExplorerTypeSettings() { 1568 1569 return Collections.unmodifiableList(m_explorerTypeSettingsFromXml); 1570 } 1571 1572 /** 1573 * Returns the workplace locale from the current user's settings.<p> 1574 * 1575 * @param cms the current cms object 1576 * 1577 * @return the workplace locale 1578 */ 1579 public Locale getWorkplaceLocale(CmsObject cms) { 1580 1581 return getWorkplaceLocale(cms.getRequestContext()); 1582 } 1583 1584 /** 1585 * Gets the workplace locale for the given request context.<p> 1586 * 1587 * @param requestContext the request context 1588 * 1589 * @return the workplace locale for the request context 1590 */ 1591 public Locale getWorkplaceLocale(CmsRequestContext requestContext) { 1592 1593 Locale wpLocale = new CmsUserSettings(requestContext.getCurrentUser()).getLocale(); 1594 if (wpLocale == null) { 1595 // fall back 1596 wpLocale = getDefaultLocale(); 1597 if (wpLocale == null) { 1598 // fall back 1599 wpLocale = requestContext.getLocale(); 1600 } 1601 } 1602 return wpLocale; 1603 1604 } 1605 1606 /** 1607 * Returns the workplace locale for the user. 1608 * @param user the user to get the workplace locale for. 1609 * @return the workplace locale for the user. 1610 */ 1611 public Locale getWorkplaceLocale(CmsUser user) { 1612 1613 Locale wpLocale = new CmsUserSettings(user).getLocale(); 1614 if (wpLocale == null) { 1615 // fall back 1616 wpLocale = OpenCms.getWorkplaceManager().getDefaultLocale(); 1617 if (wpLocale == null) { 1618 // fall back 1619 wpLocale = CmsLocaleManager.MASTER_LOCALE; 1620 } 1621 } 1622 return wpLocale; 1623 1624 } 1625 1626 /** 1627 * @see org.opencms.i18n.I_CmsLocaleHandler#initHandler(org.opencms.file.CmsObject) 1628 */ 1629 public void initHandler(CmsObject cms) { 1630 1631 // initialize the workplace locale set 1632 m_locales = initWorkplaceLocales(cms); 1633 } 1634 1635 /** 1636 * Initializes the workplace manager with the OpenCms system configuration.<p> 1637 * 1638 * @param cms an OpenCms context object that must have been initialized with "Admin" permissions 1639 * 1640 * @throws CmsRoleViolationException if the provided OpenCms user context does 1641 * not have <code>{@link CmsRole#WORKPLACE_MANAGER}</code> role permissions 1642 * @throws CmsException if something goes wrong 1643 */ 1644 public synchronized void initialize(CmsObject cms) throws CmsException, CmsRoleViolationException { 1645 1646 try { 1647 // ensure that the current user has permissions to initialize the workplace 1648 OpenCms.getRoleManager().checkRole(cms, CmsRole.WORKPLACE_MANAGER); 1649 1650 // set the workplace encoding 1651 try { 1652 // workplace encoding is set on the workplace parent folder /system/workplace/ 1653 CmsResource wpFolderRes = cms.readResource(CmsWorkplace.VFS_PATH_WORKPLACE); 1654 m_encoding = CmsLocaleManager.getResourceEncoding(cms, wpFolderRes); 1655 } catch (CmsVfsResourceNotFoundException e) { 1656 // workplace parent folder could not be read - use configured default encoding 1657 m_encoding = OpenCms.getSystemInfo().getDefaultEncoding(); 1658 } 1659 1660 // configure direct edit provider with default if not available 1661 if (m_directEditProvider == null) { 1662 m_directEditProvider = new CmsDirectEditDefaultProvider(); 1663 } 1664 1665 // throw away all currently configured module explorer types 1666 m_explorerTypeSettingsFromModules.clear(); 1667 // now add the additional explorer types found in the modules 1668 CmsModuleManager moduleManager = OpenCms.getModuleManager(); 1669 Iterator<String> moduleNameIterator = moduleManager.getModuleNames().iterator(); 1670 while (moduleNameIterator.hasNext()) { 1671 CmsModule module = moduleManager.getModule(moduleNameIterator.next()); 1672 if (module != null) { 1673 addExplorerTypeSettings(module); 1674 } 1675 } 1676 // initialize the explorer type settings 1677 initExplorerTypeSettings(); 1678 // initialize the workplace views 1679 initWorkplaceViews(cms); 1680 // initialize the workplace editor manager 1681 m_editorManager = new CmsWorkplaceEditorManager(cms); 1682 // initialize the locale handler 1683 initHandler(cms); 1684 1685 if (CmsLog.INIT.isInfoEnabled()) { 1686 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_VFS_ACCESS_INITIALIZED_0)); 1687 } 1688 try { 1689 // read the temporary file project 1690 m_tempFileProject = cms.readProject(I_CmsProjectDriver.TEMP_FILE_PROJECT_NAME); 1691 } catch (CmsException e) { 1692 // during initial setup of OpenCms the temp file project does not yet exist... 1693 LOG.error(Messages.get().getBundle().key(Messages.LOG_NO_TEMP_FILE_PROJECT_0)); 1694 } 1695 // create an instance of editor display options 1696 m_editorDisplayOptions = new CmsEditorDisplayOptions(); 1697 1698 // throw away all current gallery settings 1699 m_galleries.clear(); 1700 // read out the configured gallery classes 1701 Iterator<I_CmsResourceType> typesIterator = OpenCms.getResourceManager().getResourceTypes().iterator(); 1702 while (typesIterator.hasNext()) { 1703 I_CmsResourceType resourceType = typesIterator.next(); 1704 if (resourceType instanceof CmsResourceTypeFolderExtended) { 1705 // found a configured extended folder resource type 1706 CmsResourceTypeFolderExtended galleryType = (CmsResourceTypeFolderExtended)resourceType; 1707 String folderClassName = galleryType.getFolderClassName(); 1708 if (CmsStringUtil.isNotEmpty(folderClassName)) { 1709 // only process this as a gallery if the folder name is not empty 1710 try { 1711 // check, if the folder class is a subclass of A_CmsGallery 1712 if (A_CmsAjaxGallery.class.isAssignableFrom(Class.forName(folderClassName))) { 1713 // create gallery class instance 1714 A_CmsAjaxGallery galleryInstance = (A_CmsAjaxGallery)Class.forName( 1715 folderClassName).newInstance(); 1716 // set gallery folder resource type 1717 galleryInstance.setResourceType(galleryType); 1718 // store the gallery class instance with the type name as lookup key 1719 m_galleries.put(galleryType.getTypeName(), galleryInstance); 1720 } 1721 } catch (ClassNotFoundException e) { 1722 LOG.error(e.getLocalizedMessage()); 1723 } catch (InstantiationException e) { 1724 LOG.error(e.getLocalizedMessage()); 1725 } catch (IllegalAccessException e) { 1726 LOG.error(e.getLocalizedMessage()); 1727 } 1728 } 1729 } 1730 } 1731 1732 getDefaultUserSettings().initPreferences(this); 1733 1734 // configures the tool manager 1735 getToolManager().configure(cms); 1736 1737 flushMessageCache(); 1738 getUploadRestriction().setAdminCmsObject(cms); 1739 1740 // register this object as event listener 1741 OpenCms.addCmsEventListener(this, new int[] {I_CmsEventListener.EVENT_CLEAR_CACHES}); 1742 } catch (CmsException e) { 1743 if (LOG.isErrorEnabled()) { 1744 LOG.error(e.getLocalizedMessage(), e); 1745 } 1746 throw new CmsException(Messages.get().container(Messages.ERR_INITIALIZE_WORKPLACE_0)); 1747 } 1748 m_adminCms = cms; 1749 } 1750 1751 /** 1752 * Returns the default property editing mode on resources.<p> 1753 * 1754 * @return the default property editing mode on resources 1755 */ 1756 public boolean isDefaultPropertiesOnStructure() { 1757 1758 return m_defaultPropertiesOnStructure; 1759 } 1760 1761 /** 1762 * Returns a flag, indicating if the categories should be displayed separated by repository in the category selection dialog. 1763 * 1764 * @return a flag, indicating if the categories should be displayed separated by repository in the category selection dialog. 1765 */ 1766 public boolean isDisplayCategoriesByRepository() { 1767 1768 return m_displayCategoriesByRepository; 1769 } 1770 1771 /** 1772 * Returns a flag, indicating if the category selection dialog should have all entries completely collapsed when opened. 1773 * 1774 * @return a flag, indicating if the category selection dialog should have all entries completely collapsed when opened. 1775 */ 1776 public boolean isDisplayCategorySelectionCollapsed() { 1777 1778 return m_displayCategorySelectionCollapsed; 1779 } 1780 1781 /** 1782 * Returns if tabs in the advanced property dialog are enabled.<p> 1783 * 1784 * @return <code>true</code> if tabs should be enabled, otherwise <code>false</code> 1785 */ 1786 public boolean isEnableAdvancedPropertyTabs() { 1787 1788 return m_enableAdvancedPropertyTabs; 1789 } 1790 1791 /** 1792 * Returns true if "keep alive" mode is active. 1793 * 1794 * @return true if the session should be kept alive 1795 */ 1796 public boolean isKeepAlive() { 1797 1798 return isKeepAlive(true).booleanValue(); 1799 } 1800 1801 /** 1802 * Returns true if the session should be kept alive.<p> 1803 * 1804 * @param useDefault if true, the default value will be returned if the "keep alive" setting is not explicitly configured 1805 * 1806 * @return True if the "keep alive" mode is active 1807 */ 1808 public Boolean isKeepAlive(boolean useDefault) { 1809 1810 if (m_keepAlive != null) { 1811 return m_keepAlive; 1812 } 1813 if (useDefault) { 1814 return Boolean.TRUE; 1815 } else { 1816 return null; 1817 } 1818 1819 } 1820 1821 /** 1822 * Returns if XML content is automatically corrected when opened with the editor.<p> 1823 * 1824 * @return <code>true</code> if XML content is automatically corrected when opened with the editor, otherwise <code>false</code> 1825 */ 1826 public boolean isXmlContentAutoCorrect() { 1827 1828 return m_xmlContentAutoCorrect; 1829 } 1830 1831 /** 1832 * Returns if lazy user lists are enabled.<p> 1833 * 1834 * @return <code>true</code> if lazy user lists are enabled 1835 */ 1836 public boolean lazyUserListsEnabled() { 1837 1838 return true; 1839 } 1840 1841 /** 1842 * Removes the list of explorer type settings from the given module.<p> 1843 * 1844 * @param module the module witch contains the explorer type settings to remove 1845 */ 1846 public void removeExplorerTypeSettings(CmsModule module) { 1847 1848 List<CmsExplorerTypeSettings> explorerTypes = module.getExplorerTypes(); 1849 if ((explorerTypes != null) && (explorerTypes.size() > 0)) { 1850 Iterator<CmsExplorerTypeSettings> i = explorerTypes.iterator(); 1851 while (i.hasNext()) { 1852 CmsExplorerTypeSettings settings = i.next(); 1853 if (m_explorerTypeSettingsFromModules.contains(settings)) { 1854 m_explorerTypeSettingsFromModules.remove(settings); 1855 if (CmsLog.INIT.isInfoEnabled()) { 1856 CmsLog.INIT.info( 1857 Messages.get().getBundle().key( 1858 Messages.INIT_REMOVE_EXPLORER_TYPE_SETTING_1, 1859 settings.getName())); 1860 } 1861 } 1862 } 1863 // reset the list of all explorer type settings 1864 initExplorerTypeSettings(); 1865 } 1866 } 1867 1868 /** 1869 * Sets the value of the acacia-unlock configuration option.<p> 1870 * 1871 * @param value the value of the acacia-unlock configuration option 1872 */ 1873 public void setAcaciaUnlock(String value) { 1874 1875 m_acaciaUnlock = value; 1876 1877 } 1878 1879 /** 1880 * Sets the additional log folder configuration.<p> 1881 * 1882 * @param logConfig the additional log folder configuration 1883 */ 1884 public void setAdditionalLogFolderConfiguration(CmsAdditionalLogFolderConfig logConfig) { 1885 1886 m_logFolderConfig = logConfig; 1887 } 1888 1889 /** 1890 * Sets if the autolock resources feature is enabled.<p> 1891 * 1892 * @param value <code>"true"</code> if the autolock resources feature is enabled, otherwise false 1893 */ 1894 public void setAutoLock(String value) { 1895 1896 m_autoLockResources = Boolean.valueOf(value).booleanValue(); 1897 if (CmsLog.INIT.isInfoEnabled()) { 1898 CmsLog.INIT.info( 1899 Messages.get().getBundle().key( 1900 m_autoLockResources ? Messages.INIT_AUTO_LOCK_ENABLED_0 : Messages.INIT_AUTO_LOCK_DISABLED_0)); 1901 } 1902 } 1903 1904 /** 1905 * Sets the category display options that affect how the category selection dialog is shown. 1906 * 1907 * @param displayCategoriesByRepository if true, the categories are shown separated by repository. 1908 * @param displayCategorySelectionCollapsed if true, the selection dialog opens showing only the top-level categories 1909 * (or the various repositories) in collapsed state. 1910 */ 1911 public void setCategoryDisplayOptions( 1912 String displayCategoriesByRepository, 1913 String displayCategorySelectionCollapsed) { 1914 1915 m_displayCategoriesByRepository = Boolean.parseBoolean(displayCategoriesByRepository); 1916 m_displayCategorySelectionCollapsed = Boolean.parseBoolean(displayCategorySelectionCollapsed); 1917 } 1918 1919 /** 1920 * Sets the name of the local category folder(s).<p> 1921 * 1922 * @param categoryFolder the name of the local category folder(s) 1923 */ 1924 public void setCategoryFolder(String categoryFolder) { 1925 1926 m_categoryFolder = categoryFolder; 1927 } 1928 1929 /** 1930 * Sets the access object of the type settings.<p> 1931 * 1932 * @param access access object 1933 */ 1934 public void setDefaultAccess(CmsExplorerTypeAccess access) { 1935 1936 m_defaultAccess = access; 1937 } 1938 1939 /** 1940 * Sets the Workplace default locale.<p> 1941 * 1942 * @param locale the locale to set 1943 */ 1944 public void setDefaultLocale(String locale) { 1945 1946 try { 1947 m_defaultLocale = CmsLocaleManager.getLocale(locale); 1948 } catch (Exception e) { 1949 if (CmsLog.INIT.isWarnEnabled()) { 1950 CmsLog.INIT.warn(Messages.get().getBundle().key(Messages.INIT_NONCRIT_ERROR_0), e); 1951 } 1952 } 1953 if (CmsLog.INIT.isInfoEnabled()) { 1954 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_DEFAULT_LOCALE_1, m_defaultLocale)); 1955 } 1956 } 1957 1958 /** 1959 * Sets the default property editing mode on resources.<p> 1960 * 1961 * @param defaultPropertiesOnStructure the default property editing mode on resources 1962 */ 1963 public void setDefaultPropertiesOnStructure(String defaultPropertiesOnStructure) { 1964 1965 m_defaultPropertiesOnStructure = Boolean.valueOf(defaultPropertiesOnStructure).booleanValue(); 1966 if (CmsLog.INIT.isInfoEnabled()) { 1967 CmsLog.INIT.info( 1968 Messages.get().getBundle().key( 1969 m_defaultPropertiesOnStructure 1970 ? Messages.INIT_PROP_ON_STRUCT_TRUE_0 1971 : Messages.INIT_PROP_ON_STRUCT_FALSE_0)); 1972 } 1973 } 1974 1975 /** 1976 * Sets the Workplace default user settings.<p> 1977 * 1978 * @param defaultUserSettings the user settings to set 1979 */ 1980 public void setDefaultUserSettings(CmsDefaultUserSettings defaultUserSettings) { 1981 1982 m_defaultUserSettings = defaultUserSettings; 1983 1984 if (CmsLog.INIT.isInfoEnabled()) { 1985 CmsLog.INIT.info( 1986 Messages.get().getBundle().key( 1987 Messages.INIT_DEFAULT_USER_SETTINGS_1, 1988 m_defaultUserSettings.getClass().getName())); 1989 } 1990 } 1991 1992 /** 1993 * Sets the direct edit provider.<p> 1994 * 1995 * @param clazz the direct edit provider to set 1996 */ 1997 public void setDirectEditProvider(I_CmsDirectEditProvider clazz) { 1998 1999 m_directEditProvider = clazz; 2000 if (CmsLog.INIT.isInfoEnabled()) { 2001 CmsLog.INIT.info( 2002 Messages.get().getBundle().key( 2003 Messages.INIT_DIRECT_EDIT_PROVIDER_1, 2004 m_directEditProvider.getClass().getName())); 2005 } 2006 } 2007 2008 /** 2009 * Sets the editor action class.<p> 2010 * 2011 * @param clazz the editor action class to set 2012 */ 2013 public void setEditorAction(I_CmsEditorActionHandler clazz) { 2014 2015 m_editorAction = clazz; 2016 if (CmsLog.INIT.isInfoEnabled()) { 2017 CmsLog.INIT.info( 2018 Messages.get().getBundle().key( 2019 Messages.INIT_EDITOR_ACTION_CLASS_1, 2020 m_editorAction.getClass().getName())); 2021 } 2022 } 2023 2024 /** 2025 * Sets the editor display option class.<p> 2026 * 2027 * @param clazz the editor display option class to set 2028 */ 2029 public void setEditorDisplayOptions(CmsEditorDisplayOptions clazz) { 2030 2031 m_editorDisplayOptions = clazz; 2032 if (CmsLog.INIT.isInfoEnabled()) { 2033 CmsLog.INIT.info( 2034 Messages.get().getBundle().key( 2035 Messages.INIT_EDITOR_DISPLAY_OPTS_1, 2036 m_editorAction.getClass().getName())); 2037 } 2038 } 2039 2040 /** 2041 * Sets the editor handler class.<p> 2042 * 2043 * @param clazz the editor handler class to set 2044 */ 2045 public void setEditorHandler(I_CmsEditorHandler clazz) { 2046 2047 m_editorHandler = clazz; 2048 if (CmsLog.INIT.isInfoEnabled()) { 2049 CmsLog.INIT.info( 2050 Messages.get().getBundle().key( 2051 Messages.INIT_EDITOR_HANDLER_CLASS_1, 2052 m_editorHandler.getClass().getName())); 2053 } 2054 } 2055 2056 /** 2057 * Sets the element delete mode.<p> 2058 * 2059 * @param deleteMode the element delete mode 2060 */ 2061 public void setElementDeleteMode(String deleteMode) { 2062 2063 try { 2064 m_elementDeleteMode = ElementDeleteMode.valueOf(deleteMode); 2065 } catch (Throwable t) { 2066 m_elementDeleteMode = ElementDeleteMode.askDelete; 2067 } 2068 } 2069 2070 /** 2071 * Sets if tabs in the advanced property dialog are enabled.<p> 2072 * 2073 * @param enableAdvancedPropertyTabs true if tabs should be enabled, otherwise false 2074 */ 2075 public void setEnableAdvancedPropertyTabs(String enableAdvancedPropertyTabs) { 2076 2077 m_enableAdvancedPropertyTabs = Boolean.valueOf(enableAdvancedPropertyTabs).booleanValue(); 2078 if (CmsLog.INIT.isInfoEnabled()) { 2079 CmsLog.INIT.info( 2080 Messages.get().getBundle().key( 2081 m_enableAdvancedPropertyTabs 2082 ? Messages.INIT_ADV_PROP_DIALOG_SHOW_TABS_0 2083 : Messages.INIT_ADV_PROP_DIALOG_HIDE_TABS_0)); 2084 } 2085 } 2086 2087 /** 2088 * Sets the value (in kb) for the maximum file upload size.<p> 2089 * 2090 * @param value the value (in kb) for the maximum file upload size 2091 */ 2092 public void setFileMaxUploadSize(String value) { 2093 2094 try { 2095 m_fileMaxUploadSize = Integer.valueOf(value).intValue(); 2096 } catch (NumberFormatException e) { 2097 // can usually be ignored 2098 if (LOG.isInfoEnabled()) { 2099 LOG.info(e.getLocalizedMessage()); 2100 } 2101 m_fileMaxUploadSize = -1; 2102 } 2103 if (CmsLog.INIT.isInfoEnabled()) { 2104 if (m_fileMaxUploadSize > 0) { 2105 CmsLog.INIT.info( 2106 Messages.get().getBundle().key( 2107 Messages.INIT_MAX_FILE_UPLOAD_SIZE_1, 2108 new Integer(m_fileMaxUploadSize))); 2109 } else { 2110 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_MAX_FILE_UPLOAD_SIZE_UNLIMITED_0)); 2111 } 2112 2113 } 2114 } 2115 2116 /** 2117 * Sets the system-wide file view settings for the workplace.<p> 2118 * 2119 * @param cms the CmsObject for ensuring security constraints. 2120 * 2121 * @param fileViewSettings the system-wide file view settings for the workplace to set 2122 * 2123 * @throws CmsRoleViolationException if the current user does not own the administrator role ({@link CmsRole#ROOT_ADMIN}) 2124 * */ 2125 public void setFileViewSettings(CmsObject cms, CmsRfsFileViewer fileViewSettings) throws CmsRoleViolationException { 2126 2127 if (OpenCms.getRunLevel() > OpenCms.RUNLEVEL_2_INITIALIZING) { 2128 OpenCms.getRoleManager().checkRole(cms, CmsRole.ROOT_ADMIN); 2129 } 2130 m_fileViewSettings = fileViewSettings; 2131 // disallow modifications of this "new original" 2132 m_fileViewSettings.setFrozen(true); 2133 } 2134 2135 /** 2136 * Sets the gallery default scope.<p> 2137 * 2138 * @param galleryDefaultScope the gallery default scope 2139 */ 2140 public void setGalleryDefaultScope(String galleryDefaultScope) { 2141 2142 m_galleryDefaultScope = galleryDefaultScope; 2143 try { 2144 CmsGallerySearchScope.valueOf(galleryDefaultScope); 2145 } catch (Throwable t) { 2146 LOG.warn(t.getLocalizedMessage(), t); 2147 } 2148 } 2149 2150 /** 2151 * Sets the group translation class name.<p> 2152 * 2153 * @param translationClassName the group translation class name 2154 */ 2155 public void setGroupTranslationClass(String translationClassName) { 2156 2157 m_groupTranslationClass = translationClassName; 2158 } 2159 2160 /** 2161 * Sets the "keep alive" mode.<p> 2162 * 2163 * @param keepAlive the keep-alive mode 2164 */ 2165 public void setKeepAlive(String keepAlive) { 2166 2167 m_keepAlive = Boolean.valueOf(keepAlive); 2168 } 2169 2170 /** 2171 * Sets the post upload dialog handler.<p> 2172 * 2173 * @param uploadHandler the post upload handler 2174 */ 2175 public void setPostUploadHandler(I_CmsPostUploadDialogHandler uploadHandler) { 2176 2177 m_postUploadHandler = uploadHandler; 2178 } 2179 2180 /** 2181 * Sets the repository folder handler.<p> 2182 * 2183 * @param clazz the repository folder handler 2184 */ 2185 public void setRepositoryFolderHandler(I_CmsRepositoryFolderHandler clazz) { 2186 2187 m_repositoryFolderHandler = clazz; 2188 if (CmsLog.INIT.isInfoEnabled()) { 2189 CmsLog.INIT.info( 2190 org.opencms.configuration.Messages.get().getBundle().key( 2191 org.opencms.configuration.Messages.INIT_REPOSITORY_FOLDER_1, 2192 m_repositoryFolderHandler.getClass().getName())); 2193 } 2194 } 2195 2196 /** 2197 * Sets the name of the role necessary for editing the sitemap configuration. 2198 * 2199 * @param roleName the name of the role necessary for editing the sitemap configuration 2200 */ 2201 public void setSitemapConfigEditRole(String roleName) { 2202 2203 m_sitemapConfigEditRole = roleName; 2204 } 2205 2206 /** 2207 * Sets the tool Manager object.<p> 2208 * 2209 * @param toolManager the tool Manager object to set 2210 */ 2211 public void setToolManager(CmsToolManager toolManager) { 2212 2213 m_toolManager = toolManager; 2214 } 2215 2216 /** 2217 * Sets the upload restriciton. 2218 * 2219 * @param uploadRestriction the upload restriction 2220 */ 2221 public void setUploadRestriction(I_CmsUploadRestriction uploadRestriction) { 2222 2223 if (m_uploadRestrictionSet) { 2224 throw new IllegalStateException("Upload restriction has already been set."); 2225 } 2226 m_uploadRestriction = uploadRestriction; 2227 m_uploadRestrictionSet = true; 2228 } 2229 2230 /** 2231 * Sets the user additional information configuration manager.<p> 2232 * 2233 * @param userInfoManager the manager to set 2234 */ 2235 public void setUserInfoManager(CmsWorkplaceUserInfoManager userInfoManager) { 2236 2237 m_userInfoManager = userInfoManager; 2238 } 2239 2240 /** 2241 * Sets the user list mode.<p> 2242 * 2243 * @param mode the user list mode 2244 */ 2245 public void setUserListMode(String mode) { 2246 2247 m_userListMode = mode; 2248 } 2249 2250 /** 2251 * Controls if the user/group icon in the administration view should be shown.<p> 2252 * 2253 * @param value <code>"true"</code> if the user/group icon in the administration view should be shown, otherwise false 2254 */ 2255 public void setUserManagementEnabled(String value) { 2256 2257 m_showUserGroupIcon = Boolean.valueOf(value).booleanValue(); 2258 if (CmsLog.INIT.isInfoEnabled()) { 2259 if (m_showUserGroupIcon) { 2260 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_USER_MANAGEMENT_ICON_ENABLED_0)); 2261 } else { 2262 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_USER_MANAGEMENT_ICON_DISABLED_0)); 2263 } 2264 } 2265 } 2266 2267 /** 2268 * Sets the auto correction of XML contents when they are opened with the editor.<p> 2269 * 2270 * @param xmlContentAutoCorrect if "true", the content will be corrected without notification, otherwise a confirmation is needed 2271 */ 2272 public void setXmlContentAutoCorrect(String xmlContentAutoCorrect) { 2273 2274 m_xmlContentAutoCorrect = Boolean.valueOf(xmlContentAutoCorrect).booleanValue(); 2275 if (CmsLog.INIT.isInfoEnabled()) { 2276 CmsLog.INIT.info( 2277 Messages.get().getBundle().key( 2278 m_xmlContentAutoCorrect 2279 ? Messages.INIT_XMLCONTENT_AUTOCORRECT_ENABLED_0 2280 : Messages.INIT_XMLCONTENT_AUTOCORRECT_DISABLED_0)); 2281 } 2282 } 2283 2284 /** 2285 * Returns true if the Acacia editor in standalone mode should automatically unlock resources.<p> 2286 * 2287 * @return true if resources should be automatically unlocked in standalone mode 2288 */ 2289 public boolean shouldAcaciaUnlock() { 2290 2291 if (m_acaciaUnlock == null) { 2292 return true; 2293 } else { 2294 return Boolean.parseBoolean(m_acaciaUnlock); 2295 } 2296 } 2297 2298 /** 2299 * Returns if the user/group icon in the administration view should be shown.<p> 2300 * 2301 * @return true if the user/group icon in the administration view should be shown, otherwise false 2302 */ 2303 public boolean showUserGroupIcon() { 2304 2305 return m_showUserGroupIcon; 2306 } 2307 2308 /** 2309 * Returns true if lazy user lists should be used.<p> 2310 * 2311 * @return true if lazy user lists should be used 2312 */ 2313 public boolean supportsLazyUserLists() { 2314 2315 boolean result = "lazy".equalsIgnoreCase(m_userListMode); 2316 if (org.opencms.db.mssql.CmsUserDriver.isInstantiated()) { 2317 LOG.warn("Lazy user lists currently not supported on MSSQL, using classic user list mode as a fallback."); 2318 result = false; 2319 } 2320 return result; 2321 2322 } 2323 2324 /** 2325 * Translates a group name using the configured {@link I_CmsGroupNameTranslation}.<p> 2326 * 2327 * @param groupName the group name 2328 * @param keepOu if true, the OU will be appended to the translated name 2329 * 2330 * @return the translated group name 2331 */ 2332 public String translateGroupName(String groupName, boolean keepOu) { 2333 2334 I_CmsGroupNameTranslation translation = getGroupNameTranslation(); 2335 return translation.translateGroupName(groupName, keepOu); 2336 } 2337 2338 /** 2339 * Gets the default view name ( = explorer type) for the given type.<p> 2340 * 2341 * @param typeName a resource type name 2342 * @return the default view for the given type 2343 */ 2344 String getDefaultView(String typeName) { 2345 2346 String result = m_defaultViewRules.getViewForType(typeName); 2347 if (result == null) { 2348 result = "view_other"; 2349 try { 2350 if (OpenCms.getResourceManager().hasResourceType(typeName) 2351 && OpenCms.getResourceManager().getResourceType(typeName).isFolder()) { 2352 result = "view_folders"; 2353 } 2354 } catch (CmsLoaderException e) { 2355 LOG.error(e.getLocalizedMessage(), e); 2356 } 2357 } 2358 return result; 2359 } 2360 2361 /** 2362 * Creates a copy of the admin cms object which is initialize with the data of the current cms object.<p> 2363 * 2364 * @param cms the current cms object 2365 * @return the new admin cms object 2366 * 2367 * @throws CmsException if something goes wrong 2368 */ 2369 private CmsObject getAdminCms(CmsObject cms) throws CmsException { 2370 2371 CmsObject adminCms = OpenCms.initCmsObject(m_adminCms); 2372 adminCms.getRequestContext().setSiteRoot(cms.getRequestContext().getSiteRoot()); 2373 adminCms.getRequestContext().setRequestTime(cms.getRequestContext().getRequestTime()); 2374 adminCms.getRequestContext().setCurrentProject(cms.getRequestContext().getCurrentProject()); 2375 adminCms.getRequestContext().setEncoding(cms.getRequestContext().getEncoding()); 2376 adminCms.getRequestContext().setUri(cms.getRequestContext().getUri()); 2377 return adminCms; 2378 } 2379 2380 /** 2381 * Returns a dummy group name translation which leaves the group names unchanged.<p> 2382 * 2383 * @return a dummy group name translation 2384 */ 2385 private I_CmsGroupNameTranslation getDefaultGroupNameTranslation() { 2386 2387 return new I_CmsGroupNameTranslation() { 2388 2389 public String translateGroupName(String group, boolean keepOu) { 2390 2391 return keepOu ? group : CmsOrganizationalUnit.getSimpleName(group); 2392 } 2393 }; 2394 } 2395 2396 /** 2397 * Initializes the configured explorer type settings.<p> 2398 */ 2399 private synchronized void initExplorerTypeSettings() { 2400 2401 Map<String, CmsExplorerTypeSettings> explorerTypeSettingsMap = new HashMap<String, CmsExplorerTypeSettings>(); 2402 List<CmsExplorerTypeSettings> explorerTypeSettings = new ArrayList<CmsExplorerTypeSettings>(); 2403 2404 if (m_defaultAccess.getAccessControlList() == null) { 2405 try { 2406 // initialize the default access control configuration 2407 m_defaultAccess.createAccessControlList(CmsExplorerTypeAccess.PRINCIPAL_DEFAULT); 2408 } catch (CmsException e) { 2409 if (CmsLog.INIT.isInfoEnabled()) { 2410 CmsLog.INIT.info( 2411 Messages.get().getBundle().key( 2412 Messages.INIT_ADD_TYPE_SETTING_FAILED_1, 2413 CmsExplorerTypeAccess.PRINCIPAL_DEFAULT), 2414 e); 2415 } 2416 } 2417 } 2418 2419 explorerTypeSettings.addAll(m_explorerTypeSettingsFromXml); 2420 explorerTypeSettings.addAll(m_explorerTypeSettingsFromModules); 2421 2422 for (int i = 0; i < explorerTypeSettings.size(); i++) { 2423 CmsExplorerTypeSettings settings = explorerTypeSettings.get(i); 2424 // put the settings in the lookup map 2425 explorerTypeSettingsMap.put(settings.getName(), settings); 2426 if (getDefaultAccess() == settings.getAccess()) { 2427 continue; 2428 } 2429 try { 2430 // initialize the access control configuration of the explorer type 2431 settings.getAccess().createAccessControlList(settings.getName()); 2432 } catch (CmsException e) { 2433 if (CmsLog.INIT.isInfoEnabled()) { 2434 CmsLog.INIT.info( 2435 Messages.get().getBundle().key(Messages.INIT_ADD_TYPE_SETTING_FAILED_1, settings.getName()), 2436 e); 2437 } 2438 } 2439 } 2440 // sort the explorer type settings 2441 Collections.sort(explorerTypeSettings); 2442 // make the settings unmodifiable and store them in the global variables 2443 m_explorerTypeSettings = Collections.unmodifiableList(explorerTypeSettings); 2444 m_explorerTypeSettingsMap = Collections.unmodifiableMap(explorerTypeSettingsMap); 2445 2446 m_explorerTypeViews = Maps.newHashMap(); 2447 Set<String> explorerTypeViews = Sets.newHashSet(); 2448 for (CmsExplorerTypeSettings explorerType : getExplorerTypeSettings()) { 2449 if (explorerType.isView()) { 2450 explorerTypeViews.add(explorerType.getName()); 2451 } 2452 } 2453 2454 for (String typeName : explorerTypeViews) { 2455 CmsExplorerTypeSettings explorerType = OpenCms.getWorkplaceManager().getExplorerTypeSetting(typeName); 2456 CmsElementView elemView = new CmsElementView(explorerType); 2457 m_explorerTypeViews.put(elemView.getId(), elemView); 2458 } 2459 2460 } 2461 2462 /** 2463 * Initializes the workplace locale set.<p> 2464 * 2465 * Currently, this is defined by the existence of a special folder 2466 * <code>/system/workplace/locales/{locale-name}/</code>. 2467 * This is likely to change in future implementations.<p> 2468 * 2469 * @param cms an OpenCms context object that must have been initialized with "Admin" permissions 2470 * 2471 * @return the workplace locale set 2472 */ 2473 private List<Locale> initWorkplaceLocales(CmsObject cms) { 2474 2475 Set<Locale> locales = new HashSet<Locale>(); 2476 2477 // collect locales from the VFS 2478 if (cms.existsResource(CmsWorkplace.VFS_PATH_LOCALES)) { 2479 List<CmsResource> localeFolders; 2480 try { 2481 localeFolders = cms.getSubFolders(CmsWorkplace.VFS_PATH_LOCALES); 2482 } catch (CmsException e) { 2483 LOG.warn( 2484 Messages.get().getBundle().key( 2485 Messages.LOG_WORKPLACE_INIT_NO_LOCALES_1, 2486 CmsWorkplace.VFS_PATH_LOCALES), 2487 e); 2488 // can not throw exception here since then OpenCms would not even start in shell mode (runlevel 2) 2489 localeFolders = new ArrayList<CmsResource>(); 2490 } 2491 Iterator<CmsResource> i = localeFolders.iterator(); 2492 while (i.hasNext()) { 2493 CmsFolder folder = (CmsFolder)i.next(); 2494 Locale locale = CmsLocaleManager.getLocale(folder.getName()); 2495 // add locale 2496 locales.add(locale); 2497 // add less specialized locale 2498 locales.add(new Locale(locale.getLanguage(), locale.getCountry())); 2499 // add even less specialized locale 2500 locales.add(new Locale(locale.getLanguage())); 2501 } 2502 } 2503 // collect locales from JAR manifests 2504 try { 2505 Enumeration<URL> resources = getClass().getClassLoader().getResources(MANIFEST_RESOURCE_NAME); 2506 2507 while (resources.hasMoreElements()) { 2508 URL resUrl = resources.nextElement(); 2509 try { 2510 Manifest manifest = new Manifest(resUrl.openStream()); 2511 String localeString = manifest.getMainAttributes().getValue(LOCALIZATION_ATTRIBUTE_NAME); 2512 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(localeString)) { 2513 Locale locale = CmsLocaleManager.getLocale(localeString); 2514 // add locale 2515 locales.add(locale); 2516 // add less specialized locale 2517 locales.add(new Locale(locale.getLanguage(), locale.getCountry())); 2518 // add even less specialized locale 2519 locales.add(new Locale(locale.getLanguage())); 2520 } 2521 } catch (IOException e) { 2522 LOG.warn( 2523 "Error reading manifest from " + resUrl + " while evaluating available workplace localization.", 2524 e); 2525 } 2526 } 2527 } catch (IOException e) { 2528 LOG.error("Error evaluating available workplace localization from JAR manifests.", e); 2529 } 2530 2531 // sort the result 2532 ArrayList<Locale> result = new ArrayList<Locale>(); 2533 result.addAll(locales); 2534 Collections.sort(result, CmsLocaleComparator.getComparator()); 2535 return result; 2536 } 2537 2538 /** 2539 * Initializes the available workplace views.<p> 2540 * 2541 * Currently, this is defined by iterating the subfolder of the folder 2542 * <code>/system/workplace/views/</code>. 2543 * These subfolders must have the properties NavPos, NavText and default-file set.<p> 2544 * 2545 * @param cms an OpenCms context object that must have been initialized with "Admin" permissions 2546 * @return the available workplace views 2547 */ 2548 private List<CmsWorkplaceView> initWorkplaceViews(CmsObject cms) { 2549 2550 List<CmsResource> viewFolders; 2551 try { 2552 // get the subfolders of the "views" folder 2553 viewFolders = cms.getSubFolders(CmsWorkplace.VFS_PATH_VIEWS); 2554 } catch (CmsException e) { 2555 if ((OpenCms.getRunLevel() > OpenCms.RUNLEVEL_2_INITIALIZING) && LOG.isInfoEnabled()) { 2556 LOG.info( 2557 Messages.get().getBundle().key(Messages.LOG_WORKPLACE_INIT_NO_VIEWS_1, CmsWorkplace.VFS_PATH_VIEWS), 2558 e); 2559 } 2560 // can not throw exception here since then OpenCms would not even start in shell mode (runlevel 2) 2561 viewFolders = new ArrayList<CmsResource>(); 2562 } 2563 m_views = new ArrayList<CmsWorkplaceView>(viewFolders.size()); 2564 for (int i = 0; i < viewFolders.size(); i++) { 2565 // loop through all view folders 2566 CmsFolder folder = (CmsFolder)viewFolders.get(i); 2567 String folderPath = cms.getSitePath(folder); 2568 try { 2569 // get view information from folder properties 2570 String order = cms.readPropertyObject( 2571 folderPath, 2572 CmsPropertyDefinition.PROPERTY_NAVPOS, 2573 false).getValue(); 2574 String key = cms.readPropertyObject( 2575 folderPath, 2576 CmsPropertyDefinition.PROPERTY_NAVTEXT, 2577 false).getValue(); 2578 String viewUri = cms.readPropertyObject( 2579 folderPath, 2580 CmsPropertyDefinition.PROPERTY_DEFAULT_FILE, 2581 false).getValue(); 2582 if (viewUri == null) { 2583 // no view URI found 2584 viewUri = folderPath; 2585 } else if (!viewUri.startsWith("/")) { 2586 // default file is in current view folder, create absolute path to view URI 2587 viewUri = folderPath + viewUri; 2588 } 2589 if (order == null) { 2590 // no valid NavPos property value found, use loop count as order value 2591 order = "" + i; 2592 } 2593 Float orderValue; 2594 try { 2595 // create Float order object 2596 orderValue = Float.valueOf(order); 2597 } catch (NumberFormatException e) { 2598 // String was not formatted correctly, use loop counter 2599 orderValue = Float.valueOf(i); 2600 } 2601 if (key == null) { 2602 // no language key found, use default String to avoid NullPointerException 2603 key = "View " + i; 2604 // if no navtext is given do not display the view 2605 continue; 2606 } 2607 // create new view object 2608 CmsWorkplaceView view = new CmsWorkplaceView(key, viewUri, orderValue); 2609 m_views.add(view); 2610 // log the view 2611 if (CmsLog.INIT.isInfoEnabled()) { 2612 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_WORKPLACE_VIEW_1, view.getUri())); 2613 } 2614 } catch (CmsException e) { 2615 // should usually never happen 2616 LOG.error(Messages.get().getBundle().key(Messages.LOG_READING_VIEW_FOLDER_FAILED_1, folderPath), e); 2617 } 2618 } 2619 // sort the views by their order number 2620 Collections.sort(m_views); 2621 return m_views; 2622 } 2623}