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