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.configuration;
029
030import org.opencms.ade.detailpage.CmsDefaultDetailPageHandler;
031import org.opencms.ade.detailpage.I_CmsDetailPageHandler;
032import org.opencms.crypto.CmsAESTextEncryption;
033import org.opencms.crypto.I_CmsTextEncryption;
034import org.opencms.db.CmsCacheSettings;
035import org.opencms.db.CmsDefaultUsers;
036import org.opencms.db.CmsLoginManager;
037import org.opencms.db.CmsSubscriptionManager;
038import org.opencms.db.I_CmsDbContextFactory;
039import org.opencms.flex.CmsFlexCacheConfiguration;
040import org.opencms.i18n.CmsLocaleManager;
041import org.opencms.jsp.userdata.CmsUserDataRequestManager;
042import org.opencms.letsencrypt.CmsLetsEncryptConfiguration;
043import org.opencms.mail.CmsMailHost;
044import org.opencms.mail.CmsMailSettings;
045import org.opencms.main.CmsDefaultSessionStorageProvider;
046import org.opencms.main.CmsEventManager;
047import org.opencms.main.CmsHttpAuthenticationSettings;
048import org.opencms.main.CmsLog;
049import org.opencms.main.CmsServletContainerSettings;
050import org.opencms.main.I_CmsRequestHandler;
051import org.opencms.main.I_CmsResourceInit;
052import org.opencms.main.I_CmsSessionStorageProvider;
053import org.opencms.main.OpenCms;
054import org.opencms.monitor.CmsMemoryMonitorConfiguration;
055import org.opencms.publish.CmsPublishManager;
056import org.opencms.rmi.CmsRemoteShellConstants;
057import org.opencms.security.CmsDefaultAuthorizationHandler;
058import org.opencms.security.CmsDefaultCredentialsResolver;
059import org.opencms.security.CmsDefaultValidationHandler;
060import org.opencms.security.I_CmsAuthorizationHandler;
061import org.opencms.security.I_CmsCredentialsResolver;
062import org.opencms.security.I_CmsPasswordHandler;
063import org.opencms.security.I_CmsValidationHandler;
064import org.opencms.security.twofactor.CmsTwoFactorAuthenticationConfig;
065import org.opencms.util.CmsStringUtil;
066import org.opencms.workflow.CmsDefaultWorkflowManager;
067import org.opencms.workflow.I_CmsWorkflowManager;
068import org.opencms.xml.CmsXmlUtils;
069import org.opencms.xml.containerpage.CmsADECacheSettings;
070import org.opencms.xml.xml2json.I_CmsApiAuthorizationHandler;
071
072import java.util.ArrayList;
073import java.util.Collections;
074import java.util.HashMap;
075import java.util.Iterator;
076import java.util.LinkedHashMap;
077import java.util.List;
078import java.util.Locale;
079import java.util.Map;
080
081import javax.xml.parsers.DocumentBuilderFactory;
082import javax.xml.parsers.ParserConfigurationException;
083
084import org.apache.commons.digester3.Digester;
085import org.apache.commons.digester3.NodeCreateRule;
086import org.apache.commons.digester3.Rule;
087import org.apache.commons.lang3.RandomStringUtils;
088import org.apache.commons.lang3.StringUtils;
089import org.apache.commons.logging.Log;
090
091import org.dom4j.Element;
092import org.w3c.dom.Document;
093import org.xml.sax.Attributes;
094
095/**
096 * System master configuration class.<p>
097 *
098 * @since 6.0.0
099 */
100public class CmsSystemConfiguration extends A_CmsXmlConfiguration {
101
102    /**
103     * Data for creating API authorization handlers.
104     */
105    public static class ApiAuthorizationConfig {
106
107        /** The class name. */
108        private String m_class;
109
110        /** The name. */
111        private String m_name;
112
113        /** The parameters. */
114        private CmsParameterConfiguration m_params = new CmsParameterConfiguration();
115
116        /**
117         * Writes the data back to the given XML element.
118         *
119         * @param element an XML element
120         */
121        public void fillXml(Element element) {
122
123            element.addElement("name").addText(getName());
124            element.addElement("class").addText(getClassName());
125            for (Map.Entry<String, String> entry : m_params.entrySet()) {
126                Element paramElem = element.addElement("param");
127                paramElem.addAttribute("name", entry.getKey());
128                paramElem.addText(entry.getValue());
129            }
130        }
131
132        /**
133         * Gets the API authorization class name.
134         *
135         * @return the class name
136         */
137        public String getClassName() {
138
139            return m_class;
140        }
141
142        /**
143         * Gets the identifier for the authorization handler.
144         *
145         * @return the identifier for the handler
146         */
147        public String getName() {
148
149            return m_name;
150        }
151
152        /**
153         * Gets the parameters for the handler.
154         *
155         * @return the parameters for the handler
156         */
157        public CmsParameterConfiguration getParams() {
158
159            return m_params;
160        }
161
162        /**
163         * Sets the class name.
164         *
165         * @param class1 the class name
166         */
167        public void setClassName(String class1) {
168
169            m_class = class1;
170        }
171
172        /**
173         * Sets the name of the handler.
174         *
175         * @param name the handler name
176         */
177        public void setName(String name) {
178
179            m_name = name;
180        }
181
182        /**
183        * Sets one parameter.
184        *
185        * @param key the parameter name
186        * @param value the parameter value
187        */
188        public void setParam(String key, String value) {
189
190            m_params.put(key, value);
191        }
192
193    }
194
195    /** Enum for the user session mode. */
196    public enum UserSessionMode {
197        /** Only a single session per user is allowed. */
198        single,
199        /** Any number of sessions for a user are allowed. */
200        standard
201    }
202
203    /** The attribute name for the deleted node. */
204    public static final String A_DELETED = "deleted";
205
206    /** The "error" attribute. */
207    public static final String A_ERROR = "error";
208
209    /** The "errorPage" attribute. */
210    public static final String A_ERROR_PAGE = "errorPage";
211
212    /** The "exclusive" attribute. */
213    public static final String A_EXCLUSIVE = "exclusive";
214
215    /** The attribute name for the localization mode. */
216    public static final String A_LOCALIZATION_MODE = "localizationMode";
217
218    /** The "maxvisited" attribute. */
219    public static final String A_MAXVISITED = "maxvisited";
220
221    /** The "offline" attribute. */
222    public static final String A_OFFLINE = "offline";
223
224    /** The "online" attribute. */
225    public static final String A_ONLINE = "online";
226    /** The "poolname" attribute. */
227    public static final String A_POOLNAME = "poolname";
228    /** The "security" attribute. */
229    public static final String A_SECURITY = "security";
230
231    /** The name of the DTD for this configuration. */
232    public static final String CONFIGURATION_DTD_NAME = "opencms-system.dtd";
233    /** The default user session mode. */
234    public static final UserSessionMode DEFAULT_USER_SESSION_MODE = UserSessionMode.standard;
235    /** The name of the default XML file for this configuration. */
236    public static final String DEFAULT_XML_FILE_NAME = "opencms-system.xml";
237
238    /** The ade node name. */
239    public static final String N_ADE = "ade";
240
241    /** The ade-cache node name. */
242    public static final String N_ADE_CACHE = "ade-cache";
243
244    /** Node name for a single API authorization handler. */
245    public static final String N_API_AUTHORIZATION = "api-authorization";
246
247    /** Node name for the group of API authorization handlers. */
248    public static final String N_API_AUTHORIZATIONS = "api-authorizations";
249
250    /** The node name for the authorization handler. */
251    public static final String N_AUTHORIZATIONHANDLER = "authorizationhandler";
252
253    /** The node name for the avgcachebytes node. */
254    public static final String N_AVGCACHEBYTES = "avgcachebytes";
255
256    /** The node name for the browser-based node. */
257    public static final String N_BROWSER_BASED = "browser-based";
258
259    /** The node name for the cache-enabled node. */
260    public static final String N_CACHE_ENABLED = "cache-enabled";
261
262    /** The node name for the cache-offline node. */
263    public static final String N_CACHE_OFFLINE = "cache-offline";
264
265    /** The node name for a job class. */
266    public static final String N_CLASS = "class";
267
268    /** The configuration node name. */
269    public static final String N_CONFIGURATION = "configuration";
270
271    /** The containerpages node name. */
272    public static final String N_CONTAINERPAGES = "containerpages";
273
274    /** The duration after which responsible resource owners will be notified about out-dated content. */
275    public static final String N_CONTENT_NOTIFICATION = "content-notification";
276
277    /** The node name for the defaultcontentencoding node. */
278    public static final String N_DEFAULT_CONTENT_ENCODING = "defaultcontentencoding";
279
280    /** The node name for the defaultusers expression. */
281    public static final String N_DEFAULTUSERS = "defaultusers";
282
283    /** The node name for the detail page handler. */
284    public static final String N_DETAIL_PAGE_HANDLER = "detail-page-handler";
285
286    /** The node name for the device selector node. */
287    public static final String N_DEVICESELECTOR = "device-selector";
288
289    /** The node name for the digest type. */
290    public static final String N_DIGESTTYPE = "digest-type";
291
292    /** The node name for the login account lock minutes.  */
293    public static final String N_DISABLEMINUTES = "disableMinutes";
294
295    /** The node name for the sitemap cache for documents. */
296    public static final String N_DOCUMENTS = "documents";
297
298    /** The node name for the email-interval node. */
299    public static final String N_EMAIL_INTERVAL = "email-interval";
300
301    /** The node name for the email-receiver node. */
302    public static final String N_EMAIL_RECEIVER = "email-receiver";
303
304    /** The node name for the email-sender node. */
305    public static final String N_EMAIL_SENDER = "email-sender";
306
307    /** The node name for the login security option enabled flag. */
308    public static final String N_ENABLESCURITY = "enableSecurity";
309
310    /** Node name for the encryption section. */
311    public static final String N_ENCRYPTION = "encryption";
312
313    /** The node name for the request handler classes. */
314    public static final String N_EVENTMANAGER = "eventmanager";
315
316    /** The node name for the events node. */
317    public static final String N_EVENTS = "events";
318
319    /** The node name for the flexcache node. */
320    public static final String N_FLEXCACHE = "flexcache";
321
322    /** The node name for the form-based node. */
323    public static final String N_FORM_BASED = "form-based";
324
325    /** The node name for the group-administrators node. */
326    public static final String N_GROUP_ADMINISTRATORS = "group-administrators";
327
328    /** The node name for the group-guests node. */
329    public static final String N_GROUP_GUESTS = "group-guests";
330
331    /** The node name for the group-projectmanagers node. */
332    public static final String N_GROUP_PROJECTMANAGERS = "group-projectmanagers";
333
334    /** The node name for the group-users node. */
335    public static final String N_GROUP_USERS = "group-users";
336
337    /** The groupcontainers node name. */
338    public static final String N_GROUPCONTAINERS = "groupcontainers";
339
340    /** The node name for the publish "history-size" value. */
341    public static final String N_HISTORYSIZE = "history-size";
342
343    /** The node name for the http-authentication node. */
344    public static final String N_HTTP_AUTHENTICATION = "http-authentication";
345
346    /** The node name for the internationalization node. */
347    public static final String N_I18N = "internationalization";
348
349    /** The name of the class to generate cache keys. */
350    public static final String N_KEYGENERATOR = "keygenerator";
351
352    /** The node name for individual locales. */
353    public static final String N_LOCALE = "locale";
354
355    /** The node name for the locale handler. */
356    public static final String N_LOCALEHANDLER = "localehandler";
357
358    /** The node name for the configured locales. */
359    public static final String N_LOCALESCONFIGURED = "localesconfigured";
360
361    /** The node name for the default locale(s). */
362    public static final String N_LOCALESDEFAULT = "localesdefault";
363
364    /** The node name for the log-interval node. */
365    public static final String N_LOG_INTERVAL = "log-interval";
366
367    /** The node name for the login manager. */
368    public static final String N_LOGINMANAGER = "loginmanager";
369
370    /** Node name for the logout URI.*/
371    public static final String N_LOGOUT_URI = "logoutUri";
372
373    /** The node name for the mail configuration. */
374    public static final String N_MAIL = "mail";
375
376    /** The node name for the "mail from" node. */
377    public static final String N_MAILFROM = "mailfrom";
378
379    /** The node name for the "mail host" node. */
380    public static final String N_MAILHOST = "mailhost";
381
382    /** The node name for the login manager bad attempt count. */
383    public static final String N_MAXBADATTEMPTS = "maxBadAttempts";
384
385    /** The node name for the maxcachebytes node. */
386    public static final String N_MAXCACHEBYTES = "maxcachebytes";
387
388    /** The node name for the maxentrybytes node. */
389    public static final String N_MAXENTRYBYTES = "maxentrybytes";
390
391    /** The node name for the maxkeys node. */
392    public static final String N_MAXKEYS = "maxkeys";
393
394    /** The node name for the maxusagepercent node. */
395    public static final String N_MAXUSAGE_PERCENT = "maxusagepercent";
396
397    /** The node name for the memorymonitor node. */
398    public static final String N_MEMORYMONITOR = "memorymonitor";
399
400    /** The duration after which responsibles will be notified about out-dated content. */
401    public static final String N_NOTIFICATION_PROJECT = "notification-project";
402
403    /** The duration after which responsibles will be notified about out-dated content. */
404    public static final String N_NOTIFICATION_TIME = "notification-time";
405
406    /** The node name for the parameters. */
407    public static final String N_PARAMETERS = "parameters";
408
409    /** Node name for the password change interval. */
410    public static final String N_PASSWORD_CHANGE_INTERVAL = "passwordChangeInterval";
411
412    /** The node name for the password encoding. */
413    public static final String N_PASSWORDENCODING = "encoding";
414
415    /** The node name for the password handler. */
416    public static final String N_PASSWORDHANDLER = "passwordhandler";
417
418    /** The node name for the permission handler. */
419    public static final String N_PERMISSIONHANDLER = "permissionhandler";
420
421    /** The node name for the prevent-response-flush node. */
422    public static final String N_PREVENTRESPONSEFLUSH = "prevent-response-flush";
423
424    /** The node name for the publish list remove mode. */
425    public static final String N_PUBLISH_LIST_REMOVE_MODE = "publish-list-remove-mode";
426
427    /** The node name for the "publishhistory" section. */
428    public static final String N_PUBLISHMANAGER = "publishmanager";
429
430    /** The node name for the "publishhistory" section. */
431    public static final String N_QUEUEPERSISTANCE = "queue-persistance";
432
433    /** The node name for the "publishhistory" section. */
434    public static final String N_QUEUESHUTDOWNTIME = "queue-shutdowntime";
435
436    /** The node name for the memory email receiver. */
437    public static final String N_RECEIVER = "receiver";
438
439    /** The node name for the release-tags-after-end node. */
440    public static final String N_RELEASETAGSAFTEREND = "release-tags-after-end";
441
442    /** The node name for the request-error-page-attribute node. */
443    public static final String N_REQUESTERRORPAGEATTRIBUTE = "request-error-page-attribute";
444
445    /** The node name for the request handler classes. */
446    public static final String N_REQUESTHANDLER = "requesthandler";
447
448    /** The node name for the request handlers. */
449    public static final String N_REQUESTHANDLERS = "requesthandlers";
450
451    /** The node name for the resource init classes. */
452    public static final String N_RESOURCEINIT = "resourceinit";
453
454    /** The node name for the resource init classes. */
455    public static final String N_RESOURCEINITHANDLER = "resourceinithandler";
456
457    /** Node name for the restrict-detail-contents option. */
458    public static final String N_RESTRICT_DETAIL_CONTENTS = "restrict-detail-contents";
459
460    /** the result cache node. */
461    public static final String N_RESULTCACHE = "resultcache";
462
463    /** The node name for the runtime info. */
464    public static final String N_RUNTIMECLASSES = "runtimeclasses";
465
466    /** The node name for the runtime info factory. */
467    public static final String N_RUNTIMEINFO = "runtimeinfo";
468
469    /** The node name for the runtime properties node. */
470    public static final String N_RUNTIMEPROPERTIES = "runtimeproperties";
471
472    /** The node name for the sax-impl-system-properties node. */
473    public static final String N_SAX_IMPL_SYSTEM_PROPERTIES = "sax-impl-system-properties";
474
475    /** The node name for the servlet container settings. */
476    public static final String N_SERVLETCONTAINERSETTINGS = "servletcontainer-settings";
477
478    /** The node name for the session-storageprovider node. */
479    public static final String N_SESSION_STORAGEPROVIDER = "session-storageprovider";
480
481    /** The sitemap node name. */
482    public static final String N_SITEMAP = "sitemap";
483
484    /** The sitemap-cache node name. */
485    public static final String N_SITEMAP_CACHE = "sitemap-cache";
486
487    /** The size of the memory monitor's cache for ACLS. */
488    public static final String N_SIZE_ACLS = "size-accesscontrollists";
489
490    /** The size of the memory monitor's cache for offline container pages. */
491    public static final String N_SIZE_CONTAINERPAGE_OFFLINE = "size-containerpage-offline";
492
493    /** The size of the memory monitor's cache for online container pages. */
494    public static final String N_SIZE_CONTAINERPAGE_ONLINE = "size-containerpage-online";
495
496    /** The size of the memory monitor's cache for groups. */
497    public static final String N_SIZE_GROUPS = "size-groups";
498
499    /** The size of the memory monitor's cache for organizational units. */
500    public static final String N_SIZE_ORGUNITS = "size-orgunits";
501
502    /** The size of the memory monitor's cache for permission checks. */
503    public static final String N_SIZE_PERMISSIONS = "size-permissions";
504
505    /** The size of the memory monitor's cache for project resources. */
506    public static final String N_SIZE_PROJECTRESOURCES = "size-projectresources";
507
508    /** The size of the memory monitor's cache for projects. */
509    public static final String N_SIZE_PROJECTS = "size-projects";
510
511    /** The size of the memory monitor's cache for properties. */
512    public static final String N_SIZE_PROPERTIES = "size-properties";
513
514    /** The size of the memory monitor's cache for property lists. */
515    public static final String N_SIZE_PROPERTYLISTS = "size-propertylists";
516
517    /** The size of the memory monitor's cache for lists of resources. */
518    public static final String N_SIZE_RESOURCELISTS = "size-resourcelists";
519
520    /** The size of the memory monitor's cache for resources. */
521    public static final String N_SIZE_RESOURCES = "size-resources";
522
523    /** The size of the memory monitor's cache for roles. */
524    public static final String N_SIZE_ROLES = "size-roles";
525
526    /** The size of the memory monitor's cache for user/group relations. */
527    public static final String N_SIZE_USERGROUPS = "size-usergroups";
528
529    /** The size of the memory monitor's cache for users. */
530    public static final String N_SIZE_USERS = "size-users";
531
532    /** The subscriptionmanager node name. */
533    public static final String N_SUBSCRIPTIONMANAGER = "subscriptionmanager";
534
535    /** The main system configuration node name. */
536    public static final String N_SYSTEM = "system";
537
538    /** Node name for declaring a single text encryption. */
539    public static final String N_TEXT_ENCRYPTION = "text-encryption";
540
541    /** The node name for the time zone configuration. */
542    public static final String N_TIMEZONE = "timezone";
543
544    /** Node name for the authorization token lifetime. */
545    public static final String N_TOKEN_LIFETIME = "tokenLifetime";
546
547    /** The node name for the user-admin node. */
548    public static final String N_USER_ADMIN = "user-admin";
549
550    /** Node name for the user data check interval. */
551    public static final String N_USER_DATA_CHECK_INTERVAL = "userDataCheckInterval";
552
553    /** The node name for the user-deletedresource node. */
554    public static final String N_USER_DELETEDRESOURCE = "user-deletedresource";
555
556    /** The node name for the user-export node. */
557    public static final String N_USER_EXPORT = "user-export";
558
559    /** The node name for the user-guest node. */
560    public static final String N_USER_GUEST = "user-guest";
561
562    /** The node name for the validation handler. */
563    public static final String N_VALIDATIONHANDLER = "validationhandler";
564
565    /** The node name for the version history. */
566    public static final String N_VERSIONHISTORY = "versionhistory";
567
568    /** The node name for the warning-interval node. */
569    public static final String N_WARNING_INTERVAL = "warning-interval";
570
571    /** The node name which indicates if apache should be configurable in sitemanager. */
572    public static final String N_WEBSERVERSCRIPTING = "webserver-scripting";
573
574    public static final String N_WEBSERVERSCRIPTING_CONFIGTEMPLATE = "configtemplate";
575
576    public static final String N_WEBSERVERSCRIPTING_FILENAMEPREFIX = "filenameprefix";
577
578    public static final String N_WEBSERVERSCRIPTING_LOGGINGDIR = "loggingdir";
579
580    public static final String N_WEBSERVERSCRIPTING_SECURETEMPLATE = "securetemplate";
581
582    public static final String N_WEBSERVERSCRIPTING_TARGETPATH = "targetpath";
583
584    public static final String N_WEBSERVERSCRIPTING_WEBSERVERSCRIPT = "webserverscript";
585
586    /** The node name for the workflow configuration. */
587    public static final String N_WORKFLOW = "workflow";
588
589    /** The log object for this class. */
590    private static final Log LOG = CmsLog.getLog(CmsSystemConfiguration.class);
591
592    /** Node name for auto history cleanup setting. */
593    private static final String N_AUTO_CLEANUP_HISTORY_ENTRIES = "auto-cleanup-history-entries";
594
595    /** Node name for the credentials resolver setting. */
596    private static final String N_CREDENTIALS_RESOLVER = "credentials-resolver";
597
598    /** Node name for the user max inactive time. */
599    private static final String N_MAX_INACTIVE_TIME = "maxInactiveTime";
600
601    /** Node name for the 'require org unit' option. */
602    private static final String N_REQUIRE_ORGUNIT = "requireOrgUnit";
603
604    /** Node name for the element reuse mode. */
605    private static final String N_REUSE_ELEMENTS = "reuse-elements";
606
607    /** Node name for the shell server options. */
608    private static final String N_SHELL_SERVER = "shell-server";
609
610    /** Node name for two-factor auth configuration. */
611    private static final String N_TWO_FACTOR_AUTHENTICATION = "two-factor-authentication";
612
613    /** Node name for the user session mode. */
614    private static final String N_USER_SESSION_MODE = "user-session-mode";
615
616    /** The ADE cache settings. */
617    private CmsADECacheSettings m_adeCacheSettings;
618
619    /** The ADE configuration. */
620    private String m_adeConfiguration;
621
622    /** The ADE configuration parameters. */
623    private Map<String, String> m_adeParameters = new LinkedHashMap<String, String>();
624
625    private Map<String, I_CmsApiAuthorizationHandler> m_apiAuthorizationMap = new HashMap<>();
626
627    private List<ApiAuthorizationConfig> m_apiAuthorizations = new ArrayList<>();
628
629    /** Parameters for the authorization handler. */
630    private Map<String, String> m_authHandlerParams = new HashMap<>();
631
632    /** The authorization handler. */
633    private String m_authorizationHandler;
634
635    /** The settings of the memory monitor. */
636    private CmsCacheSettings m_cacheSettings;
637
638    /** The configured OpenCms default users and groups. */
639    private CmsDefaultUsers m_cmsDefaultUsers;
640
641    /** The flex cache configuration object. */
642    private CmsFlexCacheConfiguration m_cmsFlexCacheConfiguration;
643
644    /** The memory monitor configuration. */
645    private CmsMemoryMonitorConfiguration m_cmsMemoryMonitorConfiguration;
646
647    /** The credentials resolver instance. */
648    private I_CmsCredentialsResolver m_credentialsResolver;
649
650    /** The configured credentials resolver class name. */
651    private String m_credentialsResolverClass;
652
653    /** The default content encoding. */
654    private String m_defaultContentEncoding;
655
656    /** The detail page handler. */
657    private I_CmsDetailPageHandler m_detailPageHandler = new CmsDefaultDetailPageHandler();
658
659    /** The configured OpenCms event manager. */
660    private CmsEventManager m_eventManager;
661
662    /** Indicates if the version history is enabled. */
663    private boolean m_historyEnabled;
664
665    /** The maximum number of historical versions per resource. */
666    private int m_historyVersions;
667
668    /** The maximum number of historical versions for deleted resources. */
669    private int m_historyVersionsAfterDeletion;
670
671    /** The HTTP basic authentication settings. */
672    private CmsHttpAuthenticationSettings m_httpAuthenticationSettings;
673
674    /** The LetsEncrypt configuration. */
675    private CmsLetsEncryptConfiguration m_letsEncryptConfig;
676
677    /** The configured locale manager for multi language support. */
678    private CmsLocaleManager m_localeManager;
679
680    /** The configured login manager. */
681    private CmsLoginManager m_loginManager;
682
683    /** The mail settings. */
684    private CmsMailSettings m_mailSettings;
685
686    /** Notification project. */
687    private String m_notificationProject;
688
689    /** The duration after which responsibles will be notified about out-dated content (in days). */
690    // It is an Integer object so that it can be distinguished if this optional element was set or not
691    private Integer m_notificationTime;
692
693    /** The password handler. */
694    private I_CmsPasswordHandler m_passwordHandler;
695
696    /** The permission handler. */
697    private String m_permissionHandler;
698
699    /** The configured publish list remove mode. */
700    private String m_publishListRemoveMode;
701
702    /** The configured publish manager. */
703    private CmsPublishManager m_publishManager;
704
705    /** A list of instantiated request handler classes. */
706    private List<I_CmsRequestHandler> m_requestHandlers;
707
708    /** A list of instantiated resource init handler classes. */
709    private List<I_CmsResourceInit> m_resourceInitHandlers;
710
711    /** Value of the restrict-detail-contents option. */
712    private String m_restrictDetailContents;
713
714    /** The runtime info factory. */
715    private I_CmsDbContextFactory m_runtimeInfoFactory;
716
717    /** The runtime properties. */
718    private Map<String, String> m_runtimeProperties;
719
720    /** Flag indicating if the SAX parser implementation classes should be stored in system properties
721     *  to improve the unmarshalling performance. */
722    private boolean m_saxImplProperties;
723
724    /** The configured session storage provider class name. */
725    private String m_sessionStorageProvider;
726
727    /** The shell server options. */
728    private CmsRemoteShellConfiguration m_shellServerOptions;
729
730    /** The subscription manager. */
731    private CmsSubscriptionManager m_subscriptionManager;
732
733    /** The temporary file project id. */
734    private int m_tempFileProjectId;
735
736    private Map<String, I_CmsTextEncryption> m_textEncryptions = new LinkedHashMap<>();
737
738    /** Two-factor authentication configuration. */
739    private CmsTwoFactorAuthenticationConfig m_twoFactorConfig;
740
741    private CmsUserDataRequestManager m_userDataRequestManager;
742
743    /** The user session mode. */
744    private UserSessionMode m_userSessionMode;
745
746    /** The configured validation handler. */
747    private String m_validationHandler;
748
749    /** The configured workflow manager. */
750    private I_CmsWorkflowManager m_workflowManager;
751
752    /**
753     * Adds an ADE configuration parameter.<p>
754     *
755     * @param name the parameter name
756     * @param value the parameter value
757     */
758    public void addAdeParameter(String name, String value) {
759
760        m_adeParameters.put(name, value);
761    }
762
763    /**
764     * Adds a parameter for the authorization handler.
765     *
766     * @param name the parameter name
767     * @param value the parameter value
768     */
769    public void addAuthorizationHandlerParam(String name, String value) {
770
771        m_authHandlerParams.put(name, value);
772    }
773
774    /**
775     * @see org.opencms.configuration.I_CmsConfigurationParameterHandler#addConfigurationParameter(java.lang.String, java.lang.String)
776     */
777    @Override
778    public void addConfigurationParameter(String paramName, String paramValue) {
779
780        m_runtimeProperties.put(paramName, paramValue);
781    }
782
783    /**
784     * Adds the event manager class.<p>
785     *
786     * @param clazz the class name of event manager class  to instantiate and add
787     */
788    public void addEventManager(String clazz) {
789
790        try {
791            m_eventManager = (CmsEventManager)Class.forName(clazz).newInstance();
792            if (CmsLog.INIT.isInfoEnabled()) {
793                CmsLog.INIT.info(
794                    Messages.get().getBundle().key(Messages.INIT_EVENTMANAGER_CLASS_SUCCESS_1, m_eventManager));
795            }
796        } catch (Throwable t) {
797            LOG.error(Messages.get().getBundle().key(Messages.INIT_EVENTMANAGER_CLASS_INVALID_1, clazz), t);
798            return;
799        }
800    }
801
802    /**
803     * Adds a new instance of a request handler class.<p>
804     *
805     * @param clazz the class name of the request handler to instantiate and add
806     */
807    public void addRequestHandler(String clazz, CmsParameterConfiguration params) {
808
809        Object handler;
810        try {
811            handler = Class.forName(clazz).newInstance();
812        } catch (Throwable t) {
813            LOG.error(Messages.get().getBundle().key(Messages.LOG_INIT_REQUEST_HANDLER_FAILURE_1, clazz), t);
814            return;
815        }
816        if (handler instanceof I_CmsRequestHandler) {
817            ((I_CmsRequestHandler)handler).initParameters(params);
818            m_requestHandlers.add((I_CmsRequestHandler)handler);
819            if (CmsLog.INIT.isInfoEnabled()) {
820                CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_REQUEST_HANDLER_SUCCESS_1, clazz));
821            }
822        } else {
823            if (CmsLog.INIT.isErrorEnabled()) {
824                CmsLog.INIT.error(Messages.get().getBundle().key(Messages.INIT_REQUEST_HANDLER_INVALID_1, clazz));
825            }
826        }
827    }
828
829    /**
830     * Adds a new instance of a resource init handler class.<p>
831     *
832     * @param clazz the class name of the resource init handler to instantiate and add
833     * @param params the parameters set for the resource init handler (parameters need to be copied out, the object will be modified after use)
834     */
835    public void addResourceInitHandler(String clazz, CmsParameterConfiguration params)
836    throws CmsConfigurationException {
837
838        Object initClass;
839        try {
840            initClass = Class.forName(clazz).newInstance();
841        } catch (Throwable t) {
842            LOG.error(Messages.get().getBundle().key(Messages.LOG_RESOURCE_INIT_CLASS_INVALID_1, clazz), t);
843            return;
844        }
845        if (initClass instanceof I_CmsResourceInit) {
846            ((I_CmsResourceInit)initClass).initParameters(params);
847            m_resourceInitHandlers.add((I_CmsResourceInit)initClass);
848            if (CmsLog.INIT.isInfoEnabled()) {
849                CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_RESOURCE_INIT_SUCCESS_1, clazz));
850            }
851        } else {
852            if (CmsLog.INIT.isErrorEnabled()) {
853                CmsLog.INIT.error(Messages.get().getBundle().key(Messages.INIT_RESOURCE_INIT_INVALID_CLASS_1, clazz));
854            }
855        }
856    }
857
858    /**
859     * @see org.opencms.configuration.I_CmsXmlConfiguration#addXmlDigesterRules(org.apache.commons.digester3.Digester)
860     */
861    public void addXmlDigesterRules(Digester digester) {
862
863        // add finish rule
864        digester.addCallMethod("*/" + N_SYSTEM, "initializeFinished");
865
866        // add rule for internationalization
867        digester.addObjectCreate("*/" + N_SYSTEM + "/" + N_I18N, CmsLocaleManager.class);
868        digester.addSetNext("*/" + N_SYSTEM + "/" + N_I18N, "setLocaleManager");
869
870        // add locale handler creation rule
871        digester.addObjectCreate(
872            "*/" + N_SYSTEM + "/" + N_I18N + "/" + N_LOCALEHANDLER,
873            CmsConfigurationException.class.getName(),
874            A_CLASS);
875        digester.addSetNext("*/" + N_SYSTEM + "/" + N_I18N + "/" + N_LOCALEHANDLER, "setLocaleHandler");
876
877        // add locale rules
878        digester.addCallMethod(
879            "*/" + N_SYSTEM + "/" + N_I18N + "/" + N_LOCALESCONFIGURED + "/" + N_LOCALE,
880            "addAvailableLocale",
881            0);
882        digester.addCallMethod(
883            "*/" + N_SYSTEM + "/" + N_I18N + "/" + N_LOCALESDEFAULT + "/" + N_LOCALE,
884            "addDefaultLocale",
885            0);
886        // add time zone rule
887        digester.addCallMethod("*/" + N_SYSTEM + "/" + N_I18N + "/" + N_TIMEZONE, "setTimeZone", 0);
888        digester.addCallMethod("*/" + N_SYSTEM + "/" + N_I18N + "/" + N_REUSE_ELEMENTS, "setReuseElements", 0);
889
890        // add version history rules
891        digester.addCallMethod("*/" + N_SYSTEM + "/" + N_VERSIONHISTORY, "setHistorySettings", 3);
892        digester.addCallParam("*/" + N_SYSTEM + "/" + N_VERSIONHISTORY, 0, A_ENABLED);
893        digester.addCallParam("*/" + N_SYSTEM + "/" + N_VERSIONHISTORY, 1, A_COUNT);
894        digester.addCallParam("*/" + N_SYSTEM + "/" + N_VERSIONHISTORY, 2, A_DELETED);
895
896        // add mail configuration rule
897        digester.addObjectCreate("*/" + N_SYSTEM + "/" + N_MAIL, CmsMailSettings.class);
898        digester.addCallMethod("*/" + N_SYSTEM + "/" + N_MAIL + "/" + N_MAILFROM, "setMailFromDefault", 0);
899        digester.addSetNext("*/" + N_SYSTEM + "/" + N_MAIL, "setMailSettings");
900
901        // add mail host configuration rule
902        digester.addCallMethod("*/" + N_SYSTEM + "/" + N_MAIL + "/" + N_MAILHOST, "addMailHost", 7);
903        digester.addCallParam("*/" + N_SYSTEM + "/" + N_MAIL + "/" + N_MAILHOST, 0, A_NAME);
904        digester.addCallParam("*/" + N_SYSTEM + "/" + N_MAIL + "/" + N_MAILHOST, 1, A_PORT);
905        digester.addCallParam("*/" + N_SYSTEM + "/" + N_MAIL + "/" + N_MAILHOST, 2, A_ORDER);
906        digester.addCallParam("*/" + N_SYSTEM + "/" + N_MAIL + "/" + N_MAILHOST, 3, A_PROTOCOL);
907        digester.addCallParam("*/" + N_SYSTEM + "/" + N_MAIL + "/" + N_MAILHOST, 4, A_SECURITY);
908        digester.addCallParam("*/" + N_SYSTEM + "/" + N_MAIL + "/" + N_MAILHOST, 5, A_USER);
909        digester.addCallParam("*/" + N_SYSTEM + "/" + N_MAIL + "/" + N_MAILHOST, 6, A_PASSWORD);
910
911        // add event classes
912        digester.addCallMethod("*/" + N_SYSTEM + "/" + N_EVENTS + "/" + N_EVENTMANAGER, "addEventManager", 1);
913        digester.addCallParam("*/" + N_SYSTEM + "/" + N_EVENTS + "/" + N_EVENTMANAGER, 0, A_CLASS);
914
915        // use array so we can modify it in the inner class and give each resource init handler a fresh CmsParameterConfiguration instance
916        CmsParameterConfiguration resourceHandlerParams[] = new CmsParameterConfiguration[] {null};
917
918        digester.addRule("*/" + N_SYSTEM + "/" + N_RESOURCEINIT + "/" + N_RESOURCEINITHANDLER, new Rule() {
919
920            private String m_class;
921
922            @Override
923            public void begin(String namespace, String name, Attributes attributes) throws Exception {
924
925                m_class = attributes.getValue(A_CLASS);
926                resourceHandlerParams[0] = new CmsParameterConfiguration();
927            }
928
929            @Override
930            public void end(String namespace, String name) throws Exception {
931
932                addResourceInitHandler(m_class, resourceHandlerParams[0]);
933
934            }
935        });
936
937        digester.addRule(
938            "*/" + N_SYSTEM + "/" + N_RESOURCEINIT + "/" + N_RESOURCEINITHANDLER + "/" + N_PARAM,
939            new Rule() {
940
941                private String m_name;
942                private String m_value;
943
944                @Override
945                public void begin(String namespace, String name, Attributes attributes) throws Exception {
946
947                    m_name = attributes.getValue(A_NAME);
948                    m_value = null;
949                }
950
951                @Override
952                public void body(String namespace, String name, String text) throws Exception {
953
954                    m_value = text;
955                }
956
957                @Override
958                public void end(String namespace, String name) throws Exception {
959
960                    resourceHandlerParams[0].add(m_name, m_value);
961                }
962            });
963
964        CmsParameterConfiguration[] requestHandlerParams = new CmsParameterConfiguration[] {null};
965        digester.addRule(
966            "*/" + N_SYSTEM + "/" + N_REQUESTHANDLERS + "/" + N_REQUESTHANDLER + "/" + N_PARAM,
967            new Rule() {
968
969                private String m_name;
970                private String m_value;
971
972                @Override
973                public void begin(String namespace, String name, Attributes attributes) throws Exception {
974
975                    m_name = attributes.getValue(A_NAME);
976                    m_value = null;
977                }
978
979                @Override
980                public void body(String namespace, String name, String text) throws Exception {
981
982                    m_value = text;
983                }
984
985                @Override
986                public void end(String namespace, String name) throws Exception {
987
988                    requestHandlerParams[0].add(m_name, m_value);
989                }
990            });
991        digester.addRule("*/" + N_SYSTEM + "/" + N_REQUESTHANDLERS + "/" + N_REQUESTHANDLER, new Rule() {
992
993            private String m_class;
994
995            @Override
996            public void begin(String namespace, String name, Attributes attributes) throws Exception {
997
998                m_class = attributes.getValue(A_CLASS);
999                requestHandlerParams[0] = new CmsParameterConfiguration();
1000            }
1001
1002            @Override
1003            public void end(String namespace, String name) throws Exception {
1004
1005                addRequestHandler(m_class, requestHandlerParams[0]);
1006            }
1007
1008        });
1009
1010        // add password handler creation rule
1011        digester.addObjectCreate(
1012            "*/" + N_SYSTEM + "/" + N_PASSWORDHANDLER,
1013            CmsConfigurationException.class.getName(),
1014            A_CLASS);
1015        digester.addCallMethod(
1016            "*/" + N_SYSTEM + "/" + N_PASSWORDHANDLER,
1017            I_CmsConfigurationParameterHandler.INIT_CONFIGURATION_METHOD);
1018        digester.addBeanPropertySetter(
1019            "*/" + N_SYSTEM + "/" + N_PASSWORDHANDLER + "/" + N_PASSWORDENCODING,
1020            "inputEncoding");
1021        digester.addBeanPropertySetter("*/" + N_SYSTEM + "/" + N_PASSWORDHANDLER + "/" + N_DIGESTTYPE, "digestType");
1022        digester.addSetNext("*/" + N_SYSTEM + "/" + N_PASSWORDHANDLER, "setPasswordHandler");
1023
1024        // add generic parameter rules for password handler
1025        digester.addCallMethod(
1026            "*/" + I_CmsXmlConfiguration.N_PARAM,
1027            I_CmsConfigurationParameterHandler.ADD_PARAMETER_METHOD,
1028            2);
1029        digester.addCallParam("*/" + I_CmsXmlConfiguration.N_PARAM, 0, I_CmsXmlConfiguration.A_NAME);
1030        digester.addCallParam("*/" + I_CmsXmlConfiguration.N_PARAM, 1);
1031
1032        // add validation handler creation rules
1033        digester.addCallMethod("*/" + N_SYSTEM + "/" + N_VALIDATIONHANDLER, "setValidationHandler", 1);
1034        digester.addCallParam("*/" + N_SYSTEM + "/" + N_VALIDATIONHANDLER, 0, A_CLASS);
1035
1036        // add login manager creation rules
1037        digester.addCallMethod("*/" + N_LOGINMANAGER, "setLoginManager", 9);
1038        digester.addCallParam("*/" + N_LOGINMANAGER + "/" + N_DISABLEMINUTES, 0);
1039        digester.addCallParam("*/" + N_LOGINMANAGER + "/" + N_MAXBADATTEMPTS, 1);
1040        digester.addCallParam("*/" + N_LOGINMANAGER + "/" + N_ENABLESCURITY, 2);
1041        digester.addCallParam("*/" + N_LOGINMANAGER + "/" + N_TOKEN_LIFETIME, 3);
1042        digester.addCallParam("*/" + N_LOGINMANAGER + "/" + N_MAX_INACTIVE_TIME, 4);
1043        digester.addCallParam("*/" + N_LOGINMANAGER + "/" + N_PASSWORD_CHANGE_INTERVAL, 5);
1044        digester.addCallParam("*/" + N_LOGINMANAGER + "/" + N_USER_DATA_CHECK_INTERVAL, 6);
1045        digester.addCallParam("*/" + N_LOGINMANAGER + "/" + N_REQUIRE_ORGUNIT, 7);
1046        digester.addCallParam("*/" + N_LOGINMANAGER + "/" + N_LOGOUT_URI, 8);
1047
1048        try {
1049            digester.addRule("*/" + N_TWO_FACTOR_AUTHENTICATION, new NodeCreateRule() {
1050
1051                @Override
1052                public void end(String namespace, String name) throws Exception {
1053
1054                    org.w3c.dom.Element elem = (org.w3c.dom.Element)digester.pop();
1055                    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
1056                    Document doc = dbf.newDocumentBuilder().newDocument();
1057                    doc.appendChild(doc.importNode(elem, true));
1058                    org.dom4j.Document dom4jDoc = CmsXmlUtils.convertDocumentFromW3CToDom4j(doc);
1059                    m_twoFactorConfig = new CmsTwoFactorAuthenticationConfig(dom4jDoc.getRootElement());
1060                }
1061
1062            });
1063        } catch (ParserConfigurationException e) {
1064            LOG.error(e.getLocalizedMessage(), e);
1065        }
1066
1067        digester.addCallMethod(
1068            "*/" + N_SYSTEM + "/" + N_SAX_IMPL_SYSTEM_PROPERTIES,
1069            "setUseSaxImplSystemProperties",
1070            1);
1071        digester.addCallParam("*/" + N_SYSTEM + "/" + N_SAX_IMPL_SYSTEM_PROPERTIES, 0);
1072
1073        // add compatibility parameter rules
1074        digester.addCallMethod(
1075            "*/" + N_SYSTEM + "/" + N_RUNTIMEPROPERTIES + "/" + N_PARAM,
1076            I_CmsConfigurationParameterHandler.ADD_PARAMETER_METHOD,
1077            2);
1078        digester.addCallParam(
1079            "*/" + N_SYSTEM + "/" + N_RUNTIMEPROPERTIES + "/" + N_PARAM,
1080            0,
1081            I_CmsXmlConfiguration.A_NAME);
1082        digester.addCallParam("*/" + N_SYSTEM + "/" + N_RUNTIMEPROPERTIES + "/" + N_PARAM, 1);
1083
1084        // add runtime classes configuration rules
1085        digester.addCallMethod(
1086            "*/" + N_SYSTEM + "/" + N_RUNTIMECLASSES + "/" + N_RUNTIMEINFO,
1087            "setRuntimeInfoFactory",
1088            1);
1089        digester.addCallParam("*/" + N_SYSTEM + "/" + N_RUNTIMECLASSES + "/" + N_RUNTIMEINFO, 0, A_CLASS);
1090
1091        // add default users rule
1092        digester.addCallMethod("*/" + N_SYSTEM + "/" + N_DEFAULTUSERS, "setCmsDefaultUsers", 7);
1093        digester.addCallParam("*/" + N_SYSTEM + "/" + N_DEFAULTUSERS + "/" + N_USER_ADMIN, 0);
1094        digester.addCallParam("*/" + N_SYSTEM + "/" + N_DEFAULTUSERS + "/" + N_USER_GUEST, 1);
1095        digester.addCallParam("*/" + N_SYSTEM + "/" + N_DEFAULTUSERS + "/" + N_USER_EXPORT, 2);
1096        digester.addCallParam("*/" + N_SYSTEM + "/" + N_DEFAULTUSERS + "/" + N_USER_DELETEDRESOURCE, 3);
1097        digester.addCallParam("*/" + N_SYSTEM + "/" + N_DEFAULTUSERS + "/" + N_GROUP_ADMINISTRATORS, 4);
1098        digester.addCallParam("*/" + N_SYSTEM + "/" + N_DEFAULTUSERS + "/" + N_GROUP_USERS, 5);
1099        digester.addCallParam("*/" + N_SYSTEM + "/" + N_DEFAULTUSERS + "/" + N_GROUP_GUESTS, 6);
1100
1101        // add defaultContentEncoding rule
1102        digester.addCallMethod("*/" + N_SYSTEM + "/" + N_DEFAULT_CONTENT_ENCODING, "setDefaultContentEncoding", 1);
1103        digester.addCallParam("*/" + N_SYSTEM + "/" + N_DEFAULT_CONTENT_ENCODING, 0);
1104
1105        // add memorymonitor configuration rule
1106        digester.addObjectCreate("*/" + N_SYSTEM + "/" + N_MEMORYMONITOR, CmsMemoryMonitorConfiguration.class);
1107        digester.addCallMethod("*/" + N_SYSTEM + "/" + N_MEMORYMONITOR, "initialize", 5);
1108        digester.addCallParam("*/" + N_SYSTEM + "/" + N_MEMORYMONITOR, 0, A_CLASS);
1109        digester.addCallParam("*/" + N_SYSTEM + "/" + N_MEMORYMONITOR + "/" + N_MAXUSAGE_PERCENT, 1);
1110        digester.addCallParam("*/" + N_SYSTEM + "/" + N_MEMORYMONITOR + "/" + N_LOG_INTERVAL, 2);
1111        digester.addCallParam("*/" + N_SYSTEM + "/" + N_MEMORYMONITOR + "/" + N_EMAIL_INTERVAL, 3);
1112        digester.addCallParam("*/" + N_SYSTEM + "/" + N_MEMORYMONITOR + "/" + N_WARNING_INTERVAL, 4);
1113        digester.addCallMethod("*/" + N_SYSTEM + "/" + N_MEMORYMONITOR + "/" + N_EMAIL_SENDER, "setEmailSender", 0);
1114        digester.addCallMethod(
1115            "*/" + N_SYSTEM + "/" + N_MEMORYMONITOR + "/" + N_EMAIL_RECEIVER + "/" + N_RECEIVER,
1116            "addEmailReceiver",
1117            0);
1118
1119        // set the MemoryMonitorConfiguration initialized once before
1120        digester.addSetNext("*/" + N_SYSTEM + "/" + N_MEMORYMONITOR, "setCmsMemoryMonitorConfiguration");
1121
1122        // add flexcache configuration rule
1123        digester.addObjectCreate("*/" + N_SYSTEM + "/" + N_FLEXCACHE, CmsFlexCacheConfiguration.class);
1124        digester.addCallMethod("*/" + N_SYSTEM + "/" + N_FLEXCACHE, "initialize", 6);
1125        digester.addCallParam("*/" + N_SYSTEM + "/" + N_FLEXCACHE + "/" + N_CACHE_ENABLED, 0);
1126        digester.addCallParam("*/" + N_SYSTEM + "/" + N_FLEXCACHE + "/" + N_CACHE_OFFLINE, 1);
1127        digester.addCallParam("*/" + N_SYSTEM + "/" + N_FLEXCACHE + "/" + N_MAXCACHEBYTES, 2);
1128        digester.addCallParam("*/" + N_SYSTEM + "/" + N_FLEXCACHE + "/" + N_AVGCACHEBYTES, 3);
1129        digester.addCallParam("*/" + N_SYSTEM + "/" + N_FLEXCACHE + "/" + N_MAXENTRYBYTES, 4);
1130        digester.addCallParam("*/" + N_SYSTEM + "/" + N_FLEXCACHE + "/" + N_MAXKEYS, 5);
1131        // add flexcache device selector
1132        digester.addCallMethod(
1133            "*/" + N_SYSTEM + "/" + N_FLEXCACHE + "/" + N_DEVICESELECTOR,
1134            "setDeviceSelectorConfiguration",
1135            1);
1136        digester.addCallParam("*/" + N_SYSTEM + "/" + N_FLEXCACHE + "/" + N_DEVICESELECTOR, 0, A_CLASS);
1137
1138        // set the FlexCacheConfiguration initialized once before
1139        digester.addSetNext("*/" + N_SYSTEM + "/" + N_FLEXCACHE, "setCmsFlexCacheConfiguration");
1140
1141        // add http basic authentication rules
1142        digester.addObjectCreate("*/" + N_SYSTEM + "/" + N_HTTP_AUTHENTICATION, CmsHttpAuthenticationSettings.class);
1143        digester.addCallMethod(
1144            "*/" + N_SYSTEM + "/" + N_HTTP_AUTHENTICATION + "/" + N_BROWSER_BASED,
1145            "setUseBrowserBasedHttpAuthentication",
1146            0);
1147        digester.addCallMethod(
1148            "*/" + N_SYSTEM + "/" + N_HTTP_AUTHENTICATION + "/" + N_FORM_BASED,
1149            "setFormBasedHttpAuthenticationUri",
1150            0);
1151        digester.addSetNext("*/" + N_SYSTEM + "/" + N_HTTP_AUTHENTICATION, "setHttpAuthenticationSettings");
1152
1153        // cache rules
1154        digester.addObjectCreate("*/" + N_SYSTEM + "/" + N_RESULTCACHE, CmsCacheSettings.class);
1155        digester.addCallMethod("*/" + N_SYSTEM + "/" + N_RESULTCACHE + "/" + N_KEYGENERATOR, "setCacheKeyGenerator", 0);
1156        digester.addCallMethod("*/" + N_SYSTEM + "/" + N_RESULTCACHE + "/" + N_SIZE_USERS, "setUserCacheSize", 0);
1157        digester.addCallMethod("*/" + N_SYSTEM + "/" + N_RESULTCACHE + "/" + N_SIZE_GROUPS, "setGroupCacheSize", 0);
1158        digester.addCallMethod("*/" + N_SYSTEM + "/" + N_RESULTCACHE + "/" + N_SIZE_ORGUNITS, "setOrgUnitCacheSize", 0);
1159        digester.addCallMethod(
1160            "*/" + N_SYSTEM + "/" + N_RESULTCACHE + "/" + N_SIZE_USERGROUPS,
1161            "setUserGroupsCacheSize",
1162            0);
1163        digester.addCallMethod("*/" + N_SYSTEM + "/" + N_RESULTCACHE + "/" + N_SIZE_PROJECTS, "setProjectCacheSize", 0);
1164        digester.addCallMethod(
1165            "*/" + N_SYSTEM + "/" + N_RESULTCACHE + "/" + N_SIZE_PROJECTRESOURCES,
1166            "setProjectResourcesCacheSize",
1167            0);
1168        digester.addCallMethod(
1169            "*/" + N_SYSTEM + "/" + N_RESULTCACHE + "/" + N_SIZE_RESOURCES,
1170            "setResourceCacheSize",
1171            0);
1172        digester.addCallMethod("*/" + N_SYSTEM + "/" + N_RESULTCACHE + "/" + N_SIZE_ROLES, "setRolesCacheSize", 0);
1173        digester.addCallMethod(
1174            "*/" + N_SYSTEM + "/" + N_RESULTCACHE + "/" + N_SIZE_RESOURCELISTS,
1175            "setResourcelistCacheSize",
1176            0);
1177        digester.addCallMethod(
1178            "*/" + N_SYSTEM + "/" + N_RESULTCACHE + "/" + N_SIZE_PROPERTIES,
1179            "setPropertyCacheSize",
1180            0);
1181        digester.addCallMethod(
1182            "*/" + N_SYSTEM + "/" + N_RESULTCACHE + "/" + N_SIZE_PROPERTYLISTS,
1183            "setPropertyListsCacheSize",
1184            0);
1185        digester.addCallMethod("*/" + N_SYSTEM + "/" + N_RESULTCACHE + "/" + N_SIZE_ACLS, "setAclCacheSize", 0);
1186        digester.addCallMethod(
1187            "*/" + N_SYSTEM + "/" + N_RESULTCACHE + "/" + N_SIZE_PERMISSIONS,
1188            "setPermissionCacheSize",
1189            0);
1190        digester.addCallMethod(
1191            "*/" + N_SYSTEM + "/" + N_RESULTCACHE + "/" + N_SIZE_CONTAINERPAGE_OFFLINE,
1192            "setContainerPageOfflineSize",
1193            0);
1194        digester.addCallMethod(
1195            "*/" + N_SYSTEM + "/" + N_RESULTCACHE + "/" + N_SIZE_CONTAINERPAGE_ONLINE,
1196            "setContainerPageOnlineSize",
1197            0);
1198        digester.addSetNext("*/" + N_SYSTEM + "/" + N_RESULTCACHE, "setCacheSettings");
1199
1200        // set the notification time
1201        digester.addCallMethod(
1202            "*/" + N_SYSTEM + "/" + N_CONTENT_NOTIFICATION + "/" + N_NOTIFICATION_TIME,
1203            "setNotificationTime",
1204            1);
1205        digester.addCallParam("*/" + N_SYSTEM + "/" + N_CONTENT_NOTIFICATION + "/" + N_NOTIFICATION_TIME, 0);
1206
1207        // set the notification project
1208        digester.addCallMethod(
1209            "*/" + N_SYSTEM + "/" + N_CONTENT_NOTIFICATION + "/" + N_NOTIFICATION_PROJECT,
1210            "setNotificationProject",
1211            1);
1212        digester.addCallParam("*/" + N_SYSTEM + "/" + N_CONTENT_NOTIFICATION + "/" + N_NOTIFICATION_PROJECT, 0);
1213
1214        // add authorization handler creation rules
1215        digester.addCallMethod("*/" + N_SYSTEM + "/" + N_AUTHORIZATIONHANDLER, "setAuthorizationHandler", 1);
1216        digester.addCallParam("*/" + N_SYSTEM + "/" + N_AUTHORIZATIONHANDLER, 0, A_CLASS);
1217
1218        digester.addCallMethod(
1219            "*/" + N_SYSTEM + "/" + N_AUTHORIZATIONHANDLER + "/parameters/param",
1220            "addAuthorizationHandlerParam",
1221            2);
1222        digester.addCallParam("*/" + N_SYSTEM + "/" + N_AUTHORIZATIONHANDLER + "/parameters/param", 0, "name");
1223        digester.addCallParam("*/" + N_SYSTEM + "/" + N_AUTHORIZATIONHANDLER + "/parameters/param", 1);
1224
1225        String apiAuthPath = "*/system/" + N_API_AUTHORIZATIONS + "/" + N_API_AUTHORIZATION;
1226        digester.addRule(apiAuthPath, new Rule() {
1227
1228            @Override
1229            public void begin(String namespace, String name, Attributes attributes) throws Exception {
1230
1231                digester.push(new ApiAuthorizationConfig());
1232            }
1233
1234            @Override
1235            public void end(String namespace, String name) throws Exception {
1236
1237                ApiAuthorizationConfig config = (ApiAuthorizationConfig)digester.pop();
1238                addApiAuthorization(config);
1239            }
1240        });
1241
1242        String namePath = apiAuthPath + "/name";
1243        digester.addCallMethod(namePath, "setName", 1);
1244        digester.addCallParam(namePath, 0);
1245
1246        String classNamePath = apiAuthPath + "/class";
1247        digester.addCallMethod(classNamePath, "setClassName", 1);
1248        digester.addCallParam(classNamePath, 0);
1249
1250        String paramPath = apiAuthPath + "/param";
1251        digester.addCallMethod(paramPath, "setParam", 2);
1252        digester.addCallParam(paramPath, 0, "name");
1253        digester.addCallParam(paramPath, 1);
1254
1255        // add publish manager configuration rule
1256        digester.addObjectCreate("*/" + N_SYSTEM + "/" + N_PUBLISHMANAGER, CmsPublishManager.class);
1257        digester.addCallMethod(
1258            "*/" + N_SYSTEM + "/" + N_PUBLISHMANAGER + "/" + N_HISTORYSIZE,
1259            "setPublishHistorySize",
1260            0);
1261        digester.addCallMethod(
1262            "*/" + N_SYSTEM + "/" + N_PUBLISHMANAGER + "/" + N_QUEUEPERSISTANCE,
1263            "setPublishQueuePersistance",
1264            0);
1265        digester.addCallMethod(
1266            "*/" + N_SYSTEM + "/" + N_PUBLISHMANAGER + "/" + N_QUEUESHUTDOWNTIME,
1267            "setPublishQueueShutdowntime",
1268            0);
1269        digester.addCallMethod(
1270            "*/" + N_SYSTEM + "/" + N_PUBLISHMANAGER + "/" + N_AUTO_CLEANUP_HISTORY_ENTRIES,
1271            "setAutoCleanupHistoryEntries",
1272            0);
1273        digester.addSetNext("*/" + N_SYSTEM + "/" + N_PUBLISHMANAGER, "setPublishManager");
1274
1275        // add rule for session storage provider
1276        digester.addCallMethod("*/" + N_SYSTEM + "/" + N_SESSION_STORAGEPROVIDER, "setSessionStorageProvider", 1);
1277        digester.addCallParam("*/" + N_SYSTEM + "/" + N_SESSION_STORAGEPROVIDER, 0, A_CLASS);
1278
1279        // add rule for permission handler
1280        digester.addCallMethod("*/" + N_SYSTEM + "/" + N_PERMISSIONHANDLER, "setPermissionHandler", 1);
1281        digester.addCallParam("*/" + N_SYSTEM + "/" + N_PERMISSIONHANDLER, 0, A_CLASS);
1282
1283        // add rules for servlet container settings
1284        digester.addCallMethod(
1285            "*/" + N_SYSTEM + "/" + N_SERVLETCONTAINERSETTINGS + "/" + N_PREVENTRESPONSEFLUSH,
1286            "setPreventResponseFlush",
1287            0);
1288        digester.addCallMethod(
1289            "*/" + N_SYSTEM + "/" + N_SERVLETCONTAINERSETTINGS + "/" + N_RELEASETAGSAFTEREND,
1290            "setReleaseTagsAfterEnd",
1291            0);
1292        digester.addCallMethod(
1293            "*/" + N_SYSTEM + "/" + N_SERVLETCONTAINERSETTINGS + "/" + N_REQUESTERRORPAGEATTRIBUTE,
1294            "setRequestErrorPageAttribute",
1295            0);
1296        digester.addCallMethod(
1297            "*/" + N_SYSTEM + "/" + N_SERVLETCONTAINERSETTINGS,
1298            "setServletContainerSettingsMode",
1299            1);
1300        digester.addCallParam("*/" + N_SYSTEM + "/" + N_SERVLETCONTAINERSETTINGS, 0, A_MODE);
1301
1302        // add rule for ADE cache settings
1303        String adeCachePath = "*/" + N_SYSTEM + "/" + N_ADE + "/" + N_ADE_CACHE;
1304        digester.addObjectCreate(adeCachePath, CmsADECacheSettings.class);
1305        // container page cache
1306        digester.addCallMethod(adeCachePath + "/" + N_CONTAINERPAGES, "setContainerPageOfflineSize", 1);
1307        digester.addCallParam(adeCachePath + "/" + N_CONTAINERPAGES, 0, A_OFFLINE);
1308        digester.addCallMethod(adeCachePath + "/" + N_CONTAINERPAGES, "setContainerPageOnlineSize", 1);
1309        digester.addCallParam(adeCachePath + "/" + N_CONTAINERPAGES, 0, A_ONLINE);
1310        // groupcontainer cache
1311        digester.addCallMethod(adeCachePath + "/" + N_GROUPCONTAINERS, "setGroupContainerOfflineSize", 1);
1312        digester.addCallParam(adeCachePath + "/" + N_GROUPCONTAINERS, 0, A_OFFLINE);
1313        digester.addCallMethod(adeCachePath + "/" + N_GROUPCONTAINERS, "setGroupContainerOnlineSize", 1);
1314        digester.addCallParam(adeCachePath + "/" + N_GROUPCONTAINERS, 0, A_ONLINE);
1315        // set the settings
1316        digester.addSetNext(adeCachePath, "setAdeCacheSettings");
1317
1318        String adeParamPath = "*/" + N_SYSTEM + "/" + N_ADE + "/" + N_PARAMETERS + "/" + N_PARAM;
1319        digester.addCallMethod(adeParamPath, "addAdeParameter", 2);
1320        digester.addCallParam(adeParamPath, 0, I_CmsXmlConfiguration.A_NAME);
1321        digester.addCallParam(adeParamPath, 1);
1322
1323        // add rule for subscription manager settings
1324        digester.addObjectCreate("*/" + N_SYSTEM + "/" + N_SUBSCRIPTIONMANAGER, CmsSubscriptionManager.class);
1325        digester.addCallMethod("*/" + N_SYSTEM + "/" + N_SUBSCRIPTIONMANAGER, "setEnabled", 1);
1326        digester.addCallParam("*/" + N_SYSTEM + "/" + N_SUBSCRIPTIONMANAGER, 0, A_ENABLED);
1327        digester.addCallMethod("*/" + N_SYSTEM + "/" + N_SUBSCRIPTIONMANAGER, "setPoolName", 1);
1328        digester.addCallParam("*/" + N_SYSTEM + "/" + N_SUBSCRIPTIONMANAGER, 0, A_POOLNAME);
1329        digester.addCallMethod("*/" + N_SYSTEM + "/" + N_SUBSCRIPTIONMANAGER, "setMaxVisitedCount", 1);
1330        digester.addCallParam("*/" + N_SYSTEM + "/" + N_SUBSCRIPTIONMANAGER, 0, A_MAXVISITED);
1331        digester.addSetNext("*/" + N_SYSTEM + "/" + N_SUBSCRIPTIONMANAGER, "setSubscriptionManager");
1332
1333        digester.addCallMethod("*/" + N_SYSTEM + "/" + N_PUBLISH_LIST_REMOVE_MODE, "setPublishListRemoveMode", 1);
1334        digester.addCallParam("*/" + N_SYSTEM + "/" + N_PUBLISH_LIST_REMOVE_MODE, 0, A_MODE);
1335
1336        String workflowXpath = "*/" + N_SYSTEM + "/" + N_WORKFLOW;
1337        digester.addObjectCreate(workflowXpath, CmsDefaultWorkflowManager.class.getName(), A_CLASS);
1338        digester.addObjectCreate(workflowXpath + "/" + N_PARAMETERS, LinkedHashMap.class);
1339        digester.addCallMethod(workflowXpath + "/" + N_PARAMETERS + "/" + N_PARAM, "put", 2);
1340        digester.addCallParam(workflowXpath + "/" + N_PARAMETERS + "/" + N_PARAM, 0, A_NAME);
1341        digester.addCallParam(workflowXpath + "/" + N_PARAMETERS + "/" + N_PARAM, 1);
1342        digester.addSetNext(workflowXpath + "/" + N_PARAMETERS, "setParameters");
1343        digester.addSetNext(workflowXpath, "setWorkflowManager");
1344
1345        CmsLetsEncryptConfiguration.CONFIG_HELPER.addRules(digester);
1346        digester.addSetNext(CmsLetsEncryptConfiguration.CONFIG_HELPER.getBasePath(), "setLetsEncryptConfig");
1347
1348        digester.addRule("*/" + N_SYSTEM + "/" + N_ENCRYPTION + "/" + N_TEXT_ENCRYPTION, new Rule() {
1349
1350            @Override
1351            public void begin(String namespace, String name, Attributes attributes) throws Exception {
1352
1353                String className = attributes.getValue(A_CLASS);
1354                String instanceName = attributes.getValue(A_NAME);
1355                I_CmsTextEncryption encrypter = (I_CmsTextEncryption)Class.forName(className).newInstance();
1356                encrypter.setName(instanceName);
1357                digester.push(encrypter);
1358            }
1359
1360            @Override
1361            public void end(String namespace, String name) throws Exception {
1362
1363                I_CmsTextEncryption encrypter = (I_CmsTextEncryption)digester.pop();
1364                m_textEncryptions.put(encrypter.getName(), encrypter);
1365            }
1366        });
1367
1368        // make sure that a 'default' text encryption exists, but attach the rule to the system element
1369        // because the <encryption> element doesn't necessarily exist,
1370        digester.addRule("*/" + N_SYSTEM, new Rule() {
1371
1372            public void end(String namespace, String name) throws Exception {
1373
1374                if (m_textEncryptions.get("default") == null) {
1375                    CmsAESTextEncryption defaultEncryption = new CmsAESTextEncryption();
1376                    defaultEncryption.setName("default");
1377                    defaultEncryption.addConfigurationParameter(
1378                        CmsAESTextEncryption.PARAM_SECRET,
1379                        RandomStringUtils.randomAlphanumeric(24));
1380                    m_textEncryptions.put("default", defaultEncryption);
1381                }
1382            };
1383        });
1384
1385        String userSessionPath = "*/" + N_SYSTEM + "/" + N_USER_SESSION_MODE;
1386        digester.addCallMethod(userSessionPath, "setUserSessionMode", 0);
1387
1388        String credentialsResolverPath = "*/" + N_SYSTEM + "/" + N_CREDENTIALS_RESOLVER;
1389        digester.addCallMethod(credentialsResolverPath, "setCredentialsResolver", 0);
1390
1391        digester.addCallMethod("*/" + N_SYSTEM + "/" + N_RESTRICT_DETAIL_CONTENTS, "setRestrictDetailContents", 1);
1392        digester.addCallParam("*/" + N_SYSTEM + "/" + N_RESTRICT_DETAIL_CONTENTS, 0);
1393
1394        String shellServerPath = "*/" + N_SYSTEM + "/" + N_SHELL_SERVER;
1395        digester.addCallMethod(shellServerPath, "setShellServerOptions", 2);
1396        digester.addCallParam(shellServerPath, 0, A_ENABLED);
1397        digester.addCallParam(shellServerPath, 1, A_PORT);
1398
1399        String detailPageHandlerPath = "*/" + N_SYSTEM + "/" + N_DETAIL_PAGE_HANDLER;
1400        digester.addObjectCreate(detailPageHandlerPath, CmsDefaultDetailPageHandler.class.getName(), A_CLASS);
1401        digester.addSetNext(detailPageHandlerPath, "setDetailPageHandler");
1402
1403        String userdataPath = "*/" + N_SYSTEM + "/" + CmsUserDataRequestManager.N_USERDATA;
1404        CmsUserDataRequestManager.addDigesterRules(digester, userdataPath);
1405        digester.addSetNext(userdataPath, "setUserDataRequestManager");
1406    }
1407
1408    /**
1409     * @see org.opencms.configuration.I_CmsXmlConfiguration#generateXml(org.dom4j.Element)
1410     */
1411    public Element generateXml(Element parent) {
1412
1413        // generate system node and sub notes
1414        Element systemElement = parent.addElement(N_SYSTEM);
1415
1416        if (OpenCms.getRunLevel() >= OpenCms.RUNLEVEL_3_SHELL_ACCESS) {
1417            // initialized OpenCms instance is available, use latest values
1418            m_localeManager = OpenCms.getLocaleManager();
1419            m_mailSettings = OpenCms.getSystemInfo().getMailSettings();
1420            m_historyEnabled = OpenCms.getSystemInfo().isHistoryEnabled();
1421            m_historyVersions = OpenCms.getSystemInfo().getHistoryVersions();
1422            m_historyVersionsAfterDeletion = OpenCms.getSystemInfo().getHistoryVersionsAfterDeletion();
1423            // m_resourceInitHandlers instance must be the one from configuration
1424            // m_requestHandlers instance must be the one from configuration
1425            m_loginManager = OpenCms.getLoginManager();
1426        }
1427
1428        // i18n nodes
1429        Element i18nElement = systemElement.addElement(N_I18N);
1430        i18nElement.addElement(N_LOCALEHANDLER).addAttribute(
1431            A_CLASS,
1432            m_localeManager.getLocaleHandler().getClass().getName());
1433        Iterator<Locale> loc;
1434        Element localesElement;
1435        localesElement = i18nElement.addElement(N_LOCALESCONFIGURED);
1436        loc = m_localeManager.getAvailableLocales().iterator();
1437        while (loc.hasNext()) {
1438            localesElement.addElement(N_LOCALE).addText(loc.next().toString());
1439        }
1440        localesElement = i18nElement.addElement(N_LOCALESDEFAULT);
1441        loc = m_localeManager.getDefaultLocales().iterator();
1442        while (loc.hasNext()) {
1443            localesElement.addElement(N_LOCALE).setText(loc.next().toString());
1444        }
1445        i18nElement.addElement(N_TIMEZONE).setText(m_localeManager.getTimeZone().getID());
1446        if (null != m_localeManager.getReuseElementsStr()) {
1447            i18nElement.addElement(N_REUSE_ELEMENTS).setText(m_localeManager.getReuseElementsStr());
1448        }
1449
1450        // mail nodes
1451        Element mailElement = systemElement.addElement(N_MAIL);
1452        mailElement.addElement(N_MAILFROM).setText(m_mailSettings.getMailFromDefault());
1453        Iterator<CmsMailHost> hosts = m_mailSettings.getMailHosts().iterator();
1454        while (hosts.hasNext()) {
1455            CmsMailHost host = hosts.next();
1456            Element hostElement = mailElement.addElement(N_MAILHOST).addAttribute(
1457                A_NAME,
1458                host.getHostname()).addAttribute(A_PORT, Integer.toString(host.getPort())).addAttribute(
1459                    A_ORDER,
1460                    host.getOrder().toString()).addAttribute(A_PROTOCOL, host.getProtocol()).addAttribute(
1461                        A_SECURITY,
1462                        host.getSecurity());
1463            if (host.isAuthenticating()) {
1464                hostElement.addAttribute(A_USER, host.getUsername()).addAttribute(A_PASSWORD, host.getPassword());
1465            }
1466        }
1467
1468        // scheduler node
1469
1470        // <events> node
1471        Element eventsElement = systemElement.addElement(N_EVENTS);
1472        Element eventManagerElement = eventsElement.addElement(N_EVENTMANAGER);
1473        eventManagerElement.addAttribute(A_CLASS, m_eventManager.getClass().getName());
1474
1475        // version history
1476        Element historyElement = systemElement.addElement(N_VERSIONHISTORY);
1477        historyElement.addAttribute(A_ENABLED, String.valueOf(m_historyEnabled));
1478        historyElement.addAttribute(A_COUNT, new Integer(m_historyVersions).toString());
1479        historyElement.addAttribute(A_DELETED, new Integer(m_historyVersionsAfterDeletion).toString());
1480
1481        // resourceinit
1482        Element resourceinitElement = systemElement.addElement(N_RESOURCEINIT);
1483        Iterator<I_CmsResourceInit> resHandlers = m_resourceInitHandlers.iterator();
1484        while (resHandlers.hasNext()) {
1485            I_CmsResourceInit handler = resHandlers.next();
1486            Element handlerElement = resourceinitElement.addElement(N_RESOURCEINITHANDLER);
1487            handlerElement.addAttribute(A_CLASS, handler.getClass().getName());
1488            CmsParameterConfiguration config = handler.getConfiguration();
1489            if (config != null) {
1490                for (String key : config.keySet()) {
1491                    handlerElement.addElement(N_PARAM).addAttribute(A_NAME, key).addText(config.get(key));
1492                }
1493            }
1494        }
1495
1496        // request handlers
1497        Element requesthandlersElement = systemElement.addElement(N_REQUESTHANDLERS);
1498        Iterator<I_CmsRequestHandler> reqHandlers = m_requestHandlers.iterator();
1499        while (reqHandlers.hasNext()) {
1500            I_CmsRequestHandler handler = reqHandlers.next();
1501            Element handlerElement = requesthandlersElement.addElement(N_REQUESTHANDLER);
1502            handlerElement.addAttribute(A_CLASS, handler.getClass().getName());
1503            CmsParameterConfiguration config = handler.getConfiguration();
1504            if (config != null) {
1505                for (String key : config.keySet()) {
1506                    handlerElement.addElement(N_PARAM).addAttribute(A_NAME, key).addText(config.get(key));
1507                }
1508            }
1509        }
1510
1511        // password handler
1512        Element passwordhandlerElement = systemElement.addElement(N_PASSWORDHANDLER).addAttribute(
1513            A_CLASS,
1514            m_passwordHandler.getClass().getName());
1515        passwordhandlerElement.addElement(N_PASSWORDENCODING).addText(m_passwordHandler.getInputEncoding());
1516        passwordhandlerElement.addElement(N_DIGESTTYPE).addText(m_passwordHandler.getDigestType());
1517        CmsParameterConfiguration handlerParameters = m_passwordHandler.getConfiguration();
1518        if (handlerParameters != null) {
1519            handlerParameters.appendToXml(passwordhandlerElement);
1520        }
1521
1522        // validation handler
1523        if (m_validationHandler != null) {
1524            Element valHandlerElem = systemElement.addElement(N_VALIDATIONHANDLER);
1525            valHandlerElem.addAttribute(A_CLASS, m_validationHandler);
1526        }
1527
1528        // login manager
1529        if (m_loginManager != null) {
1530            Element managerElement = systemElement.addElement(N_LOGINMANAGER);
1531            managerElement.addElement(N_DISABLEMINUTES).addText(String.valueOf(m_loginManager.getDisableMinutes()));
1532            managerElement.addElement(N_MAXBADATTEMPTS).addText(String.valueOf(m_loginManager.getMaxBadAttempts()));
1533            managerElement.addElement(N_ENABLESCURITY).addText(String.valueOf(m_loginManager.isEnableSecurity()));
1534            String tokenLifetimeStr = m_loginManager.getTokenLifetimeStr();
1535            if (tokenLifetimeStr != null) {
1536                managerElement.addElement(N_TOKEN_LIFETIME).addText(tokenLifetimeStr);
1537            }
1538            if (m_loginManager.getMaxInactive() != null) {
1539                managerElement.addElement(N_MAX_INACTIVE_TIME).addText(m_loginManager.getMaxInactive());
1540            }
1541
1542            if (m_loginManager.getPasswordChangeIntervalStr() != null) {
1543                managerElement.addElement(N_PASSWORD_CHANGE_INTERVAL).addText(
1544                    m_loginManager.getPasswordChangeIntervalStr());
1545            }
1546
1547            if (m_loginManager.getUserDataCheckIntervalStr() != null) {
1548                managerElement.addElement(N_USER_DATA_CHECK_INTERVAL).addText(
1549                    m_loginManager.getUserDataCheckIntervalStr());
1550            }
1551            if (m_loginManager.isOrgUnitRequired()) {
1552                managerElement.addElement(N_REQUIRE_ORGUNIT).addText("true");
1553            }
1554
1555            if (m_loginManager.getLogoutUri() != null) {
1556                managerElement.addElement(N_LOGOUT_URI).addText(m_loginManager.getLogoutUri());
1557            }
1558        }
1559        if (m_twoFactorConfig != null) {
1560            // the 2FA configuration is immutable, so we can just reuse the original element here
1561            systemElement.add(m_twoFactorConfig.getConfigElement());
1562        }
1563
1564        Element saxImpl = systemElement.addElement(N_SAX_IMPL_SYSTEM_PROPERTIES);
1565        saxImpl.setText(String.valueOf(m_saxImplProperties));
1566
1567        // create <runtimeproperties> node
1568        Element runtimepropertiesElement = systemElement.addElement(N_RUNTIMEPROPERTIES);
1569        if (m_runtimeProperties != null) {
1570            List<String> sortedRuntimeProperties = new ArrayList<String>(m_runtimeProperties.keySet());
1571            Collections.sort(sortedRuntimeProperties);
1572            Iterator<String> it = sortedRuntimeProperties.iterator();
1573            while (it.hasNext()) {
1574                String key = it.next();
1575                // create <param name="">value</param> subnodes
1576                runtimepropertiesElement.addElement(N_PARAM).addAttribute(A_NAME, key).addText(
1577                    m_runtimeProperties.get(key));
1578            }
1579        }
1580
1581        // create <runtimeinfo> node
1582        Element runtimeinfoElement = systemElement.addElement(N_RUNTIMECLASSES);
1583        Element runtimeinfofactoryElement = runtimeinfoElement.addElement(N_RUNTIMEINFO);
1584        runtimeinfofactoryElement.addAttribute(A_CLASS, getRuntimeInfoFactory().getClass().getName());
1585
1586        // create <defaultusers> node
1587        Element defaultusersElement = systemElement.addElement(N_DEFAULTUSERS);
1588        // create <user-admin> subnode
1589        defaultusersElement.addElement(N_USER_ADMIN).addText(m_cmsDefaultUsers.getUserAdmin());
1590        // create <user-guest> subnode
1591        defaultusersElement.addElement(N_USER_GUEST).addText(m_cmsDefaultUsers.getUserGuest());
1592        // create <user-export> subnode
1593        defaultusersElement.addElement(N_USER_EXPORT).addText(m_cmsDefaultUsers.getUserExport());
1594        if (!m_cmsDefaultUsers.getUserDeletedResource().equals(m_cmsDefaultUsers.getUserAdmin())) {
1595            // create <user-deletedresource> subnode
1596            defaultusersElement.addElement(N_USER_DELETEDRESOURCE).addText(m_cmsDefaultUsers.getUserDeletedResource());
1597        }
1598        // create <group-administrators> subnode
1599        defaultusersElement.addElement(N_GROUP_ADMINISTRATORS).addText(m_cmsDefaultUsers.getGroupAdministrators());
1600        // create <group-users> subnode
1601        defaultusersElement.addElement(N_GROUP_USERS).addText(m_cmsDefaultUsers.getGroupUsers());
1602        // create <group-guests> subnode
1603        defaultusersElement.addElement(N_GROUP_GUESTS).addText(m_cmsDefaultUsers.getGroupGuests());
1604
1605        // create <defaultcontentencoding> node
1606        systemElement.addElement(N_DEFAULT_CONTENT_ENCODING).addText(getDefaultContentEncoding());
1607
1608        // create <memorymonitor> node
1609        if (m_cmsMemoryMonitorConfiguration != null) {
1610            Element memorymonitorElement = systemElement.addElement(N_MEMORYMONITOR);
1611            if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(m_cmsMemoryMonitorConfiguration.getClassName())) {
1612                memorymonitorElement.addAttribute(A_CLASS, m_cmsMemoryMonitorConfiguration.getClassName());
1613            }
1614
1615            memorymonitorElement.addElement(N_MAXUSAGE_PERCENT).addText(
1616                String.valueOf(m_cmsMemoryMonitorConfiguration.getMaxUsagePercent()));
1617
1618            memorymonitorElement.addElement(N_LOG_INTERVAL).addText(
1619                String.valueOf(m_cmsMemoryMonitorConfiguration.getLogInterval()));
1620
1621            if (m_cmsMemoryMonitorConfiguration.getEmailInterval() >= 0) {
1622                memorymonitorElement.addElement(N_EMAIL_INTERVAL).addText(
1623                    String.valueOf(m_cmsMemoryMonitorConfiguration.getEmailInterval()));
1624            }
1625
1626            memorymonitorElement.addElement(N_WARNING_INTERVAL).addText(
1627                String.valueOf(m_cmsMemoryMonitorConfiguration.getWarningInterval()));
1628
1629            if (m_cmsMemoryMonitorConfiguration.getEmailSender() != null) {
1630                memorymonitorElement.addElement(N_EMAIL_SENDER).addText(
1631                    m_cmsMemoryMonitorConfiguration.getEmailSender());
1632            }
1633            List<String> emailReceiver = m_cmsMemoryMonitorConfiguration.getEmailReceiver();
1634            if (!emailReceiver.isEmpty()) {
1635                Element emailreceiverElement = memorymonitorElement.addElement(N_EMAIL_RECEIVER);
1636                Iterator<String> iter = emailReceiver.iterator();
1637                while (iter.hasNext()) {
1638                    emailreceiverElement.addElement(N_RECEIVER).addText(iter.next());
1639                }
1640            }
1641        }
1642
1643        // create <flexcache> node
1644        Element flexcacheElement = systemElement.addElement(N_FLEXCACHE);
1645        flexcacheElement.addElement(N_CACHE_ENABLED).addText(
1646            String.valueOf(m_cmsFlexCacheConfiguration.isCacheEnabled()));
1647        flexcacheElement.addElement(N_CACHE_OFFLINE).addText(
1648            String.valueOf(m_cmsFlexCacheConfiguration.isCacheOffline()));
1649        flexcacheElement.addElement(N_MAXCACHEBYTES).addText(
1650            String.valueOf(m_cmsFlexCacheConfiguration.getMaxCacheBytes()));
1651        flexcacheElement.addElement(N_AVGCACHEBYTES).addText(
1652            String.valueOf(m_cmsFlexCacheConfiguration.getAvgCacheBytes()));
1653        flexcacheElement.addElement(N_MAXENTRYBYTES).addText(
1654            String.valueOf(m_cmsFlexCacheConfiguration.getMaxEntryBytes()));
1655        flexcacheElement.addElement(N_MAXKEYS).addText(String.valueOf(m_cmsFlexCacheConfiguration.getMaxKeys()));
1656        if (m_cmsFlexCacheConfiguration.getDeviceSelectorConfiguration() != null) {
1657            Element flexcacheDeviceSelectorElement = flexcacheElement.addElement(N_DEVICESELECTOR);
1658            flexcacheDeviceSelectorElement.addAttribute(
1659                A_CLASS,
1660                m_cmsFlexCacheConfiguration.getDeviceSelectorConfiguration());
1661        }
1662
1663        // create <http-authentication> node
1664        Element httpAuthenticationElement = systemElement.addElement(N_HTTP_AUTHENTICATION);
1665        httpAuthenticationElement.addElement(N_BROWSER_BASED).setText(
1666            m_httpAuthenticationSettings.getConfigBrowserBasedAuthentication());
1667        if (m_httpAuthenticationSettings.getFormBasedHttpAuthenticationUri() != null) {
1668            httpAuthenticationElement.addElement(N_FORM_BASED).setText(
1669                m_httpAuthenticationSettings.getFormBasedHttpAuthenticationUri());
1670        }
1671
1672        // cache settings
1673        Element cacheElement = systemElement.addElement(N_RESULTCACHE);
1674        cacheElement.addElement(N_KEYGENERATOR).setText(m_cacheSettings.getCacheKeyGenerator());
1675        cacheElement.addElement(N_SIZE_USERS).setText(Integer.toString(m_cacheSettings.getUserCacheSize()));
1676        cacheElement.addElement(N_SIZE_GROUPS).setText(Integer.toString(m_cacheSettings.getGroupCacheSize()));
1677        if (m_cacheSettings.getConfiguredOrgUnitCacheSize() > -1) {
1678            cacheElement.addElement(N_SIZE_ORGUNITS).setText(
1679                Integer.toString(m_cacheSettings.getConfiguredOrgUnitCacheSize()));
1680        }
1681        cacheElement.addElement(N_SIZE_USERGROUPS).setText(Integer.toString(m_cacheSettings.getUserGroupsCacheSize()));
1682        cacheElement.addElement(N_SIZE_PROJECTS).setText(Integer.toString(m_cacheSettings.getProjectCacheSize()));
1683        if (m_cacheSettings.getConfiguredProjectResourcesCacheSize() > -1) {
1684            cacheElement.addElement(N_SIZE_PROJECTRESOURCES).setText(
1685                Integer.toString(m_cacheSettings.getConfiguredProjectResourcesCacheSize()));
1686        }
1687        cacheElement.addElement(N_SIZE_RESOURCES).setText(Integer.toString(m_cacheSettings.getResourceCacheSize()));
1688        if (m_cacheSettings.getConfiguredRolesCacheSize() > -1) {
1689            cacheElement.addElement(N_SIZE_ROLES).setText(
1690                Integer.toString(m_cacheSettings.getConfiguredRolesCacheSize()));
1691        }
1692        cacheElement.addElement(N_SIZE_RESOURCELISTS).setText(
1693            Integer.toString(m_cacheSettings.getResourcelistCacheSize()));
1694        cacheElement.addElement(N_SIZE_PROPERTIES).setText(Integer.toString(m_cacheSettings.getPropertyCacheSize()));
1695        if (m_cacheSettings.getConfiguredPropertyListsCacheSize() > -1) {
1696            cacheElement.addElement(N_SIZE_PROPERTYLISTS).setText(
1697                Integer.toString(m_cacheSettings.getConfiguredPropertyListsCacheSize()));
1698        }
1699        cacheElement.addElement(N_SIZE_ACLS).setText(Integer.toString(m_cacheSettings.getAclCacheSize()));
1700        cacheElement.addElement(N_SIZE_PERMISSIONS).setText(Integer.toString(m_cacheSettings.getPermissionCacheSize()));
1701
1702        // content notification settings
1703        if ((m_notificationTime != null) || (m_notificationProject != null)) {
1704            Element notificationElement = systemElement.addElement(N_CONTENT_NOTIFICATION);
1705            if (m_notificationTime != null) {
1706                notificationElement.addElement(N_NOTIFICATION_TIME).setText(m_notificationTime.toString());
1707            }
1708            if (m_notificationProject != null) {
1709                notificationElement.addElement(N_NOTIFICATION_PROJECT).setText(m_notificationProject);
1710            }
1711        }
1712
1713        // authorization handler
1714        if (m_authorizationHandler != null) {
1715            Element authorizationHandlerElem = systemElement.addElement(N_AUTHORIZATIONHANDLER);
1716            authorizationHandlerElem.addAttribute(A_CLASS, m_authorizationHandler);
1717        }
1718
1719        if (m_apiAuthorizations.size() > 0) {
1720            Element authsElement = systemElement.addElement(N_API_AUTHORIZATIONS);
1721            for (ApiAuthorizationConfig apiAuth : m_apiAuthorizations) {
1722                apiAuth.fillXml(authsElement.addElement(N_API_AUTHORIZATION));
1723            }
1724        }
1725
1726        Element encryptionElement = systemElement.addElement(N_ENCRYPTION);
1727        for (I_CmsTextEncryption encrypter : m_textEncryptions.values()) {
1728            Element textEncryption = encryptionElement.addElement(N_TEXT_ENCRYPTION);
1729            textEncryption.addAttribute(A_CLASS, encrypter.getClass().getName());
1730            textEncryption.addAttribute(A_NAME, encrypter.getName());
1731            CmsParameterConfiguration config = encrypter.getConfiguration();
1732            for (Map.Entry<String, String> entry : config.entrySet()) {
1733                textEncryption.addElement(N_PARAM).addAttribute(A_NAME, entry.getKey()).addText(entry.getValue());
1734            }
1735        }
1736
1737        // optional publish manager nodes
1738        if (m_publishManager != null) {
1739            Element pubHistElement = systemElement.addElement(N_PUBLISHMANAGER);
1740            pubHistElement.addElement(N_HISTORYSIZE).setText(String.valueOf(m_publishManager.getPublishHistorySize()));
1741            // optional nodes for publish queue
1742            pubHistElement.addElement(N_QUEUEPERSISTANCE).setText(
1743                String.valueOf(m_publishManager.isPublishQueuePersistanceEnabled()));
1744            pubHistElement.addElement(N_QUEUESHUTDOWNTIME).setText(
1745                String.valueOf(m_publishManager.getPublishQueueShutdowntime()));
1746            pubHistElement.addElement(N_AUTO_CLEANUP_HISTORY_ENTRIES).setText(
1747                String.valueOf(m_publishManager.isAutoCleanupHistoryEntries()));
1748        }
1749
1750        // session storage provider
1751        if (m_sessionStorageProvider != null) {
1752            Element sessionStorageProviderElem = systemElement.addElement(N_SESSION_STORAGEPROVIDER);
1753            sessionStorageProviderElem.addAttribute(A_CLASS, m_sessionStorageProvider);
1754        }
1755
1756        // permission handler
1757        if (m_permissionHandler != null) {
1758            Element permissionHandlerElem = systemElement.addElement(N_PERMISSIONHANDLER);
1759            permissionHandlerElem.addAttribute(A_CLASS, m_permissionHandler);
1760        }
1761
1762        // servlet container settings
1763        CmsServletContainerSettings servletContainerSettings = OpenCms.getSystemInfo().getServletContainerSettings();
1764        if (!servletContainerSettings.getMode().isNone()) {
1765            Element servletContainerSettingsElem = systemElement.addElement(N_SERVLETCONTAINERSETTINGS);
1766            servletContainerSettingsElem.addAttribute(A_MODE, servletContainerSettings.getMode().getMode());
1767            if (!servletContainerSettings.getMode().isAuto()) {
1768                servletContainerSettingsElem.addElement(N_PREVENTRESPONSEFLUSH).addText(
1769                    "" + servletContainerSettings.isPreventResponseFlush());
1770                servletContainerSettingsElem.addElement(N_RELEASETAGSAFTEREND).addText(
1771                    "" + servletContainerSettings.isReleaseTagsAfterEnd());
1772            }
1773            // always write back the error page attribute
1774            if (servletContainerSettings.getRequestErrorPageAttribute() != null) {
1775                servletContainerSettingsElem.addElement(N_REQUESTERRORPAGEATTRIBUTE).addText(
1776                    servletContainerSettings.getRequestErrorPageAttribute());
1777            }
1778        }
1779
1780        // ADE settings
1781        if ((getAdeConfiguration() != null) || (getAdeCacheSettings() != null) || !m_adeParameters.isEmpty()) {
1782            Element adeElem = systemElement.addElement(N_ADE);
1783            if (getAdeConfiguration() != null) {
1784                adeElem.addElement(N_CONFIGURATION).addAttribute(A_CLASS, getAdeConfiguration());
1785            }
1786            if (!m_adeParameters.isEmpty()) {
1787                Element paramsElement = adeElem.addElement(N_PARAMETERS);
1788                for (Map.Entry<String, String> entry : m_adeParameters.entrySet()) {
1789                    String name = entry.getKey();
1790                    String value = entry.getValue();
1791                    Element paramElement = paramsElement.addElement(N_PARAM);
1792                    paramElement.addAttribute(N_NAME, name);
1793                    paramElement.setText(value);
1794                }
1795            }
1796            if (getAdeCacheSettings() != null) {
1797                Element cacheElem = adeElem.addElement(N_ADE_CACHE);
1798                // container page cache
1799                Element cntPageCacheElem = cacheElem.addElement(N_CONTAINERPAGES);
1800                cntPageCacheElem.addAttribute(A_OFFLINE, "" + getAdeCacheSettings().getContainerPageOfflineSize());
1801                cntPageCacheElem.addAttribute(A_ONLINE, "" + getAdeCacheSettings().getContainerPageOnlineSize());
1802                // group-container cache
1803                Element groupContainerCacheElem = cacheElem.addElement(N_GROUPCONTAINERS);
1804                groupContainerCacheElem.addAttribute(
1805                    A_OFFLINE,
1806                    "" + getAdeCacheSettings().getGroupContainerOfflineSize());
1807                groupContainerCacheElem.addAttribute(
1808                    A_ONLINE,
1809                    "" + getAdeCacheSettings().getGroupContainerOnlineSize());
1810            }
1811        }
1812
1813        // subscription manager settings
1814        if (getSubscriptionManager() != null) {
1815            Element subscrManElem = systemElement.addElement(N_SUBSCRIPTIONMANAGER);
1816            subscrManElem.addAttribute(A_ENABLED, Boolean.toString(getSubscriptionManager().isEnabled()));
1817            subscrManElem.addAttribute(A_POOLNAME, getSubscriptionManager().getPoolName());
1818            subscrManElem.addAttribute(A_MAXVISITED, String.valueOf(getSubscriptionManager().getMaxVisitedCount()));
1819        }
1820
1821        I_CmsWorkflowManager workflowMan = getWorkflowManager();
1822        if (workflowMan != null) {
1823            Element workflowElem = systemElement.addElement(N_WORKFLOW);
1824            workflowElem.addAttribute(A_CLASS, workflowMan.getClass().getName());
1825            Map<String, String> parameters = workflowMan.getParameters();
1826            Element parametersElem = workflowElem.addElement(N_PARAMETERS);
1827            for (Map.Entry<String, String> entry : parameters.entrySet()) {
1828                Element paramElem = parametersElem.addElement(N_PARAM);
1829                paramElem.addAttribute(A_NAME, entry.getKey());
1830                paramElem.addText(entry.getValue());
1831            }
1832        }
1833
1834        if (m_userSessionMode != null) {
1835            Element userSessionElem = systemElement.addElement(N_USER_SESSION_MODE);
1836            userSessionElem.setText(m_userSessionMode.toString());
1837        }
1838
1839        if (m_credentialsResolverClass != null) {
1840            systemElement.addElement(N_CREDENTIALS_RESOLVER).setText(m_credentialsResolverClass);
1841        }
1842
1843        if (m_publishListRemoveMode != null) {
1844            systemElement.addElement(N_PUBLISH_LIST_REMOVE_MODE).addAttribute(A_MODE, m_publishListRemoveMode);
1845        }
1846
1847        if (m_detailPageHandler != null) {
1848            Element handlerElement = systemElement.addElement(N_DETAIL_PAGE_HANDLER).addAttribute(
1849                A_CLASS,
1850                m_detailPageHandler.getClass().getName());
1851            CmsParameterConfiguration config = m_detailPageHandler.getConfiguration();
1852            if (config != null) {
1853                for (String key : config.keySet()) {
1854                    handlerElement.addElement(N_PARAM).addAttribute(A_NAME, key).addText(config.get(key));
1855                }
1856            }
1857        }
1858
1859        if (m_restrictDetailContents != null) {
1860            Element restrictDetailContentsElem = systemElement.addElement(N_RESTRICT_DETAIL_CONTENTS);
1861            restrictDetailContentsElem.addText(m_restrictDetailContents);
1862        }
1863
1864        if (m_shellServerOptions != null) {
1865            systemElement.addElement(N_SHELL_SERVER).addAttribute(
1866                A_ENABLED,
1867                "" + m_shellServerOptions.isEnabled()).addAttribute(A_PORT, "" + m_shellServerOptions.getPort());
1868        }
1869        CmsLetsEncryptConfiguration.CONFIG_HELPER.generateXml(systemElement, m_letsEncryptConfig);
1870
1871        if (m_userDataRequestManager != null) {
1872            m_userDataRequestManager.appendToXml(systemElement);
1873        }
1874
1875        // return the system node
1876        return systemElement;
1877    }
1878
1879    /**
1880     * Returns the settings of the ADE cache.<p>
1881     *
1882     * @return the settings of the ADE cache
1883     */
1884    public CmsADECacheSettings getAdeCacheSettings() {
1885
1886        return m_adeCacheSettings;
1887    }
1888
1889    /**
1890     * Returns the ade configuration class name.<p>
1891     *
1892     * @return the ade configuration class name
1893     */
1894    public String getAdeConfiguration() {
1895
1896        return m_adeConfiguration;
1897    }
1898
1899    /**
1900     * Gets the ADE configuration parameters.<p>
1901     *
1902     * @return the ADE configuration parameters
1903     */
1904    public Map<String, String> getAdeParameters() {
1905
1906        return m_adeParameters;
1907    }
1908
1909    /**
1910     * Gets the map of API authorization handlers (with names as keys).
1911     *
1912     * @return the map of API authorization handlers
1913     */
1914    public Map<String, I_CmsApiAuthorizationHandler> getApiAuthorizations() {
1915
1916        return m_apiAuthorizationMap;
1917    }
1918
1919    /**
1920     * Returns an instance of the configured authorization handler.<p>
1921     *
1922     * @return an instance of the configured authorization handler
1923     */
1924    public I_CmsAuthorizationHandler getAuthorizationHandler() {
1925
1926        if (CmsStringUtil.isEmptyOrWhitespaceOnly(m_authorizationHandler)) {
1927            return new CmsDefaultAuthorizationHandler();
1928        }
1929        try {
1930            I_CmsAuthorizationHandler authorizationHandler = (I_CmsAuthorizationHandler)Class.forName(
1931                m_authorizationHandler).newInstance();
1932            if (LOG.isInfoEnabled()) {
1933                LOG.info(
1934                    Messages.get().getBundle().key(
1935                        Messages.INIT_AUTHORIZATION_HANDLER_CLASS_SUCCESS_1,
1936                        m_authorizationHandler));
1937            }
1938            authorizationHandler.setParameters(new HashMap<>(m_authHandlerParams));
1939            return authorizationHandler;
1940        } catch (Throwable t) {
1941            LOG.error(
1942                Messages.get().getBundle().key(
1943                    Messages.INIT_AUTHORIZATION_HANDLER_CLASS_INVALID_1,
1944                    m_authorizationHandler),
1945                t);
1946            return new CmsDefaultAuthorizationHandler();
1947        }
1948    }
1949
1950    /**
1951     * Returns the settings of the memory monitor.<p>
1952     *
1953     * @return the settings of the memory monitor
1954     */
1955    public CmsCacheSettings getCacheSettings() {
1956
1957        return m_cacheSettings;
1958    }
1959
1960    /**
1961     * Returns the default users.<p>
1962     *
1963     * @return the default users
1964     */
1965    public CmsDefaultUsers getCmsDefaultUsers() {
1966
1967        return m_cmsDefaultUsers;
1968    }
1969
1970    /**
1971     * Returns the flexCacheConfiguration.<p>
1972     *
1973     * @return the flexCacheConfiguration
1974     */
1975    public CmsFlexCacheConfiguration getCmsFlexCacheConfiguration() {
1976
1977        return m_cmsFlexCacheConfiguration;
1978    }
1979
1980    /**
1981     * Returns the memory monitor configuration.<p>
1982     *
1983     * @return the memory monitor configuration
1984     */
1985    public CmsMemoryMonitorConfiguration getCmsMemoryMonitorConfiguration() {
1986
1987        return m_cmsMemoryMonitorConfiguration;
1988    }
1989
1990    /**
1991     * Gets the credentials resolver.<p>
1992     *
1993     * @return the credentials resolver
1994     */
1995    public I_CmsCredentialsResolver getCredentialsResolver() {
1996
1997        if (m_credentialsResolver == null) {
1998            m_credentialsResolver = new CmsDefaultCredentialsResolver();
1999        }
2000        return m_credentialsResolver;
2001    }
2002
2003    /**
2004     * Gets the configured credentials resolver class name (null if no class is explicity configured).<p>
2005     *
2006     * @return the name of the configured credentials resolver class
2007     */
2008    public String getCredentialsResolverClass() {
2009
2010        return m_credentialsResolverClass;
2011    }
2012
2013    /**
2014     * Returns the defaultContentEncoding.<p>
2015     *
2016     * @return the defaultContentEncoding
2017     */
2018    public String getDefaultContentEncoding() {
2019
2020        return m_defaultContentEncoding;
2021    }
2022
2023    /**
2024     * Gets the detail page handler.
2025     *
2026     * @return the detail page handler
2027     */
2028    public I_CmsDetailPageHandler getDetailPageHandler() {
2029
2030        return m_detailPageHandler;
2031    }
2032
2033    /**
2034     * @see org.opencms.configuration.I_CmsXmlConfiguration#getDtdFilename()
2035     */
2036    public String getDtdFilename() {
2037
2038        return CONFIGURATION_DTD_NAME;
2039    }
2040
2041    /**
2042     * Returns the configured OpenCms event manager instance.<p>
2043     *
2044     * @return the configured OpenCms event manager instance
2045     */
2046    public CmsEventManager getEventManager() {
2047
2048        return m_eventManager;
2049    }
2050
2051    /**
2052     * Returns the maximum number of versions that are kept per resource in the VFS version history.<p>
2053     *
2054     * If the version history is disabled, this setting has no effect.<p>
2055     *
2056     * @return the maximum number of versions that are kept per resource
2057     *
2058     * @see #isHistoryEnabled()
2059     */
2060    public int getHistoryVersions() {
2061
2062        return m_historyVersions;
2063    }
2064
2065    /**
2066     * Returns the maximum number of versions that are kept in the VFS version history for deleted resources.<p>
2067     *
2068     * If the version history is disabled, this setting has no effect.<p>
2069     *
2070     * @return the maximum number of versions that are kept for deleted resources
2071     *
2072     * @see #isHistoryEnabled()
2073     */
2074    public int getHistoryVersionsAfterDeletion() {
2075
2076        return m_historyVersionsAfterDeletion;
2077    }
2078
2079    /**
2080     * Returns the HTTP authentication settings.<p>
2081     *
2082     * @return the HTTP authentication settings
2083     */
2084    public CmsHttpAuthenticationSettings getHttpAuthenticationSettings() {
2085
2086        return m_httpAuthenticationSettings;
2087    }
2088
2089    /**
2090     * Gets the LetsEncrypt configuration.<p>
2091     *
2092     * @return the LetsEncrypt configuration
2093     */
2094    public CmsLetsEncryptConfiguration getLetsEncryptConfig() {
2095
2096        return m_letsEncryptConfig;
2097    }
2098
2099    /**
2100     * Returns the configured locale manager for multi language support.<p>
2101     *
2102     * @return the configured locale manager for multi language support
2103     */
2104    public CmsLocaleManager getLocaleManager() {
2105
2106        return m_localeManager;
2107    }
2108
2109    /**
2110     * Returns the configured login manager.<p>
2111     *
2112     * @return the configured login manager
2113     */
2114    public CmsLoginManager getLoginManager() {
2115
2116        if (m_loginManager == null) {
2117            // no login manager configured, create default
2118            m_loginManager = new CmsLoginManager(
2119                CmsLoginManager.DISABLE_MINUTES_DEFAULT,
2120                CmsLoginManager.MAX_BAD_ATTEMPTS_DEFAULT,
2121                CmsLoginManager.ENABLE_SECURITY_DEFAULT,
2122                null,
2123                null,
2124                null,
2125                null,
2126                false,
2127                null);
2128        }
2129        return m_loginManager;
2130    }
2131
2132    /**
2133     * Returns the configured mail settings.<p>
2134     *
2135     * @return the configured mail settings
2136     */
2137    public CmsMailSettings getMailSettings() {
2138
2139        return m_mailSettings;
2140    }
2141
2142    /**
2143     * Returns the project in which timestamps for the content notification are read.<p>
2144     *
2145     * @return the project in which timestamps for the content notification are read
2146     */
2147    public String getNotificationProject() {
2148
2149        return m_notificationProject;
2150    }
2151
2152    /**
2153     * Returns the duration after which responsibles will be notified about out-dated content (in days).<p>
2154     *
2155     * @return the duration after which responsibles will be notified about out-dated content
2156     */
2157    public int getNotificationTime() {
2158
2159        if (m_notificationTime != null) {
2160            return m_notificationTime.intValue();
2161        } else {
2162            return -1;
2163        }
2164    }
2165
2166    /**
2167     * Returns the configured password handler.<p>
2168     *
2169     * @return the configured password handler
2170     */
2171    public I_CmsPasswordHandler getPasswordHandler() {
2172
2173        return m_passwordHandler;
2174    }
2175
2176    /**
2177     * Returns the permission Handler class name.<p>
2178     *
2179     * @return the permission Handler class name
2180     */
2181    public String getPermissionHandler() {
2182
2183        return m_permissionHandler;
2184    }
2185
2186    /**
2187     * Returns the configured publish list remove mode, or a default value if there is no configured value or an erroneous configured value.<p>
2188     *
2189     * @return the publish list remove mode
2190     */
2191    public CmsPublishManager.PublishListRemoveMode getPublishListRemoveMode() {
2192
2193        try {
2194            // trim preserves null
2195            return CmsPublishManager.PublishListRemoveMode.valueOf(StringUtils.trim(m_publishListRemoveMode));
2196        } catch (Exception e) {
2197            return CmsPublishManager.PublishListRemoveMode.allUsers;
2198        }
2199    }
2200
2201    /**
2202     * Returns the configured publish list remove mode as a string, or null if no publish list remove mode has been configured.<p>
2203     *
2204     * @return the publish list remove mode string from the configuration
2205     */
2206    public String getPublishListRemoveModeStr() {
2207
2208        return m_publishListRemoveMode;
2209    }
2210
2211    /**
2212     * Returns the configured publish manager.<p>
2213     *
2214     * @return the configured publish manager
2215     */
2216    public CmsPublishManager getPublishManager() {
2217
2218        if (m_publishManager == null) {
2219            // no publish manager configured, create default
2220            m_publishManager = new CmsPublishManager(
2221                CmsPublishManager.DEFAULT_HISTORY_SIZE,
2222                CmsPublishManager.DEFAULT_QUEUE_PERSISTANCE,
2223                CmsPublishManager.DEFAULT_QUEUE_SHUTDOWNTIME);
2224        }
2225        return m_publishManager;
2226    }
2227
2228    /**
2229     * Returns the list of instantiated request handler classes.<p>
2230     *
2231     * @return the list of instantiated request handler classes
2232     */
2233    public List<I_CmsRequestHandler> getRequestHandlers() {
2234
2235        return m_requestHandlers;
2236    }
2237
2238    /**
2239     * Returns the list of instantiated resource init handler classes.<p>
2240     *
2241     * @return the list of instantiated resource init handler classes
2242     */
2243    public List<I_CmsResourceInit> getResourceInitHandlers() {
2244
2245        return m_resourceInitHandlers;
2246    }
2247
2248    /**
2249     * Returns the runtime info factory instance.<p>
2250     *
2251     * @return the runtime info factory instance
2252     */
2253    public I_CmsDbContextFactory getRuntimeInfoFactory() {
2254
2255        return m_runtimeInfoFactory;
2256    }
2257
2258    /**
2259     * Returns the runtime Properties.<p>
2260     *
2261     * @return the runtime Properties
2262     */
2263    public Map<String, String> getRuntimeProperties() {
2264
2265        return m_runtimeProperties;
2266    }
2267
2268    /**
2269     * Returns an instance of the configured session storage provider.<p>
2270     *
2271     * @return an instance of the configured session storage provider
2272     */
2273    public I_CmsSessionStorageProvider getSessionStorageProvider() {
2274
2275        if (CmsStringUtil.isEmptyOrWhitespaceOnly(m_sessionStorageProvider)) {
2276            return new CmsDefaultSessionStorageProvider();
2277        }
2278        try {
2279            I_CmsSessionStorageProvider sessionCacheProvider = (I_CmsSessionStorageProvider)Class.forName(
2280                m_sessionStorageProvider).newInstance();
2281            if (CmsLog.INIT.isInfoEnabled()) {
2282                CmsLog.INIT.info(
2283                    Messages.get().getBundle().key(
2284                        Messages.INIT_SESSION_STORAGEPROVIDER_SUCCESS_1,
2285                        m_sessionStorageProvider));
2286            }
2287            return sessionCacheProvider;
2288        } catch (Throwable t) {
2289            LOG.error(
2290                Messages.get().getBundle().key(
2291                    Messages.LOG_INIT_SESSION_STORAGEPROVIDER_FAILURE_1,
2292                    m_sessionStorageProvider),
2293                t);
2294            return new CmsDefaultSessionStorageProvider();
2295        }
2296    }
2297
2298    /**
2299     * Returns the shell server options.<p>
2300     *
2301     * @return the shell server options
2302     */
2303    public CmsRemoteShellConfiguration getShellServerOptions() {
2304
2305        return m_shellServerOptions;
2306    }
2307
2308    /**
2309     * Returns the configured subscription manager.<p>
2310     *
2311     * @return the configured subscription manager
2312     */
2313    public CmsSubscriptionManager getSubscriptionManager() {
2314
2315        if (m_subscriptionManager == null) {
2316            // no subscription manager configured, create default
2317            m_subscriptionManager = new CmsSubscriptionManager();
2318        }
2319        return m_subscriptionManager;
2320    }
2321
2322    /**
2323     * Returns temporary file project id.<p>
2324     *
2325     * @return temporary file project id
2326     */
2327    public int getTempFileProjectId() {
2328
2329        return m_tempFileProjectId;
2330    }
2331
2332    /**
2333     * Gets the map of text encryptions.
2334     *
2335     * @return the map of text encryptions
2336     */
2337    public Map<String, I_CmsTextEncryption> getTextEncryptions() {
2338
2339        return Collections.unmodifiableMap(m_textEncryptions);
2340    }
2341
2342    /**
2343     * Gets the two-factor authentication configuration.
2344     *
2345     * @return the two-factor auth configuration
2346     */
2347    public CmsTwoFactorAuthenticationConfig getTwoFactorAuthenticationConfig() {
2348
2349        return m_twoFactorConfig;
2350    }
2351
2352    /**
2353     * Gets the user data request manager.
2354     *
2355     * @return the user data request manager
2356     */
2357    public CmsUserDataRequestManager getUserDataRequestManager() {
2358
2359        return m_userDataRequestManager;
2360    }
2361
2362    /**
2363     * Gets the user session mode.<p>
2364     *
2365     * @param useDefault if true, and no user session mode was configured, this will return the default value
2366     *
2367     * @return the user session mode
2368     */
2369    public UserSessionMode getUserSessionMode(boolean useDefault) {
2370
2371        if (m_userSessionMode != null) {
2372            return m_userSessionMode;
2373        } else if (useDefault) {
2374            return DEFAULT_USER_SESSION_MODE;
2375        } else {
2376            return null;
2377        }
2378    }
2379
2380    /**
2381     * Returns an instance of the configured validation handler.<p>
2382     *
2383     * @return an instance of the configured validation handler
2384     */
2385    public I_CmsValidationHandler getValidationHandler() {
2386
2387        if (CmsStringUtil.isEmptyOrWhitespaceOnly(m_validationHandler)) {
2388            return new CmsDefaultValidationHandler();
2389        }
2390        try {
2391            I_CmsValidationHandler validationHandler = (I_CmsValidationHandler)Class.forName(
2392                m_validationHandler).newInstance();
2393            if (LOG.isInfoEnabled()) {
2394                LOG.info(
2395                    Messages.get().getBundle().key(
2396                        Messages.INIT_VALIDATION_HANDLER_CLASS_SUCCESS_1,
2397                        m_validationHandler));
2398            }
2399            return validationHandler;
2400        } catch (Throwable t) {
2401            LOG.error(
2402                Messages.get().getBundle().key(Messages.INIT_VALIDATION_HANDLER_CLASS_INVALID_1, m_validationHandler),
2403                t);
2404            return new CmsDefaultValidationHandler();
2405        }
2406    }
2407
2408    /**
2409     * Gets the configured workflow manager instance.<p>
2410     *
2411     * @return the configured workflow manager instance.
2412     */
2413    public I_CmsWorkflowManager getWorkflowManager() {
2414
2415        return m_workflowManager;
2416    }
2417
2418    /**
2419     * Will be called when configuration of this object is finished.<p>
2420     */
2421    public void initializeFinished() {
2422
2423        if (CmsLog.INIT.isInfoEnabled()) {
2424            CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_SYSTEM_CONFIG_FINISHED_0));
2425        }
2426    }
2427
2428    /**
2429     * Returns if the VFS version history is enabled.<p>
2430     *
2431     * @return if the VFS version history is enabled
2432     */
2433    public boolean isHistoryEnabled() {
2434
2435        return m_historyEnabled;
2436    }
2437
2438    /**
2439     * Returns true if detail contents are restricted to detail pages from the same site.<p>
2440     *
2441     * @return true if detail contents are restricted to detail pages from the same site
2442     */
2443    public boolean isRestrictDetailContents() {
2444
2445        return (m_restrictDetailContents == null) || Boolean.parseBoolean(m_restrictDetailContents.trim());
2446
2447    }
2448
2449    /**
2450     * Sets the cache settings for ADE.<p>
2451     *
2452     * @param settings the cache settings for ADE
2453     */
2454    public void setAdeCacheSettings(CmsADECacheSettings settings) {
2455
2456        m_adeCacheSettings = settings;
2457    }
2458
2459    /**
2460     * Sets the ADE configuration class name.<p>
2461     *
2462     * @param className the class name to set
2463     */
2464    public void setAdeConfiguration(String className) {
2465
2466        m_adeConfiguration = className;
2467    }
2468
2469    /**
2470     * Sets the authorization handler.<p>
2471     *
2472     * @param authorizationHandlerClass the authorization handler class to set.
2473     */
2474    public void setAuthorizationHandler(String authorizationHandlerClass) {
2475
2476        m_authorizationHandler = authorizationHandlerClass;
2477    }
2478
2479    /**
2480     * Sets the settings of the memory monitor.<p>
2481     *
2482     * @param settings the settings of the memory monitor
2483     */
2484    public void setCacheSettings(CmsCacheSettings settings) {
2485
2486        m_cacheSettings = settings;
2487    }
2488
2489    /**
2490     * Sets the CmsDefaultUsers.<p>
2491     *
2492     * @param userAdmin the name of the default admin user
2493     * @param userGuest the name of the guest user
2494     * @param userExport the name of the export user
2495     * @param userDeletedResource the name of the deleted resource user, can be <code>null</code>
2496     * @param groupAdministrators the name of the administrators group
2497     * @param groupUsers the name of the users group
2498     * @param groupGuests the name of the guests group
2499     */
2500    public void setCmsDefaultUsers(
2501
2502        String userAdmin,
2503        String userGuest,
2504        String userExport,
2505        String userDeletedResource,
2506        String groupAdministrators,
2507        String groupUsers,
2508        String groupGuests) {
2509
2510        if (CmsLog.INIT.isInfoEnabled()) {
2511            CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_CHECKING_DEFAULT_USER_NAMES_0));
2512        }
2513        m_cmsDefaultUsers = new CmsDefaultUsers(
2514            userAdmin,
2515            userGuest,
2516            userExport,
2517            userDeletedResource,
2518            groupAdministrators,
2519            groupUsers,
2520            groupGuests);
2521
2522        if (CmsLog.INIT.isInfoEnabled()) {
2523            CmsLog.INIT.info(
2524                Messages.get().getBundle().key(Messages.INIT_ADMIN_USER_1, m_cmsDefaultUsers.getUserAdmin()));
2525            CmsLog.INIT.info(
2526                Messages.get().getBundle().key(Messages.INIT_GUEST_USER_1, m_cmsDefaultUsers.getUserGuest()));
2527            CmsLog.INIT.info(
2528                Messages.get().getBundle().key(Messages.INIT_EXPORT_USER_1, m_cmsDefaultUsers.getUserExport()));
2529            CmsLog.INIT.info(
2530                Messages.get().getBundle().key(
2531                    Messages.INIT_DELETED_RESOURCE_USER_1,
2532                    m_cmsDefaultUsers.getUserDeletedResource()));
2533            CmsLog.INIT.info(
2534                Messages.get().getBundle().key(
2535                    Messages.INIT_ADMIN_GROUP_1,
2536                    m_cmsDefaultUsers.getGroupAdministrators()));
2537            CmsLog.INIT.info(
2538                Messages.get().getBundle().key(Messages.INIT_USERS_GROUP_1, m_cmsDefaultUsers.getGroupUsers()));
2539            CmsLog.INIT.info(
2540                Messages.get().getBundle().key(Messages.INIT_GUESTS_GROUP_1, m_cmsDefaultUsers.getGroupGuests()));
2541            CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_DEFAULT_USER_NAMES_INITIALIZED_0));
2542        }
2543    }
2544
2545    /**
2546     * Sets the flexCacheConfiguration.<p>
2547     *
2548     * @param flexCacheConfiguration the flexCacheConfiguration to set
2549     */
2550    public void setCmsFlexCacheConfiguration(CmsFlexCacheConfiguration flexCacheConfiguration) {
2551
2552        m_cmsFlexCacheConfiguration = flexCacheConfiguration;
2553    }
2554
2555    /**
2556     * Sets the cmsMemoryMonitorConfiguration.<p>
2557     *
2558     * @param cmsMemoryMonitorConfiguration the cmsMemoryMonitorConfiguration to set
2559     */
2560    public void setCmsMemoryMonitorConfiguration(CmsMemoryMonitorConfiguration cmsMemoryMonitorConfiguration) {
2561
2562        m_cmsMemoryMonitorConfiguration = cmsMemoryMonitorConfiguration;
2563    }
2564
2565    /**
2566     * Sets the credentials resolver class.<p>
2567     *
2568     * @param className the name of the credentials resolver class
2569     *
2570     * @throws Exception if something goes wrong
2571     */
2572    public void setCredentialsResolver(String className) throws Exception {
2573
2574        String originalClassName = className;
2575        className = className.trim();
2576        Class<?> resolverClass = Class.forName(className);
2577        m_credentialsResolver = (I_CmsCredentialsResolver)(resolverClass.newInstance());
2578        m_credentialsResolverClass = originalClassName;
2579    }
2580
2581    /**
2582     * Sets the defaultContentEncoding.<p>
2583     *
2584     * @param defaultContentEncoding the defaultContentEncoding to set
2585     */
2586    public void setDefaultContentEncoding(String defaultContentEncoding) {
2587
2588        m_defaultContentEncoding = defaultContentEncoding;
2589    }
2590
2591    /**
2592     * Sets the detail page handler.
2593     *
2594     * @param handler the detail page handler
2595     */
2596    public void setDetailPageHandler(I_CmsDetailPageHandler handler) {
2597
2598        m_detailPageHandler = handler;
2599
2600    }
2601
2602    /**
2603     * VFS version history settings are set here.<p>
2604     *
2605     * @param historyEnabled if true the history is enabled
2606     * @param historyVersions the maximum number of versions that are kept per VFS resource
2607     * @param historyVersionsAfterDeletion the maximum number of versions for deleted resources
2608     */
2609    public void setHistorySettings(String historyEnabled, String historyVersions, String historyVersionsAfterDeletion) {
2610
2611        m_historyEnabled = Boolean.valueOf(historyEnabled).booleanValue();
2612        m_historyVersions = Integer.valueOf(historyVersions).intValue();
2613        m_historyVersionsAfterDeletion = Integer.valueOf(historyVersionsAfterDeletion).intValue();
2614        if (CmsLog.INIT.isInfoEnabled()) {
2615            CmsLog.INIT.info(
2616                Messages.get().getBundle().key(
2617                    Messages.INIT_HISTORY_SETTINGS_3,
2618                    Boolean.valueOf(m_historyEnabled),
2619                    new Integer(m_historyVersions),
2620                    new Integer(m_historyVersionsAfterDeletion)));
2621        }
2622    }
2623
2624    /**
2625     * Sets the HTTP authentication settings.<p>
2626     *
2627     * @param httpAuthenticationSettings the HTTP authentication settings to set
2628     */
2629    public void setHttpAuthenticationSettings(CmsHttpAuthenticationSettings httpAuthenticationSettings) {
2630
2631        m_httpAuthenticationSettings = httpAuthenticationSettings;
2632    }
2633
2634    /**
2635     * Sets the LetsEncrypt configuration.<p>
2636     *
2637     * @param letsEncryptConfig the LetsEncrypt configuration
2638     */
2639    public void setLetsEncryptConfig(CmsLetsEncryptConfiguration letsEncryptConfig) {
2640
2641        m_letsEncryptConfig = letsEncryptConfig;
2642    }
2643
2644    /**
2645     * Sets the locale manager for multi language support.<p>
2646     *
2647     * @param localeManager the locale manager to set
2648     */
2649    public void setLocaleManager(CmsLocaleManager localeManager) {
2650
2651        m_localeManager = localeManager;
2652        if (CmsLog.INIT.isInfoEnabled()) {
2653            CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_CONFIG_I18N_FINISHED_0));
2654        }
2655    }
2656
2657    /**
2658     * Sets the configured login manager.<p>
2659     *
2660     * @param maxBadAttemptsStr the number of allowed bad login attempts
2661     * @param disableMinutesStr the time an account gets locked if to many bad logins are attempted
2662     * @param enableSecurityStr flag to determine if the security option should be enabled on the login dialog
2663     * @param tokenLifetime the token lifetime
2664     * @param maxInactive maximum time since last login before CmsLockInactiveAccountsJob locks an account
2665     * @param passwordChangeInterval the password change interval
2666     * @param userDataCheckInterval the user data check interval
2667     * @param logoutUri the alternative logout handler URI (may be null)
2668     */
2669    public void setLoginManager(
2670        String disableMinutesStr,
2671        String maxBadAttemptsStr,
2672        String enableSecurityStr,
2673        String tokenLifetime,
2674        String maxInactive,
2675        String passwordChangeInterval,
2676        String userDataCheckInterval,
2677        String requireOrgUnitStr,
2678        String logoutUri) {
2679
2680        int disableMinutes;
2681        try {
2682            disableMinutes = Integer.valueOf(disableMinutesStr).intValue();
2683        } catch (NumberFormatException e) {
2684            disableMinutes = CmsLoginManager.DISABLE_MINUTES_DEFAULT;
2685        }
2686        int maxBadAttempts;
2687        try {
2688            maxBadAttempts = Integer.valueOf(maxBadAttemptsStr).intValue();
2689        } catch (NumberFormatException e) {
2690            maxBadAttempts = CmsLoginManager.MAX_BAD_ATTEMPTS_DEFAULT;
2691        }
2692        boolean enableSecurity = Boolean.valueOf(enableSecurityStr).booleanValue();
2693        boolean requireOrgUnit = Boolean.valueOf(requireOrgUnitStr).booleanValue();
2694        m_loginManager = new CmsLoginManager(
2695            disableMinutes,
2696            maxBadAttempts,
2697            enableSecurity,
2698            tokenLifetime,
2699            maxInactive,
2700            passwordChangeInterval,
2701            userDataCheckInterval,
2702            requireOrgUnit,
2703            logoutUri);
2704        if (CmsLog.INIT.isInfoEnabled()) {
2705            CmsLog.INIT.info(
2706                Messages.get().getBundle().key(
2707                    Messages.INIT_LOGINMANAGER_3,
2708                    new Integer(disableMinutes),
2709                    new Integer(maxBadAttempts),
2710                    new Boolean(enableSecurity)));
2711        }
2712    }
2713
2714    /**
2715     * Sets the mail settings.<p>
2716     *
2717     * @param mailSettings the mail settings to set.
2718     */
2719    public void setMailSettings(CmsMailSettings mailSettings) {
2720
2721        m_mailSettings = mailSettings;
2722        if (LOG.isDebugEnabled()) {
2723            LOG.debug(Messages.get().getBundle().key(Messages.LOG_MAIL_SETTINGS_1, mailSettings));
2724        }
2725    }
2726
2727    /**
2728     * Sets the project in which timestamps for the content notification are read.<p>
2729     *
2730     * @param notificationProject the project in which timestamps for the content notification are read
2731     */
2732    public void setNotificationProject(String notificationProject) {
2733
2734        m_notificationProject = notificationProject;
2735        if (CmsLog.INIT.isInfoEnabled()) {
2736            CmsLog.INIT.info(
2737                Messages.get().getBundle().key(Messages.INIT_NOTIFICATION_PROJECT_1, m_notificationProject));
2738        }
2739    }
2740
2741    /**
2742     * Sets the duration after which responsibles will be notified about out-dated content (in days).<p>
2743     *
2744     * @param notificationTime the duration after which responsibles will be notified about out-dated content
2745     */
2746    public void setNotificationTime(String notificationTime) {
2747
2748        try {
2749            m_notificationTime = new Integer(notificationTime);
2750        } catch (Throwable t) {
2751            m_notificationTime = new Integer(-1);
2752        }
2753        if (CmsLog.INIT.isInfoEnabled()) {
2754            CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_NOTIFICATION_TIME_1, m_notificationTime));
2755        }
2756    }
2757
2758    /**
2759     * Sets the password handler class.<p>
2760     *
2761     * @param passwordHandler the password handler to set
2762     */
2763    public void setPasswordHandler(I_CmsPasswordHandler passwordHandler) {
2764
2765        m_passwordHandler = passwordHandler;
2766        if (CmsLog.INIT.isInfoEnabled()) {
2767            CmsLog.INIT.info(
2768                Messages.get().getBundle().key(
2769                    Messages.INIT_PWD_HANDLER_SUCCESS_1,
2770                    passwordHandler.getClass().getName()));
2771        }
2772    }
2773
2774    /**
2775     * Sets the permission Handler class name.<p>
2776     *
2777     * @param permissionHandler the class name to set
2778     */
2779    public void setPermissionHandler(String permissionHandler) {
2780
2781        m_permissionHandler = permissionHandler;
2782    }
2783
2784    /**
2785     * Sets the servlet container specific setting.<p>
2786     *
2787     * @param configValue the configuration value
2788     */
2789    public void setPreventResponseFlush(String configValue) {
2790
2791        OpenCms.getSystemInfo().getServletContainerSettings().setPreventResponseFlush(
2792            Boolean.valueOf(configValue).booleanValue());
2793    }
2794
2795    /**
2796     * Sets the publish list remove mode.<p>
2797     *
2798     * @param removeMode the publish list remove mode
2799     */
2800    public void setPublishListRemoveMode(String removeMode) {
2801
2802        m_publishListRemoveMode = removeMode;
2803    }
2804
2805    /**
2806     * Sets the publish manager.<p>
2807     *
2808     * @param publishManager the publish manager
2809     */
2810    public void setPublishManager(CmsPublishManager publishManager) {
2811
2812        m_publishManager = publishManager;
2813    }
2814
2815    /**
2816     * Sets the servlet container specific setting.<p>
2817     *
2818     * @param configValue the configuration value
2819     */
2820    public void setReleaseTagsAfterEnd(String configValue) {
2821
2822        OpenCms.getSystemInfo().getServletContainerSettings().setReleaseTagsAfterEnd(
2823            Boolean.valueOf(configValue).booleanValue());
2824    }
2825
2826    /**
2827     * Sets the servlet container specific setting.<p>
2828     *
2829     * @param configValue the configuration value
2830     */
2831    public void setRequestErrorPageAttribute(String configValue) {
2832
2833        OpenCms.getSystemInfo().getServletContainerSettings().setRequestErrorPageAttribute(configValue);
2834    }
2835
2836    /**
2837     * Sets the 'restrict detail contents' option.<p>
2838     *
2839     * @param restrictDetailContents the value of the option
2840     */
2841    public void setRestrictDetailContents(String restrictDetailContents) {
2842
2843        m_restrictDetailContents = restrictDetailContents;
2844    }
2845
2846    /**
2847     * Sets the runtime info factory.<p>
2848     *
2849     * @param className the class name of the configured runtime info factory
2850     */
2851    public void setRuntimeInfoFactory(String className) {
2852
2853        Object objectInstance;
2854
2855        try {
2856            objectInstance = Class.forName(className).newInstance();
2857        } catch (Throwable t) {
2858            LOG.error(Messages.get().getBundle().key(Messages.LOG_CLASS_INIT_FAILURE_1, className), t);
2859            return;
2860        }
2861
2862        if (objectInstance instanceof I_CmsDbContextFactory) {
2863            m_runtimeInfoFactory = (I_CmsDbContextFactory)objectInstance;
2864            if (CmsLog.INIT.isInfoEnabled()) {
2865                CmsLog.INIT.info(
2866                    Messages.get().getBundle().key(Messages.INIT_RUNTIME_INFO_FACTORY_SUCCESS_1, className));
2867            }
2868        } else {
2869            if (CmsLog.INIT.isFatalEnabled()) {
2870                CmsLog.INIT.fatal(
2871                    Messages.get().getBundle().key(Messages.INIT_RUNTIME_INFO_FACTORY_FAILURE_1, className));
2872            }
2873        }
2874
2875    }
2876
2877    /**
2878     * Sets the servlet container settings configuration mode.<p>
2879     *
2880     * @param configValue the value to set
2881     */
2882    public void setServletContainerSettingsMode(String configValue) {
2883
2884        OpenCms.getSystemInfo().getServletContainerSettings().setMode(configValue);
2885    }
2886
2887    /**
2888     * Sets the session storage provider.<p>
2889     *
2890     * @param sessionStorageProviderClass the session storage provider class to set.
2891     */
2892    public void setSessionStorageProvider(String sessionStorageProviderClass) {
2893
2894        m_sessionStorageProvider = sessionStorageProviderClass;
2895    }
2896
2897    /**
2898     * Sets the shell server options from the confriguration.<p>
2899     *
2900     * @param enabled the value of the 'enabled' attribute
2901     * @param portStr the value of the 'port' attribute
2902     */
2903    public void setShellServerOptions(String enabled, String portStr) {
2904
2905        int port;
2906        try {
2907            port = Integer.parseInt(portStr);
2908        } catch (NumberFormatException e) {
2909            port = CmsRemoteShellConstants.DEFAULT_PORT;
2910        }
2911        m_shellServerOptions = new CmsRemoteShellConfiguration(Boolean.parseBoolean(enabled), port);
2912
2913    }
2914
2915    /**
2916     * Sets the subscription manager.<p>
2917     *
2918     * @param subscriptionManager the subscription manager
2919     */
2920    public void setSubscriptionManager(CmsSubscriptionManager subscriptionManager) {
2921
2922        m_subscriptionManager = subscriptionManager;
2923    }
2924
2925    /**
2926     * Sets the temporary file project id.<p>
2927     *
2928     * @param tempFileProjectId the temporary file project id to set
2929     */
2930    public void setTempFileProjectId(String tempFileProjectId) {
2931
2932        try {
2933            m_tempFileProjectId = Integer.valueOf(tempFileProjectId).intValue();
2934        } catch (Throwable t) {
2935            m_tempFileProjectId = -1;
2936        }
2937        if (CmsLog.INIT.isInfoEnabled()) {
2938            CmsLog.INIT.info(
2939                Messages.get().getBundle().key(Messages.INIT_TEMPFILE_PROJECT_ID_1, new Integer(m_tempFileProjectId)));
2940        }
2941    }
2942
2943    /**
2944     * Sets the user data request manager.
2945     *
2946     * @param manager the user data request manager
2947     */
2948    public void setUserDataRequestManager(CmsUserDataRequestManager manager) {
2949
2950        m_userDataRequestManager = manager;
2951
2952    }
2953
2954    /**
2955     * Sets the user session mode.<p>
2956     *
2957     * @param userSessionMode the user session mode
2958     */
2959    public void setUserSessionMode(String userSessionMode) {
2960
2961        if ((userSessionMode == null) || (m_userSessionMode != null)) {
2962            throw new IllegalStateException("Can't set user session mode to " + userSessionMode);
2963        }
2964        m_userSessionMode = UserSessionMode.valueOf(userSessionMode);
2965    }
2966
2967    /**
2968     * Sets if the SAX parser implementation classes should be stored in system properties
2969     * to improve the unmarshalling performance.<p>
2970     *
2971     * @param enabled <code>true</code> to store SAX parser implementation classes in system properties
2972     */
2973    public void setUseSaxImplSystemProperties(String enabled) {
2974
2975        m_saxImplProperties = Boolean.parseBoolean(enabled);
2976    }
2977
2978    /**
2979     * Sets the validation handler.<p>
2980     *
2981     * @param validationHandlerClass the validation handler class to set.
2982     */
2983    public void setValidationHandler(String validationHandlerClass) {
2984
2985        m_validationHandler = validationHandlerClass;
2986    }
2987
2988    /**
2989     * Sets the configured workflow manager instance.<p>
2990     *
2991     * @param workflowManager the configured workflow manager
2992     */
2993    public void setWorkflowManager(I_CmsWorkflowManager workflowManager) {
2994
2995        m_workflowManager = workflowManager;
2996    }
2997
2998    /**
2999     * Returns whether the SAX parser implementation classes should be stored in system properties
3000     * to improve the unmarshalling performance.<p>
3001     *
3002     * @return <code>true</code> if the SAX parser implementation classes should be stored in system properties
3003     */
3004    public boolean useSaxImplSystemProperties() {
3005
3006        return m_saxImplProperties;
3007    }
3008
3009    /**
3010     * Adds a new authorization configuration.
3011     *
3012     * @param config the authorization configuration to add
3013     */
3014    protected void addApiAuthorization(ApiAuthorizationConfig config) {
3015
3016        m_apiAuthorizations.add(config);
3017        try {
3018            Class<?> cls = Class.forName(config.getClassName(), false, getClass().getClassLoader());
3019            I_CmsApiAuthorizationHandler handler = (I_CmsApiAuthorizationHandler)(cls.getDeclaredConstructor().newInstance());
3020            handler.setParameters(config.getParams());
3021            m_apiAuthorizationMap.put(config.getName(), handler);
3022        } catch (Exception e) {
3023            LOG.error(e.getLocalizedMessage(), e);
3024        }
3025    }
3026
3027    /**
3028     * @see org.opencms.configuration.A_CmsXmlConfiguration#initMembers()
3029     */
3030    @Override
3031    protected void initMembers() {
3032
3033        setXmlFileName(DEFAULT_XML_FILE_NAME);
3034        m_historyEnabled = true;
3035        m_historyVersions = 10;
3036        m_historyVersionsAfterDeletion = -1; // use m_historyVersions instead
3037        m_resourceInitHandlers = new ArrayList<I_CmsResourceInit>();
3038        m_requestHandlers = new ArrayList<I_CmsRequestHandler>();
3039        m_runtimeProperties = new HashMap<String, String>();
3040        m_eventManager = new CmsEventManager();
3041        if (CmsLog.INIT.isInfoEnabled()) {
3042            CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_SYSTEM_CONFIG_INIT_0));
3043        }
3044    }
3045
3046}