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.main; 029 030import org.opencms.ade.configuration.CmsADEManager; 031import org.opencms.configuration.CmsConfigurationException; 032import org.opencms.configuration.CmsConfigurationManager; 033import org.opencms.configuration.CmsImportExportConfiguration; 034import org.opencms.configuration.CmsModuleConfiguration; 035import org.opencms.configuration.CmsParameterConfiguration; 036import org.opencms.configuration.CmsSchedulerConfiguration; 037import org.opencms.configuration.CmsSearchConfiguration; 038import org.opencms.configuration.CmsSitesConfiguration; 039import org.opencms.configuration.CmsSystemConfiguration; 040import org.opencms.configuration.CmsVariablesConfiguration; 041import org.opencms.configuration.CmsVfsConfiguration; 042import org.opencms.configuration.CmsWorkplaceConfiguration; 043import org.opencms.db.CmsAliasManager; 044import org.opencms.db.CmsDbEntryNotFoundException; 045import org.opencms.db.CmsDefaultUsers; 046import org.opencms.db.CmsExportPoint; 047import org.opencms.db.CmsLoginManager; 048import org.opencms.db.CmsSecurityManager; 049import org.opencms.db.CmsSqlManager; 050import org.opencms.db.CmsSubscriptionManager; 051import org.opencms.db.timing.CmsDefaultProfilingHandler; 052import org.opencms.db.timing.CmsThreadStatsTreeProfilingHandler; 053import org.opencms.file.CmsObject; 054import org.opencms.file.CmsProject; 055import org.opencms.file.CmsProperty; 056import org.opencms.file.CmsPropertyDefinition; 057import org.opencms.file.CmsRequestContext; 058import org.opencms.file.CmsResource; 059import org.opencms.file.CmsUser; 060import org.opencms.file.CmsVfsResourceNotFoundException; 061import org.opencms.flex.CmsFlexCache; 062import org.opencms.flex.CmsFlexCacheConfiguration; 063import org.opencms.flex.CmsFlexController; 064import org.opencms.gwt.CmsGwtService; 065import org.opencms.gwt.CmsGwtServiceContext; 066import org.opencms.i18n.CmsEncoder; 067import org.opencms.i18n.CmsI18nInfo; 068import org.opencms.i18n.CmsLocaleManager; 069import org.opencms.i18n.CmsMessageContainer; 070import org.opencms.i18n.CmsSingleTreeLocaleHandler; 071import org.opencms.i18n.CmsVfsBundleManager; 072import org.opencms.importexport.CmsImportExportManager; 073import org.opencms.jsp.jsonpart.CmsJsonPartFilter; 074import org.opencms.letsencrypt.CmsLetsEncryptConfiguration; 075import org.opencms.loader.CmsResourceManager; 076import org.opencms.loader.CmsTemplateContextManager; 077import org.opencms.loader.I_CmsFlexCacheEnabledLoader; 078import org.opencms.loader.I_CmsResourceLoader; 079import org.opencms.lock.CmsLockManager; 080import org.opencms.module.CmsModuleManager; 081import org.opencms.monitor.CmsMemoryMonitor; 082import org.opencms.monitor.CmsMemoryMonitorConfiguration; 083import org.opencms.publish.CmsPublishEngine; 084import org.opencms.publish.CmsPublishManager; 085import org.opencms.repository.CmsRepositoryManager; 086import org.opencms.rmi.CmsRemoteShellServer; 087import org.opencms.scheduler.CmsScheduleManager; 088import org.opencms.search.CmsSearchManager; 089import org.opencms.security.CmsOrgUnitManager; 090import org.opencms.security.CmsPersistentLoginTokenHandler; 091import org.opencms.security.CmsRole; 092import org.opencms.security.CmsRoleManager; 093import org.opencms.security.CmsRoleViolationException; 094import org.opencms.security.CmsSecurityException; 095import org.opencms.security.I_CmsAuthorizationHandler; 096import org.opencms.security.I_CmsCredentialsResolver; 097import org.opencms.security.I_CmsPasswordHandler; 098import org.opencms.security.I_CmsValidationHandler; 099import org.opencms.site.CmsSite; 100import org.opencms.site.CmsSiteManagerImpl; 101import org.opencms.site.CmsSiteMatcher; 102import org.opencms.staticexport.CmsDefaultLinkSubstitutionHandler; 103import org.opencms.staticexport.CmsLinkManager; 104import org.opencms.staticexport.CmsStaticExportManager; 105import org.opencms.ugc.CmsUgcSessionFactory; 106import org.opencms.ui.apps.CmsWorkplaceAppManager; 107import org.opencms.ui.error.CmsErrorUI; 108import org.opencms.ui.login.CmsLoginHelper; 109import org.opencms.ui.login.CmsLoginUI; 110import org.opencms.util.CmsRequestUtil; 111import org.opencms.util.CmsStringUtil; 112import org.opencms.util.CmsUUID; 113import org.opencms.workflow.CmsDefaultWorkflowManager; 114import org.opencms.workflow.I_CmsWorkflowManager; 115import org.opencms.workplace.CmsWorkplace; 116import org.opencms.workplace.CmsWorkplaceLoginHandler; 117import org.opencms.workplace.CmsWorkplaceManager; 118import org.opencms.workplace.CmsWorkplaceSettings; 119import org.opencms.xml.CmsXmlContentTypeManager; 120import org.opencms.xml.CmsXmlUtils; 121import org.opencms.xml.containerpage.CmsFormatterConfiguration; 122 123import java.io.FileOutputStream; 124import java.io.IOException; 125import java.security.Security; 126import java.util.ArrayList; 127import java.util.Collections; 128import java.util.Date; 129import java.util.HashMap; 130import java.util.HashSet; 131import java.util.Hashtable; 132import java.util.Iterator; 133import java.util.List; 134import java.util.Locale; 135import java.util.Map; 136import java.util.Set; 137import java.util.concurrent.ScheduledThreadPoolExecutor; 138import java.util.concurrent.TimeUnit; 139 140import javax.servlet.ServletConfig; 141import javax.servlet.ServletContext; 142import javax.servlet.ServletException; 143import javax.servlet.http.HttpServletRequest; 144import javax.servlet.http.HttpServletResponse; 145import javax.servlet.http.HttpSession; 146 147import org.apache.commons.logging.Log; 148 149import org.antlr.stringtemplate.StringTemplate; 150 151import com.google.common.base.Optional; 152 153import cryptix.jce.provider.CryptixCrypto; 154 155/** 156 * The internal implementation of the core OpenCms "operating system" functions.<p> 157 * 158 * All access to this class must be done through the public static methods 159 * of the <code>{@link org.opencms.main.OpenCms}</code> object. 160 * Under no circumstances should you ever try to access this class directly.<p> 161 * 162 * This class is so OpenCms internal you should not even be reading this documentation ;-)<p> 163 * 164 * Any request to the <code>{@link org.opencms.main.OpenCmsServlet}</code> will be forwarded to this core class. 165 * The core will then try to map the request to a VFS (Virtual File System) URI, 166 * that is a <code>{@link org.opencms.file.CmsResource}</code> in the OpenCms database. 167 * If a resource is found, it will be read and forwarded to 168 * to the corresponding <code>{@link org.opencms.loader.I_CmsResourceLoader}</code>, 169 * which will then generate the output for the requested resource and return it to the requesting client.<p> 170 * 171 * There will be only one singleton instance of this object created for 172 * this core class. This means that in the default configuration, where 173 * OpenCms is accessed through a servlet context, there will be only one instance of 174 * the core in that servlet context.<p> 175 * 176 * @since 6.0.0 177 */ 178public final class OpenCmsCore { 179 180 /** The static log object for this class. */ 181 static final Log LOG = CmsLog.getLog(OpenCmsCore.class); 182 183 /** Lock object for synchronization. */ 184 private static final Object LOCK = new Object(); 185 186 /** Indicates if the configuration was successfully finished or not. */ 187 private static CmsMessageContainer m_errorCondition; 188 189 /** One instance to rule them all, one instance to find them... */ 190 private static OpenCmsCore m_instance; 191 192 /** The ADE manager instance. */ 193 private CmsADEManager m_adeManager; 194 195 /** The manager for page aliases. */ 196 private CmsAliasManager m_aliasManager; 197 198 /** The configured authorization handler. */ 199 private I_CmsAuthorizationHandler m_authorizationHandler; 200 201 /** The configuration manager that contains the information from the XML configuration. */ 202 private CmsConfigurationManager m_configurationManager; 203 204 /** The object used for resolving database user credentials. */ 205 private I_CmsCredentialsResolver m_credentialsResolver; 206 207 /** List of configured directory default file names. */ 208 private List<String> m_defaultFiles; 209 210 /** The default user and group names. */ 211 private CmsDefaultUsers m_defaultUsers; 212 213 /** The event manager for the event handling. */ 214 private CmsEventManager m_eventManager; 215 216 /** The thread pool executor. */ 217 private ScheduledThreadPoolExecutor m_executor; 218 219 /** The set of configured export points. */ 220 private Set<CmsExportPoint> m_exportPoints; 221 222 /** The flex cache instance. */ 223 private CmsFlexCache m_flexCache; 224 225 /** The context objects for GWT services. */ 226 private Map<String, CmsGwtServiceContext> m_gwtServiceContexts; 227 228 /** The site manager contains information about the Cms import/export. */ 229 private CmsImportExportManager m_importExportManager; 230 231 /** The LetsEncrypt configuration. */ 232 private CmsLetsEncryptConfiguration m_letsEncryptConfig; 233 234 /** The link manager to resolve links in <cms:link> tags. */ 235 private CmsLinkManager m_linkManager; 236 237 /** The locale manager used for obtaining the current locale. */ 238 private CmsLocaleManager m_localeManager; 239 240 /** The login manager. */ 241 private CmsLoginManager m_loginManager; 242 243 /** The memory monitor for the collection of memory and runtime statistics. */ 244 private CmsMemoryMonitor m_memoryMonitor; 245 246 /** The module manager. */ 247 private CmsModuleManager m_moduleManager; 248 249 /** The organizational unit manager. */ 250 private CmsOrgUnitManager m_orgUnitManager; 251 252 /** The password handler used to digest and validate passwords. */ 253 private I_CmsPasswordHandler m_passwordHandler; 254 255 /** The publish engine. */ 256 private CmsPublishEngine m_publishEngine; 257 258 /** The publish manager instance. */ 259 private CmsPublishManager m_publishManager; 260 261 /** The remote shell server. */ 262 private CmsRemoteShellServer m_remoteShellServer; 263 264 /** The repository manager. */ 265 private CmsRepositoryManager m_repositoryManager; 266 267 /** The configured request handlers that handle "special" requests, for example in the static export on demand. */ 268 private Map<String, I_CmsRequestHandler> m_requestHandlers; 269 270 /** Stores the resource init handlers that allow modification of the requested resource. */ 271 private List<I_CmsResourceInit> m_resourceInitHandlers; 272 273 /** The resource manager. */ 274 private CmsResourceManager m_resourceManager; 275 276 /** The role manager. */ 277 private CmsRoleManager m_roleManager; 278 279 /** The runlevel of this OpenCmsCore object instance. */ 280 private int m_runLevel; 281 282 /** The runtime properties allow storage of system wide accessible runtime information. */ 283 private Map<Object, Object> m_runtimeProperties; 284 285 /** The configured scheduler manager. */ 286 private CmsScheduleManager m_scheduleManager; 287 288 /** The search manager provides indexing and searching. */ 289 private CmsSearchManager m_searchManager; 290 291 /** The security manager to access the database and validate user permissions. */ 292 private CmsSecurityManager m_securityManager; 293 294 /** The session manager. */ 295 private CmsSessionManager m_sessionManager; 296 297 /** The site manager contains information about all configured sites. */ 298 private CmsSiteManagerImpl m_siteManager; 299 300 /** The static export manager. */ 301 private CmsStaticExportManager m_staticExportManager; 302 303 /** The subscription manager. */ 304 private CmsSubscriptionManager m_subscriptionManager; 305 306 /** The system information container for "read only" system settings. */ 307 private CmsSystemInfo m_systemInfo; 308 309 /** The template context manager. */ 310 private CmsTemplateContextManager m_templateContextManager; 311 312 /** The thread store. */ 313 private CmsThreadStore m_threadStore; 314 315 /** The runtime validation handler. */ 316 private I_CmsValidationHandler m_validationHandler; 317 318 /** The VFS bundle manager. */ 319 private CmsVfsBundleManager m_vfsBundleManager; 320 321 /** The workflow manager instance. */ 322 private I_CmsWorkflowManager m_workflowManager; 323 324 /** The workplace app manager. */ 325 private CmsWorkplaceAppManager m_workplaceAppManager; 326 327 /** The workplace manager contains information about the global workplace settings. */ 328 private CmsWorkplaceManager m_workplaceManager; 329 330 /** The XML content type manager that contains the initialized XML content types. */ 331 private CmsXmlContentTypeManager m_xmlContentTypeManager; 332 333 /** 334 * Protected constructor that will initialize the singleton OpenCms instance 335 * with runlevel {@link OpenCms#RUNLEVEL_1_CORE_OBJECT}.<p> 336 * 337 * @throws CmsInitException in case of errors during the initialization 338 */ 339 private OpenCmsCore() 340 throws CmsInitException { 341 342 if ((m_instance != null) && (m_instance.getRunLevel() > OpenCms.RUNLEVEL_0_OFFLINE)) { 343 throw new CmsInitException(Messages.get().container(Messages.ERR_ALREADY_INITIALIZED_0)); 344 } 345 initMembers(); 346 m_instance = this; 347 setRunLevel(OpenCms.RUNLEVEL_1_CORE_OBJECT); 348 } 349 350 /** 351 * Returns the initialized OpenCms singleton instance.<p> 352 * 353 * @return the initialized OpenCms singleton instance 354 */ 355 protected static OpenCmsCore getInstance() { 356 357 if (m_errorCondition != null) { 358 // OpenCms is not properly initialized 359 throw new CmsInitException(m_errorCondition, false); 360 } 361 362 if (m_instance != null) { 363 return m_instance; 364 } 365 synchronized (LOCK) { 366 if (m_instance == null) { 367 try { 368 // create a new core object with runlevel 1 369 m_instance = new OpenCmsCore(); 370 } catch (CmsInitException e) { 371 // already initialized, this is all we need 372 LOG.debug(e.getMessage(), e); 373 } 374 } 375 } 376 return m_instance; 377 } 378 379 /** 380 * Sets the error condition.<p> 381 * 382 * @param errorCondition the error condition to set 383 */ 384 protected static void setErrorCondition(CmsMessageContainer errorCondition) { 385 386 // init exceptions should only be thrown during setup process 387 if ((m_instance != null) && (m_instance.getRunLevel() < OpenCms.RUNLEVEL_3_SHELL_ACCESS)) { 388 if (!Messages.ERR_CRITICAL_INIT_WIZARD_0.equals(errorCondition.getKey())) { 389 // if wizard is still enabled allow retry of initialization (for setup wizard) 390 m_errorCondition = errorCondition; 391 // output an error message to the console 392 System.err.println( 393 Messages.get().getBundle().key(Messages.LOG_INIT_FAILURE_MESSAGE_1, errorCondition.key())); 394 } 395 LOG.error(errorCondition.key(), new CmsException(errorCondition)); 396 m_instance = null; 397 } else if (m_instance != null) { 398 // OpenCms already was successful initialized 399 LOG.warn( 400 Messages.get().getBundle().key( 401 Messages.LOG_INIT_INVALID_ERROR_2, 402 new Integer(m_instance.getRunLevel()), 403 errorCondition.key())); 404 } 405 } 406 407 /** 408 * Gets a string containing all keys and variations currently in the flex cache, for debug purposes.<p> 409 * 410 * @return a debug information string with the flex cache data 411 */ 412 public String getFlexCacheKeyDump() { 413 414 if (m_flexCache != null) { 415 StringBuffer buffer = new StringBuffer(); 416 m_flexCache.dumpKeys(buffer); 417 return buffer.toString(); 418 } else { 419 return null; 420 } 421 } 422 423 /** 424 * Gets the LetsEncrypt configuration.<p> 425 * 426 * @return the LetsEncrypt configuration 427 */ 428 public CmsLetsEncryptConfiguration getLetsEncryptConfig() { 429 430 return m_letsEncryptConfig; 431 } 432 433 /** 434 * Adds the specified request handler to the Map of OpenCms request handlers. <p> 435 * 436 * @param handler the handler to add 437 */ 438 protected void addRequestHandler(I_CmsRequestHandler handler) { 439 440 if (handler == null) { 441 return; 442 } 443 String[] names = handler.getHandlerNames(); 444 for (int i = 0; i < names.length; i++) { 445 String name = names[i]; 446 if (m_requestHandlers.get(name) != null) { 447 CmsLog.INIT.error(Messages.get().getBundle().key(Messages.LOG_DUPLICATE_REQUEST_HANDLER_1, name)); 448 continue; 449 } 450 m_requestHandlers.put(name, handler); 451 if (CmsLog.INIT.isInfoEnabled()) { 452 CmsLog.INIT.info( 453 Messages.get().getBundle().key( 454 Messages.INIT_ADDED_REQUEST_HANDLER_2, 455 name, 456 handler.getClass().getName())); 457 } 458 } 459 } 460 461 /** 462 * Gets the ADE manager, and makes sure it is initialized.<p> 463 * 464 * @return the initialized ADE manager 465 */ 466 protected CmsADEManager getADEManager() { 467 468 if (!m_adeManager.isInitialized()) { 469 m_adeManager.initialize(); 470 } 471 return m_adeManager; 472 } 473 474 /** 475 * Returns the alias manager.<p> 476 * 477 * @return the alias manager 478 */ 479 protected CmsAliasManager getAliasManager() { 480 481 return m_aliasManager; 482 } 483 484 /** 485 * Returns the configured authorization handler.<p> 486 * 487 * @return the configured authorization handler 488 */ 489 protected I_CmsAuthorizationHandler getAuthorizationHandler() { 490 491 return m_authorizationHandler; 492 } 493 494 /** 495 * Returns the initialized OpenCms configuration manager.<p> 496 * 497 * @return the initialized OpenCms configuration manager 498 */ 499 protected CmsConfigurationManager getConfigurationManager() { 500 501 return m_configurationManager; 502 } 503 504 /** 505 * Gets the configured credentials resolver instance.<p> 506 * 507 * @return the credentials resolver 508 */ 509 protected I_CmsCredentialsResolver getCredentialsResolver() { 510 511 if (m_credentialsResolver == null) { 512 CmsSystemConfiguration systemConfig = (CmsSystemConfiguration)m_configurationManager.getConfiguration( 513 CmsSystemConfiguration.class); 514 return systemConfig.getCredentialsResolver(); 515 } 516 517 return m_credentialsResolver; 518 } 519 520 /** 521 * Gets the database pool names.<p> 522 * 523 * @return the configured database pool names 524 */ 525 protected List<String> getDbPoolNames() { 526 527 return new ArrayList<>(m_configurationManager.getConfiguration().getList("db.pools")); 528 529 } 530 531 /** 532 * Returns the configured list of default directory file names.<p> 533 * 534 * @return the configured list of default directory file names 535 */ 536 protected List<String> getDefaultFiles() { 537 538 return m_defaultFiles; 539 } 540 541 /** 542 * Returns the default user and group name configuration.<p> 543 * 544 * @return the default user and group name configuration 545 */ 546 protected CmsDefaultUsers getDefaultUsers() { 547 548 return m_defaultUsers; 549 } 550 551 /** 552 * Returns the OpenCms event manager.<p> 553 * 554 * @return the OpenCms event manager 555 */ 556 protected CmsEventManager getEventManager() { 557 558 return m_eventManager; 559 } 560 561 /** 562 * Gets the thread pool executor.<p> 563 * 564 * @return the thread pool executor 565 */ 566 protected ScheduledThreadPoolExecutor getExecutor() { 567 568 return m_executor; 569 } 570 571 /** 572 * Returns the configured export points, 573 * the returned set being an unmodifiable set.<p> 574 * 575 * @return an unmodifiable set of the configured export points 576 */ 577 protected Set<CmsExportPoint> getExportPoints() { 578 579 return m_exportPoints; 580 } 581 582 /** 583 * Gets the flex cache. 584 * @return CmsFlexCache 585 */ 586 587 protected CmsFlexCache getFlexCache() { 588 589 return m_flexCache; 590 } 591 592 /** 593 * Returns the initialized import/export manager, 594 * which contains information about the Cms import/export.<p> 595 * 596 * @return the initialized import/export manager 597 */ 598 protected CmsImportExportManager getImportExportManager() { 599 600 return m_importExportManager; 601 } 602 603 /** 604 * Returns the link manager to resolve links in <link> tags.<p> 605 * 606 * @return the link manager to resolve links in <link> tags 607 */ 608 protected CmsLinkManager getLinkManager() { 609 610 return m_linkManager; 611 } 612 613 /** 614 * Returns the locale manager used for obtaining the current locale.<p> 615 * 616 * @return the locale manager 617 */ 618 protected CmsLocaleManager getLocaleManager() { 619 620 return m_localeManager; 621 } 622 623 /** 624 * Returns the lock manager used for the locking mechanism.<p> 625 * 626 * @return the lock manager used for the locking mechanism 627 */ 628 protected CmsLockManager getLockManager() { 629 630 return m_securityManager.getLockManager(); 631 } 632 633 /** 634 * Returns the login manager used to check the validity of a login.<p> 635 * 636 * @return the login manager 637 */ 638 protected CmsLoginManager getLoginManager() { 639 640 return m_loginManager; 641 } 642 643 /** 644 * Returns the memory monitor.<p> 645 * 646 * @return the memory monitor 647 */ 648 protected CmsMemoryMonitor getMemoryMonitor() { 649 650 return m_memoryMonitor; 651 } 652 653 /** 654 * Returns the module manager.<p> 655 * 656 * @return the module manager 657 */ 658 protected CmsModuleManager getModuleManager() { 659 660 return m_moduleManager; 661 } 662 663 /** 664 * Returns the organizational unit manager.<p> 665 * 666 * @return the organizational unit manager 667 */ 668 protected CmsOrgUnitManager getOrgUnitManager() { 669 670 return m_orgUnitManager; 671 } 672 673 /** 674 * Return the password handler.<p> 675 * 676 * @return the password handler 677 */ 678 protected I_CmsPasswordHandler getPasswordHandler() { 679 680 return m_passwordHandler; 681 } 682 683 /** 684 * Returns the path for the request.<p> 685 * 686 * First checks the {@link HttpServletRequest#getPathInfo()}, then 687 * the configured request error page attribute (if set), and then 688 * if still undefined the <code>/</code> is returned as path info.<p> 689 * 690 * This is only needed when the {@link HttpServletRequest#getPathInfo()} 691 * is not really working as expected like in BEA WLS 9.x, where we have 692 * to use the 'weblogic.servlet.errorPage' request attribute.<p> 693 * 694 * @param req the http request context 695 * 696 * @return the path for the request 697 */ 698 protected String getPathInfo(HttpServletRequest req) { 699 700 String path = req.getPathInfo(); 701 if (path == null) { 702 // if the HttpServletRequest#getPathInfo() method does not work properly 703 String requestErrorPageAttribute = getSystemInfo().getServletContainerSettings().getRequestErrorPageAttribute(); 704 if (requestErrorPageAttribute != null) { 705 // use the proper page attribute 706 path = (String)req.getAttribute(requestErrorPageAttribute); 707 if (path != null) { 708 int pos = path.indexOf("/", 1); 709 if (pos > 0) { 710 // cut off the servlet name 711 path = path.substring(pos); 712 } 713 } 714 } 715 } 716 if (path == null) { 717 path = "/"; 718 } 719 return path; 720 } 721 722 /** 723 * Returns the publish manager instance.<p> 724 * 725 * @return the publish manager instance 726 */ 727 protected CmsPublishManager getPublishManager() { 728 729 return m_publishManager; 730 } 731 732 /** 733 * Returns the repository manager.<p> 734 * 735 * @return the repository manager 736 */ 737 protected CmsRepositoryManager getRepositoryManager() { 738 739 return m_repositoryManager; 740 } 741 742 /** 743 * Returns the handler instance for the specified name, 744 * or null if the name does not match any handler name.<p> 745 * 746 * @param name the name of the handler instance to return 747 * @return the handler instance for the specified name 748 */ 749 protected I_CmsRequestHandler getRequestHandler(String name) { 750 751 return m_requestHandlers.get(name); 752 } 753 754 /** 755 * Returns the resource manager.<p> 756 * 757 * @return the resource manager 758 */ 759 protected CmsResourceManager getResourceManager() { 760 761 return m_resourceManager; 762 } 763 764 /** 765 * Returns the role manager.<p> 766 * 767 * @return the role manager 768 */ 769 protected CmsRoleManager getRoleManager() { 770 771 return m_roleManager; 772 } 773 774 /** 775 * Returns the runlevel of this OpenCmsCore object instance.<p> 776 * 777 * For a detailed description about the possible run levels, 778 * please see {@link OpenCms#getRunLevel()}.<p> 779 * 780 * @return the runlevel of this OpenCmsCore object instance 781 * 782 * @see OpenCms#getRunLevel() 783 */ 784 protected int getRunLevel() { 785 786 return m_runLevel; 787 } 788 789 /** 790 * Looks up a value in the runtime property Map.<p> 791 * 792 * @param key the key to look up in the runtime properties 793 * @return the value for the key, or null if the key was not found 794 */ 795 protected Object getRuntimeProperty(Object key) { 796 797 return m_runtimeProperties.get(key); 798 } 799 800 /** 801 * Returns the configured schedule manager.<p> 802 * 803 * @return the configured schedule manager 804 */ 805 protected CmsScheduleManager getScheduleManager() { 806 807 return m_scheduleManager; 808 } 809 810 /** 811 * Returns the initialized search manager, 812 * which provides indexing and searching operations.<p> 813 * 814 * @return the initialized search manager 815 */ 816 protected CmsSearchManager getSearchManager() { 817 818 return m_searchManager; 819 } 820 821 /** 822 * Returns the initialized OpenCms security manager.<p> 823 * 824 * @return the initialized OpenCms security manager 825 */ 826 protected CmsSecurityManager getSecurityManager() { 827 828 return m_securityManager; 829 } 830 831 /** 832 * Returns the session manager.<p> 833 * 834 * @return the session manager 835 */ 836 protected CmsSessionManager getSessionManager() { 837 838 return m_sessionManager; 839 } 840 841 /** 842 * Returns the initialized site manager, 843 * which contains information about all configured sites.<p> 844 * 845 * @return the initialized site manager 846 */ 847 protected CmsSiteManagerImpl getSiteManager() { 848 849 return m_siteManager; 850 } 851 852 /** 853 * Returns an instance of the common sql manager.<p> 854 * 855 * @return an instance of the common sql manager 856 */ 857 protected CmsSqlManager getSqlManager() { 858 859 return m_securityManager.getSqlManager(); 860 } 861 862 /** 863 * Returns the properties for the static export.<p> 864 * 865 * @return the properties for the static export 866 */ 867 protected CmsStaticExportManager getStaticExportManager() { 868 869 return m_staticExportManager; 870 } 871 872 /** 873 * Returns the subscription manager.<p> 874 * 875 * @return the subscription manager 876 */ 877 protected CmsSubscriptionManager getSubscriptionManager() { 878 879 return m_subscriptionManager; 880 } 881 882 /** 883 * Returns the system information storage.<p> 884 * 885 * @return the system information storage 886 */ 887 protected CmsSystemInfo getSystemInfo() { 888 889 return m_systemInfo; 890 } 891 892 /** 893 * Gets the template context manager instance.<p> 894 * 895 * @return the template context manager instance 896 */ 897 protected CmsTemplateContextManager getTemplateContextManager() { 898 899 return m_templateContextManager; 900 901 } 902 903 /** 904 * Returns the OpenCms Thread store.<p> 905 * 906 * @return the OpenCms Thread store 907 */ 908 protected CmsThreadStore getThreadStore() { 909 910 return m_threadStore; 911 } 912 913 /** 914 * Returns the runtime validation handler.<p> 915 * 916 * @return the validation handler 917 */ 918 protected I_CmsValidationHandler getValidationHandler() { 919 920 return m_validationHandler; 921 } 922 923 /** 924 * Returns the workflow manager instance.<p> 925 * 926 * @return the workflow manager 927 */ 928 protected I_CmsWorkflowManager getWorkflowManager() { 929 930 return m_workflowManager; 931 } 932 933 /** 934 * Returns the workplace app manager.<p> 935 * 936 * @return the workplace app manager 937 */ 938 protected CmsWorkplaceAppManager getWorkplaceAppManager() { 939 940 return m_workplaceAppManager; 941 } 942 943 /** 944 * Returns the initialized workplace manager, 945 * which contains information about the global workplace settings.<p> 946 * 947 * @return the initialized workplace manager 948 */ 949 protected CmsWorkplaceManager getWorkplaceManager() { 950 951 return m_workplaceManager; 952 } 953 954 /** 955 * Returns the XML content type manager.<p> 956 * 957 * @return the XML content type manager 958 */ 959 protected CmsXmlContentTypeManager getXmlContentTypeManager() { 960 961 if (m_xmlContentTypeManager != null) { 962 return m_xmlContentTypeManager; 963 } 964 if (getRunLevel() == OpenCms.RUNLEVEL_1_CORE_OBJECT) { 965 // this is only to enable test cases to run 966 m_xmlContentTypeManager = CmsXmlContentTypeManager.createTypeManagerForTestCases(); 967 } 968 return m_xmlContentTypeManager; 969 } 970 971 /** 972 * Initializes the OpenCms context for Vaadin UI servlet.<p> 973 * 974 * @param req the request 975 * @param res the response 976 * @param servlet the UI servlet 977 * 978 * @throws IOException if user authentication fails 979 * @throws CmsException if something goes wrong 980 */ 981 protected void initCmsContextForUI(HttpServletRequest req, HttpServletResponse res, CmsUIServlet servlet) 982 throws IOException, CmsException { 983 984 // instantiate CMS context 985 String originalEncoding = req.getCharacterEncoding(); 986 String referrer = req.getHeader("referer"); 987 boolean allowPrivilegedLogin = (referrer == null) || !referrer.contains(CmsWorkplaceLoginHandler.LOGIN_HANDLER); 988 989 CmsObject cms = initCmsObject(req, res, allowPrivilegedLogin); 990 servlet.setCms(cms); 991 if (originalEncoding != null) { 992 // getI18NInfo sets wrong encoding 993 req.setCharacterEncoding(originalEncoding); 994 } 995 } 996 997 /** 998 * Returns an independent copy of the provided CmsObject.<p> 999 * 1000 * This can be useful in case a permanent reference to a CmsObject is stored. 1001 * Changing the request context values (for example project, siteroot) in the new CmsObject 1002 * will have no side effects to the CmsObject it was copied form.<p> 1003 * 1004 * The request time (<code>{@link CmsRequestContext#getRequestTime()}</code>) 1005 * is set to the current time.<p> 1006 * 1007 * @param cms the CmsObject to create a copy of 1008 * 1009 * @return an independent copy of the provided CmsObject 1010 * 1011 * @throws CmsException in case the initialization failed 1012 * 1013 * @see OpenCms#initCmsObject(CmsObject) 1014 * @see OpenCms#initCmsObject(CmsObject, CmsContextInfo) 1015 * @see OpenCms#initCmsObject(String) 1016 */ 1017 protected CmsObject initCmsObject(CmsObject cms) throws CmsException { 1018 1019 CmsContextInfo contextInfo = new CmsContextInfo(cms.getRequestContext()); 1020 contextInfo.setRequestTime(CmsContextInfo.CURRENT_TIME); 1021 return initCmsObject(contextInfo); 1022 } 1023 1024 /** 1025 * Returns an initialized CmsObject with the user and context initialized as provided.<p> 1026 * 1027 * Note: Only if the provided <code>adminCms</code> CmsObject has admin permissions, 1028 * this method allows the creation a CmsObject for any existing user. Otherwise 1029 * only the default users 'Guest' and 'Export' can initialized with 1030 * this method, all other user names will throw an Exception.<p> 1031 * 1032 * @param adminCms must either be initialized with "Admin" permissions, or null 1033 * @param contextInfo the context info to create a CmsObject for 1034 * 1035 * @return an initialized CmsObject with the given users permissions 1036 * 1037 * @throws CmsException if an invalid user name was provided 1038 * @throws CmsRoleViolationException if the current user does not have the role permissions to create a context for the requested user 1039 * 1040 * @see org.opencms.db.CmsDefaultUsers#getUserGuest() 1041 * @see org.opencms.db.CmsDefaultUsers#getUserExport() 1042 * @see OpenCms#initCmsObject(CmsObject) 1043 * @see OpenCms#initCmsObject(CmsObject, CmsContextInfo) 1044 * @see OpenCms#initCmsObject(String) 1045 */ 1046 protected CmsObject initCmsObject(CmsObject adminCms, CmsContextInfo contextInfo) 1047 throws CmsRoleViolationException, CmsException { 1048 1049 String userName = contextInfo.getUserName(); 1050 1051 if ((adminCms == null) || !m_roleManager.hasRole(adminCms, CmsRole.ROOT_ADMIN)) { 1052 if (!userName.endsWith(getDefaultUsers().getUserGuest()) 1053 && !userName.endsWith(getDefaultUsers().getUserExport())) { 1054 1055 // if no admin object is provided, only "Guest" or "Export" user can be generated 1056 CmsMessageContainer message = Messages.get().container( 1057 Messages.ERR_INVALID_INIT_USER_2, 1058 userName, 1059 ((adminCms != null) ? (adminCms.getRequestContext().getCurrentUser().getName()) : "")); 1060 if (LOG.isWarnEnabled()) { 1061 LOG.warn(message.key()); 1062 } 1063 throw new CmsRoleViolationException(message); 1064 } 1065 } 1066 1067 return initCmsObject(contextInfo); 1068 } 1069 1070 /** 1071 * Handles the user authentification for each request sent to OpenCms.<p> 1072 * 1073 * User authentification is done in three steps: 1074 * <ol> 1075 * <li>Session authentification: OpenCms stores information of all authentificated 1076 * users in an internal storage based on the users session.</li> 1077 * <li>Authorization handler authentification: If the session authentification fails, 1078 * the current configured authorization handler is called.</li> 1079 * <li>Default user: When both authentification methods fail, the user is set to 1080 * the default (Guest) user.</li> 1081 * </ol> 1082 * 1083 * @param req the current http request 1084 * @param res the current http response 1085 * @param allowPrivilegedLogin <code>true</code> to allow login through authorization handlers 1086 * 1087 * @return the initialized cms context 1088 * 1089 * @throws IOException if user authentication fails 1090 * @throws CmsException in case something goes wrong 1091 */ 1092 protected CmsObject initCmsObject(HttpServletRequest req, HttpServletResponse res, boolean allowPrivilegedLogin) 1093 throws IOException, CmsException { 1094 1095 // first try to restore a stored session 1096 CmsObject cms = initCmsObjectFromSession(req); 1097 if (cms != null) { 1098 return cms; 1099 } 1100 if (allowPrivilegedLogin) { 1101 // if does not work, try to authorize the request 1102 I_CmsAuthorizationHandler.I_PrivilegedLoginAction loginAction = new I_CmsAuthorizationHandler.I_PrivilegedLoginAction() { 1103 1104 private CmsObject m_adminCms; 1105 1106 /** 1107 * @see org.opencms.security.I_CmsAuthorizationHandler.I_PrivilegedLoginAction#doLogin(javax.servlet.http.HttpServletRequest, java.lang.String) 1108 */ 1109 public CmsObject doLogin(HttpServletRequest request, String principal) throws CmsException { 1110 1111 try { 1112 CmsUser user = m_adminCms.readUser(principal); 1113 if (!user.isEnabled()) { 1114 throw new CmsException( 1115 Messages.get().container(Messages.ERR_INVALID_INIT_USER_2, user.getName(), "-")); 1116 } 1117 1118 // initialize the new cms object 1119 CmsContextInfo contextInfo = new CmsContextInfo(m_adminCms.getRequestContext()); 1120 contextInfo.setUserName(principal); 1121 CmsObject newCms = initCmsObject(m_adminCms, contextInfo); 1122 1123 if ((contextInfo.getRequestedUri().startsWith("/system/workplace/") 1124 // also check for new workplace 1125 || request.getRequestURI().startsWith(OpenCms.getSystemInfo().getWorkplaceContext())) 1126 && getRoleManager().hasRole(newCms, CmsRole.ELEMENT_AUTHOR)) { 1127 LOG.debug("Handling workplace login for user " + principal); 1128 CmsWorkplaceSettings settings = CmsLoginHelper.initSiteAndProject(newCms); 1129 request.getSession(true).setAttribute( 1130 CmsWorkplaceManager.SESSION_WORKPLACE_SETTINGS, 1131 settings); 1132 OpenCms.getSessionManager().updateSessionInfo(newCms, request); 1133 } 1134 m_adminCms.updateLastLoginDate(user); 1135 1136 // fire the login user event 1137 OpenCms.fireCmsEvent( 1138 I_CmsEventListener.EVENT_LOGIN_USER, 1139 Collections.<String, Object> singletonMap("data", user)); 1140 return newCms; 1141 } finally { 1142 m_adminCms = null; 1143 } 1144 } 1145 1146 /** 1147 * @see org.opencms.security.I_CmsAuthorizationHandler.I_PrivilegedLoginAction#getCmsObject() 1148 */ 1149 public CmsObject getCmsObject() { 1150 1151 return m_adminCms; 1152 } 1153 1154 /** 1155 * @see org.opencms.security.I_CmsAuthorizationHandler.I_PrivilegedLoginAction#setCmsObject(org.opencms.file.CmsObject) 1156 */ 1157 public void setCmsObject(CmsObject adminCms) { 1158 1159 m_adminCms = adminCms; 1160 } 1161 }; 1162 loginAction.setCmsObject(initCmsObject(req, res, OpenCms.getDefaultUsers().getUserAdmin(), null, null)); 1163 cms = m_authorizationHandler.initCmsObject(req, loginAction); 1164 if (cms != null) { 1165 return cms; 1166 } 1167 1168 // authentification failed or not enough permissions, so display a login screen 1169 m_authorizationHandler.requestAuthorization(req, res, getLoginFormURL(req, res)); 1170 } 1171 cms = initCmsObject( 1172 req, 1173 m_securityManager.readUser(null, OpenCms.getDefaultUsers().getUserGuest()), 1174 getSiteManager().matchRequest(req).getSiteRoot(), 1175 CmsProject.ONLINE_PROJECT_ID, 1176 ""); 1177 // return the initialized cms user context object 1178 return cms; 1179 } 1180 1181 /** 1182 * Returns an initialized CmsObject with the user initialized as provided, 1183 * with the "Online" project selected and "/" set as the current site root.<p> 1184 * 1185 * Note: Only the default users 'Guest' and 'Export' can initialized with 1186 * this method, all other user names will throw an Exception.<p> 1187 * 1188 * @param user the user name to initialize, can only be 1189 * {@link org.opencms.db.CmsDefaultUsers#getUserGuest()} or 1190 * {@link org.opencms.db.CmsDefaultUsers#getUserExport()} 1191 * 1192 * @return an initialized CmsObject with the given users permissions 1193 * 1194 * @throws CmsException if an invalid user name was provided, or if something else goes wrong 1195 * 1196 * @see org.opencms.db.CmsDefaultUsers#getUserGuest() 1197 * @see org.opencms.db.CmsDefaultUsers#getUserExport() 1198 * @see OpenCms#initCmsObject(String) 1199 * @see #initCmsObject(CmsObject, CmsContextInfo) 1200 */ 1201 protected CmsObject initCmsObject(String user) throws CmsException { 1202 1203 return initCmsObject(null, new CmsContextInfo(user)); 1204 } 1205 1206 /** 1207 * Initializes a new cms object from the session data of the request.<p> 1208 * 1209 * If no session data is found, <code>null</code> is returned.<p> 1210 * 1211 * @param req the request 1212 * 1213 * @return the new initialized cms object 1214 * 1215 * @throws CmsException if something goes wrong 1216 */ 1217 protected CmsObject initCmsObjectFromSession(HttpServletRequest req) throws CmsException { 1218 1219 String url = req.getRequestURL().toString(); 1220 String p = "[ " + url + " ] "; 1221 if (LOG.isDebugEnabled()) { 1222 LOG.debug(p + "Trying to init cms object from session for request \"" + req.toString() + "\"."); 1223 } 1224 // try to get an OpenCms user session info object for this request 1225 CmsSessionInfo sessionInfo = m_sessionManager.getSessionInfo(req); 1226 1227 if (sessionInfo == null) { 1228 if (LOG.isDebugEnabled()) { 1229 LOG.debug(p + "No session info found."); 1230 } 1231 return null; 1232 } 1233 1234 // initialize the requested site root 1235 CmsSite site = getSiteManager().matchRequest(req); 1236 1237 // a user name is found in the session manager, reuse this user information 1238 CmsUUID project = sessionInfo.getProject(); 1239 1240 // initialize site root from request 1241 String siteroot = sessionInfo.getSiteRoot(); 1242 if (siteroot == null) { 1243 // not sure if this can actually happen? 1244 LOG.debug(p + "site root from session info was null, determining site root from current request's host"); 1245 siteroot = site.getSiteRoot(); 1246 } 1247 // initialize user from request 1248 CmsUser user = m_securityManager.readUser(null, sessionInfo.getUserId()); 1249 1250 if (LOG.isDebugEnabled()) { 1251 LOG.debug(p + "Initializing cms object with user \"" + user.getName() + "\"."); 1252 LOG.debug(p + "siteRoot = " + siteroot); 1253 } 1254 return initCmsObject(req, user, siteroot, project, sessionInfo.getOrganizationalUnitFqn()); 1255 } 1256 1257 /** 1258 * Constructor to create a new OpenCms object.<p> 1259 * 1260 * It reads the configurations from the <code>opencms.properties</code> 1261 * file in the <code>config/</code> subdirectory. With the information 1262 * from this file is inits a ResourceBroker (Database access module), 1263 * various caching systems and other options.<p> 1264 * 1265 * This will only be done once per accessing class. 1266 * 1267 * @param configuration the configurations from the <code>opencms.properties</code> file 1268 * @throws CmsInitException in case OpenCms can not be initialized 1269 */ 1270 protected synchronized void initConfiguration(CmsParameterConfiguration configuration) throws CmsInitException { 1271 1272 String serverInfo = configuration.getString("context.servlet.container", null); 1273 1274 // output startup message to log file 1275 if (CmsLog.INIT.isInfoEnabled()) { 1276 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_DOT_0)); 1277 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_DOT_0)); 1278 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_DOT_0)); 1279 CmsLog.INIT.info( 1280 ". " 1281 + Messages.get().getBundle().key( 1282 Messages.GUI_SHELL_VERSION_1, 1283 OpenCms.getSystemInfo().getVersionNumber())); 1284 for (int i = 0; i < Messages.COPYRIGHT_BY_ALKACON.length; i++) { 1285 CmsLog.INIT.info(". " + Messages.COPYRIGHT_BY_ALKACON[i]); 1286 } 1287 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_LINE_0)); 1288 CmsLog.INIT.info( 1289 Messages.get().getBundle().key(Messages.INIT_STARTUP_TIME_1, new Date(System.currentTimeMillis()))); 1290 CmsLog.INIT.info( 1291 Messages.get().getBundle().key( 1292 Messages.INIT_OPENCMS_VERSION_1, 1293 OpenCms.getSystemInfo().getVersionNumber() + " [" + OpenCms.getSystemInfo().getVersionId() + "]")); 1294 if (serverInfo != null) { 1295 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_SERVLET_CONTAINER_1, serverInfo)); 1296 } 1297 CmsLog.INIT.info( 1298 Messages.get().getBundle().key(Messages.INIT_WEBAPP_NAME_1, getSystemInfo().getWebApplicationName())); 1299 CmsLog.INIT.info( 1300 Messages.get().getBundle().key(Messages.INIT_SERVLET_PATH_1, getSystemInfo().getServletPath())); 1301 CmsLog.INIT.info( 1302 Messages.get().getBundle().key(Messages.INIT_OPENCMS_CONTEXT_1, getSystemInfo().getOpenCmsContext())); 1303 CmsLog.INIT.info( 1304 Messages.get().getBundle().key(Messages.INIT_WEBINF_PATH_1, getSystemInfo().getWebInfRfsPath())); 1305 CmsLog.INIT.info( 1306 Messages.get().getBundle().key( 1307 Messages.INIT_PROPERTY_FILE_1, 1308 getSystemInfo().getConfigurationFileRfsPath())); 1309 1310 String logFileRfsPath = getSystemInfo().getLogFileRfsPath(); 1311 CmsLog.INIT.info( 1312 Messages.get().getBundle().key( 1313 Messages.INIT_LOG_FILE_1, 1314 logFileRfsPath != null ? logFileRfsPath : "Managed by log4j")); 1315 } 1316 1317 String systemEncoding = null; 1318 try { 1319 systemEncoding = System.getProperty("file.encoding"); 1320 } catch (SecurityException se) { 1321 // security manager is active, but we will try other options before giving up 1322 LOG.debug("Security manager preventing access to file.encoding system property.", se); 1323 } 1324 Security.addProvider(new CryptixCrypto()); 1325 if (CmsLog.INIT.isInfoEnabled()) { 1326 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_FILE_ENCODING_1, systemEncoding)); 1327 } 1328 1329 // read server ethernet address (MAC) and init UUID generator 1330 String ethernetAddress = configuration.getString("server.ethernet.address", CmsStringUtil.getEthernetAddress()); 1331 if (CmsLog.INIT.isInfoEnabled()) { 1332 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_ETHERNET_ADDRESS_1, ethernetAddress)); 1333 } 1334 CmsUUID.init(ethernetAddress); 1335 1336 // set the server name 1337 String serverName = configuration.getString("server.name", "OpenCmsServer"); 1338 getSystemInfo().setServerName(serverName); 1339 1340 // check the installed Java SDK 1341 try { 1342 if (CmsLog.INIT.isInfoEnabled()) { 1343 String jdkinfo = System.getProperty("java.vm.name") + " "; 1344 jdkinfo += System.getProperty("java.vm.version") + " "; 1345 jdkinfo += System.getProperty("java.vm.info") + " "; 1346 jdkinfo += System.getProperty("java.vm.vendor") + " "; 1347 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_JAVA_VM_1, jdkinfo)); 1348 String osinfo = System.getProperty("os.name") + " "; 1349 osinfo += System.getProperty("os.version") + " "; 1350 osinfo += System.getProperty("os.arch") + " "; 1351 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_OPERATING_SYSTEM_1, osinfo)); 1352 } 1353 } catch (Exception e) { 1354 throw new CmsInitException(Messages.get().container(Messages.ERR_CRITICAL_INIT_PROP_0), e); 1355 } 1356 1357 // create the configuration manager instance 1358 m_configurationManager = new CmsConfigurationManager(getSystemInfo().getConfigFolder()); 1359 // store the configuration read from "opencms.properties" in the configuration manager 1360 m_configurationManager.setConfiguration(configuration); 1361 1362 // now load the XML configuration 1363 try { 1364 m_configurationManager.loadXmlConfiguration(); 1365 } catch (Exception e) { 1366 throw new CmsInitException(Messages.get().container(Messages.ERR_CRITICAL_INIT_XML_0), e); 1367 } 1368 1369 // get the system configuration 1370 CmsSystemConfiguration systemConfiguration = (CmsSystemConfiguration)m_configurationManager.getConfiguration( 1371 CmsSystemConfiguration.class); 1372 1373 if (systemConfiguration.useSaxImplSystemProperties()) { 1374 CmsXmlUtils.initSystemProperties(); 1375 } 1376 1377 // initialize the memory monitor 1378 CmsMemoryMonitorConfiguration memoryMonitorConfiguration = systemConfiguration.getCmsMemoryMonitorConfiguration(); 1379 // initialize the memory monitor 1380 try { 1381 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(memoryMonitorConfiguration.getClassName())) { 1382 m_memoryMonitor = (CmsMemoryMonitor)Class.forName( 1383 memoryMonitorConfiguration.getClassName()).newInstance(); 1384 } else { 1385 m_memoryMonitor = new CmsMemoryMonitor(); 1386 } 1387 } catch (Exception e) { 1388 // we can not start without a valid memory monitor 1389 throw new CmsInitException( 1390 Messages.get().container( 1391 Messages.ERR_CRITICAL_INIT_MEMORY_MONITOR_1, 1392 memoryMonitorConfiguration.getClassName()), 1393 e); 1394 } 1395 m_memoryMonitor.initialize(systemConfiguration); 1396 1397 // get the event manager from the configuration and initialize it with the events already registered 1398 CmsEventManager configuredEventManager = systemConfiguration.getEventManager(); 1399 configuredEventManager.initialize(m_eventManager); 1400 m_eventManager = configuredEventManager; 1401 1402 // check if the encoding setting is valid 1403 String setEncoding = systemConfiguration.getDefaultContentEncoding(); 1404 String defaultEncoding = CmsEncoder.lookupEncoding(setEncoding, null); 1405 if (defaultEncoding == null) { 1406 // we can not start without a valid encoding setting 1407 throw new CmsInitException(Messages.get().container(Messages.ERR_CRITICAL_INIT_ENCODING_1, setEncoding)); 1408 } 1409 if (CmsLog.INIT.isInfoEnabled()) { 1410 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_OPENCMS_ENCODING_1, defaultEncoding)); 1411 } 1412 getSystemInfo().setDefaultEncoding(defaultEncoding); 1413 1414 // set version history information 1415 getSystemInfo().setVersionHistorySettings( 1416 systemConfiguration.isHistoryEnabled(), 1417 systemConfiguration.getHistoryVersions(), 1418 systemConfiguration.getHistoryVersionsAfterDeletion()); 1419 // set mail configuration 1420 getSystemInfo().setMailSettings(systemConfiguration.getMailSettings()); 1421 // set HTTP authentication settings 1422 getSystemInfo().setHttpAuthenticationSettings(systemConfiguration.getHttpAuthenticationSettings()); 1423 getSystemInfo().setRestrictDetailContents(systemConfiguration.isRestrictDetailContents()); 1424 1425 // set content notification settings 1426 getSystemInfo().setNotificationTime(systemConfiguration.getNotificationTime()); 1427 getSystemInfo().setNotificationProject(systemConfiguration.getNotificationProject()); 1428 m_executor = new ScheduledThreadPoolExecutor(2); 1429 // set resource init classes 1430 m_resourceInitHandlers = systemConfiguration.getResourceInitHandlers(); 1431 // register request handler classes 1432 Iterator<I_CmsRequestHandler> it = systemConfiguration.getRequestHandlers().iterator(); 1433 while (it.hasNext()) { 1434 I_CmsRequestHandler handler = it.next(); 1435 addRequestHandler(handler); 1436 if (CmsLog.INIT.isInfoEnabled()) { 1437 CmsLog.INIT.info( 1438 Messages.get().getBundle().key( 1439 Messages.INIT_REQUEST_HANDLER_CLASS_1, 1440 handler.getClass().getName())); 1441 } 1442 } 1443 1444 // read the default user configuration 1445 m_defaultUsers = systemConfiguration.getCmsDefaultUsers(); 1446 1447 // get the site manager from the configuration 1448 CmsSitesConfiguration sitesConfiguration = (CmsSitesConfiguration)m_configurationManager.getConfiguration( 1449 CmsSitesConfiguration.class); 1450 m_siteManager = sitesConfiguration.getSiteManager(); 1451 1452 CmsSchedulerConfiguration schedulerConfiguration = (CmsSchedulerConfiguration)m_configurationManager.getConfiguration( 1453 CmsSchedulerConfiguration.class); 1454 // set the scheduler manager 1455 m_scheduleManager = schedulerConfiguration.getScheduleManager(); 1456 1457 CmsVariablesConfiguration variablesConfiguration = (CmsVariablesConfiguration)m_configurationManager.getConfiguration( 1458 CmsVariablesConfiguration.class); 1459 1460 // get the VFS / resource configuration 1461 CmsVfsConfiguration vfsConfiguation = (CmsVfsConfiguration)m_configurationManager.getConfiguration( 1462 CmsVfsConfiguration.class); 1463 m_resourceManager = vfsConfiguation.getResourceManager(); 1464 m_xmlContentTypeManager = vfsConfiguation.getXmlContentTypeManager(); 1465 m_defaultFiles = vfsConfiguation.getDefaultFiles(); 1466 1467 // initialize translation engines 1468 m_resourceManager.setTranslators( 1469 vfsConfiguation.getFolderTranslator(), 1470 vfsConfiguation.getFileTranslator(), 1471 vfsConfiguation.getXsdTranslator()); 1472 1473 // try to initialize the flex cache 1474 CmsFlexCache flexCache = null; 1475 try { 1476 if (CmsLog.INIT.isInfoEnabled()) { 1477 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_FLEX_CACHE_STARTING_0)); 1478 } 1479 // get the flex cache configuration from the SystemConfiguration 1480 CmsFlexCacheConfiguration flexCacheConfiguration = systemConfiguration.getCmsFlexCacheConfiguration(); 1481 getSystemInfo().setDeviceSelector(flexCacheConfiguration.getDeviceSelector()); 1482 // pass configuration to flex cache for initialization 1483 flexCache = new CmsFlexCache(flexCacheConfiguration); 1484 m_flexCache = flexCache; 1485 if (CmsLog.INIT.isInfoEnabled()) { 1486 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_FLEX_CACHE_FINISHED_0)); 1487 } 1488 } catch (Exception e) { 1489 if (CmsLog.INIT.isWarnEnabled()) { 1490 CmsLog.INIT.warn(Messages.get().getBundle().key(Messages.INIT_FLEX_CACHE_ERROR_1, e.getMessage())); 1491 } 1492 } 1493 1494 if (flexCache != null) { 1495 // check all resource loaders if they require the Flex cache 1496 Iterator<I_CmsResourceLoader> i = m_resourceManager.getLoaders().iterator(); 1497 while (i.hasNext()) { 1498 Object o = i.next(); 1499 if (o instanceof I_CmsFlexCacheEnabledLoader) { 1500 // this resource loader requires the Flex cache 1501 ((I_CmsFlexCacheEnabledLoader)o).setFlexCache(flexCache); 1502 } 1503 } 1504 } 1505 1506 // get the import/export configuration 1507 CmsImportExportConfiguration importExportConfiguration = (CmsImportExportConfiguration)m_configurationManager.getConfiguration( 1508 CmsImportExportConfiguration.class); 1509 m_importExportManager = importExportConfiguration.getImportExportManager(); 1510 m_staticExportManager = importExportConfiguration.getStaticExportManager(); 1511 m_repositoryManager = importExportConfiguration.getRepositoryManager(); 1512 1513 // get the search configuration 1514 CmsSearchConfiguration searchConfiguration = (CmsSearchConfiguration)m_configurationManager.getConfiguration( 1515 CmsSearchConfiguration.class); 1516 m_searchManager = searchConfiguration.getSearchManager(); 1517 1518 // get the workplace configuration 1519 CmsWorkplaceConfiguration workplaceConfiguration = (CmsWorkplaceConfiguration)m_configurationManager.getConfiguration( 1520 CmsWorkplaceConfiguration.class); 1521 m_workplaceManager = workplaceConfiguration.getWorkplaceManager(); 1522 // add the export points from the workplace 1523 addExportPoints(m_workplaceManager.getExportPoints()); 1524 addExportPoints(m_staticExportManager.getExportPoints()); 1525 1526 // get the module configuration 1527 CmsModuleConfiguration moduleConfiguration = (CmsModuleConfiguration)m_configurationManager.getConfiguration( 1528 CmsModuleConfiguration.class); 1529 m_moduleManager = moduleConfiguration.getModuleManager(); 1530 1531 // get the password handler 1532 m_passwordHandler = systemConfiguration.getPasswordHandler(); 1533 1534 // get the validation handler 1535 m_validationHandler = systemConfiguration.getValidationHandler(); 1536 1537 // get the authorization handler 1538 m_authorizationHandler = systemConfiguration.getAuthorizationHandler(); 1539 1540 // get the login manager 1541 m_loginManager = systemConfiguration.getLoginManager(); 1542 // set the login message 1543 try { 1544 m_loginManager.setLoginMessage(null, variablesConfiguration.getLoginMessage()); 1545 m_loginManager.setBeforeLoginMessage(null, variablesConfiguration.getBeforeLoginMessage()); 1546 } catch (CmsRoleViolationException e1) { 1547 CmsLog.INIT.error(e1.getLocalizedMessage(), e1); 1548 } 1549 1550 // initialize the publish engine 1551 m_publishEngine = new CmsPublishEngine(systemConfiguration.getRuntimeInfoFactory()); 1552 1553 // Credentials resolver - needs to be set before the driver manager is initialized 1554 m_credentialsResolver = systemConfiguration.getCredentialsResolver(); 1555 1556 // init the OpenCms security manager 1557 m_securityManager = CmsSecurityManager.newInstance( 1558 m_configurationManager, 1559 systemConfiguration.getRuntimeInfoFactory(), 1560 m_publishEngine); 1561 1562 // get the publish manager 1563 m_publishManager = systemConfiguration.getPublishManager(); 1564 1565 // get the subscription manager 1566 m_subscriptionManager = systemConfiguration.getSubscriptionManager(); 1567 1568 // initialize the role manager 1569 m_roleManager = new CmsRoleManager(m_securityManager); 1570 1571 // initialize the organizational unit manager 1572 m_orgUnitManager = new CmsOrgUnitManager(m_securityManager); 1573 1574 // initialize the Thread store 1575 m_threadStore = new CmsThreadStore(m_securityManager); 1576 1577 // initialize the link manager 1578 m_linkManager = new CmsLinkManager(m_staticExportManager.getLinkSubstitutionHandler()); 1579 1580 m_aliasManager = new CmsAliasManager(m_securityManager); 1581 1582 // store the runtime properties 1583 m_runtimeProperties.putAll(systemConfiguration.getRuntimeProperties()); 1584 1585 // initialize the session storage provider 1586 I_CmsSessionStorageProvider sessionStorageProvider = systemConfiguration.getSessionStorageProvider(); 1587 1588 // get an Admin cms context object with site root set to "/" 1589 CmsObject adminCms; 1590 try { 1591 adminCms = initCmsObject(null, null, getDefaultUsers().getUserAdmin(), (String)null, (String)null); 1592 } catch (CmsException e) { 1593 throw new CmsInitException(Messages.get().container(Messages.ERR_CRITICAL_INIT_ADMINCMS_0), e); 1594 } 1595 1596 m_repositoryManager.initializeCms(adminCms); 1597 // now initialize the other managers 1598 try { 1599 if (flexCache != null) { 1600 flexCache.initializeCms(initCmsObject(adminCms)); 1601 } 1602 1603 m_configurationManager.setAdminCms(adminCms); 1604 1605 // initialize the scheduler 1606 m_scheduleManager.initialize(initCmsObject(adminCms)); 1607 1608 // initialize the locale manager 1609 m_localeManager = systemConfiguration.getLocaleManager(); 1610 m_localeManager.initialize(initCmsObject(adminCms)); 1611 1612 // initialize the site manager 1613 m_siteManager.initialize(initCmsObject(adminCms)); 1614 1615 // initialize the static export manager 1616 m_staticExportManager.initialize(initCmsObject(adminCms)); 1617 1618 // initialize the XML content type manager 1619 m_xmlContentTypeManager.initialize(initCmsObject(adminCms)); 1620 1621 m_orgUnitManager.initialize(initCmsObject(adminCms)); 1622 1623 // initialize the module manager 1624 m_moduleManager.initialize(initCmsObject(adminCms), m_configurationManager); 1625 1626 // initialize the resource manager 1627 m_resourceManager.initialize(initCmsObject(adminCms)); 1628 1629 // initialize the publish manager 1630 m_publishManager.setPublishEngine(m_publishEngine); 1631 m_publishManager.setSecurityManager(m_securityManager); 1632 m_publishManager.setPublishListRemoveMode(systemConfiguration.getPublishListRemoveMode()); 1633 m_publishManager.initialize(initCmsObject(adminCms)); 1634 1635 // initialize the search manager 1636 m_searchManager.initialize(initCmsObject(adminCms)); 1637 1638 // initialize the VFS bundle manager 1639 m_vfsBundleManager = new CmsVfsBundleManager(adminCms); 1640 1641 // initialize the workplace manager 1642 m_workplaceManager.initialize(initCmsObject(adminCms)); 1643 1644 // initialize the session manager 1645 m_sessionManager.initialize(sessionStorageProvider); 1646 m_sessionManager.setUserSessionMode(systemConfiguration.getUserSessionMode(true)); 1647 1648 // initialize the subscription manager 1649 m_subscriptionManager.setSecurityManager(m_securityManager); 1650 m_subscriptionManager.initialize(adminCms); 1651 1652 CmsUgcSessionFactory.setAdminCms(adminCms); 1653 1654 // initialize the formatter configuration 1655 CmsFormatterConfiguration.initialize(adminCms); 1656 CmsPersistentLoginTokenHandler.setAdminCms(initCmsObject(adminCms)); 1657 CmsLoginUI.setAdminCmsObject(initCmsObject(adminCms)); 1658 1659 // initialize ade manager 1660 m_adeManager = new CmsADEManager(initCmsObject(adminCms), m_memoryMonitor, systemConfiguration); 1661 m_workplaceAppManager = new CmsWorkplaceAppManager(initCmsObject(adminCms)); 1662 m_workplaceAppManager.loadApps(); 1663 m_workplaceAppManager.initWorkplaceCssUris(m_moduleManager); 1664 1665 m_templateContextManager = new CmsTemplateContextManager(initCmsObject(adminCms)); 1666 m_workflowManager = systemConfiguration.getWorkflowManager(); 1667 m_letsEncryptConfig = systemConfiguration.getLetsEncryptConfig(); 1668 if (m_workflowManager == null) { 1669 m_workflowManager = new CmsDefaultWorkflowManager(); 1670 m_workflowManager.setParameters(new HashMap<String, String>()); 1671 } 1672 m_workflowManager.initialize(adminCms); 1673 1674 m_remoteShellServer = CmsRemoteShellServer.initialize(systemConfiguration); 1675 1676 } catch (CmsException e) { 1677 throw new CmsInitException(Messages.get().container(Messages.ERR_CRITICAL_INIT_MANAGERS_0), e); 1678 } 1679 1680 try { 1681 // mitigate potential stringtemplate 3 class loading deadlock by making sure the class is loaded on startup 1682 @SuppressWarnings("unused") 1683 StringTemplate stringTemplate = new org.antlr.stringtemplate.StringTemplate(); 1684 } catch (Exception e) { 1685 CmsLog.INIT.error("Problem with initializing stringtemplate class: " + e.getLocalizedMessage(), e); 1686 } 1687 1688 try { 1689 getEventManager().fireEvent(I_CmsEventListener.EVENT_CLEAR_CACHES); 1690 } catch (Exception e) { 1691 CmsLog.INIT.error("Problem with clearing caches after initialization: " + e.getLocalizedMessage(), e); 1692 } 1693 } 1694 1695 /** 1696 * Initialization of the OpenCms runtime environment.<p> 1697 * 1698 * The connection information for the database is read 1699 * from the <code>opencms.properties</code> configuration file and all 1700 * driver manager are initialized via the initializer, 1701 * which usually will be an instance of a <code>OpenCms</code> class. 1702 * 1703 * @param context configuration of OpenCms from <code>web.xml</code> 1704 * @throws CmsInitException in case OpenCms can not be initialized 1705 */ 1706 protected synchronized void initContext(ServletContext context) throws CmsInitException { 1707 1708 m_gwtServiceContexts = new HashMap<String, CmsGwtServiceContext>(); 1709 1710 // automatic servlet container recognition and specific behavior: 1711 CmsServletContainerSettings servletContainerSettings = new CmsServletContainerSettings(context); 1712 getSystemInfo().init(servletContainerSettings); 1713 1714 // Collect the configurations 1715 CmsParameterConfiguration configuration; 1716 try { 1717 configuration = new CmsParameterConfiguration(getSystemInfo().getConfigurationFileRfsPath()); 1718 } catch (Exception e) { 1719 throw new CmsInitException( 1720 Messages.get().container( 1721 Messages.ERR_CRITICAL_INIT_PROPFILE_1, 1722 getSystemInfo().getConfigurationFileRfsPath()), 1723 e); 1724 } 1725 1726 String throwException = configuration.getString("servlet.exception.enabled", "auto"); 1727 if (!throwException.equals("auto")) { 1728 // set the parameter is not automatic, the rest of the servlet container dependent parameters 1729 // will be set when reading the system configuration, if not set to auto 1730 boolean throwExc = Boolean.valueOf(throwException).booleanValue(); 1731 getSystemInfo().getServletContainerSettings().setServletThrowsException(throwExc); 1732 } 1733 1734 // check if the wizard is enabled, if so stop initialization 1735 if (configuration.getBoolean("wizard.enabled", true)) { 1736 throw new CmsInitException(Messages.get().container(Messages.ERR_CRITICAL_INIT_WIZARD_0)); 1737 } 1738 1739 // add an indicator that the configuration was processed from the servlet context 1740 configuration.add("context.servlet.container", context.getServerInfo()); 1741 1742 // output startup message and copyright to STDERR 1743 System.err.println( 1744 Messages.get().getBundle().key( 1745 Messages.LOG_STARTUP_CONSOLE_NOTE_2, 1746 OpenCms.getSystemInfo().getVersionNumber(), 1747 getSystemInfo().getWebApplicationName())); 1748 for (int i = 0; i < Messages.COPYRIGHT_BY_ALKACON.length; i++) { 1749 System.err.println(Messages.COPYRIGHT_BY_ALKACON[i]); 1750 } 1751 System.err.println(); 1752 1753 // initialize the configuration 1754 initConfiguration(configuration); 1755 } 1756 1757 /** 1758 * Initialize member variables.<p> 1759 */ 1760 protected void initMembers() { 1761 1762 synchronized (LOCK) { 1763 m_resourceInitHandlers = new ArrayList<I_CmsResourceInit>(); 1764 m_requestHandlers = new HashMap<String, I_CmsRequestHandler>(); 1765 m_systemInfo = new CmsSystemInfo(); 1766 m_exportPoints = Collections.emptySet(); 1767 m_defaultUsers = new CmsDefaultUsers(); 1768 m_localeManager = new CmsLocaleManager(Locale.ENGLISH); 1769 m_sessionManager = new CmsSessionManager(); 1770 m_runtimeProperties = new Hashtable<Object, Object>(); 1771 // the default event manager must be available because the configuration already registers events 1772 m_eventManager = new CmsEventManager(); 1773 // default link manager is required for test cases 1774 m_linkManager = new CmsLinkManager(new CmsDefaultLinkSubstitutionHandler()); 1775 } 1776 } 1777 1778 /** 1779 * Reads the requested resource from the OpenCms VFS, 1780 * in case a directory name is requested, the default files of the 1781 * directory will be looked up and the first match is returned.<p> 1782 * 1783 * The resource that is returned is always a <code>{@link org.opencms.file.CmsFile}</code>, 1784 * even though the content will usually not be loaded in the result. Folders are never returned since 1785 * the point of this method is really to load the default file if just a folder name is requested. If 1786 * there is no default file in a folder, then the return value is null and no CmsException is thrown.<p> 1787 * 1788 * The URI stored in the given OpenCms user context will be changed to the URI of the resource 1789 * that was found and returned.<p> 1790 * 1791 * Implementing and configuring an <code>{@link I_CmsResourceInit}</code> handler 1792 * allows to customize the process of default resource selection.<p> 1793 * 1794 * @param cms the current users OpenCms context 1795 * @param resourceName the path of the requested resource in the OpenCms VFS 1796 * @param req the current http request 1797 * @param res the current http response 1798 * 1799 * @return the requested resource read from the VFS 1800 * 1801 * @throws CmsException in case the requested file does not exist or the user has insufficient access permissions 1802 * 1803 * @see OpenCms#initResource(CmsObject, String, HttpServletRequest, HttpServletResponse) 1804 */ 1805 protected CmsResource initResource( 1806 CmsObject cms, 1807 String resourceName, 1808 HttpServletRequest req, 1809 HttpServletResponse res) 1810 throws CmsException { 1811 1812 CmsException tmpException = null; 1813 CmsResource resource; 1814 boolean handledSecure = false; 1815 1816 try { 1817 // try to read the requested resource 1818 resource = cms.readDefaultFile(resourceName); 1819 } catch (CmsException e) { 1820 // file or folder with given name does not exist, store exception 1821 tmpException = e; 1822 resource = null; 1823 } 1824 1825 if (resource != null) { 1826 // set the request uri to the right file 1827 cms.getRequestContext().setUri(cms.getSitePath(resource)); 1828 // test if this file is only available for internal access operations 1829 if (resource.isInternal()) { 1830 throw new CmsException( 1831 Messages.get().container(Messages.ERR_READ_INTERNAL_RESOURCE_1, cms.getRequestContext().getUri())); 1832 } 1833 1834 resource = handleSecureResource(cms, req, res, resource, resourceName); 1835 if (resource == null) { 1836 handledSecure = true; 1837 1838 } 1839 } 1840 1841 boolean clearErrors = false; 1842 // test if this file has to be checked or modified 1843 for (I_CmsResourceInit handler : m_resourceInitHandlers) { 1844 try { 1845 resource = handler.initResource(resource, cms, req, res); 1846 // the loop has to be interrupted when the exception is thrown! 1847 } catch (CmsResourceInitException e) { 1848 if (e.isClearErrors()) { 1849 tmpException = null; 1850 clearErrors = true; 1851 } 1852 break; 1853 } catch (CmsSecurityException e) { 1854 tmpException = e; 1855 break; 1856 } 1857 } 1858 1859 // file is still null and not found exception was thrown, so throw original exception 1860 if (resource == null) { 1861 if (tmpException != null) { 1862 throw tmpException; 1863 } else if (!clearErrors) { 1864 throw new CmsVfsResourceNotFoundException( 1865 org.opencms.main.Messages.get().container( 1866 org.opencms.main.Messages.ERR_PATH_NOT_FOUND_1, 1867 resourceName)); 1868 1869 } 1870 } else { 1871 if (!handledSecure) { 1872 if (cms.getRequestContext().getDetailContentId() != null) { 1873 // in theory we should do this for all kinds of resource init handlers, 1874 // but I'm not clear on how to handle this in general, so only do this for detail pages for now 1875 resource = handleSecureResource(cms, req, res, resource, resourceName); 1876 handledSecure = true; 1877 } 1878 } 1879 } 1880 1881 // return the resource read from the VFS 1882 return resource; 1883 } 1884 1885 /** 1886 * Initializes the system with the OpenCms servlet.<p> 1887 * 1888 * This is the final step that is called on the servlets "init()" method. 1889 * It registers the servlets request handler and also outputs the final 1890 * startup message. The servlet should auto-load since the <load-on-startup> 1891 * parameter is set in the 'web.xml' by default.<p> 1892 * 1893 * @param servlet the OpenCms servlet 1894 */ 1895 protected void initServlet(OpenCmsServlet servlet) { 1896 1897 synchronized (LOCK) { 1898 // add the servlets request handler 1899 addRequestHandler(servlet); 1900 1901 // output the final 'startup is finished' message 1902 if (CmsLog.INIT.isInfoEnabled()) { 1903 CmsLog.INIT.info( 1904 Messages.get().getBundle().key( 1905 Messages.INIT_SYSTEM_RUNNING_1, 1906 CmsStringUtil.formatRuntime(getSystemInfo().getRuntime()))); 1907 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_LINE_0)); 1908 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_DOT_0)); 1909 } 1910 } 1911 } 1912 1913 /** 1914 * Invokes the GWT servlet from within OpenCms.<p> 1915 * 1916 * @param serviceName the GWT PRC service class name 1917 * @param req the current servlet request 1918 * @param res the current servlet response 1919 * @param servletConfig the servlet configuration 1920 */ 1921 protected void invokeGwtService( 1922 String serviceName, 1923 HttpServletRequest req, 1924 HttpServletResponse res, 1925 ServletConfig servletConfig) { 1926 1927 CmsObject cms = null; 1928 try { 1929 // instantiate CMS context 1930 cms = initCmsObject(req, res); 1931 // instantiate GWT RPC service 1932 CmsGwtService rpcService = getGwtService(serviceName, servletConfig); 1933 // check permissions 1934 rpcService.checkPermissions(cms); 1935 // set runtime variables 1936 rpcService.setCms(cms); 1937 Object lock = req.getSession(); 1938 if (lock == null) { 1939 lock = new Object(); 1940 } 1941 rpcService.service(req, res); 1942 // update the session info 1943 m_sessionManager.updateSessionInfo(cms, req); 1944 } catch (CmsRoleViolationException rv) { 1945 // don't log these into the error channel 1946 LOG.debug(rv.getLocalizedMessage(), rv); 1947 // error code not set - set "unauthorized error" (401) 1948 int status = HttpServletResponse.SC_UNAUTHORIZED; 1949 res.setStatus(status); 1950 try { 1951 res.sendError(status, rv.toString()); 1952 } catch (IOException e) { 1953 // can be ignored 1954 LOG.error(e.getLocalizedMessage(), e); 1955 } 1956 } catch (Throwable t) { 1957 // error code not set - set "internal server error" (500) 1958 LOG.error(t.getLocalizedMessage(), t); 1959 int status = HttpServletResponse.SC_INTERNAL_SERVER_ERROR; 1960 res.setStatus(status); 1961 try { 1962 res.sendError(status, t.toString()); 1963 } catch (IOException e) { 1964 // can be ignored 1965 LOG.error(e.getLocalizedMessage(), e); 1966 } 1967 } 1968 } 1969 1970 /** 1971 * This method adds an Object to the OpenCms runtime properties. 1972 * The runtime properties can be used to store Objects that are shared 1973 * in the whole system.<p> 1974 * 1975 * @param key the key to add the Object with 1976 * @param value the value of the Object to add 1977 */ 1978 protected void setRuntimeProperty(Object key, Object value) { 1979 1980 m_runtimeProperties.put(key, value); 1981 } 1982 1983 /** 1984 * Displays a resource from the OpenCms by writing the result to the provided 1985 * Servlet response output stream.<p> 1986 * 1987 * @param req the current servlet request 1988 * @param res the current servlet response 1989 */ 1990 protected void showResource(HttpServletRequest req, HttpServletResponse res) { 1991 1992 CmsObject cms = null; 1993 try { 1994 cms = initCmsObject(req, res); 1995 1996 if (cms.getRequestContext().getCurrentProject().isOnlineProject()) { 1997 String uri = cms.getRequestContext().getUri(); 1998 if (uri.startsWith(CmsWorkplace.VFS_PATH_SITES)) { 1999 // resources within the sites folder may only be called with their site relative path 2000 // this should prevent showing pages from other sites with their root path 2001 throw new CmsVfsResourceNotFoundException( 2002 org.opencms.main.Messages.get().container(org.opencms.main.Messages.ERR_PATH_NOT_FOUND_1, uri)); 2003 } 2004 if (OpenCms.getStaticExportManager().isExportLink(cms, uri)) { 2005 // if we used the request's query string for getRfsName, clients could cause an unlimited number 2006 // of files to be exported just by varying the request parameters! 2007 String url = m_linkManager.getOnlineLink(cms, uri); 2008 res.sendRedirect(url); 2009 return; 2010 } 2011 } 2012 List<CmsSiteMatcher> currentSiteAliase = m_siteManager.getCurrentSite(cms).getAliases(); 2013 CmsSiteMatcher currentSiteMatcher = cms.getRequestContext().getRequestMatcher(); 2014 if (currentSiteAliase.contains(currentSiteMatcher.forDifferentScheme("http")) 2015 || currentSiteAliase.contains(currentSiteMatcher.forDifferentScheme("https"))) { 2016 int pos = currentSiteAliase.indexOf(currentSiteMatcher.forDifferentScheme("http")); 2017 if (pos == -1) { 2018 pos = currentSiteAliase.indexOf(currentSiteMatcher.forDifferentScheme("https")); 2019 } 2020 if (currentSiteAliase.get(pos).isRedirect()) { 2021 res.sendRedirect( 2022 m_siteManager.getCurrentSite(cms).getUrl() + req.getContextPath() + req.getPathInfo()); 2023 return; 2024 } 2025 } 2026 2027 // user is initialized, now deliver the requested resource 2028 CmsResource resource = initResource(cms, cms.getRequestContext().getUri(), req, res); 2029 if (resource != null) { 2030 // a file was read, go on process it 2031 m_resourceManager.loadResource(cms, resource, req, res); 2032 m_sessionManager.updateSessionInfo(cms, req); 2033 } 2034 2035 } catch (Throwable t) { 2036 errorHandling(cms, req, res, t); 2037 } 2038 } 2039 2040 /** 2041 * Destroys this OpenCms instance, called if the servlet (or shell) is shut down.<p> 2042 */ 2043 protected void shutDown() { 2044 2045 synchronized (LOCK) { 2046 if (getRunLevel() > OpenCms.RUNLEVEL_0_OFFLINE) { 2047 System.err.println( 2048 Messages.get().getBundle().key( 2049 Messages.LOG_SHUTDOWN_CONSOLE_NOTE_2, 2050 getSystemInfo().getVersionNumber(), 2051 getSystemInfo().getWebApplicationName())); 2052 if (CmsLog.INIT.isInfoEnabled()) { 2053 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_DOT_0)); 2054 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_DOT_0)); 2055 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_LINE_0)); 2056 CmsLog.INIT.info( 2057 Messages.get().getBundle().key( 2058 Messages.INIT_SHUTDOWN_START_1, 2059 getSystemInfo().getVersionNumber() + " [" + getSystemInfo().getVersionId() + "]")); 2060 CmsLog.INIT.info( 2061 Messages.get().getBundle().key(Messages.INIT_CURRENT_RUNLEVEL_1, new Integer(getRunLevel()))); 2062 CmsLog.INIT.info( 2063 Messages.get().getBundle().key( 2064 Messages.INIT_SHUTDOWN_TIME_1, 2065 new Date(System.currentTimeMillis()))); 2066 } 2067 2068 // take the system offline 2069 setRunLevel(OpenCms.RUNLEVEL_0_OFFLINE); 2070 2071 if (LOG.isDebugEnabled()) { 2072 // log exception to see which method did call the shutdown 2073 LOG.debug(Messages.get().getBundle().key(Messages.LOG_SHUTDOWN_TRACE_0), new Exception()); 2074 } 2075 2076 try { 2077 // the first thing we have to do is to wait until the current publish process finishes 2078 if (null != m_publishEngine) { 2079 m_publishEngine.shutDown(); 2080 } 2081 } catch (Throwable e) { 2082 CmsLog.INIT.error( 2083 Messages.get().getBundle().key(Messages.LOG_ERROR_PUBLISH_SHUTDOWN_1, e.getMessage()), 2084 e); 2085 } 2086 try { 2087 // search manager must be shut down early since there may be background indexing still ongoing 2088 if (m_searchManager != null) { 2089 m_searchManager.shutDown(); 2090 } 2091 } catch (Throwable e) { 2092 CmsLog.INIT.error( 2093 Messages.get().getBundle().key(Messages.LOG_ERROR_SEARCH_MANAGER_SHUTDOWN_1, e.getMessage()), 2094 e); 2095 } 2096 try { 2097 // remote shell server must be shut down early since there is a background thread ongoing that reloads from the VFS 2098 if (m_remoteShellServer != null) { 2099 m_remoteShellServer.shutDown(); 2100 } 2101 } catch (Throwable e) { 2102 CmsLog.INIT.error( 2103 Messages.get().getBundle().key(Messages.LOG_ERROR_REMOTESHELL_SHUTDOWN_1, e.getMessage()), 2104 e); 2105 } 2106 try { 2107 // VFS bundle manager must be shut down early since there is a background thread ongoing that reloads from the VFS 2108 if (m_vfsBundleManager != null) { 2109 m_vfsBundleManager.shutDown(); 2110 } 2111 } catch (Throwable e) { 2112 CmsLog.INIT.error( 2113 Messages.get().getBundle().key(Messages.LOG_ERROR_VFSBUNDLE_MANAGER_SHUTDOWN_1, e.getMessage()), 2114 e); 2115 } 2116 try { 2117 if (m_staticExportManager != null) { 2118 m_staticExportManager.shutDown(); 2119 } 2120 } catch (Throwable e) { 2121 CmsLog.INIT.error( 2122 Messages.get().getBundle().key(Messages.LOG_ERROR_EXPORT_SHUTDOWN_1, e.getMessage()), 2123 e); 2124 } 2125 try { 2126 if (m_moduleManager != null) { 2127 m_moduleManager.shutDown(); 2128 } 2129 } catch (Throwable e) { 2130 CmsLog.INIT.error( 2131 Messages.get().getBundle().key(Messages.LOG_ERROR_MODULE_SHUTDOWN_1, e.getMessage()), 2132 e); 2133 } 2134 2135 try { 2136 if (m_executor != null) { 2137 m_executor.shutdownNow(); 2138 m_executor.awaitTermination(30, TimeUnit.SECONDS); 2139 } 2140 } catch (Throwable e) { 2141 CmsLog.INIT.error( 2142 Messages.get().getBundle().key(Messages.LOG_ERROR_MODULE_SHUTDOWN_1, e.getMessage()), 2143 e); 2144 } 2145 2146 try { 2147 if (m_scheduleManager != null) { 2148 m_scheduleManager.shutDown(); 2149 } 2150 } catch (Throwable e) { 2151 CmsLog.INIT.error( 2152 Messages.get().getBundle().key(Messages.LOG_ERROR_SCHEDULE_SHUTDOWN_1, e.getMessage()), 2153 e); 2154 } 2155 try { 2156 if (m_resourceManager != null) { 2157 m_resourceManager.shutDown(); 2158 } 2159 } catch (Throwable e) { 2160 CmsLog.INIT.error( 2161 Messages.get().getBundle().key(Messages.LOG_ERROR_RESOURCE_SHUTDOWN_1, e.getMessage()), 2162 e); 2163 } 2164 2165 try { 2166 if (m_repositoryManager != null) { 2167 m_repositoryManager.shutDown(); 2168 } 2169 } catch (Throwable e) { 2170 CmsLog.INIT.error(e.getLocalizedMessage(), e); 2171 } 2172 2173 try { 2174 // has to be stopped before the security manager, since this thread uses it 2175 if (m_threadStore != null) { 2176 m_threadStore.shutDown(); 2177 } 2178 } catch (Throwable e) { 2179 CmsLog.INIT.error( 2180 Messages.get().getBundle().key(Messages.LOG_ERROR_THREAD_SHUTDOWN_1, e.getMessage()), 2181 e); 2182 } 2183 try { 2184 if (m_securityManager != null) { 2185 m_securityManager.destroy(); 2186 } 2187 } catch (Throwable e) { 2188 CmsLog.INIT.error( 2189 Messages.get().getBundle().key(Messages.LOG_ERROR_SECURITY_SHUTDOWN_1, e.getMessage()), 2190 e); 2191 } 2192 try { 2193 if (m_sessionManager != null) { 2194 m_sessionManager.shutdown(); 2195 } 2196 } catch (Throwable e) { 2197 CmsLog.INIT.error( 2198 Messages.get().getBundle().key(Messages.LOG_ERROR_SESSION_MANAGER_SHUTDOWN_1, e.getMessage()), 2199 e); 2200 } 2201 try { 2202 if (m_memoryMonitor != null) { 2203 m_memoryMonitor.shutdown(); 2204 } 2205 } catch (Throwable e) { 2206 CmsLog.INIT.error( 2207 Messages.get().getBundle().key(Messages.LOG_ERROR_MEMORY_MONITOR_SHUTDOWN_1, e.getMessage()), 2208 e); 2209 } 2210 try { 2211 if (m_adeManager != null) { 2212 m_adeManager.shutdown(); 2213 } 2214 } catch (Throwable e) { 2215 CmsLog.INIT.error( 2216 Messages.get().getBundle().key(Messages.LOG_ERROR_ADE_MANAGER_SHUTDOWN_1, e.getMessage()), 2217 e); 2218 } 2219 2220 String runtime = CmsStringUtil.formatRuntime(getSystemInfo().getRuntime()); 2221 if (CmsLog.INIT.isInfoEnabled()) { 2222 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_OPENCMS_STOPPED_1, runtime)); 2223 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_LINE_0)); 2224 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_DOT_0)); 2225 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_DOT_0)); 2226 } 2227 System.err.println(Messages.get().getBundle().key(Messages.LOG_CONSOLE_TOTAL_RUNTIME_1, runtime)); 2228 2229 } 2230 m_instance = null; 2231 } 2232 } 2233 2234 /** 2235 * This method updates the request context information.<p> 2236 * 2237 * The update information is:<br> 2238 * <ul> 2239 * <li>Requested Url</li> 2240 * <li>Locale</li> 2241 * <li>Encoding</li> 2242 * <li>Remote Address</li> 2243 * <li>Request Time</li> 2244 * </ul> 2245 * 2246 * @param request the current request 2247 * @param cms the cms object to update the request context for 2248 * 2249 * @return a new updated cms context 2250 * 2251 * @throws CmsException if something goes wrong 2252 */ 2253 protected CmsObject updateContext(HttpServletRequest request, CmsObject cms) throws CmsException { 2254 2255 // get the right site for the request 2256 String siteRoot = null; 2257 boolean isWorkplace = cms.getRequestContext().getUri().startsWith("/system/workplace/") 2258 || request.getRequestURI().startsWith(OpenCms.getSystemInfo().getWorkplaceContext()); 2259 if (isWorkplace && getRoleManager().hasRole(cms, CmsRole.ELEMENT_AUTHOR)) { 2260 // keep the site root for workplace requests 2261 siteRoot = cms.getRequestContext().getSiteRoot(); 2262 } else { 2263 CmsSite site = OpenCms.getSiteManager().matchRequest(request); 2264 siteRoot = site.getSiteRoot(); 2265 } 2266 return initCmsObject( 2267 request, 2268 cms.getRequestContext().getCurrentUser(), 2269 siteRoot, 2270 cms.getRequestContext().getCurrentProject().getUuid(), 2271 cms.getRequestContext().getOuFqn()); 2272 } 2273 2274 /** 2275 * Upgrades to runlevel {@link OpenCms#RUNLEVEL_3_SHELL_ACCESS}, 2276 * this is shell access to the database but no Servlet context.<p> 2277 * 2278 * To upgrade the runlevel, the system must be in runlevel {@link OpenCms#RUNLEVEL_1_CORE_OBJECT}, 2279 * otherwise an exception is thrown.<p> 2280 * 2281 * @param configuration the configuration 2282 * @throws CmsInitException in case OpenCms can not be initialized 2283 * @return the initialized OpenCmsCore 2284 */ 2285 protected OpenCmsCore upgradeRunlevel(CmsParameterConfiguration configuration) throws CmsInitException { 2286 2287 synchronized (LOCK) { 2288 if ((m_instance != null) && (getRunLevel() >= OpenCms.RUNLEVEL_2_INITIALIZING)) { 2289 // instance already in runlevel 3 or 4 2290 return m_instance; 2291 } 2292 if (getRunLevel() != OpenCms.RUNLEVEL_1_CORE_OBJECT) { 2293 CmsLog.INIT.error( 2294 Messages.get().getBundle().key( 2295 Messages.LOG_WRONG_INIT_SEQUENCE_2, 2296 new Integer(3), 2297 new Integer(getRunLevel()))); 2298 return m_instance; 2299 } 2300 2301 // set the runlevel to "initializing OpenCms" 2302 setRunLevel(OpenCms.RUNLEVEL_2_INITIALIZING); 2303 // initialize the configuration 2304 m_instance.initConfiguration(configuration); 2305 // upgrade the runlevel - OpenCms shell is available 2306 setRunLevel(OpenCms.RUNLEVEL_3_SHELL_ACCESS); 2307 2308 afterUpgradeRunlevel(); 2309 2310 return m_instance; 2311 } 2312 } 2313 2314 /** 2315 * Upgrades to runlevel {@link OpenCms#RUNLEVEL_4_SERVLET_ACCESS}, 2316 * this is the final runlevel with an initialized database and Servlet context.<p> 2317 * 2318 * To upgrade the runlevel, the system must be in runlevel {@link OpenCms#RUNLEVEL_1_CORE_OBJECT}, 2319 * otherwise an exception is thrown.<p> 2320 * 2321 * @param context the current servlet context 2322 * @throws CmsInitException in case OpenCms can not be initialized 2323 * @return the initialized OpenCmsCore 2324 */ 2325 protected OpenCmsCore upgradeRunlevel(ServletContext context) throws CmsInitException { 2326 2327 synchronized (LOCK) { 2328 if ((m_instance != null) && (getRunLevel() >= OpenCms.RUNLEVEL_4_SERVLET_ACCESS)) { 2329 // instance already in runlevel 5 or 6 2330 return m_instance; 2331 } 2332 if (getRunLevel() != OpenCms.RUNLEVEL_1_CORE_OBJECT) { 2333 CmsLog.INIT.error( 2334 Messages.get().getBundle().key( 2335 Messages.LOG_WRONG_INIT_SEQUENCE_2, 2336 new Integer(4), 2337 new Integer(getRunLevel()))); 2338 return m_instance; 2339 } 2340 2341 // set the runlevel to "initializing OpenCms" 2342 setRunLevel(OpenCms.RUNLEVEL_2_INITIALIZING); 2343 // initialize the servlet context 2344 m_instance.initContext(context); 2345 // initialization successfully finished - OpenCms servlet is online 2346 // the runlevel will change from 2 directly to 4, this is on purpose 2347 setRunLevel(OpenCms.RUNLEVEL_4_SERVLET_ACCESS); 2348 2349 afterUpgradeRunlevel(); 2350 2351 return m_instance; 2352 } 2353 } 2354 2355 /** 2356 * Writes the XML configuration for the provided configuration class.<p> 2357 * 2358 * @param clazz the configuration class to write the XML for 2359 */ 2360 protected void writeConfiguration(Class<?> clazz) { 2361 2362 // exception handling is provided here to ensure identical log messages 2363 try { 2364 m_configurationManager.writeConfiguration(clazz); 2365 } catch (IOException e) { 2366 CmsLog.getLog(CmsConfigurationManager.class).error( 2367 Messages.get().getBundle().key(Messages.LOG_ERROR_WRITING_CONFIG_1, clazz.getName()), 2368 e); 2369 } catch (CmsConfigurationException e) { 2370 CmsLog.getLog(CmsConfigurationManager.class).error( 2371 Messages.get().getBundle().key(Messages.LOG_ERROR_WRITING_CONFIG_1, clazz.getName()), 2372 e); 2373 } 2374 } 2375 2376 /** 2377 * Adds the given set of export points to the list of all configured export points.<p> 2378 * 2379 * @param exportPoints the export points to add 2380 */ 2381 private void addExportPoints(Set<CmsExportPoint> exportPoints) { 2382 2383 // create a new immutable set of export points 2384 HashSet<CmsExportPoint> newSet = new HashSet<CmsExportPoint>(m_exportPoints.size() + exportPoints.size()); 2385 newSet.addAll(exportPoints); 2386 newSet.addAll(m_exportPoints); 2387 m_exportPoints = Collections.unmodifiableSet(newSet); 2388 } 2389 2390 /** 2391 * Finishes the startup sequence after last runlevel upgrade.<p> 2392 */ 2393 private void afterUpgradeRunlevel() { 2394 2395 try { 2396 // read the persistent locks 2397 m_instance.m_securityManager.readLocks(); 2398 } catch (CmsException e) { 2399 if (LOG.isErrorEnabled()) { 2400 LOG.error( 2401 org.opencms.lock.Messages.get().getBundle().key(org.opencms.lock.Messages.ERR_READ_LOCKS_0), 2402 e); 2403 } 2404 } 2405 2406 if (OpenCms.getRunLevel() == OpenCms.RUNLEVEL_4_SERVLET_ACCESS) { 2407 // only init ADE manager in case of servlet initialization, it won't be needed in case of shell access 2408 CmsThreadStatsTreeProfilingHandler stats = new CmsThreadStatsTreeProfilingHandler(); 2409 try { 2410 CmsDefaultProfilingHandler.INSTANCE.addHandler(stats); 2411 m_adeManager.initialize(); 2412 } finally { 2413 CmsDefaultProfilingHandler.INSTANCE.removeHandler(stats); 2414 if (stats.hasData()) { 2415 String adeInitData = stats.dump(); 2416 String prefix = String.format("%010X", Long.valueOf(System.currentTimeMillis() / 1000)); 2417 String path = OpenCms.getSystemInfo().getAbsoluteRfsPathRelativeToWebInf( 2418 "logs/" + prefix + "_startup-ade-driver-report.xml"); 2419 try (FileOutputStream out = new FileOutputStream(path)) { 2420 out.write(adeInitData.getBytes("UTF-8")); 2421 } catch (Exception e) { 2422 LOG.error( 2423 "Could not write ADE init profiling data to file, writing to log instead: " 2424 + e.getLocalizedMessage(), 2425 e); 2426 LOG.error(adeInitData); 2427 } 2428 } 2429 } 2430 2431 try { 2432 // get an Admin cms context object with site root set to "/" 2433 CmsObject adminCms = initCmsObject( 2434 null, 2435 null, 2436 getDefaultUsers().getUserAdmin(), 2437 (String)null, 2438 (String)null); 2439 OpenCms.getSearchManager().initSpellcheckIndex(adminCms); 2440 } catch (CmsException e) { 2441 throw new CmsInitException(Messages.get().container(Messages.ERR_CRITICAL_INIT_ADMINCMS_0), e); 2442 } 2443 2444 } 2445 // everything is initialized, now start publishing 2446 m_publishManager.startPublishing(); 2447 } 2448 2449 /** 2450 * This method performs the error handling for OpenCms.<p> 2451 * 2452 * @param cms the current cms context, might be null ! 2453 * @param req the client request 2454 * @param res the client response 2455 * @param t the exception that occurred 2456 */ 2457 private void errorHandling(CmsObject cms, HttpServletRequest req, HttpServletResponse res, Throwable t) { 2458 2459 // remove the controller attribute from the request 2460 CmsFlexController.removeController(req); 2461 2462 boolean canWrite = (!res.isCommitted() && !res.containsHeader("Location")); 2463 int status = -1; 2464 boolean isGuest = true; 2465 2466 if (t instanceof ServletException) { 2467 ServletException s = (ServletException)t; 2468 if (s.getRootCause() != null) { 2469 t = s.getRootCause(); 2470 } 2471 LOG.error(t.getLocalizedMessage() + " rendering URL " + req.getRequestURL(), t); 2472 } else if (t instanceof CmsSecurityException) { 2473 LOG.warn(t.getLocalizedMessage() + " rendering URL " + req.getRequestURL(), t); 2474 // access error - display login dialog 2475 if (canWrite) { 2476 try { 2477 m_authorizationHandler.requestAuthorization(req, res, getLoginFormURL(req, res)); 2478 } catch (IOException ioe) { 2479 LOG.debug("Error calling authorization handler.", ioe); 2480 } 2481 return; 2482 } 2483 } else if (t instanceof CmsDbEntryNotFoundException) { 2484 LOG.warn(t.getLocalizedMessage() + " rendering URL " + req.getRequestURL(), t); 2485 // user or group does not exist 2486 status = HttpServletResponse.SC_SERVICE_UNAVAILABLE; 2487 isGuest = false; 2488 } else if (t instanceof CmsVfsResourceNotFoundException) { 2489 LOG.warn(t.getLocalizedMessage() + " rendering URL " + req.getRequestURL(), t); 2490 // file not found - display 404 error. 2491 status = HttpServletResponse.SC_NOT_FOUND; 2492 } else if (t instanceof CmsException) { 2493 LOG.error(t.getLocalizedMessage() + " rendering URL " + req.getRequestURL(), t); 2494 if (t.getCause() != null) { 2495 t = t.getCause(); 2496 } 2497 } else if (t.getClass().getName().equals("org.apache.catalina.connector.ClientAbortException")) { 2498 // only log to debug channel any exceptions caused by a client abort - this is tomcat specific 2499 LOG.debug(t.getLocalizedMessage() + " rendering URL " + req.getRequestURL(), t); 2500 } else { 2501 LOG.error(t.getLocalizedMessage() + " rendering URL " + req.getRequestURL(), t); 2502 } 2503 2504 if (status < 1) { 2505 // error code not set - set "internal server error" (500) 2506 status = HttpServletResponse.SC_INTERNAL_SERVER_ERROR; 2507 } 2508 res.setStatus(status); 2509 2510 try { 2511 if ((cms != null) && (cms.getRequestContext().getCurrentUser() != null)) { 2512 isGuest = isGuest 2513 && (cms.getRequestContext().getCurrentUser().isGuestUser() 2514 || cms.userInGroup( 2515 cms.getRequestContext().getCurrentUser().getName(), 2516 OpenCms.getDefaultUsers().getGroupGuests())); 2517 } 2518 } catch (CmsException e) { 2519 // result is false 2520 LOG.error(e.getLocalizedMessage(), e); 2521 } 2522 2523 if (canWrite) { 2524 res.setContentType("text/html"); 2525 CmsRequestUtil.setNoCacheHeaders(res); 2526 if ((status != 404) 2527 && !isGuest 2528 && (cms != null) 2529 && (!CmsJsonPartFilter.isJsonRequest(req)) 2530 && !cms.getRequestContext().getCurrentProject().isOnlineProject()) { 2531 try { 2532 res.setStatus(HttpServletResponse.SC_OK); 2533 res.getWriter().print(CmsErrorUI.getBootstrapPage(cms, t, req)); 2534 } catch (IOException e) { 2535 // can be ignored 2536 LOG.error(e.getLocalizedMessage(), e); 2537 } 2538 } else { 2539 try { 2540 res.sendError(status, t.toString()); 2541 } catch (IOException e) { 2542 // can be ignored 2543 LOG.error(e.getLocalizedMessage(), e); 2544 } 2545 } 2546 } 2547 } 2548 2549 /** 2550 * 2551 * 2552 * @param serviceName the GWT PRC service class name 2553 * @param servletConfig the servlet configuration 2554 * 2555 * @return the GWT service instance 2556 * 2557 * @throws Throwable if something goes wrong 2558 */ 2559 private synchronized CmsGwtService getGwtService(String serviceName, ServletConfig servletConfig) throws Throwable { 2560 2561 CmsGwtServiceContext context = m_gwtServiceContexts.get(serviceName); 2562 if (context == null) { 2563 context = new CmsGwtServiceContext(serviceName); 2564 m_gwtServiceContexts.put(serviceName, context); 2565 } 2566 CmsGwtService gwtService = (CmsGwtService)Class.forName(serviceName).newInstance(); 2567 gwtService.init(servletConfig); 2568 gwtService.setContext(context); 2569 return gwtService; 2570 } 2571 2572 /** 2573 * Reads the login form which should be used for authenticating the current request.<p> 2574 * 2575 * @param req current request 2576 * @param res current response 2577 * 2578 * @return the URL of the login form or <code>null</code> if not set 2579 * 2580 * @throws IOException in case of IO errors 2581 */ 2582 private String getLoginFormURL(HttpServletRequest req, HttpServletResponse res) throws IOException { 2583 2584 CmsHttpAuthenticationSettings httpAuthenticationSettings = OpenCms.getSystemInfo().getHttpAuthenticationSettings(); 2585 String loginFormURL = null; 2586 2587 // this will create an admin user with the "right" site root already set 2588 CmsObject adminCms; 2589 try { 2590 adminCms = initCmsObject(req, res, OpenCms.getDefaultUsers().getUserAdmin(), null, null); 2591 } catch (CmsException e) { 2592 // this should never happen, if it does we can't continue 2593 throw new IOException( 2594 Messages.get().getBundle().key( 2595 Messages.ERR_INVALID_INIT_USER_2, 2596 OpenCms.getDefaultUsers().getUserAdmin(), 2597 2598 null), 2599 e); 2600 } 2601 // get the requested resource 2602 String path = adminCms.getRequestContext().getUri(); 2603 CmsProperty propertyLoginForm = null; 2604 try { 2605 propertyLoginForm = adminCms.readPropertyObject(path, CmsPropertyDefinition.PROPERTY_LOGIN_FORM, true); 2606 } catch (Throwable t) { 2607 if (t instanceof CmsVfsResourceNotFoundException) { 2608 // if we can't read the property from the path, try to use the resource init handlers to find the 2609 // resource to read it from 2610 CmsResource alternativeResource = null; 2611 try { 2612 // use null as the response to avoid side effects like redirects, etc. 2613 alternativeResource = initResource(adminCms, path, req, null); 2614 if (alternativeResource != null) { 2615 propertyLoginForm = adminCms.readPropertyObject( 2616 adminCms.getSitePath(alternativeResource), 2617 CmsPropertyDefinition.PROPERTY_LOGIN_FORM, 2618 true); 2619 } 2620 } catch (Exception e) { 2621 LOG.error(e.getLocalizedMessage(), e); 2622 } 2623 } 2624 2625 if (propertyLoginForm == null) { 2626 if (LOG.isWarnEnabled()) { 2627 LOG.warn( 2628 Messages.get().getBundle().key( 2629 Messages.LOG_ERROR_READING_AUTH_PROP_2, 2630 CmsPropertyDefinition.PROPERTY_LOGIN_FORM, 2631 path), 2632 t); 2633 } 2634 2635 } 2636 } 2637 2638 String params = null; 2639 if ((propertyLoginForm != null) 2640 && (propertyLoginForm != CmsProperty.getNullProperty()) 2641 && CmsStringUtil.isNotEmpty(propertyLoginForm.getValue())) { 2642 // login form property value was found 2643 // build a redirect URL using the value of the property 2644 // "__loginform" is a dummy request parameter that could be used in a JSP template to trigger 2645 // if the template should display a login formular or not 2646 loginFormURL = propertyLoginForm.getValue(); 2647 params = "__loginform=true"; 2648 } else if (!httpAuthenticationSettings.useBrowserBasedHttpAuthentication() 2649 && CmsStringUtil.isNotEmpty(httpAuthenticationSettings.getFormBasedHttpAuthenticationUri())) { 2650 // login form property value not set, but form login set in configuration 2651 // build a redirect URL to the default login form URI configured in opencms.properties 2652 loginFormURL = httpAuthenticationSettings.getFormBasedHttpAuthenticationUri(); 2653 } 2654 2655 String callbackURL = CmsRequestUtil.encodeParamsWithUri(path, req); 2656 if (loginFormURL != null) { 2657 if (!loginFormURL.startsWith("http")) { 2658 loginFormURL = m_linkManager.substituteLink(adminCms, loginFormURL, null, true); 2659 } else { 2660 callbackURL = m_linkManager.getServerLink(adminCms, path); 2661 callbackURL = CmsRequestUtil.encodeParamsWithUri(callbackURL, req); 2662 } 2663 } 2664 2665 return m_authorizationHandler.getLoginFormURL(loginFormURL, params, callbackURL); 2666 } 2667 2668 /** 2669 * If we are in the Online project, check if the given resource is marked as secure, and handle it according to the secure server configuration.<p> 2670 * 2671 * @param cms the current CMS context 2672 * @param req the current request 2673 * @param res the current response 2674 * @param resource the resource to check 2675 * @param resourceName the resource path from the request 2676 * 2677 * @return the resource to replace the original resource 2678 * 2679 * @throws CmsException if something goes wrong 2680 * @throws CmsVfsResourceNotFoundException if the resource could not be found 2681 */ 2682 private CmsResource handleSecureResource( 2683 CmsObject cms, 2684 HttpServletRequest req, 2685 HttpServletResponse res, 2686 CmsResource resource, 2687 String resourceName) 2688 throws CmsException, CmsVfsResourceNotFoundException { 2689 2690 // check online project 2691 if (cms.getRequestContext().getCurrentProject().isOnlineProject() && (res != null)) { 2692 boolean secure = false; 2693 try { 2694 // check if resource is secure 2695 secure = Boolean.valueOf( 2696 cms.readPropertyObject( 2697 cms.getSitePath(resource), 2698 CmsPropertyDefinition.PROPERTY_SECURE, 2699 true).getValue()).booleanValue(); 2700 } catch (CmsVfsResourceNotFoundException e) { 2701 LOG.warn(e.getLocalizedMessage(), e); 2702 } catch (CmsException e) { 2703 LOG.error(e.getLocalizedMessage(), e); 2704 } 2705 if (secure) { 2706 CmsResource resource1 = resource; 2707 // resource is secure, check site config 2708 CmsSite site = OpenCms.getSiteManager().getCurrentSite(cms); 2709 // check the secure url 2710 String secureUrl = null; 2711 try { 2712 secureUrl = site.getSecureUrl(); 2713 } catch (Exception e) { 2714 LOG.error( 2715 Messages.get().getBundle().key(Messages.ERR_SECURE_SITE_NOT_CONFIGURED_1, resourceName), 2716 e); 2717 throw new CmsException( 2718 Messages.get().container(Messages.ERR_SECURE_SITE_NOT_CONFIGURED_1, resourceName), 2719 e); 2720 } 2721 boolean usingSec = true; 2722 if (req != null) { 2723 usingSec = req.getRequestURL().toString().toUpperCase().startsWith(secureUrl.toUpperCase()); 2724 } 2725 if (site.isExclusiveUrl() && !usingSec) { 2726 resource1 = null; 2727 // secure resource without secure protocol, check error config 2728 if (site.isExclusiveError()) { 2729 // trigger 404 error 2730 throw new CmsVfsResourceNotFoundException( 2731 Messages.get().container(Messages.ERR_REQUEST_SECURE_RESOURCE_0)); 2732 } else { 2733 // redirect 2734 String target = OpenCms.getLinkManager().getOnlineLink(cms, resourceName); 2735 if (!target.toLowerCase().startsWith(secureUrl.toLowerCase())) { 2736 Optional<String> targetWithReplacedHost = CmsStringUtil.replacePrefix( 2737 target, 2738 site.getSiteMatcher().getUrl(), 2739 secureUrl, 2740 true); 2741 if (targetWithReplacedHost.isPresent()) { 2742 target = targetWithReplacedHost.get(); 2743 } 2744 if (!target.toLowerCase().startsWith(secureUrl.toLowerCase())) { 2745 LOG.warn("Failed to generate secure URL for " + target + ", site = " + site); 2746 } 2747 } 2748 2749 try { 2750 if (site.usesPermanentRedirects()) { 2751 res.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY); 2752 res.setHeader("Location", target); 2753 } else { 2754 res.sendRedirect(target); 2755 } 2756 } catch (Exception e) { 2757 // ignore, but should never happen 2758 LOG.error("Error sending secure resource redirect.", e); 2759 } 2760 } 2761 } 2762 resource = resource1; 2763 } 2764 2765 } 2766 return resource; 2767 } 2768 2769 /** 2770 * Initializes a CmsObject with the given context information.<p> 2771 * 2772 * @param contextInfo the information for the CmsObject context to create 2773 * 2774 * @return the initialized CmsObject 2775 * 2776 * @throws CmsException if something goes wrong 2777 */ 2778 private CmsObject initCmsObject(CmsContextInfo contextInfo) throws CmsException { 2779 2780 CmsUser user = contextInfo.getUser(); 2781 if (user == null) { 2782 user = m_securityManager.readUser(null, contextInfo.getUserName()); 2783 } 2784 2785 CmsProject project = contextInfo.getProject(); 2786 if (project == null) { 2787 project = m_securityManager.readProject(contextInfo.getProjectName()); 2788 } 2789 2790 // first create the request context 2791 CmsRequestContext context = new CmsRequestContext( 2792 user, 2793 project, 2794 contextInfo.getRequestedUri(), 2795 contextInfo.getRequestMatcher(), 2796 contextInfo.getSiteRoot(), 2797 contextInfo.isSecureRequest(), 2798 contextInfo.getLocale(), 2799 contextInfo.getEncoding(), 2800 contextInfo.getRemoteAddr(), 2801 contextInfo.getRequestTime(), 2802 m_resourceManager.getFolderTranslator(), 2803 m_resourceManager.getFileTranslator(), 2804 contextInfo.getOuFqn()); 2805 context.setDetailResource(contextInfo.getDetailResource()); 2806 2807 // now initialize and return the CmsObject 2808 return new CmsObject(m_securityManager, context); 2809 } 2810 2811 /** 2812 * Initializes a {@link CmsObject} with the given users information.<p> 2813 * 2814 * @param request the current http request (or <code>null</code>) 2815 * @param user the initialized user 2816 * @param siteRoot the users current site 2817 * @param projectId the id of the users current project 2818 * @param ouFqn the organizational unit 2819 * 2820 * @return the initialized CmsObject 2821 * 2822 * @throws CmsException in case something goes wrong 2823 */ 2824 private CmsObject initCmsObject( 2825 HttpServletRequest request, 2826 CmsUser user, 2827 String siteRoot, 2828 CmsUUID projectId, 2829 String ouFqn) 2830 throws CmsException { 2831 2832 CmsProject project = null; 2833 try { 2834 project = m_securityManager.readProject(projectId); 2835 } catch (CmsDbEntryNotFoundException e) { 2836 // project not found, switch to online project 2837 project = m_securityManager.readProject(CmsProject.ONLINE_PROJECT_ID); 2838 LOG.debug("Project '" + projectId + "' was not found, switch to online project.", e); 2839 } 2840 2841 // get requested resource uri and remote IP address, as well as time for "time warp" browsing 2842 String requestedResource = null; 2843 Long requestTimeAttr = null; 2844 String remoteAddr; 2845 CmsSiteMatcher requestMatcher; 2846 2847 boolean isSecureRequest = false; 2848 2849 if (request != null) { 2850 // get path info from request 2851 requestedResource = getPathInfo(request); 2852 2853 // check for special header for remote address 2854 remoteAddr = request.getHeader(CmsRequestUtil.HEADER_X_FORWARDED_FOR); 2855 if (remoteAddr == null) { 2856 // if header is not available, use default remote address 2857 remoteAddr = request.getRemoteAddr(); 2858 } 2859 2860 // check for special "time warp" browsing 2861 HttpSession session = request.getSession(false); 2862 if (session != null) { 2863 // no new session must be created here 2864 requestTimeAttr = (Long)session.getAttribute(CmsContextInfo.ATTRIBUTE_REQUEST_TIME); 2865 } 2866 isSecureRequest = OpenCms.getSiteManager().usesSecureSite(request); 2867 2868 // create the request matcher 2869 requestMatcher = new CmsSiteMatcher(request.getRequestURL().toString()); 2870 } else { 2871 // if no request is available, the IP is always set to localhost 2872 remoteAddr = CmsContextInfo.LOCALHOST; 2873 // also the request matcher is always the workplace server 2874 requestMatcher = OpenCms.getSiteManager().getWorkplaceSiteMatcher(); 2875 } 2876 if (requestedResource == null) { 2877 // path info can still be null 2878 requestedResource = "/"; 2879 } 2880 2881 // calculate the request time 2882 long requestTime; 2883 if (requestTimeAttr == null) { 2884 requestTime = System.currentTimeMillis(); 2885 } else { 2886 requestTime = requestTimeAttr.longValue(); 2887 } 2888 2889 // get locale and encoding 2890 CmsI18nInfo i18nInfo; 2891 if (m_localeManager.isInitialized()) { 2892 // locale manager is initialized 2893 // resolve locale and encoding 2894 if ((request != null) 2895 && (requestedResource.endsWith(OpenCmsServlet.HANDLE_GWT) || isWorkplaceServletRequest(request))) { 2896 // GWT RPC or workplace servlet call, always keep the request encoding and use the default locale 2897 i18nInfo = new CmsI18nInfo(CmsLocaleManager.getDefaultLocale(), request.getCharacterEncoding()); 2898 } else { 2899 String resourceName; 2900 if (requestedResource.startsWith(CmsWorkplace.VFS_PATH_SYSTEM)) { 2901 // add site root only if resource name does not start with "/system" 2902 resourceName = requestedResource; 2903 } else if (OpenCms.getSiteManager().startsWithShared(requestedResource)) { 2904 resourceName = requestedResource; 2905 } else { 2906 resourceName = siteRoot.concat(requestedResource); 2907 } 2908 i18nInfo = m_localeManager.getI18nInfo(request, user, project, resourceName); 2909 } 2910 } else { 2911 // locale manager not initialized, this will be true _only_ during system startup 2912 // the values set does not matter, no locale information form VFS is used on system startup 2913 // this is just to protect against null pointer exceptions 2914 i18nInfo = new CmsI18nInfo(Locale.ENGLISH, getSystemInfo().getDefaultEncoding()); 2915 } 2916 2917 // decode the requested resource, always using UTF-8 2918 requestedResource = CmsEncoder.decode(requestedResource); 2919 2920 // in case the current site could be configured for single tree localization, if so, remove the locale prefix if present 2921 CmsSite site = OpenCms.getSiteManager().getSiteForSiteRoot(siteRoot); 2922 if ((site != null) && CmsSite.LocalizationMode.singleTree.equals(site.getLocalizationMode())) { 2923 Locale locale = CmsSingleTreeLocaleHandler.getLocaleFromPath(requestedResource); 2924 if (locale != null) { 2925 requestedResource = requestedResource.substring( 2926 requestedResource.indexOf(locale.toString()) + locale.toString().length()); 2927 } 2928 } 2929 2930 // initialize the context info 2931 CmsContextInfo contextInfo = new CmsContextInfo( 2932 user, 2933 project, 2934 requestedResource, 2935 requestMatcher, 2936 siteRoot, 2937 isSecureRequest, 2938 i18nInfo.getLocale(), 2939 i18nInfo.getEncoding(), 2940 remoteAddr, 2941 requestTime, 2942 ouFqn); 2943 2944 // now generate and return the CmsObject 2945 return initCmsObject(contextInfo); 2946 } 2947 2948 /** 2949 * Handles the user authentification for each request sent to OpenCms.<p> 2950 * 2951 * User authentification is done in three steps: 2952 * <ol> 2953 * <li>Session authentification: OpenCms stores information of all authentificated 2954 * users in an internal storage based on the users session.</li> 2955 * <li>Authorization handler authentification: If the session authentification fails, 2956 * the current configured authorization handler is called.</li> 2957 * <li>Default user: When both authentification methods fail, the user is set to 2958 * the default (Guest) user.</li> 2959 * </ol> 2960 * 2961 * @param req the current http request 2962 * @param res the current http response 2963 * 2964 * @return the initialized cms context 2965 * 2966 * @throws IOException if user authentication fails 2967 * @throws CmsException in case something goes wrong 2968 */ 2969 private CmsObject initCmsObject(HttpServletRequest req, HttpServletResponse res) throws IOException, CmsException { 2970 2971 return initCmsObject(req, res, true); 2972 } 2973 2974 /** 2975 * Returns an initialized CmsObject with the given users permissions.<p> 2976 * 2977 * In case the password is <code>null</code>, or the user is the <code>Guest</code> user, 2978 * no password check is done. Therefore you can initialize all users without knowing their passwords 2979 * by just supplying <code>null</code> as password. This is intended only for 2980 * internal operation in the core.<p> 2981 * 2982 * @param req the current request 2983 * @param res the current response 2984 * @param user the user to initialize the CmsObject with 2985 * @param password the password of the user 2986 * @param ouFqn the organizational unit, if <code>null</code> the users ou is used 2987 * 2988 * @return a cms context that has been initialized with "Guest" permissions 2989 * 2990 * @throws CmsException in case the CmsObject could not be initialized 2991 */ 2992 private CmsObject initCmsObject( 2993 HttpServletRequest req, 2994 HttpServletResponse res, 2995 String user, 2996 String password, 2997 String ouFqn) 2998 throws CmsException { 2999 3000 String siteroot = null; 3001 // gather information from request if provided 3002 if (req != null) { 3003 siteroot = OpenCms.getSiteManager().matchRequest(req).getSiteRoot(); 3004 } 3005 // initialize the user 3006 if (user == null) { 3007 user = getDefaultUsers().getUserGuest(); 3008 } 3009 if (siteroot == null) { 3010 siteroot = "/"; 3011 } 3012 CmsObject cms = initCmsObject( 3013 req, 3014 m_securityManager.readUser(null, user), 3015 siteroot, 3016 CmsProject.ONLINE_PROJECT_ID, 3017 ouFqn); 3018 // login the user if different from Guest and password was provided 3019 if ((password != null) && !getDefaultUsers().isUserGuest(user)) { 3020 cms.loginUser(user, password, CmsContextInfo.LOCALHOST); 3021 } 3022 return cms; 3023 } 3024 3025 /** 3026 * Checks whether the given request targets the workplace UI servlet.<p> 3027 * 3028 * @param req the request 3029 * 3030 * @return <code>true</code> in case the given request targets the workplace UI servlet 3031 */ 3032 private boolean isWorkplaceServletRequest(HttpServletRequest req) { 3033 3034 String servletPath = req.getServletPath(); 3035 return (servletPath != null) && servletPath.startsWith(CmsSystemInfo.WORKPLACE_PATH); 3036 } 3037 3038 /** 3039 * Sets the init level of this OpenCmsCore object instance.<p> 3040 * 3041 * For a detailed description about the possible run levels, 3042 * please see {@link OpenCms#getRunLevel()}.<p> 3043 * 3044 * @param level the level to set 3045 */ 3046 private void setRunLevel(int level) { 3047 3048 if (m_instance != null) { 3049 if (m_instance.m_runLevel >= OpenCms.RUNLEVEL_1_CORE_OBJECT) { 3050 // otherwise the log is not available 3051 if (CmsLog.INIT.isInfoEnabled()) { 3052 CmsLog.INIT.info( 3053 Messages.get().getBundle().key( 3054 Messages.INIT_RUNLEVEL_CHANGE_2, 3055 new Integer(m_instance.m_runLevel), 3056 new Integer(level))); 3057 } 3058 } 3059 m_instance.m_runLevel = level; 3060 } 3061 } 3062 3063}