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