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