xref: /OpenGrok/opengrok-indexer/src/main/java/org/opengrok/indexer/configuration/Configuration.java (revision 61dce4cb338e604a2107e3407eacd2a8999c2eef)
1b5840353SAdam Hornáček /*
2b5840353SAdam Hornáček  * CDDL HEADER START
3b5840353SAdam Hornáček  *
4b5840353SAdam Hornáček  * The contents of this file are subject to the terms of the
5b5840353SAdam Hornáček  * Common Development and Distribution License (the "License").
6b5840353SAdam Hornáček  * You may not use this file except in compliance with the License.
7b5840353SAdam Hornáček  *
8b5840353SAdam Hornáček  * See LICENSE.txt included in this distribution for the specific
9b5840353SAdam Hornáček  * language governing permissions and limitations under the License.
10b5840353SAdam Hornáček  *
11b5840353SAdam Hornáček  * When distributing Covered Code, include this CDDL HEADER in each
12b5840353SAdam Hornáček  * file and include the License file at LICENSE.txt.
13b5840353SAdam Hornáček  * If applicable, add the following below this CDDL HEADER, with the
14b5840353SAdam Hornáček  * fields enclosed by brackets "[]" replaced with your own identifying
15b5840353SAdam Hornáček  * information: Portions Copyright [yyyy] [name of copyright owner]
16b5840353SAdam Hornáček  *
17b5840353SAdam Hornáček  * CDDL HEADER END
18b5840353SAdam Hornáček  */
19b5840353SAdam Hornáček 
20b5840353SAdam Hornáček /*
218e5e1036SVladimir Kotal  * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.
225d9f3aa0SAdam Hornáček  * Portions Copyright (c) 2017, 2020, Chris Fraire <cfraire@me.com>.
2368c19b4cSAlexandrSergei4  * Portions Copyright (c) 2020, Aleksandr Kirillov <alexkirillovsamara@gmail.com>.
24b5840353SAdam Hornáček  */
259805b761SAdam Hornáček package org.opengrok.indexer.configuration;
26b5840353SAdam Hornáček 
27b5840353SAdam Hornáček import java.beans.ExceptionListener;
28b5840353SAdam Hornáček import java.beans.XMLDecoder;
29b5840353SAdam Hornáček import java.beans.XMLEncoder;
30b5840353SAdam Hornáček import java.io.BufferedInputStream;
31b5840353SAdam Hornáček import java.io.BufferedOutputStream;
32b5840353SAdam Hornáček import java.io.ByteArrayInputStream;
33b5840353SAdam Hornáček import java.io.ByteArrayOutputStream;
34b5840353SAdam Hornáček import java.io.File;
35b5840353SAdam Hornáček import java.io.FileInputStream;
36b5840353SAdam Hornáček import java.io.FileOutputStream;
37b5840353SAdam Hornáček import java.io.IOException;
38b5840353SAdam Hornáček import java.io.InputStream;
39b5840353SAdam Hornáček import java.io.OutputStream;
40f197cd77SVladimir Kotal import java.nio.file.Path;
41f197cd77SVladimir Kotal import java.nio.file.Paths;
42b5840353SAdam Hornáček import java.util.ArrayList;
43b5840353SAdam Hornáček import java.util.Collections;
44b5840353SAdam Hornáček import java.util.HashMap;
45b5840353SAdam Hornáček import java.util.HashSet;
46b5840353SAdam Hornáček import java.util.LinkedList;
47b5840353SAdam Hornáček import java.util.List;
48b5840353SAdam Hornáček import java.util.Map;
49b5840353SAdam Hornáček import java.util.Set;
50b5840353SAdam Hornáček import java.util.TreeSet;
51b5840353SAdam Hornáček import java.util.concurrent.ConcurrentHashMap;
52b5840353SAdam Hornáček import java.util.logging.Level;
53b5840353SAdam Hornáček import java.util.logging.Logger;
54b5840353SAdam Hornáček import java.util.regex.PatternSyntaxException;
55fcbdc96bSChris Fraire import java.util.stream.Collectors;
56fcbdc96bSChris Fraire 
579805b761SAdam Hornáček import org.opengrok.indexer.authorization.AuthControlFlag;
589805b761SAdam Hornáček import org.opengrok.indexer.authorization.AuthorizationStack;
599805b761SAdam Hornáček import org.opengrok.indexer.history.RepositoryInfo;
609805b761SAdam Hornáček import org.opengrok.indexer.logger.LoggerFactory;
61b5840353SAdam Hornáček 
6264819763SVladimir Kotal import static org.opengrok.indexer.configuration.PatternUtil.compilePattern;
6364819763SVladimir Kotal 
642ffbb0cfSVladimir Kotal 
65b5840353SAdam Hornáček /**
662ffbb0cfSVladimir Kotal  * Placeholder class for all configuration variables. Due to the multi-threaded
67b5840353SAdam Hornáček  * nature of the web application, each thread will use the same instance of the
68b5840353SAdam Hornáček  * configuration object for each page request. Class and methods should have
69b5840353SAdam Hornáček  * package scope, but that didn't work with the XMLDecoder/XMLEncoder.
7029816c3bSChris Fraire  * <p>
7129816c3bSChris Fraire  * This should be as close to a
7229816c3bSChris Fraire  * <a href="https://en.wikipedia.org/wiki/Plain_old_Java_object">POJO</a> as
7329816c3bSChris Fraire  * possible.
74b5840353SAdam Hornáček  */
75b5840353SAdam Hornáček public final class Configuration {
76b5840353SAdam Hornáček 
77b5840353SAdam Hornáček     private static final Logger LOGGER = LoggerFactory.getLogger(Configuration.class);
78b5840353SAdam Hornáček     public static final String PLUGIN_DIRECTORY_DEFAULT = "plugins";
79b5840353SAdam Hornáček 
80b5840353SAdam Hornáček     /**
81b5840353SAdam Hornáček      * Error string for negative numbers (could be int, double, long, ...).
82b5840353SAdam Hornáček      * First argument is the name of the property, second argument is the actual
83b5840353SAdam Hornáček      * value.
84b5840353SAdam Hornáček      */
85b5840353SAdam Hornáček     private static final String NEGATIVE_NUMBER_ERROR = "Invalid value for \"%s\" - \"%s\". Expected value greater or equal than 0";
86b5840353SAdam Hornáček     /**
87b5840353SAdam Hornáček      * Error string for non-positive numbers (could be int, double, long, ...).
88b5840353SAdam Hornáček      * First argument is the name of the property, second argument is the actual
89b5840353SAdam Hornáček      * value.
90b5840353SAdam Hornáček      */
91b5840353SAdam Hornáček     private static final String NONPOSITIVE_NUMBER_ERROR =
92b5840353SAdam Hornáček         "Invalid value for \"%s\" - \"%s\". Expected value greater than 0";
93b5840353SAdam Hornáček 
942ffbb0cfSVladimir Kotal     /**
952ffbb0cfSVladimir Kotal      * Path to {@code ctags} binary.
962ffbb0cfSVladimir Kotal      */
97b5840353SAdam Hornáček     private String ctags;
98e829566cSChris Fraire     private boolean webappCtags;
99b5840353SAdam Hornáček 
100b5840353SAdam Hornáček     /**
101b5840353SAdam Hornáček      * A defined value to specify the mandoc binary or else null so that mandoc
102b5840353SAdam Hornáček      * will be cross-referenced using {@code PlainXref}.
103b5840353SAdam Hornáček      */
104b5840353SAdam Hornáček     private String mandoc;
105b5840353SAdam Hornáček 
106b5840353SAdam Hornáček     /**
107b5840353SAdam Hornáček      * Should the history log be cached?
108b5840353SAdam Hornáček      */
109b5840353SAdam Hornáček     private boolean historyCache;
110b5840353SAdam Hornáček     /**
111b5840353SAdam Hornáček      * flag to generate history. This is bigger hammer than @{code historyCache}
112b5840353SAdam Hornáček      * above. If set to false, no history query will be ever made and the webapp
113b5840353SAdam Hornáček      * will not display any history related links/allow any history queries.
114b5840353SAdam Hornáček      */
115b5840353SAdam Hornáček     private boolean historyEnabled;
116b5840353SAdam Hornáček     /**
117b5840353SAdam Hornáček      * maximum number of messages in webapp.
118b5840353SAdam Hornáček      */
119b5840353SAdam Hornáček     private int messageLimit;
120b5840353SAdam Hornáček     /**
121b5840353SAdam Hornáček      * Directory with authorization plug-ins. Default value is
122b5840353SAdam Hornáček      * {@code dataRoot/../plugins} (can be {@code /var/opengrok/plugins} if dataRoot is
123b5840353SAdam Hornáček      * {@code /var/opengrok/data}).
124b5840353SAdam Hornáček      */
125b5840353SAdam Hornáček     private String pluginDirectory;
126b5840353SAdam Hornáček     /**
127b5840353SAdam Hornáček      * Enable watching the plug-in directory for changes in real time. Suitable
128b5840353SAdam Hornáček      * for development.
129b5840353SAdam Hornáček      */
130b5840353SAdam Hornáček     private boolean authorizationWatchdogEnabled;
131b5840353SAdam Hornáček     private AuthorizationStack pluginStack;
132b5840353SAdam Hornáček     private Map<String, Project> projects; // project name -> Project
133b5840353SAdam Hornáček     private Set<Group> groups;
134b5840353SAdam Hornáček     private String sourceRoot;
135b5840353SAdam Hornáček     private String dataRoot;
136a03922c4SAdam Hornáček     /**
137ff44f24aSAdam Hornáček      * Directory with include files for web application (header, footer, etc.).
138a03922c4SAdam Hornáček      */
139a03922c4SAdam Hornáček     private String includeRoot;
140b5840353SAdam Hornáček     private List<RepositoryInfo> repositories;
1417d060254SAdam Hornáček 
142b5840353SAdam Hornáček     private boolean generateHtml;
143b5840353SAdam Hornáček     /**
144b5840353SAdam Hornáček      * Default projects will be used, when no project is selected and no project
145b5840353SAdam Hornáček      * is in cookie, so basically only the first time a page is opened,
146b5840353SAdam Hornáček      * or when web cookies are cleared.
147b5840353SAdam Hornáček      */
148b5840353SAdam Hornáček     private Set<Project> defaultProjects;
149b5840353SAdam Hornáček     /**
150b5840353SAdam Hornáček      * Default size of memory to be used for flushing of Lucene docs per thread.
151b5840353SAdam Hornáček      * Lucene 4.x uses 16MB and 8 threads, so below is a nice tunable.
152b5840353SAdam Hornáček      */
153b5840353SAdam Hornáček     private double ramBufferSize;
154b5840353SAdam Hornáček     /**
155b5840353SAdam Hornáček      * If below is set, then we count how many files per project we need to
156b5840353SAdam Hornáček      * process and print percentage of completion per project.
157b5840353SAdam Hornáček      */
158b5840353SAdam Hornáček     private boolean printProgress;
159b5840353SAdam Hornáček     private boolean allowLeadingWildcard;
160b5840353SAdam Hornáček     private IgnoredNames ignoredNames;
161b5840353SAdam Hornáček     private Filter includedNames;
162b5840353SAdam Hornáček     private String userPage;
163b5840353SAdam Hornáček     private String userPageSuffix;
164b5840353SAdam Hornáček     private String bugPage;
165b5840353SAdam Hornáček     private String bugPattern;
166b5840353SAdam Hornáček     private String reviewPage;
167b5840353SAdam Hornáček     private String reviewPattern;
168b5840353SAdam Hornáček     private String webappLAF;
169b5840353SAdam Hornáček     private RemoteSCM remoteScmSupported;
170b5840353SAdam Hornáček     private boolean optimizeDatabase;
17129816c3bSChris Fraire     private boolean quickContextScan;
1727d060254SAdam Hornáček 
173b5840353SAdam Hornáček     private LuceneLockName luceneLocking = LuceneLockName.OFF;
174b5840353SAdam Hornáček     private boolean compressXref;
175b5840353SAdam Hornáček     private boolean indexVersionedFilesOnly;
176b5840353SAdam Hornáček     private int indexingParallelism;
1772123e367SVladimir Kotal     private int repositoryInvalidationParallelism;
178b5840353SAdam Hornáček     private int historyParallelism;
179dc607a84SVladimir Kotal     private int historyFileParallelism;
180b5840353SAdam Hornáček     private boolean tagsEnabled;
181b5840353SAdam Hornáček     private int hitsPerPage;
182b5840353SAdam Hornáček     private int cachePages;
183b5840353SAdam Hornáček     private short contextLimit; // initialized non-zero in ctor
184b5840353SAdam Hornáček     private short contextSurround;
185b5840353SAdam Hornáček     private boolean lastEditedDisplayMode;
186b5840353SAdam Hornáček     private String CTagsExtraOptionsFile;
187b5840353SAdam Hornáček     private int scanningDepth;
1882402fe1cSChris Fraire     private int nestingMaximum;
189b5840353SAdam Hornáček     private Set<String> allowedSymlinks;
1900e0ac58dSChris Fraire     private Set<String> canonicalRoots;
191b5840353SAdam Hornáček     private boolean obfuscatingEMailAddresses;
192b5840353SAdam Hornáček     private boolean chattyStatusPage;
193b5840353SAdam Hornáček     private final Map<String, String> cmds;  // repository type -> command
194b5840353SAdam Hornáček     private int tabSize;
195a904b83aSVladimir Kotal     private int indexerCommandTimeout; // in seconds
196b5840353SAdam Hornáček     private int interactiveCommandTimeout; // in seconds
197a904b83aSVladimir Kotal     private int webappStartCommandTimeout; // in seconds
198a904b83aSVladimir Kotal     private int restfulCommandTimeout; // in seconds
199b124dbe6SVladimir Kotal     private long ctagsTimeout; // in seconds
200e92cec67SVladimir Kotal     private long xrefTimeout; // in seconds
201b5840353SAdam Hornáček     private boolean scopesEnabled;
202b5840353SAdam Hornáček     private boolean projectsEnabled;
203b5840353SAdam Hornáček     private boolean foldingEnabled;
204b5840353SAdam Hornáček     /*
205b5840353SAdam Hornáček      * Set to false if we want to disable fetching history of individual files
206b5840353SAdam Hornáček      * (by running appropriate SCM command) when the history is not found
207b5840353SAdam Hornáček      * in history cache for repositories capable of fetching history for
208ec5b57ecSVladimir Kotal      * directories.
209b5840353SAdam Hornáček      */
210b5840353SAdam Hornáček     private boolean fetchHistoryWhenNotInCache;
211b5840353SAdam Hornáček     /*
212b5840353SAdam Hornáček      * Set to false to disable extended handling of history of files across
213b5840353SAdam Hornáček      * renames, i.e. support getting diffs of revisions across renames
214b5840353SAdam Hornáček      * for capable repositories.
215b5840353SAdam Hornáček      */
216b5840353SAdam Hornáček     private boolean handleHistoryOfRenamedFiles;
217b5840353SAdam Hornáček 
2188e5e1036SVladimir Kotal     private boolean mergeCommitsEnabled;
2198e5e1036SVladimir Kotal 
220b5840353SAdam Hornáček     public static final double defaultRamBufferSize = 16;
221b5840353SAdam Hornáček 
222b5840353SAdam Hornáček     /**
223b5840353SAdam Hornáček      * The directory hierarchy depth to limit the scanning for repositories.
224b5840353SAdam Hornáček      * E.g. if the /mercurial/ directory (relative to source root) is a repository
225b5840353SAdam Hornáček      * and /mercurial/usr/closed/ is sub-repository, the latter will be discovered
2268df660a0SVladimir Kotal      * only if the depth is set to 2 or greater.
227b5840353SAdam Hornáček      */
2288df660a0SVladimir Kotal     public static final int defaultScanningDepth = 2;
229b5840353SAdam Hornáček 
230b5840353SAdam Hornáček     /**
231b5840353SAdam Hornáček      * The name of the eftar file relative to the <var>DATA_ROOT</var>, which
232b5840353SAdam Hornáček      * contains definition tags.
233b5840353SAdam Hornáček      */
234f197cd77SVladimir Kotal     public static final String EFTAR_DTAGS_NAME = "dtags.eftar";
235b5840353SAdam Hornáček 
236b5840353SAdam Hornáček     /**
237b5840353SAdam Hornáček      * Revision messages will be collapsible if they exceed this many number of
238b5840353SAdam Hornáček      * characters. Front end enforces an appropriate minimum.
239b5840353SAdam Hornáček      */
240b5840353SAdam Hornáček     private int revisionMessageCollapseThreshold;
241b5840353SAdam Hornáček 
242b5840353SAdam Hornáček     /**
243b5840353SAdam Hornáček      * Groups are collapsed if number of repositories is greater than this
244b5840353SAdam Hornáček      * threshold. This applies only for non-favorite groups - groups which don't
245b5840353SAdam Hornáček      * contain a project which is considered as a favorite project for the user.
246b5840353SAdam Hornáček      * Favorite projects are the projects which the user browses and searches
247b5840353SAdam Hornáček      * and are stored in a cookie. Favorite groups are always expanded.
248b5840353SAdam Hornáček      */
249b5840353SAdam Hornáček     private int groupsCollapseThreshold;
250b5840353SAdam Hornáček 
251b5840353SAdam Hornáček     /**
252b5840353SAdam Hornáček      * Current indexed message will be collapsible if they exceed this many
253b5840353SAdam Hornáček      * number of characters. Front end enforces an appropriate minimum.
254b5840353SAdam Hornáček      */
255b5840353SAdam Hornáček     private int currentIndexedCollapseThreshold;
256b5840353SAdam Hornáček 
257b5840353SAdam Hornáček     /**
258b5840353SAdam Hornáček      * Upper bound for number of threads used for performing multi-project
259fb531549SVladimir Kotal      * searches. This is total for the whole webapp.
260b5840353SAdam Hornáček      */
261b5840353SAdam Hornáček     private int MaxSearchThreadCount;
262b5840353SAdam Hornáček 
263b5840353SAdam Hornáček     /**
264fb531549SVladimir Kotal      * Upper bound for number of threads used for getting revision contents.
265fb531549SVladimir Kotal      * This is total for the whole webapp.
266fb531549SVladimir Kotal      */
267fb531549SVladimir Kotal     private int MaxRevisionThreadCount;
268fb531549SVladimir Kotal 
269fb531549SVladimir Kotal     /**
270b5840353SAdam Hornáček      * If false, do not display listing or projects/repositories on the index page.
271b5840353SAdam Hornáček      */
272b5840353SAdam Hornáček     private boolean displayRepositories;
273b5840353SAdam Hornáček 
274b5840353SAdam Hornáček     /**
275b5840353SAdam Hornáček      * If true, list directories first in xref directory listing.
276b5840353SAdam Hornáček      */
277b5840353SAdam Hornáček     private boolean listDirsFirst = true;
278b5840353SAdam Hornáček 
279326dace0SVladimir Kotal     /**
280326dace0SVladimir Kotal      * A flag if the navigate window should be opened by default when browsing
281326dace0SVladimir Kotal      * the source code of projects.
282326dace0SVladimir Kotal      */
283326dace0SVladimir Kotal     private boolean navigateWindowEnabled;
284326dace0SVladimir Kotal 
285911e8af0SAdam Hornáček     private SuggesterConfig suggesterConfig = new SuggesterConfig();
286911e8af0SAdam Hornáček 
2870d7ace53SVladimir Kotal     private StatsdConfig statsdConfig = new StatsdConfig();
2880d7ace53SVladimir Kotal 
28929816c3bSChris Fraire     private Set<String> disabledRepositories;
29029816c3bSChris Fraire 
291b118f02bSVladimir Kotal     private Set<String> authenticationTokens; // for non-localhost API access
2928d34347cSVladimir Kotal     private String indexerAuthenticationToken;
29360e45c9fSVladimir Kotal     private boolean allowInsecureTokens;
294b0a23e73SVladimir Kotal 
295a2f09795SVladimir Kotal     private int historyChunkCount;
2965a635a8eSVladimir Kotal     private boolean historyCachePerPartesEnabled = true;
297a2f09795SVladimir Kotal 
2980516dd21SVladimir Kotal     private String serverName;  // for reverse proxy environment
2990516dd21SVladimir Kotal 
3001c258122SVladimir Kotal     private int connectTimeout = -1;    // connect timeout in seconds
3011c258122SVladimir Kotal     private int apiTimeout = -1;    // API timeout in seconds
3021c258122SVladimir Kotal 
303f4571972SVladimir Kotal     private boolean historyBasedReindex;
30412365fb4SVladimir Kotal 
305b5840353SAdam Hornáček     /*
306b5840353SAdam Hornáček      * types of handling history for remote SCM repositories:
307b5840353SAdam Hornáček      *  ON - index history and display it in webapp
308b5840353SAdam Hornáček      *  OFF - do not index or display history in webapp
309b5840353SAdam Hornáček      *  DIRBASED - index history only for repositories capable
310b5840353SAdam Hornáček      *             of getting history for directories
311b5840353SAdam Hornáček      *  UIONLY - display history only in webapp (do not index it)
312b5840353SAdam Hornáček      */
313b5840353SAdam Hornáček     public enum RemoteSCM {
314b5840353SAdam Hornáček         ON, OFF, DIRBASED, UIONLY
315b5840353SAdam Hornáček     }
316b5840353SAdam Hornáček 
317b5840353SAdam Hornáček     /**
318b5840353SAdam Hornáček      * Get the default tab size (number of space characters per tab character)
319b5840353SAdam Hornáček      * to use for each project. If {@code <= 0} tabs are read/write as is.
320b5840353SAdam Hornáček      *
321b5840353SAdam Hornáček      * @return current tab size set.
322b5840353SAdam Hornáček      * @see Project#getTabSize()
3239805b761SAdam Hornáček      * @see org.opengrok.indexer.analysis.ExpandTabsReader
324b5840353SAdam Hornáček      */
getTabSize()325b5840353SAdam Hornáček     public int getTabSize() {
326b5840353SAdam Hornáček         return tabSize;
327b5840353SAdam Hornáček     }
328b5840353SAdam Hornáček 
329b5840353SAdam Hornáček     /**
330b5840353SAdam Hornáček      * Set the default tab size (number of space characters per tab character)
331b5840353SAdam Hornáček      * to use for each project. If {@code <= 0} tabs are read/write as is.
332b5840353SAdam Hornáček      *
333b5840353SAdam Hornáček      * @param tabSize tabsize to set.
334b5840353SAdam Hornáček      * @see Project#setTabSize(int)
3359805b761SAdam Hornáček      * @see org.opengrok.indexer.analysis.ExpandTabsReader
336b5840353SAdam Hornáček      */
setTabSize(int tabSize)337b5840353SAdam Hornáček     public void setTabSize(int tabSize) {
338b5840353SAdam Hornáček         this.tabSize = tabSize;
339b5840353SAdam Hornáček     }
340b5840353SAdam Hornáček 
getScanningDepth()341b5840353SAdam Hornáček     public int getScanningDepth() {
342b5840353SAdam Hornáček         return scanningDepth;
343b5840353SAdam Hornáček     }
344b5840353SAdam Hornáček 
345b5840353SAdam Hornáček     /**
346ff44f24aSAdam Hornáček      * Set the scanning depth to a new value.
347b5840353SAdam Hornáček      *
348b5840353SAdam Hornáček      * @param scanningDepth the new value
349b5840353SAdam Hornáček      * @throws IllegalArgumentException when the scanningDepth is negative
350b5840353SAdam Hornáček      */
setScanningDepth(int scanningDepth)351b5840353SAdam Hornáček     public void setScanningDepth(int scanningDepth) throws IllegalArgumentException {
352b5840353SAdam Hornáček         if (scanningDepth < 0) {
353b5840353SAdam Hornáček             throw new IllegalArgumentException(
354b5840353SAdam Hornáček                     String.format(NEGATIVE_NUMBER_ERROR, "scanningDepth", scanningDepth));
355b5840353SAdam Hornáček         }
356b5840353SAdam Hornáček         this.scanningDepth = scanningDepth;
357b5840353SAdam Hornáček     }
358b5840353SAdam Hornáček 
3592402fe1cSChris Fraire     /**
3602402fe1cSChris Fraire      * Gets the nesting maximum of repositories. Default is 1.
3612402fe1cSChris Fraire      */
getNestingMaximum()3622402fe1cSChris Fraire     public int getNestingMaximum() {
3632402fe1cSChris Fraire         return nestingMaximum;
3642402fe1cSChris Fraire     }
3652402fe1cSChris Fraire 
3662402fe1cSChris Fraire     /**
3672402fe1cSChris Fraire      * Sets the nesting maximum of repositories to a specified value.
3682402fe1cSChris Fraire      * @param nestingMaximum the new value
3692402fe1cSChris Fraire      * @throws IllegalArgumentException if {@code nestingMaximum} is negative
3702402fe1cSChris Fraire      */
setNestingMaximum(int nestingMaximum)3712402fe1cSChris Fraire     public void setNestingMaximum(int nestingMaximum) throws IllegalArgumentException {
3722402fe1cSChris Fraire         if (nestingMaximum < 0) {
3732402fe1cSChris Fraire             throw new IllegalArgumentException(
3742402fe1cSChris Fraire                     String.format(NEGATIVE_NUMBER_ERROR, "nestingMaximum", nestingMaximum));
3752402fe1cSChris Fraire         }
3762402fe1cSChris Fraire         this.nestingMaximum = nestingMaximum;
3772402fe1cSChris Fraire     }
3782402fe1cSChris Fraire 
getIndexerCommandTimeout()379a904b83aSVladimir Kotal     public int getIndexerCommandTimeout() {
380a904b83aSVladimir Kotal         return indexerCommandTimeout;
381b5840353SAdam Hornáček     }
382b5840353SAdam Hornáček 
383b5840353SAdam Hornáček     /**
384ff44f24aSAdam Hornáček      * Set the command timeout to a new value.
385b5840353SAdam Hornáček      *
386a904b83aSVladimir Kotal      * @param timeout the new value
387b5840353SAdam Hornáček      * @throws IllegalArgumentException when the timeout is negative
388b5840353SAdam Hornáček      */
setIndexerCommandTimeout(int timeout)389a904b83aSVladimir Kotal     public void setIndexerCommandTimeout(int timeout) throws IllegalArgumentException {
390a904b83aSVladimir Kotal         if (timeout < 0) {
391b5840353SAdam Hornáček             throw new IllegalArgumentException(
392a904b83aSVladimir Kotal                     String.format(NEGATIVE_NUMBER_ERROR, "commandTimeout", timeout));
393b5840353SAdam Hornáček         }
394a904b83aSVladimir Kotal         this.indexerCommandTimeout = timeout;
395a904b83aSVladimir Kotal     }
396a904b83aSVladimir Kotal 
getRestfulCommandTimeout()397a904b83aSVladimir Kotal     public int getRestfulCommandTimeout() {
398a904b83aSVladimir Kotal         return restfulCommandTimeout;
399a904b83aSVladimir Kotal     }
400a904b83aSVladimir Kotal 
401a904b83aSVladimir Kotal     /**
402a904b83aSVladimir Kotal      * Set the command timeout to a new value.
403a904b83aSVladimir Kotal      *
404a904b83aSVladimir Kotal      * @param timeout the new value
405a904b83aSVladimir Kotal      * @throws IllegalArgumentException when the timeout is negative
406a904b83aSVladimir Kotal      */
setRestfulCommandTimeout(int timeout)407a904b83aSVladimir Kotal     public void setRestfulCommandTimeout(int timeout) throws IllegalArgumentException {
408a904b83aSVladimir Kotal         if (timeout < 0) {
409a904b83aSVladimir Kotal             throw new IllegalArgumentException(
410a904b83aSVladimir Kotal                     String.format(NEGATIVE_NUMBER_ERROR, "restfulCommandTimeout", timeout));
411a904b83aSVladimir Kotal         }
412a904b83aSVladimir Kotal         this.restfulCommandTimeout = timeout;
413a904b83aSVladimir Kotal     }
414a904b83aSVladimir Kotal 
getWebappStartCommandTimeout()415a904b83aSVladimir Kotal     public int getWebappStartCommandTimeout() {
416a904b83aSVladimir Kotal         return webappStartCommandTimeout;
417a904b83aSVladimir Kotal     }
418a904b83aSVladimir Kotal 
419a904b83aSVladimir Kotal     /**
420a904b83aSVladimir Kotal      * Set the command timeout to a new value.
421a904b83aSVladimir Kotal      *
422a904b83aSVladimir Kotal      * @param timeout the new value
423a904b83aSVladimir Kotal      * @throws IllegalArgumentException when the timeout is negative
424a904b83aSVladimir Kotal      */
setWebappStartCommandTimeout(int timeout)425a904b83aSVladimir Kotal     public void setWebappStartCommandTimeout(int timeout) throws IllegalArgumentException {
426a904b83aSVladimir Kotal         if (timeout < 0) {
427a904b83aSVladimir Kotal             throw new IllegalArgumentException(
428a904b83aSVladimir Kotal                     String.format(NEGATIVE_NUMBER_ERROR, "webappStartCommandTimeout", timeout));
429a904b83aSVladimir Kotal         }
430a904b83aSVladimir Kotal         this.webappStartCommandTimeout = timeout;
431b5840353SAdam Hornáček     }
432b5840353SAdam Hornáček 
getInteractiveCommandTimeout()433b5840353SAdam Hornáček     public int getInteractiveCommandTimeout() {
434b5840353SAdam Hornáček         return interactiveCommandTimeout;
435b5840353SAdam Hornáček     }
436b5840353SAdam Hornáček 
437b5840353SAdam Hornáček     /**
438b5840353SAdam Hornáček      * Set the interactive command timeout to a new value.
439b5840353SAdam Hornáček      *
440a904b83aSVladimir Kotal      * @param timeout the new value
441b5840353SAdam Hornáček      * @throws IllegalArgumentException when the timeout is negative
442b5840353SAdam Hornáček      */
setInteractiveCommandTimeout(int timeout)443a904b83aSVladimir Kotal     public void setInteractiveCommandTimeout(int timeout) throws IllegalArgumentException {
444a904b83aSVladimir Kotal         if (timeout < 0) {
445b5840353SAdam Hornáček             throw new IllegalArgumentException(
446a904b83aSVladimir Kotal                     String.format(NEGATIVE_NUMBER_ERROR, "interactiveCommandTimeout", timeout));
447b5840353SAdam Hornáček         }
448a904b83aSVladimir Kotal         this.interactiveCommandTimeout = timeout;
449b5840353SAdam Hornáček     }
450b5840353SAdam Hornáček 
getCtagsTimeout()451b124dbe6SVladimir Kotal     public long getCtagsTimeout() {
452b82c5e9dSVladimir Kotal         return ctagsTimeout;
453b82c5e9dSVladimir Kotal     }
454b82c5e9dSVladimir Kotal 
455b82c5e9dSVladimir Kotal     /**
456b82c5e9dSVladimir Kotal      * Set the ctags timeout to a new value.
457b82c5e9dSVladimir Kotal      *
458b82c5e9dSVladimir Kotal      * @param timeout the new value
459b82c5e9dSVladimir Kotal      * @throws IllegalArgumentException when the timeout is negative
460b82c5e9dSVladimir Kotal      */
setCtagsTimeout(long timeout)461b124dbe6SVladimir Kotal     public void setCtagsTimeout(long timeout) throws IllegalArgumentException {
462a904b83aSVladimir Kotal         if (timeout < 0) {
463b82c5e9dSVladimir Kotal             throw new IllegalArgumentException(
464b82c5e9dSVladimir Kotal                     String.format(NEGATIVE_NUMBER_ERROR, "ctagsTimeout", timeout));
465b82c5e9dSVladimir Kotal         }
466b82c5e9dSVladimir Kotal         this.ctagsTimeout = timeout;
467b82c5e9dSVladimir Kotal     }
468b82c5e9dSVladimir Kotal 
getXrefTimeout()469e92cec67SVladimir Kotal     public long getXrefTimeout() {
470e92cec67SVladimir Kotal         return xrefTimeout;
471e92cec67SVladimir Kotal     }
472e92cec67SVladimir Kotal 
473e92cec67SVladimir Kotal     /**
474e92cec67SVladimir Kotal      * Set the timeout for generating xrefs to a new value.
475e92cec67SVladimir Kotal      *
476e92cec67SVladimir Kotal      * @param timeout the new value
477e92cec67SVladimir Kotal      * @throws IllegalArgumentException when the timeout is negative
478e92cec67SVladimir Kotal      */
setXrefTimeout(long timeout)479e92cec67SVladimir Kotal     public void setXrefTimeout(long timeout) throws IllegalArgumentException {
480e92cec67SVladimir Kotal         if (timeout < 0) {
481e92cec67SVladimir Kotal             throw new IllegalArgumentException(
482e92cec67SVladimir Kotal                     String.format(NEGATIVE_NUMBER_ERROR, "xrefTimeout", timeout));
483e92cec67SVladimir Kotal         }
484e92cec67SVladimir Kotal         this.xrefTimeout = timeout;
485e92cec67SVladimir Kotal     }
486e92cec67SVladimir Kotal 
isLastEditedDisplayMode()487b5840353SAdam Hornáček     public boolean isLastEditedDisplayMode() {
488b5840353SAdam Hornáček         return lastEditedDisplayMode;
489b5840353SAdam Hornáček     }
490b5840353SAdam Hornáček 
setLastEditedDisplayMode(boolean lastEditedDisplayMode)491b5840353SAdam Hornáček     public void setLastEditedDisplayMode(boolean lastEditedDisplayMode) {
492b5840353SAdam Hornáček         this.lastEditedDisplayMode = lastEditedDisplayMode;
493b5840353SAdam Hornáček     }
494b5840353SAdam Hornáček 
getGroupsCollapseThreshold()495b5840353SAdam Hornáček     public int getGroupsCollapseThreshold() {
496b5840353SAdam Hornáček         return groupsCollapseThreshold;
497b5840353SAdam Hornáček     }
498b5840353SAdam Hornáček 
499b5840353SAdam Hornáček     /**
500ff44f24aSAdam Hornáček      * Set the groups collapse threshold to a new value.
501b5840353SAdam Hornáček      *
502b5840353SAdam Hornáček      * @param groupsCollapseThreshold the new value
503b5840353SAdam Hornáček      * @throws IllegalArgumentException when the timeout is negative
504b5840353SAdam Hornáček      */
setGroupsCollapseThreshold(int groupsCollapseThreshold)505b5840353SAdam Hornáček     public void setGroupsCollapseThreshold(int groupsCollapseThreshold) throws IllegalArgumentException {
506b5840353SAdam Hornáček         if (groupsCollapseThreshold < 0) {
507b5840353SAdam Hornáček             throw new IllegalArgumentException(
508b5840353SAdam Hornáček                     String.format(NEGATIVE_NUMBER_ERROR, "groupsCollapseThreshold", groupsCollapseThreshold));
509b5840353SAdam Hornáček         }
510b5840353SAdam Hornáček         this.groupsCollapseThreshold = groupsCollapseThreshold;
511b5840353SAdam Hornáček     }
512b5840353SAdam Hornáček 
513b5840353SAdam Hornáček     /**
514b82c5e9dSVladimir Kotal      * Creates a new instance of Configuration with default values.
515b5840353SAdam Hornáček      */
Configuration()516b5840353SAdam Hornáček     public Configuration() {
517b82c5e9dSVladimir Kotal         // This list of calls is sorted alphabetically so please keep it.
518b5840353SAdam Hornáček         cmds = new HashMap<>();
5195b7cea89SLubos Kosco         setAllowLeadingWildcard(true);
520b5840353SAdam Hornáček         setAllowedSymlinks(new HashSet<>());
521acac8e33SVladimir Kotal         setAuthenticationTokens(new HashSet<>());
522b5840353SAdam Hornáček         setAuthorizationWatchdogEnabled(false);
523b5840353SAdam Hornáček         //setBugPage("http://bugs.myserver.org/bugdatabase/view_bug.do?bug_id=");
524b5840353SAdam Hornáček         setBugPattern("\\b([12456789][0-9]{6})\\b");
525b5840353SAdam Hornáček         setCachePages(5);
5260e0ac58dSChris Fraire         setCanonicalRoots(new HashSet<>());
527a904b83aSVladimir Kotal         setIndexerCommandTimeout(600); // 10 minutes
528a904b83aSVladimir Kotal         setRestfulCommandTimeout(60);
529b5840353SAdam Hornáček         setInteractiveCommandTimeout(30);
530a904b83aSVladimir Kotal         setWebappStartCommandTimeout(5);
531b5840353SAdam Hornáček         setCompressXref(true);
532b5840353SAdam Hornáček         setContextLimit((short) 10);
533b5840353SAdam Hornáček         //contextSurround is default(short)
534b5840353SAdam Hornáček         //ctags is default(String)
535b124dbe6SVladimir Kotal         setCtagsTimeout(10);
536b5840353SAdam Hornáček         setCurrentIndexedCollapseThreshold(27);
537b5840353SAdam Hornáček         setDataRoot(null);
538b5840353SAdam Hornáček         setDisplayRepositories(true);
539b5840353SAdam Hornáček         setFetchHistoryWhenNotInCache(true);
540b5840353SAdam Hornáček         setFoldingEnabled(true);
541b5840353SAdam Hornáček         setGenerateHtml(true);
542b5840353SAdam Hornáček         setGroups(new TreeSet<>());
543b5840353SAdam Hornáček         setGroupsCollapseThreshold(4);
544b5840353SAdam Hornáček         setHandleHistoryOfRenamedFiles(false);
545b5840353SAdam Hornáček         setHistoryCache(true);
546b5840353SAdam Hornáček         setHistoryEnabled(true);
547b5840353SAdam Hornáček         setHitsPerPage(25);
548b5840353SAdam Hornáček         setIgnoredNames(new IgnoredNames());
549b5840353SAdam Hornáček         setIncludedNames(new Filter());
550b5840353SAdam Hornáček         setIndexVersionedFilesOnly(false);
551b5840353SAdam Hornáček         setLastEditedDisplayMode(true);
552b5840353SAdam Hornáček         //luceneLocking default is OFF
553b5840353SAdam Hornáček         //mandoc is default(String)
554b5840353SAdam Hornáček         setMaxSearchThreadCount(2 * Runtime.getRuntime().availableProcessors());
555fb531549SVladimir Kotal         setMaxRevisionThreadCount(Runtime.getRuntime().availableProcessors());
556610d9085SVladimir Kotal         setMergeCommitsEnabled(false);
557b5840353SAdam Hornáček         setMessageLimit(500);
558326dace0SVladimir Kotal         setNavigateWindowEnabled(false);
5592402fe1cSChris Fraire         setNestingMaximum(1);
560b5840353SAdam Hornáček         setOptimizeDatabase(true);
561b5840353SAdam Hornáček         setPluginDirectory(null);
562b5840353SAdam Hornáček         setPluginStack(new AuthorizationStack(AuthControlFlag.REQUIRED, "default stack"));
563b5840353SAdam Hornáček         setPrintProgress(false);
56429816c3bSChris Fraire         setDisabledRepositories(new HashSet<>());
565b5840353SAdam Hornáček         setProjects(new ConcurrentHashMap<>());
566b5840353SAdam Hornáček         setQuickContextScan(true);
567b5840353SAdam Hornáček         //below can cause an outofmemory error, since it is defaulting to NO LIMIT
568b5840353SAdam Hornáček         setRamBufferSize(defaultRamBufferSize); //MB
569b5840353SAdam Hornáček         setRemoteScmSupported(RemoteSCM.OFF);
570b5840353SAdam Hornáček         setRepositories(new ArrayList<>());
571b5840353SAdam Hornáček         //setReviewPage("http://arc.myserver.org/caselog/PSARC/");
572b5840353SAdam Hornáček         setReviewPattern("\\b(\\d{4}/\\d{3})\\b"); // in form e.g. PSARC 2008/305
573b5840353SAdam Hornáček         setRevisionMessageCollapseThreshold(200);
574b5840353SAdam Hornáček         setScanningDepth(defaultScanningDepth); // default depth of scanning for repositories
575b5840353SAdam Hornáček         setScopesEnabled(true);
576b5840353SAdam Hornáček         setSourceRoot(null);
577b5840353SAdam Hornáček         //setTabSize(4);
578b5840353SAdam Hornáček         setTagsEnabled(false);
579b5840353SAdam Hornáček         //setUserPage("http://www.myserver.org/viewProfile.jspa?username=");
580e92cec67SVladimir Kotal         // Set to empty string so we can append it to the URL unconditionally later.
581f4571972SVladimir Kotal         setHistoryBasedReindex(true);
582b5840353SAdam Hornáček         setUserPageSuffix("");
583b5840353SAdam Hornáček         setWebappLAF("default");
584e829566cSChris Fraire         // webappCtags is default(boolean)
585e92cec67SVladimir Kotal         setXrefTimeout(30);
5861c258122SVladimir Kotal         setApiTimeout(300); // 5 minutes
5871c258122SVladimir Kotal         setConnectTimeout(3);
588b5840353SAdam Hornáček     }
589b5840353SAdam Hornáček 
getRepoCmd(String clazzName)590b5840353SAdam Hornáček     public String getRepoCmd(String clazzName) {
591b5840353SAdam Hornáček         return cmds.get(clazzName);
592b5840353SAdam Hornáček     }
593b5840353SAdam Hornáček 
setRepoCmd(String clazzName, String cmd)594b5840353SAdam Hornáček     public String setRepoCmd(String clazzName, String cmd) {
595b5840353SAdam Hornáček         if (clazzName == null) {
596b5840353SAdam Hornáček             return null;
597b5840353SAdam Hornáček         }
598b5840353SAdam Hornáček         if (cmd == null || cmd.length() == 0) {
599b5840353SAdam Hornáček             return cmds.remove(clazzName);
600b5840353SAdam Hornáček         }
601b5840353SAdam Hornáček         return cmds.put(clazzName, cmd);
602b5840353SAdam Hornáček     }
603b5840353SAdam Hornáček 
604b5840353SAdam Hornáček     // just to satisfy bean/de|encoder stuff
getCmds()605b5840353SAdam Hornáček     public Map<String, String> getCmds() {
606b5840353SAdam Hornáček         return Collections.unmodifiableMap(cmds);
607b5840353SAdam Hornáček     }
608b5840353SAdam Hornáček 
609b5840353SAdam Hornáček     /**
6101a2bb6b6SAdam Hornáček      * @see org.opengrok.indexer.web.messages.MessagesContainer
611b5840353SAdam Hornáček      *
612b5840353SAdam Hornáček      * @return int the current message limit
613b5840353SAdam Hornáček      */
getMessageLimit()614b5840353SAdam Hornáček     public int getMessageLimit() {
615b5840353SAdam Hornáček         return messageLimit;
616b5840353SAdam Hornáček     }
617b5840353SAdam Hornáček 
618b5840353SAdam Hornáček     /**
6191a2bb6b6SAdam Hornáček      * @see org.opengrok.indexer.web.messages.MessagesContainer
620b5840353SAdam Hornáček      *
621b5840353SAdam Hornáček      * @param messageLimit the limit
622b5840353SAdam Hornáček      * @throws IllegalArgumentException when the limit is negative
623b5840353SAdam Hornáček      */
setMessageLimit(int messageLimit)624b5840353SAdam Hornáček     public void setMessageLimit(int messageLimit) throws IllegalArgumentException {
625b5840353SAdam Hornáček         if (messageLimit < 0) {
626b5840353SAdam Hornáček             throw new IllegalArgumentException(
627b5840353SAdam Hornáček                     String.format(NEGATIVE_NUMBER_ERROR, "messageLimit", messageLimit));
628b5840353SAdam Hornáček         }
629b5840353SAdam Hornáček         this.messageLimit = messageLimit;
630b5840353SAdam Hornáček     }
631b5840353SAdam Hornáček 
getPluginDirectory()632b5840353SAdam Hornáček     public String getPluginDirectory() {
633b5840353SAdam Hornáček         return pluginDirectory;
634b5840353SAdam Hornáček     }
635b5840353SAdam Hornáček 
setPluginDirectory(String pluginDirectory)636b5840353SAdam Hornáček     public void setPluginDirectory(String pluginDirectory) {
637b5840353SAdam Hornáček         this.pluginDirectory = pluginDirectory;
638b5840353SAdam Hornáček     }
639b5840353SAdam Hornáček 
isAuthorizationWatchdogEnabled()640b5840353SAdam Hornáček     public boolean isAuthorizationWatchdogEnabled() {
641b5840353SAdam Hornáček         return authorizationWatchdogEnabled;
642b5840353SAdam Hornáček     }
643b5840353SAdam Hornáček 
setAuthorizationWatchdogEnabled(boolean authorizationWatchdogEnabled)644b5840353SAdam Hornáček     public void setAuthorizationWatchdogEnabled(boolean authorizationWatchdogEnabled) {
645b5840353SAdam Hornáček         this.authorizationWatchdogEnabled = authorizationWatchdogEnabled;
646b5840353SAdam Hornáček     }
647b5840353SAdam Hornáček 
getPluginStack()648b5840353SAdam Hornáček     public AuthorizationStack getPluginStack() {
649b5840353SAdam Hornáček         return pluginStack;
650b5840353SAdam Hornáček     }
651b5840353SAdam Hornáček 
setPluginStack(AuthorizationStack pluginStack)652b5840353SAdam Hornáček     public void setPluginStack(AuthorizationStack pluginStack) {
653b5840353SAdam Hornáček         this.pluginStack = pluginStack;
654b5840353SAdam Hornáček     }
655b5840353SAdam Hornáček 
setCmds(Map<String, String> cmds)656b5840353SAdam Hornáček     public void setCmds(Map<String, String> cmds) {
657b5840353SAdam Hornáček         this.cmds.clear();
658b5840353SAdam Hornáček         this.cmds.putAll(cmds);
659b5840353SAdam Hornáček     }
660b5840353SAdam Hornáček 
661b5840353SAdam Hornáček     /**
662b5840353SAdam Hornáček      * Gets the configuration's ctags command. Default is null.
663b5840353SAdam Hornáček      * @return the configured value
664b5840353SAdam Hornáček      */
getCtags()665b5840353SAdam Hornáček     public String getCtags() {
666b5840353SAdam Hornáček         return ctags;
667b5840353SAdam Hornáček     }
668b5840353SAdam Hornáček 
669b5840353SAdam Hornáček     /**
670b5840353SAdam Hornáček      * Sets the configuration's ctags command.
671b5840353SAdam Hornáček      * @param ctags A program name (full-path if necessary) or {@code null}
672b5840353SAdam Hornáček      */
setCtags(String ctags)673b5840353SAdam Hornáček     public void setCtags(String ctags) {
674b5840353SAdam Hornáček         this.ctags = ctags;
675b5840353SAdam Hornáček     }
676b5840353SAdam Hornáček 
677b5840353SAdam Hornáček     /**
678b5840353SAdam Hornáček      * Gets the configuration's mandoc command. Default is {@code null}.
679b5840353SAdam Hornáček      * @return the configured value
680b5840353SAdam Hornáček      */
getMandoc()681b5840353SAdam Hornáček     public String getMandoc() {
682b5840353SAdam Hornáček         return mandoc;
683b5840353SAdam Hornáček     }
684b5840353SAdam Hornáček 
685b5840353SAdam Hornáček     /**
686b5840353SAdam Hornáček      * Sets the configuration's mandoc command.
687b5840353SAdam Hornáček      * @param value A program name (full-path if necessary) or {@code null}
688b5840353SAdam Hornáček      */
setMandoc(String value)689b5840353SAdam Hornáček     public void setMandoc(String value) {
690b5840353SAdam Hornáček         this.mandoc = value;
691b5840353SAdam Hornáček     }
692b5840353SAdam Hornáček 
693b5840353SAdam Hornáček     /**
694b5840353SAdam Hornáček      * Gets the total number of context lines per file to show in cases where it
695b5840353SAdam Hornáček      * is limited. Default is 10.
696b5840353SAdam Hornáček      * @return a value greater than zero
697b5840353SAdam Hornáček      */
getContextLimit()698b5840353SAdam Hornáček     public short getContextLimit() {
699b5840353SAdam Hornáček         return contextLimit;
700b5840353SAdam Hornáček     }
701b5840353SAdam Hornáček 
702b5840353SAdam Hornáček     /**
703b5840353SAdam Hornáček      * Sets the total number of context lines per file to show in cases where it
704b5840353SAdam Hornáček      * is limited.
705b5840353SAdam Hornáček      * @param value a value greater than zero
706b5840353SAdam Hornáček      * @throws IllegalArgumentException if {@code value} is not positive
707b5840353SAdam Hornáček      */
setContextLimit(short value)708b5840353SAdam Hornáček     public void setContextLimit(short value) throws IllegalArgumentException {
709b5840353SAdam Hornáček         if (value < 1) {
710b5840353SAdam Hornáček             throw new IllegalArgumentException(
711b5840353SAdam Hornáček                 String.format(NONPOSITIVE_NUMBER_ERROR, "contextLimit", value));
712b5840353SAdam Hornáček         }
713b5840353SAdam Hornáček         this.contextLimit = value;
714b5840353SAdam Hornáček     }
715b5840353SAdam Hornáček 
716b5840353SAdam Hornáček     /**
717b5840353SAdam Hornáček      * Gets the number of context lines to show before or after any match.
718b5840353SAdam Hornáček      * Default is zero.
719b5840353SAdam Hornáček      * @return a value greater than or equal to zero
720b5840353SAdam Hornáček      */
getContextSurround()721b5840353SAdam Hornáček     public short getContextSurround() {
722b5840353SAdam Hornáček         return contextSurround;
723b5840353SAdam Hornáček     }
724b5840353SAdam Hornáček 
725b5840353SAdam Hornáček     /**
726b5840353SAdam Hornáček      * Sets the number of context lines to show before or after any match.
727b5840353SAdam Hornáček      * @param value a value greater than or equal to zero
728b5840353SAdam Hornáček      * @throws IllegalArgumentException if {@code value} is negative
729b5840353SAdam Hornáček      */
setContextSurround(short value)730b5840353SAdam Hornáček     public void setContextSurround(short value)
731b5840353SAdam Hornáček             throws IllegalArgumentException {
732b5840353SAdam Hornáček         if (value < 0) {
733b5840353SAdam Hornáček             throw new IllegalArgumentException(
734b5840353SAdam Hornáček                 String.format(NEGATIVE_NUMBER_ERROR, "contextSurround", value));
735b5840353SAdam Hornáček         }
736b5840353SAdam Hornáček         this.contextSurround = value;
737b5840353SAdam Hornáček     }
738b5840353SAdam Hornáček 
getCachePages()739b5840353SAdam Hornáček     public int getCachePages() {
740b5840353SAdam Hornáček         return cachePages;
741b5840353SAdam Hornáček     }
742b5840353SAdam Hornáček 
743b5840353SAdam Hornáček     /**
744ff44f24aSAdam Hornáček      * Set the cache pages to a new value.
745b5840353SAdam Hornáček      *
746b5840353SAdam Hornáček      * @param cachePages the new value
747b5840353SAdam Hornáček      * @throws IllegalArgumentException when the cachePages is negative
748b5840353SAdam Hornáček      */
setCachePages(int cachePages)749b5840353SAdam Hornáček     public void setCachePages(int cachePages) throws IllegalArgumentException {
750b5840353SAdam Hornáček         if (cachePages < 0) {
751b5840353SAdam Hornáček             throw new IllegalArgumentException(
752b5840353SAdam Hornáček                     String.format(NEGATIVE_NUMBER_ERROR, "cachePages", cachePages));
753b5840353SAdam Hornáček         }
754b5840353SAdam Hornáček         this.cachePages = cachePages;
755b5840353SAdam Hornáček     }
756b5840353SAdam Hornáček 
getHitsPerPage()757b5840353SAdam Hornáček     public int getHitsPerPage() {
758b5840353SAdam Hornáček         return hitsPerPage;
759b5840353SAdam Hornáček     }
760b5840353SAdam Hornáček 
761b5840353SAdam Hornáček     /**
762ff44f24aSAdam Hornáček      * Set the hits per page to a new value.
763b5840353SAdam Hornáček      *
764b5840353SAdam Hornáček      * @param hitsPerPage the new value
765b5840353SAdam Hornáček      * @throws IllegalArgumentException when the hitsPerPage is negative
766b5840353SAdam Hornáček      */
setHitsPerPage(int hitsPerPage)767b5840353SAdam Hornáček     public void setHitsPerPage(int hitsPerPage) throws IllegalArgumentException {
768b5840353SAdam Hornáček         if (hitsPerPage < 0) {
769b5840353SAdam Hornáček             throw new IllegalArgumentException(
770b5840353SAdam Hornáček                     String.format(NEGATIVE_NUMBER_ERROR, "hitsPerPage", hitsPerPage));
771b5840353SAdam Hornáček         }
772b5840353SAdam Hornáček         this.hitsPerPage = hitsPerPage;
773b5840353SAdam Hornáček     }
774b5840353SAdam Hornáček 
775b5840353SAdam Hornáček     /**
776b5840353SAdam Hornáček      * Should the history be enabled ?
777b5840353SAdam Hornáček      *
778b5840353SAdam Hornáček      * @return {@code true} if history is enabled, {@code false} otherwise
779b5840353SAdam Hornáček      */
isHistoryEnabled()780b5840353SAdam Hornáček     public boolean isHistoryEnabled() {
781b5840353SAdam Hornáček         return historyEnabled;
782b5840353SAdam Hornáček     }
783b5840353SAdam Hornáček 
784b5840353SAdam Hornáček     /**
785b5840353SAdam Hornáček      * Set whether history should be enabled.
786b5840353SAdam Hornáček      *
787b5840353SAdam Hornáček      * @param flag if {@code true} enable history
788b5840353SAdam Hornáček      */
setHistoryEnabled(boolean flag)789b5840353SAdam Hornáček     public void setHistoryEnabled(boolean flag) {
790b5840353SAdam Hornáček         this.historyEnabled = flag;
791b5840353SAdam Hornáček     }
792b5840353SAdam Hornáček 
793b5840353SAdam Hornáček     /**
794b5840353SAdam Hornáček      * Should the history log be cached?
795b5840353SAdam Hornáček      *
796b5840353SAdam Hornáček      * @return {@code true} if a {@code HistoryCache} implementation should be
797b5840353SAdam Hornáček      * used, {@code false} otherwise
798b5840353SAdam Hornáček      */
isHistoryCache()799b5840353SAdam Hornáček     public boolean isHistoryCache() {
800b5840353SAdam Hornáček         return historyCache;
801b5840353SAdam Hornáček     }
802b5840353SAdam Hornáček 
803b5840353SAdam Hornáček     /**
804b5840353SAdam Hornáček      * Set whether history should be cached.
805b5840353SAdam Hornáček      *
806b5840353SAdam Hornáček      * @param historyCache if {@code true} enable history cache
807b5840353SAdam Hornáček      */
setHistoryCache(boolean historyCache)808b5840353SAdam Hornáček     public void setHistoryCache(boolean historyCache) {
809b5840353SAdam Hornáček         this.historyCache = historyCache;
810b5840353SAdam Hornáček     }
811b5840353SAdam Hornáček 
isFetchHistoryWhenNotInCache()812b5840353SAdam Hornáček     public boolean isFetchHistoryWhenNotInCache() {
813b5840353SAdam Hornáček         return fetchHistoryWhenNotInCache;
814b5840353SAdam Hornáček     }
815b5840353SAdam Hornáček 
setFetchHistoryWhenNotInCache(boolean nofetch)816b5840353SAdam Hornáček     public void setFetchHistoryWhenNotInCache(boolean nofetch) {
817b5840353SAdam Hornáček         this.fetchHistoryWhenNotInCache = nofetch;
818b5840353SAdam Hornáček     }
819b5840353SAdam Hornáček 
isHandleHistoryOfRenamedFiles()820b5840353SAdam Hornáček     public boolean isHandleHistoryOfRenamedFiles() {
821b5840353SAdam Hornáček         return handleHistoryOfRenamedFiles;
822b5840353SAdam Hornáček     }
823b5840353SAdam Hornáček 
setHandleHistoryOfRenamedFiles(boolean enable)824b5840353SAdam Hornáček     public void setHandleHistoryOfRenamedFiles(boolean enable) {
825b5840353SAdam Hornáček         this.handleHistoryOfRenamedFiles = enable;
826b5840353SAdam Hornáček     }
827b5840353SAdam Hornáček 
setMergeCommitsEnabled(boolean flag)8288e5e1036SVladimir Kotal     public void setMergeCommitsEnabled(boolean flag) {
8298e5e1036SVladimir Kotal         this.mergeCommitsEnabled = flag;
8308e5e1036SVladimir Kotal     }
8318e5e1036SVladimir Kotal 
isMergeCommitsEnabled()8328e5e1036SVladimir Kotal     public boolean isMergeCommitsEnabled() {
8338e5e1036SVladimir Kotal         return mergeCommitsEnabled;
8348e5e1036SVladimir Kotal     }
8358e5e1036SVladimir Kotal 
isNavigateWindowEnabled()836326dace0SVladimir Kotal     public boolean isNavigateWindowEnabled() {
837326dace0SVladimir Kotal         return navigateWindowEnabled;
838326dace0SVladimir Kotal     }
839326dace0SVladimir Kotal 
setNavigateWindowEnabled(boolean navigateWindowEnabled)840326dace0SVladimir Kotal     public void setNavigateWindowEnabled(boolean navigateWindowEnabled) {
841326dace0SVladimir Kotal         this.navigateWindowEnabled = navigateWindowEnabled;
842326dace0SVladimir Kotal     }
843326dace0SVladimir Kotal 
getProjects()844b5840353SAdam Hornáček     public Map<String, Project> getProjects() {
845b5840353SAdam Hornáček         return projects;
846b5840353SAdam Hornáček     }
847b5840353SAdam Hornáček 
setProjects(Map<String, Project> projects)848b5840353SAdam Hornáček     public void setProjects(Map<String, Project> projects) {
849b5840353SAdam Hornáček         this.projects = projects;
850b5840353SAdam Hornáček     }
851b5840353SAdam Hornáček 
852b5840353SAdam Hornáček     /**
853b5840353SAdam Hornáček      * Adds a group to the set. This is performed upon configuration parsing
854b5840353SAdam Hornáček      *
855b5840353SAdam Hornáček      * @param group group
856b5840353SAdam Hornáček      * @throws IOException when group is not unique across the set
857b5840353SAdam Hornáček      */
addGroup(Group group)858b5840353SAdam Hornáček     public void addGroup(Group group) throws IOException {
859b5840353SAdam Hornáček         if (!groups.add(group)) {
860b5840353SAdam Hornáček             throw new IOException(
861b5840353SAdam Hornáček                     String.format("Duplicate group name '%s' in configuration.",
862b5840353SAdam Hornáček                             group.getName()));
863b5840353SAdam Hornáček         }
864b5840353SAdam Hornáček     }
865b5840353SAdam Hornáček 
getGroups()866b5840353SAdam Hornáček     public Set<Group> getGroups() {
867b5840353SAdam Hornáček         return groups;
868b5840353SAdam Hornáček     }
869b5840353SAdam Hornáček 
setGroups(Set<Group> groups)870b5840353SAdam Hornáček     public void setGroups(Set<Group> groups) {
871b5840353SAdam Hornáček         this.groups = groups;
872b5840353SAdam Hornáček     }
873b5840353SAdam Hornáček 
getSourceRoot()874b5840353SAdam Hornáček     public String getSourceRoot() {
875b5840353SAdam Hornáček         return sourceRoot;
876b5840353SAdam Hornáček     }
877b5840353SAdam Hornáček 
setSourceRoot(String sourceRoot)878b5840353SAdam Hornáček     public void setSourceRoot(String sourceRoot) {
879b5840353SAdam Hornáček         this.sourceRoot = sourceRoot;
880b5840353SAdam Hornáček     }
881b5840353SAdam Hornáček 
getDataRoot()882b5840353SAdam Hornáček     public String getDataRoot() {
883b5840353SAdam Hornáček         return dataRoot;
884b5840353SAdam Hornáček     }
885b5840353SAdam Hornáček 
886b5840353SAdam Hornáček     /**
887b5840353SAdam Hornáček      * Sets data root.
888b5840353SAdam Hornáček      *
88961b71b09SAdam Hornacek      * This method also sets the pluginDirectory if it is not already set.
890b5840353SAdam Hornáček      *
891b5840353SAdam Hornáček      * @see #setPluginDirectory(java.lang.String)
892b5840353SAdam Hornáček      *
893b5840353SAdam Hornáček      * @param dataRoot data root path
894b5840353SAdam Hornáček      */
setDataRoot(String dataRoot)895b5840353SAdam Hornáček     public void setDataRoot(String dataRoot) {
896b5840353SAdam Hornáček         if (dataRoot != null && getPluginDirectory() == null) {
897b5840353SAdam Hornáček             setPluginDirectory(dataRoot + "/../" + PLUGIN_DIRECTORY_DEFAULT);
898b5840353SAdam Hornáček         }
899b5840353SAdam Hornáček         this.dataRoot = dataRoot;
900b5840353SAdam Hornáček     }
901b5840353SAdam Hornáček 
902a03922c4SAdam Hornáček     /**
9037d060254SAdam Hornáček      * If {@link #includeRoot} is not set, {@link #dataRoot} will be returned.
904a03922c4SAdam Hornáček      * @return web include root directory
905a03922c4SAdam Hornáček      */
getIncludeRoot()906a03922c4SAdam Hornáček     public String getIncludeRoot() {
907a03922c4SAdam Hornáček         return includeRoot != null ? includeRoot : dataRoot;
908a03922c4SAdam Hornáček     }
909a03922c4SAdam Hornáček 
setIncludeRoot(String newRoot)910a03922c4SAdam Hornáček     public void setIncludeRoot(String newRoot) {
911a03922c4SAdam Hornáček         this.includeRoot = newRoot;
912a03922c4SAdam Hornáček     }
913a03922c4SAdam Hornáček 
getRepositories()914b5840353SAdam Hornáček     public List<RepositoryInfo> getRepositories() {
915b5840353SAdam Hornáček         return repositories;
916b5840353SAdam Hornáček     }
917b5840353SAdam Hornáček 
setRepositories(List<RepositoryInfo> repositories)918b5840353SAdam Hornáček     public void setRepositories(List<RepositoryInfo> repositories) {
919b5840353SAdam Hornáček         this.repositories = repositories;
920b5840353SAdam Hornáček     }
921b5840353SAdam Hornáček 
addRepositories(List<RepositoryInfo> repositories)922b5840353SAdam Hornáček     public void addRepositories(List<RepositoryInfo> repositories) {
923b5840353SAdam Hornáček         this.repositories.addAll(repositories);
924b5840353SAdam Hornáček     }
925b5840353SAdam Hornáček 
setGenerateHtml(boolean generateHtml)926b5840353SAdam Hornáček     public void setGenerateHtml(boolean generateHtml) {
927b5840353SAdam Hornáček         this.generateHtml = generateHtml;
928b5840353SAdam Hornáček     }
929b5840353SAdam Hornáček 
isGenerateHtml()930b5840353SAdam Hornáček     public boolean isGenerateHtml() {
931b5840353SAdam Hornáček         return generateHtml;
932b5840353SAdam Hornáček     }
933b5840353SAdam Hornáček 
setDefaultProjects(Set<Project> defaultProjects)934b5840353SAdam Hornáček     public void setDefaultProjects(Set<Project> defaultProjects) {
935b5840353SAdam Hornáček         this.defaultProjects = defaultProjects;
936b5840353SAdam Hornáček     }
937b5840353SAdam Hornáček 
getDefaultProjects()938b5840353SAdam Hornáček     public Set<Project> getDefaultProjects() {
939b5840353SAdam Hornáček         return defaultProjects;
940b5840353SAdam Hornáček     }
941b5840353SAdam Hornáček 
getRamBufferSize()942b5840353SAdam Hornáček     public double getRamBufferSize() {
943b5840353SAdam Hornáček         return ramBufferSize;
944b5840353SAdam Hornáček     }
945b5840353SAdam Hornáček 
946b5840353SAdam Hornáček     /**
947ff44f24aSAdam Hornáček      * Set size of memory to be used for flushing docs (default 16 MB) (this can
948b5840353SAdam Hornáček      * improve index speed a LOT) note that this is per thread (lucene uses 8
949ff44f24aSAdam Hornáček      * threads by default in 4.x).
950b5840353SAdam Hornáček      *
951b5840353SAdam Hornáček      * @param ramBufferSize new size in MB
952b5840353SAdam Hornáček      */
setRamBufferSize(double ramBufferSize)953b5840353SAdam Hornáček     public void setRamBufferSize(double ramBufferSize) {
954b5840353SAdam Hornáček         this.ramBufferSize = ramBufferSize;
955b5840353SAdam Hornáček     }
956b5840353SAdam Hornáček 
isPrintProgress()957b5840353SAdam Hornáček     public boolean isPrintProgress() {
958b5840353SAdam Hornáček         return printProgress;
959b5840353SAdam Hornáček     }
960b5840353SAdam Hornáček 
setPrintProgress(boolean printProgress)961b5840353SAdam Hornáček     public void setPrintProgress(boolean printProgress) {
962b5840353SAdam Hornáček         this.printProgress = printProgress;
963b5840353SAdam Hornáček     }
964b5840353SAdam Hornáček 
setAllowLeadingWildcard(boolean allowLeadingWildcard)965b5840353SAdam Hornáček     public void setAllowLeadingWildcard(boolean allowLeadingWildcard) {
966b5840353SAdam Hornáček         this.allowLeadingWildcard = allowLeadingWildcard;
967b5840353SAdam Hornáček     }
968b5840353SAdam Hornáček 
isAllowLeadingWildcard()969b5840353SAdam Hornáček     public boolean isAllowLeadingWildcard() {
970b5840353SAdam Hornáček         return allowLeadingWildcard;
971b5840353SAdam Hornáček     }
972b5840353SAdam Hornáček 
isQuickContextScan()973b5840353SAdam Hornáček     public boolean isQuickContextScan() {
974b5840353SAdam Hornáček         return quickContextScan;
975b5840353SAdam Hornáček     }
976b5840353SAdam Hornáček 
setQuickContextScan(boolean quickContextScan)977b5840353SAdam Hornáček     public void setQuickContextScan(boolean quickContextScan) {
978b5840353SAdam Hornáček         this.quickContextScan = quickContextScan;
979b5840353SAdam Hornáček     }
980b5840353SAdam Hornáček 
setIgnoredNames(IgnoredNames ignoredNames)981b5840353SAdam Hornáček     public void setIgnoredNames(IgnoredNames ignoredNames) {
982b5840353SAdam Hornáček         this.ignoredNames = ignoredNames;
983b5840353SAdam Hornáček     }
984b5840353SAdam Hornáček 
getIgnoredNames()985b5840353SAdam Hornáček     public IgnoredNames getIgnoredNames() {
986b5840353SAdam Hornáček         return ignoredNames;
987b5840353SAdam Hornáček     }
988b5840353SAdam Hornáček 
setIncludedNames(Filter includedNames)989b5840353SAdam Hornáček     public void setIncludedNames(Filter includedNames) {
990b5840353SAdam Hornáček         this.includedNames = includedNames;
991b5840353SAdam Hornáček     }
992b5840353SAdam Hornáček 
getIncludedNames()993b5840353SAdam Hornáček     public Filter getIncludedNames() {
994b5840353SAdam Hornáček         return includedNames;
995b5840353SAdam Hornáček     }
996b5840353SAdam Hornáček 
setUserPage(String userPage)997b5840353SAdam Hornáček     public void setUserPage(String userPage) {
998b5840353SAdam Hornáček         this.userPage = userPage;
999b5840353SAdam Hornáček     }
1000b5840353SAdam Hornáček 
getUserPage()1001b5840353SAdam Hornáček     public String getUserPage() {
1002b5840353SAdam Hornáček         return userPage;
1003b5840353SAdam Hornáček     }
1004b5840353SAdam Hornáček 
setUserPageSuffix(String userPageSuffix)1005b5840353SAdam Hornáček     public void setUserPageSuffix(String userPageSuffix) {
1006b5840353SAdam Hornáček         this.userPageSuffix = userPageSuffix;
1007b5840353SAdam Hornáček     }
1008b5840353SAdam Hornáček 
getUserPageSuffix()1009b5840353SAdam Hornáček     public String getUserPageSuffix() {
1010b5840353SAdam Hornáček         return userPageSuffix;
1011b5840353SAdam Hornáček     }
1012b5840353SAdam Hornáček 
setBugPage(String bugPage)1013b5840353SAdam Hornáček     public void setBugPage(String bugPage) {
1014b5840353SAdam Hornáček         this.bugPage = bugPage;
1015b5840353SAdam Hornáček     }
1016b5840353SAdam Hornáček 
getBugPage()1017b5840353SAdam Hornáček     public String getBugPage() {
1018b5840353SAdam Hornáček         return bugPage;
1019b5840353SAdam Hornáček     }
1020b5840353SAdam Hornáček 
1021b5840353SAdam Hornáček     /**
1022ff44f24aSAdam Hornáček      * Set the bug pattern to a new value.
1023b5840353SAdam Hornáček      *
1024b5840353SAdam Hornáček      * @param bugPattern the new pattern
1025b5840353SAdam Hornáček      * @throws PatternSyntaxException when the pattern is not a valid regexp or
1026b5840353SAdam Hornáček      * does not contain at least one capture group and the group does not
1027b5840353SAdam Hornáček      * contain a single character
1028b5840353SAdam Hornáček      */
setBugPattern(String bugPattern)1029b5840353SAdam Hornáček     public void setBugPattern(String bugPattern) throws PatternSyntaxException {
103064819763SVladimir Kotal         this.bugPattern = compilePattern(bugPattern);
1031b5840353SAdam Hornáček     }
1032b5840353SAdam Hornáček 
getBugPattern()1033b5840353SAdam Hornáček     public String getBugPattern() {
1034b5840353SAdam Hornáček         return bugPattern;
1035b5840353SAdam Hornáček     }
1036b5840353SAdam Hornáček 
getReviewPage()1037b5840353SAdam Hornáček     public String getReviewPage() {
1038b5840353SAdam Hornáček         return reviewPage;
1039b5840353SAdam Hornáček     }
1040b5840353SAdam Hornáček 
setReviewPage(String reviewPage)1041b5840353SAdam Hornáček     public void setReviewPage(String reviewPage) {
1042b5840353SAdam Hornáček         this.reviewPage = reviewPage;
1043b5840353SAdam Hornáček     }
1044b5840353SAdam Hornáček 
getReviewPattern()1045b5840353SAdam Hornáček     public String getReviewPattern() {
1046b5840353SAdam Hornáček         return reviewPattern;
1047b5840353SAdam Hornáček     }
1048b5840353SAdam Hornáček 
1049b5840353SAdam Hornáček     /**
1050ff44f24aSAdam Hornáček      * Set the review pattern to a new value.
1051b5840353SAdam Hornáček      *
1052b5840353SAdam Hornáček      * @param reviewPattern the new pattern
1053b5840353SAdam Hornáček      * @throws PatternSyntaxException when the pattern is not a valid regexp or
1054b5840353SAdam Hornáček      * does not contain at least one capture group and the group does not
1055b5840353SAdam Hornáček      * contain a single character
1056b5840353SAdam Hornáček      */
setReviewPattern(String reviewPattern)1057b5840353SAdam Hornáček     public void setReviewPattern(String reviewPattern) throws PatternSyntaxException {
105864819763SVladimir Kotal         this.reviewPattern = compilePattern(reviewPattern);
1059b5840353SAdam Hornáček     }
1060b5840353SAdam Hornáček 
getWebappLAF()1061b5840353SAdam Hornáček     public String getWebappLAF() {
1062b5840353SAdam Hornáček         return webappLAF;
1063b5840353SAdam Hornáček     }
1064b5840353SAdam Hornáček 
setWebappLAF(String webappLAF)1065b5840353SAdam Hornáček     public void setWebappLAF(String webappLAF) {
1066b5840353SAdam Hornáček         this.webappLAF = webappLAF;
1067b5840353SAdam Hornáček     }
1068b5840353SAdam Hornáček 
1069e829566cSChris Fraire     /**
1070e829566cSChris Fraire      * Gets a value indicating if the web app should run ctags as necessary.
1071e829566cSChris Fraire      */
isWebappCtags()1072e829566cSChris Fraire     public boolean isWebappCtags() {
1073e829566cSChris Fraire         return webappCtags;
1074e829566cSChris Fraire     }
1075e829566cSChris Fraire 
1076e829566cSChris Fraire     /**
1077e829566cSChris Fraire      * Sets a value indicating if the web app should run ctags as necessary.
1078e829566cSChris Fraire      */
setWebappCtags(boolean value)1079e829566cSChris Fraire     public void setWebappCtags(boolean value) {
1080e829566cSChris Fraire         this.webappCtags = value;
1081e829566cSChris Fraire     }
1082e829566cSChris Fraire 
getRemoteScmSupported()1083b5840353SAdam Hornáček     public RemoteSCM getRemoteScmSupported() {
1084b5840353SAdam Hornáček         return remoteScmSupported;
1085b5840353SAdam Hornáček     }
1086b5840353SAdam Hornáček 
setRemoteScmSupported(RemoteSCM remoteScmSupported)1087b5840353SAdam Hornáček     public void setRemoteScmSupported(RemoteSCM remoteScmSupported) {
1088b5840353SAdam Hornáček         this.remoteScmSupported = remoteScmSupported;
1089b5840353SAdam Hornáček     }
1090b5840353SAdam Hornáček 
isOptimizeDatabase()1091b5840353SAdam Hornáček     public boolean isOptimizeDatabase() {
1092b5840353SAdam Hornáček         return optimizeDatabase;
1093b5840353SAdam Hornáček     }
1094b5840353SAdam Hornáček 
setOptimizeDatabase(boolean optimizeDatabase)1095b5840353SAdam Hornáček     public void setOptimizeDatabase(boolean optimizeDatabase) {
1096b5840353SAdam Hornáček         this.optimizeDatabase = optimizeDatabase;
1097b5840353SAdam Hornáček     }
1098b5840353SAdam Hornáček 
getLuceneLocking()1099b5840353SAdam Hornáček     public LuceneLockName getLuceneLocking() {
1100b5840353SAdam Hornáček         return luceneLocking;
1101b5840353SAdam Hornáček     }
1102b5840353SAdam Hornáček 
1103b5840353SAdam Hornáček     /**
1104b5840353SAdam Hornáček      * @param value off|on|simple|native where "on" is an alias for "simple".
1105b5840353SAdam Hornáček      * Any other value is a fallback alias for "off" (with a logged warning).
1106b5840353SAdam Hornáček      */
setLuceneLocking(LuceneLockName value)1107b5840353SAdam Hornáček     public void setLuceneLocking(LuceneLockName value) {
1108b5840353SAdam Hornáček         this.luceneLocking = value;
1109b5840353SAdam Hornáček     }
1110b5840353SAdam Hornáček 
setCompressXref(boolean compressXref)1111b5840353SAdam Hornáček     public void setCompressXref(boolean compressXref) {
1112b5840353SAdam Hornáček         this.compressXref = compressXref;
1113b5840353SAdam Hornáček     }
1114b5840353SAdam Hornáček 
isCompressXref()1115b5840353SAdam Hornáček     public boolean isCompressXref() {
1116b5840353SAdam Hornáček         return compressXref;
1117b5840353SAdam Hornáček     }
1118b5840353SAdam Hornáček 
isIndexVersionedFilesOnly()1119b5840353SAdam Hornáček     public boolean isIndexVersionedFilesOnly() {
1120b5840353SAdam Hornáček         return indexVersionedFilesOnly;
1121b5840353SAdam Hornáček     }
1122b5840353SAdam Hornáček 
setIndexVersionedFilesOnly(boolean indexVersionedFilesOnly)1123b5840353SAdam Hornáček     public void setIndexVersionedFilesOnly(boolean indexVersionedFilesOnly) {
1124b5840353SAdam Hornáček         this.indexVersionedFilesOnly = indexVersionedFilesOnly;
1125b5840353SAdam Hornáček     }
1126b5840353SAdam Hornáček 
getIndexingParallelism()1127b5840353SAdam Hornáček     public int getIndexingParallelism() {
1128b5840353SAdam Hornáček         return indexingParallelism;
1129b5840353SAdam Hornáček     }
1130b5840353SAdam Hornáček 
setIndexingParallelism(int value)1131b5840353SAdam Hornáček     public void setIndexingParallelism(int value) {
1132c6f0939bSAdam Hornacek         this.indexingParallelism = Math.max(value, 0);
1133b5840353SAdam Hornáček     }
1134b5840353SAdam Hornáček 
getRepositoryInvalidationParallelism()11352123e367SVladimir Kotal     public int getRepositoryInvalidationParallelism() {
11362123e367SVladimir Kotal         return repositoryInvalidationParallelism;
11372123e367SVladimir Kotal     }
11382123e367SVladimir Kotal 
setRepositoryInvalidationParallelism(int value)11392123e367SVladimir Kotal     public void setRepositoryInvalidationParallelism(int value) {
11402123e367SVladimir Kotal         this.repositoryInvalidationParallelism = Math.max(value, 0);
11412123e367SVladimir Kotal     }
11422123e367SVladimir Kotal 
getHistoryParallelism()1143b5840353SAdam Hornáček     public int getHistoryParallelism() {
1144b5840353SAdam Hornáček         return historyParallelism;
1145b5840353SAdam Hornáček     }
1146b5840353SAdam Hornáček 
setHistoryParallelism(int value)1147b5840353SAdam Hornáček     public void setHistoryParallelism(int value) {
1148c6f0939bSAdam Hornacek         this.historyParallelism = Math.max(value, 0);
1149b5840353SAdam Hornáček     }
1150b5840353SAdam Hornáček 
getHistoryFileParallelism()1151dc607a84SVladimir Kotal     public int getHistoryFileParallelism() {
1152dc607a84SVladimir Kotal         return historyFileParallelism;
1153b5840353SAdam Hornáček     }
1154b5840353SAdam Hornáček 
setHistoryFileParallelism(int value)1155dc607a84SVladimir Kotal     public void setHistoryFileParallelism(int value) {
1156dc607a84SVladimir Kotal         this.historyFileParallelism = Math.max(value, 0);
1157b5840353SAdam Hornáček     }
1158b5840353SAdam Hornáček 
isTagsEnabled()1159b5840353SAdam Hornáček     public boolean isTagsEnabled() {
1160b5840353SAdam Hornáček         return this.tagsEnabled;
1161b5840353SAdam Hornáček     }
1162b5840353SAdam Hornáček 
setTagsEnabled(boolean tagsEnabled)1163b5840353SAdam Hornáček     public void setTagsEnabled(boolean tagsEnabled) {
1164b5840353SAdam Hornáček         this.tagsEnabled = tagsEnabled;
1165b5840353SAdam Hornáček     }
1166b5840353SAdam Hornáček 
setRevisionMessageCollapseThreshold(int threshold)1167b5840353SAdam Hornáček     public void setRevisionMessageCollapseThreshold(int threshold) {
1168b5840353SAdam Hornáček         this.revisionMessageCollapseThreshold = threshold;
1169b5840353SAdam Hornáček     }
1170b5840353SAdam Hornáček 
getRevisionMessageCollapseThreshold()1171b5840353SAdam Hornáček     public int getRevisionMessageCollapseThreshold() {
1172b5840353SAdam Hornáček         return this.revisionMessageCollapseThreshold;
1173b5840353SAdam Hornáček     }
1174b5840353SAdam Hornáček 
getCurrentIndexedCollapseThreshold()1175b5840353SAdam Hornáček     public int getCurrentIndexedCollapseThreshold() {
1176b5840353SAdam Hornáček         return currentIndexedCollapseThreshold;
1177b5840353SAdam Hornáček     }
1178b5840353SAdam Hornáček 
setCurrentIndexedCollapseThreshold(int currentIndexedCollapseThreshold)1179b5840353SAdam Hornáček     public void setCurrentIndexedCollapseThreshold(int currentIndexedCollapseThreshold) {
1180b5840353SAdam Hornáček         this.currentIndexedCollapseThreshold = currentIndexedCollapseThreshold;
1181b5840353SAdam Hornáček     }
1182b5840353SAdam Hornáček 
isDisplayRepositories()1183ad8a45cdSVladimir Kotal     public boolean isDisplayRepositories() {
1184b5840353SAdam Hornáček         return this.displayRepositories;
1185b5840353SAdam Hornáček     }
1186b5840353SAdam Hornáček 
setDisplayRepositories(boolean flag)1187b5840353SAdam Hornáček     public void setDisplayRepositories(boolean flag) {
1188b5840353SAdam Hornáček         this.displayRepositories = flag;
1189b5840353SAdam Hornáček     }
1190b5840353SAdam Hornáček 
getListDirsFirst()1191b5840353SAdam Hornáček     public boolean getListDirsFirst() {
1192b5840353SAdam Hornáček         return listDirsFirst;
1193b5840353SAdam Hornáček     }
1194b5840353SAdam Hornáček 
setListDirsFirst(boolean flag)1195b5840353SAdam Hornáček     public void setListDirsFirst(boolean flag) {
1196b5840353SAdam Hornáček         listDirsFirst = flag;
1197b5840353SAdam Hornáček     }
1198b5840353SAdam Hornáček 
1199b5840353SAdam Hornáček     /**
1200b5840353SAdam Hornáček      * The name of the file relative to the <var>DATA_ROOT</var>, which should
1201b5840353SAdam Hornáček      * be included into the footer of generated web pages.
1202b5840353SAdam Hornáček      */
1203b5840353SAdam Hornáček     public static final String FOOTER_INCLUDE_FILE = "footer_include";
1204b5840353SAdam Hornáček 
1205b5840353SAdam Hornáček     /**
1206b5840353SAdam Hornáček      * The name of the file relative to the <var>DATA_ROOT</var>, which should
1207b5840353SAdam Hornáček      * be included into the header of generated web pages.
1208b5840353SAdam Hornáček      */
1209b5840353SAdam Hornáček     public static final String HEADER_INCLUDE_FILE = "header_include";
1210b5840353SAdam Hornáček 
1211b5840353SAdam Hornáček     /**
1212b5840353SAdam Hornáček      * The name of the file relative to the <var>DATA_ROOT</var>, which should
1213b5840353SAdam Hornáček      * be included into the body of web app's "Home" page.
1214b5840353SAdam Hornáček      */
1215b5840353SAdam Hornáček     public static final String BODY_INCLUDE_FILE = "body_include";
1216b5840353SAdam Hornáček 
1217b5840353SAdam Hornáček     /**
1218b5840353SAdam Hornáček      * The name of the file relative to the <var>DATA_ROOT</var>, which should
1219b5840353SAdam Hornáček      * be included into the error page handling access forbidden errors - HTTP
1220b5840353SAdam Hornáček      * code 403 Forbidden.
1221b5840353SAdam Hornáček      */
1222b5840353SAdam Hornáček     public static final String E_FORBIDDEN_INCLUDE_FILE = "error_forbidden_include";
1223b5840353SAdam Hornáček 
122468c19b4cSAlexandrSergei4 
122568c19b4cSAlexandrSergei4     /**
122668c19b4cSAlexandrSergei4      * The name of the file relative to the <var>DATA_ROOT</var>, which should
122768c19b4cSAlexandrSergei4      * be included into the HTTP header of generated web pages.
122868c19b4cSAlexandrSergei4      */
122968c19b4cSAlexandrSergei4     public static final String HTTP_HEADER_INCLUDE_FILE = "http_header_include";
123068c19b4cSAlexandrSergei4 
1231b5840353SAdam Hornáček     /**
1232f197cd77SVladimir Kotal      * @return path to the file holding compiled path descriptions for the web application
1233f197cd77SVladimir Kotal      */
getDtagsEftarPath()1234f197cd77SVladimir Kotal     public Path getDtagsEftarPath() {
12350b77b425SVladimir Kotal         return Paths.get(getDataRoot(), EFTAR_DTAGS_NAME);
1236f197cd77SVladimir Kotal     }
1237f197cd77SVladimir Kotal 
getCTagsExtraOptionsFile()1238b5840353SAdam Hornáček     public String getCTagsExtraOptionsFile() {
1239b5840353SAdam Hornáček         return CTagsExtraOptionsFile;
1240b5840353SAdam Hornáček     }
1241b5840353SAdam Hornáček 
setCTagsExtraOptionsFile(String filename)1242b5840353SAdam Hornáček     public void setCTagsExtraOptionsFile(String filename) {
1243b5840353SAdam Hornáček         this.CTagsExtraOptionsFile = filename;
1244b5840353SAdam Hornáček     }
1245b5840353SAdam Hornáček 
getAllowedSymlinks()1246b5840353SAdam Hornáček     public Set<String> getAllowedSymlinks() {
1247b5840353SAdam Hornáček         return allowedSymlinks;
1248b5840353SAdam Hornáček     }
1249b5840353SAdam Hornáček 
setAllowedSymlinks(Set<String> allowedSymlinks)1250b5840353SAdam Hornáček     public void setAllowedSymlinks(Set<String> allowedSymlinks) {
1251b5840353SAdam Hornáček         this.allowedSymlinks = allowedSymlinks;
1252b5840353SAdam Hornáček     }
1253b5840353SAdam Hornáček 
getCanonicalRoots()12540e0ac58dSChris Fraire     public Set<String> getCanonicalRoots() {
12550e0ac58dSChris Fraire         return canonicalRoots;
12560e0ac58dSChris Fraire     }
12570e0ac58dSChris Fraire 
setCanonicalRoots(Set<String> canonicalRoots)12580e0ac58dSChris Fraire     public void setCanonicalRoots(Set<String> canonicalRoots) {
12590e0ac58dSChris Fraire         this.canonicalRoots = canonicalRoots;
12600e0ac58dSChris Fraire     }
12610e0ac58dSChris Fraire 
isObfuscatingEMailAddresses()1262b5840353SAdam Hornáček     public boolean isObfuscatingEMailAddresses() {
1263b5840353SAdam Hornáček         return obfuscatingEMailAddresses;
1264b5840353SAdam Hornáček     }
1265b5840353SAdam Hornáček 
setObfuscatingEMailAddresses(boolean obfuscate)1266b5840353SAdam Hornáček     public void setObfuscatingEMailAddresses(boolean obfuscate) {
1267b5840353SAdam Hornáček         this.obfuscatingEMailAddresses = obfuscate;
1268b5840353SAdam Hornáček     }
1269b5840353SAdam Hornáček 
isChattyStatusPage()1270b5840353SAdam Hornáček     public boolean isChattyStatusPage() {
1271b5840353SAdam Hornáček         return chattyStatusPage;
1272b5840353SAdam Hornáček     }
1273b5840353SAdam Hornáček 
setChattyStatusPage(boolean chattyStatusPage)1274b5840353SAdam Hornáček     public void setChattyStatusPage(boolean chattyStatusPage) {
1275b5840353SAdam Hornáček         this.chattyStatusPage = chattyStatusPage;
1276b5840353SAdam Hornáček     }
1277b5840353SAdam Hornáček 
isScopesEnabled()1278b5840353SAdam Hornáček     public boolean isScopesEnabled() {
1279b5840353SAdam Hornáček         return scopesEnabled;
1280b5840353SAdam Hornáček     }
1281b5840353SAdam Hornáček 
setScopesEnabled(boolean scopesEnabled)1282b5840353SAdam Hornáček     public void setScopesEnabled(boolean scopesEnabled) {
1283b5840353SAdam Hornáček         this.scopesEnabled = scopesEnabled;
1284b5840353SAdam Hornáček     }
1285b5840353SAdam Hornáček 
isFoldingEnabled()1286b5840353SAdam Hornáček     public boolean isFoldingEnabled() {
1287b5840353SAdam Hornáček         return foldingEnabled;
1288b5840353SAdam Hornáček     }
1289b5840353SAdam Hornáček 
setFoldingEnabled(boolean foldingEnabled)1290b5840353SAdam Hornáček     public void setFoldingEnabled(boolean foldingEnabled) {
1291b5840353SAdam Hornáček         this.foldingEnabled = foldingEnabled;
1292b5840353SAdam Hornáček     }
1293b5840353SAdam Hornáček 
getMaxSearchThreadCount()1294b5840353SAdam Hornáček     public int getMaxSearchThreadCount() {
1295b5840353SAdam Hornáček         return MaxSearchThreadCount;
1296b5840353SAdam Hornáček     }
1297b5840353SAdam Hornáček 
setMaxSearchThreadCount(int count)1298b5840353SAdam Hornáček     public void setMaxSearchThreadCount(int count) {
1299b5840353SAdam Hornáček         this.MaxSearchThreadCount = count;
1300b5840353SAdam Hornáček     }
1301b5840353SAdam Hornáček 
getMaxRevisionThreadCount()1302fb531549SVladimir Kotal     public int getMaxRevisionThreadCount() {
1303fb531549SVladimir Kotal         return MaxRevisionThreadCount;
1304fb531549SVladimir Kotal     }
1305fb531549SVladimir Kotal 
setMaxRevisionThreadCount(int count)1306fb531549SVladimir Kotal     public void setMaxRevisionThreadCount(int count) {
1307fb531549SVladimir Kotal         this.MaxRevisionThreadCount = count;
1308fb531549SVladimir Kotal     }
1309fb531549SVladimir Kotal 
isProjectsEnabled()1310b5840353SAdam Hornáček     public boolean isProjectsEnabled() {
1311b5840353SAdam Hornáček         return projectsEnabled;
1312b5840353SAdam Hornáček     }
1313b5840353SAdam Hornáček 
setProjectsEnabled(boolean flag)1314b5840353SAdam Hornáček     public void setProjectsEnabled(boolean flag) {
1315b5840353SAdam Hornáček         this.projectsEnabled = flag;
1316b5840353SAdam Hornáček     }
1317b5840353SAdam Hornáček 
getSuggesterConfig()1318911e8af0SAdam Hornáček     public SuggesterConfig getSuggesterConfig() {
1319911e8af0SAdam Hornáček         return suggesterConfig;
1320911e8af0SAdam Hornáček     }
1321911e8af0SAdam Hornáček 
setSuggesterConfig(final SuggesterConfig config)1322911e8af0SAdam Hornáček     public void setSuggesterConfig(final SuggesterConfig config) {
1323911e8af0SAdam Hornáček         if (config == null) {
1324911e8af0SAdam Hornáček             throw new IllegalArgumentException("Cannot set Suggester configuration to null");
1325911e8af0SAdam Hornáček         }
1326911e8af0SAdam Hornáček         this.suggesterConfig = config;
1327911e8af0SAdam Hornáček     }
1328911e8af0SAdam Hornáček 
getStatsdConfig()13290d7ace53SVladimir Kotal     public StatsdConfig getStatsdConfig() {
13300d7ace53SVladimir Kotal         return statsdConfig;
13310d7ace53SVladimir Kotal     }
13320d7ace53SVladimir Kotal 
setStatsdConfig(final StatsdConfig config)13330d7ace53SVladimir Kotal     public void setStatsdConfig(final StatsdConfig config) {
13340d7ace53SVladimir Kotal         if (config == null) {
13350d7ace53SVladimir Kotal             throw new IllegalArgumentException("Cannot set Statsd configuration to null");
13360d7ace53SVladimir Kotal         }
13370d7ace53SVladimir Kotal         this.statsdConfig = config;
13380d7ace53SVladimir Kotal     }
13390d7ace53SVladimir Kotal 
getDisabledRepositories()134029816c3bSChris Fraire     public Set<String> getDisabledRepositories() {
134129816c3bSChris Fraire         return disabledRepositories;
134229816c3bSChris Fraire     }
134329816c3bSChris Fraire 
setDisabledRepositories(Set<String> disabledRepositories)134429816c3bSChris Fraire     public void setDisabledRepositories(Set<String> disabledRepositories) {
134529816c3bSChris Fraire         this.disabledRepositories = disabledRepositories;
134629816c3bSChris Fraire     }
134729816c3bSChris Fraire 
getAuthenticationTokens()1348b0a23e73SVladimir Kotal     public Set<String> getAuthenticationTokens() {
1349b0a23e73SVladimir Kotal         return authenticationTokens;
1350b0a23e73SVladimir Kotal     }
1351b0a23e73SVladimir Kotal 
setAuthenticationTokens(Set<String> tokens)1352b0a23e73SVladimir Kotal     public void setAuthenticationTokens(Set<String> tokens) {
1353b0a23e73SVladimir Kotal         this.authenticationTokens = tokens;
1354b0a23e73SVladimir Kotal     }
1355b0a23e73SVladimir Kotal 
getIndexerAuthenticationToken()13568d34347cSVladimir Kotal     public String getIndexerAuthenticationToken() {
13578d34347cSVladimir Kotal         return indexerAuthenticationToken;
13588d34347cSVladimir Kotal     }
13598d34347cSVladimir Kotal 
setIndexerAuthenticationToken(String token)13608d34347cSVladimir Kotal     public void setIndexerAuthenticationToken(String token) {
13618d34347cSVladimir Kotal         this.indexerAuthenticationToken = token;
13628d34347cSVladimir Kotal     }
13638d34347cSVladimir Kotal 
isAllowInsecureTokens()136460e45c9fSVladimir Kotal     public boolean isAllowInsecureTokens() {
136560e45c9fSVladimir Kotal         return this.allowInsecureTokens;
136660e45c9fSVladimir Kotal     }
136760e45c9fSVladimir Kotal 
setAllowInsecureTokens(boolean value)136860e45c9fSVladimir Kotal     public void setAllowInsecureTokens(boolean value) {
136960e45c9fSVladimir Kotal         this.allowInsecureTokens = value;
137060e45c9fSVladimir Kotal     }
137160e45c9fSVladimir Kotal 
getHistoryChunkCount()1372a2f09795SVladimir Kotal     public int getHistoryChunkCount() {
1373a2f09795SVladimir Kotal         return historyChunkCount;
1374a2f09795SVladimir Kotal     }
1375a2f09795SVladimir Kotal 
setHistoryChunkCount(int historyChunkCount)1376a2f09795SVladimir Kotal     public void setHistoryChunkCount(int historyChunkCount) {
1377a2f09795SVladimir Kotal         this.historyChunkCount = historyChunkCount;
1378a2f09795SVladimir Kotal     }
1379a2f09795SVladimir Kotal 
isHistoryCachePerPartesEnabled()13805a635a8eSVladimir Kotal     public boolean isHistoryCachePerPartesEnabled() {
13815a635a8eSVladimir Kotal         return historyCachePerPartesEnabled;
13825a635a8eSVladimir Kotal     }
13835a635a8eSVladimir Kotal 
setHistoryCachePerPartesEnabled(boolean historyCachePerPartesEnabled)13845a635a8eSVladimir Kotal     public void setHistoryCachePerPartesEnabled(boolean historyCachePerPartesEnabled) {
13855a635a8eSVladimir Kotal         this.historyCachePerPartesEnabled = historyCachePerPartesEnabled;
13865a635a8eSVladimir Kotal     }
13875a635a8eSVladimir Kotal 
getServerName()13880516dd21SVladimir Kotal     public String getServerName() {
13890516dd21SVladimir Kotal         return serverName;
13900516dd21SVladimir Kotal     }
13910516dd21SVladimir Kotal 
setServerName(String serverName)13920516dd21SVladimir Kotal     public void setServerName(String serverName) {
13930516dd21SVladimir Kotal         this.serverName = serverName;
13940516dd21SVladimir Kotal     }
13950516dd21SVladimir Kotal 
getConnectTimeout()13961c258122SVladimir Kotal     public int getConnectTimeout() {
13971c258122SVladimir Kotal         return connectTimeout;
13981c258122SVladimir Kotal     }
13991c258122SVladimir Kotal 
setConnectTimeout(int connectTimeout)14001c258122SVladimir Kotal     public void setConnectTimeout(int connectTimeout) {
14011c258122SVladimir Kotal         if (connectTimeout < 0) {
14021c258122SVladimir Kotal             throw new IllegalArgumentException(String.format(NEGATIVE_NUMBER_ERROR, "connectTimeout", connectTimeout));
14031c258122SVladimir Kotal         }
14041c258122SVladimir Kotal         this.connectTimeout = connectTimeout;
14051c258122SVladimir Kotal     }
14061c258122SVladimir Kotal 
getApiTimeout()14071c258122SVladimir Kotal     public int getApiTimeout() {
14081c258122SVladimir Kotal         return apiTimeout;
14091c258122SVladimir Kotal     }
14101c258122SVladimir Kotal 
setApiTimeout(int apiTimeout)14111c258122SVladimir Kotal     public void setApiTimeout(int apiTimeout) {
14121c258122SVladimir Kotal         if (apiTimeout < 0) {
14131c258122SVladimir Kotal             throw new IllegalArgumentException(String.format(NEGATIVE_NUMBER_ERROR, "apiTimeout", apiTimeout));
14141c258122SVladimir Kotal         }
14151c258122SVladimir Kotal         this.apiTimeout = apiTimeout;
14161c258122SVladimir Kotal     }
14171c258122SVladimir Kotal 
isHistoryBasedReindex()1418f4571972SVladimir Kotal     public boolean isHistoryBasedReindex() {
1419f4571972SVladimir Kotal         return historyBasedReindex;
142012365fb4SVladimir Kotal     }
142112365fb4SVladimir Kotal 
setHistoryBasedReindex(boolean flag)1422f4571972SVladimir Kotal     public void setHistoryBasedReindex(boolean flag) {
1423f4571972SVladimir Kotal         historyBasedReindex = flag;
142412365fb4SVladimir Kotal     }
142512365fb4SVladimir Kotal 
1426b5840353SAdam Hornáček     /**
1427ff44f24aSAdam Hornáček      * Write the current configuration to a file.
1428b5840353SAdam Hornáček      *
1429b5840353SAdam Hornáček      * @param file the file to write the configuration into
1430b5840353SAdam Hornáček      * @throws IOException if an error occurs
1431b5840353SAdam Hornáček      */
write(File file)1432b5840353SAdam Hornáček     public void write(File file) throws IOException {
1433b5840353SAdam Hornáček         try (FileOutputStream out = new FileOutputStream(file)) {
1434b5840353SAdam Hornáček             this.encodeObject(out);
1435b5840353SAdam Hornáček         }
1436b5840353SAdam Hornáček     }
1437b5840353SAdam Hornáček 
getXMLRepresentationAsString()1438b5840353SAdam Hornáček     public String getXMLRepresentationAsString() {
1439b5840353SAdam Hornáček         ByteArrayOutputStream bos = new ByteArrayOutputStream();
1440b5840353SAdam Hornáček         this.encodeObject(bos);
1441b5840353SAdam Hornáček         return bos.toString();
1442b5840353SAdam Hornáček     }
1443b5840353SAdam Hornáček 
encodeObject(OutputStream out)1444b5840353SAdam Hornáček     public void encodeObject(OutputStream out) {
1445b5840353SAdam Hornáček         try (XMLEncoder e = new XMLEncoder(new BufferedOutputStream(out))) {
1446b5840353SAdam Hornáček             e.writeObject(this);
1447b5840353SAdam Hornáček         }
1448b5840353SAdam Hornáček     }
1449b5840353SAdam Hornáček 
read(File file)1450b5840353SAdam Hornáček     public static Configuration read(File file) throws IOException {
1451b5840353SAdam Hornáček         LOGGER.log(Level.INFO, "Reading configuration from {0}", file.getCanonicalPath());
1452b5840353SAdam Hornáček         try (FileInputStream in = new FileInputStream(file)) {
1453b5840353SAdam Hornáček             return decodeObject(in);
1454b5840353SAdam Hornáček         }
1455b5840353SAdam Hornáček     }
1456b5840353SAdam Hornáček 
makeXMLStringAsConfiguration(String xmlconfig)1457b5840353SAdam Hornáček     public static Configuration makeXMLStringAsConfiguration(String xmlconfig) throws IOException {
1458b5840353SAdam Hornáček         final Configuration ret;
1459b5840353SAdam Hornáček         final ByteArrayInputStream in = new ByteArrayInputStream(xmlconfig.getBytes());
1460b5840353SAdam Hornáček         ret = decodeObject(in);
1461b5840353SAdam Hornáček         return ret;
1462b5840353SAdam Hornáček     }
1463b5840353SAdam Hornáček 
146434836723SVladimir Kotal     @SuppressWarnings("lgtm[java/unsafe-deserialization]")
decodeObject(InputStream in)1465b5840353SAdam Hornáček     private static Configuration decodeObject(InputStream in) throws IOException {
1466b5840353SAdam Hornáček         final Object ret;
1467b5840353SAdam Hornáček         final LinkedList<Exception> exceptions = new LinkedList<>();
1468c6f0939bSAdam Hornacek         ExceptionListener listener = exceptions::addLast;
1469b5840353SAdam Hornáček 
147081511796SAdam Hornacek         try (XMLDecoder d = new XMLDecoder(new BufferedInputStream(in), null, listener,
147181511796SAdam Hornacek                 new ConfigurationClassLoader())) {
1472b5840353SAdam Hornáček             ret = d.readObject();
1473b5840353SAdam Hornáček         }
1474b5840353SAdam Hornáček 
1475b5840353SAdam Hornáček         if (!(ret instanceof Configuration)) {
1476b5840353SAdam Hornáček             throw new IOException("Not a valid config file");
1477b5840353SAdam Hornáček         }
1478b5840353SAdam Hornáček 
1479b5840353SAdam Hornáček         if (!exceptions.isEmpty()) {
1480b5840353SAdam Hornáček             // There was an exception during parsing.
148134836723SVladimir Kotal             // see addGroup()
1482b5840353SAdam Hornáček             if (exceptions.getFirst() instanceof IOException) {
1483b5840353SAdam Hornáček                 throw (IOException) exceptions.getFirst();
1484b5840353SAdam Hornáček             }
1485b5840353SAdam Hornáček             throw new IOException(exceptions.getFirst());
1486b5840353SAdam Hornáček         }
1487b5840353SAdam Hornáček 
1488b5840353SAdam Hornáček         Configuration conf = ((Configuration) ret);
1489b5840353SAdam Hornáček 
149034836723SVladimir Kotal         // Removes all non-root groups.
1491b5840353SAdam Hornáček         // This ensures that when the configuration is reloaded then the set
1492b5840353SAdam Hornáček         // contains only root groups. Subgroups are discovered again
1493b5840353SAdam Hornáček         // as follows below
1494c6f0939bSAdam Hornacek         conf.groups.removeIf(g -> g.getParent() != null);
1495b5840353SAdam Hornáček 
1496b5840353SAdam Hornáček         // Traversing subgroups and checking for duplicates,
1497b5840353SAdam Hornáček         // effectively transforms the group tree to a structure (Set)
1498b5840353SAdam Hornáček         // supporting an iterator.
1499b5840353SAdam Hornáček         TreeSet<Group> copy = new TreeSet<>();
1500b5840353SAdam Hornáček         LinkedList<Group> stack = new LinkedList<>(conf.groups);
1501b5840353SAdam Hornáček         while (!stack.isEmpty()) {
1502b5840353SAdam Hornáček             Group group = stack.pollFirst();
1503b5840353SAdam Hornáček             stack.addAll(group.getSubgroups());
1504b5840353SAdam Hornáček 
1505b5840353SAdam Hornáček             if (!copy.add(group)) {
1506b5840353SAdam Hornáček                 throw new IOException(
1507b5840353SAdam Hornáček                         String.format("Duplicate group name '%s' in configuration.",
1508b5840353SAdam Hornáček                                 group.getName()));
1509b5840353SAdam Hornáček             }
1510b5840353SAdam Hornáček 
1511b5840353SAdam Hornáček             // populate groups where the current group in in their subtree
1512b5840353SAdam Hornáček             Group tmp = group.getParent();
1513b5840353SAdam Hornáček             while (tmp != null) {
1514b5840353SAdam Hornáček                 tmp.addDescendant(group);
1515b5840353SAdam Hornáček                 tmp = tmp.getParent();
1516b5840353SAdam Hornáček             }
1517b5840353SAdam Hornáček         }
1518b5840353SAdam Hornáček         conf.setGroups(copy);
1519b5840353SAdam Hornáček 
1520fcbdc96bSChris Fraire         /*
1521fcbdc96bSChris Fraire          * Validate any defined canonicalRoot entries, and only include where
1522fcbdc96bSChris Fraire          * validation succeeds.
1523fcbdc96bSChris Fraire          */
1524fcbdc96bSChris Fraire         if (conf.canonicalRoots != null) {
1525fcbdc96bSChris Fraire             conf.canonicalRoots = conf.canonicalRoots.stream().filter(s -> {
1526fcbdc96bSChris Fraire                 String problem = CanonicalRootValidator.validate(s, "canonicalRoot element");
1527fcbdc96bSChris Fraire                 if (problem == null) {
1528fcbdc96bSChris Fraire                     return true;
1529fcbdc96bSChris Fraire                 } else {
1530fcbdc96bSChris Fraire                     LOGGER.warning(problem);
1531fcbdc96bSChris Fraire                     return false;
1532fcbdc96bSChris Fraire                 }
1533fcbdc96bSChris Fraire             }).collect(Collectors.toCollection(HashSet::new));
1534fcbdc96bSChris Fraire         }
1535fcbdc96bSChris Fraire 
1536b5840353SAdam Hornáček         return conf;
1537b5840353SAdam Hornáček     }
1538*61dce4cbSVladimir Kotal 
1539*61dce4cbSVladimir Kotal     public static class ConfigurationException extends Exception {
1540*61dce4cbSVladimir Kotal         static final long serialVersionUID = -1;
1541*61dce4cbSVladimir Kotal 
ConfigurationException(String message)1542*61dce4cbSVladimir Kotal         public ConfigurationException(String message) {
1543*61dce4cbSVladimir Kotal             super(message);
1544*61dce4cbSVladimir Kotal         }
1545*61dce4cbSVladimir Kotal     }
1546*61dce4cbSVladimir Kotal 
1547*61dce4cbSVladimir Kotal     /**
1548*61dce4cbSVladimir Kotal      * Check if configuration is populated and self-consistent.
1549*61dce4cbSVladimir Kotal      * @throws ConfigurationException on error
1550*61dce4cbSVladimir Kotal      */
checkConfiguration()1551*61dce4cbSVladimir Kotal     public void checkConfiguration() throws ConfigurationException {
1552*61dce4cbSVladimir Kotal 
1553*61dce4cbSVladimir Kotal         if (getSourceRoot() == null) {
1554*61dce4cbSVladimir Kotal             throw new ConfigurationException("Source root is not specified.");
1555*61dce4cbSVladimir Kotal         }
1556*61dce4cbSVladimir Kotal 
1557*61dce4cbSVladimir Kotal         if (getDataRoot() == null) {
1558*61dce4cbSVladimir Kotal             throw new ConfigurationException("Data root is not specified.");
1559*61dce4cbSVladimir Kotal         }
1560*61dce4cbSVladimir Kotal 
1561*61dce4cbSVladimir Kotal         if (!new File(getSourceRoot()).canRead()) {
1562*61dce4cbSVladimir Kotal             throw new ConfigurationException("Source root directory '" + getSourceRoot() + "' must be readable.");
1563*61dce4cbSVladimir Kotal         }
1564*61dce4cbSVladimir Kotal 
1565*61dce4cbSVladimir Kotal         if (!new File(getDataRoot()).canWrite()) {
1566*61dce4cbSVladimir Kotal             throw new ConfigurationException("Data root directory '" + getDataRoot() + "' must be writable.");
1567*61dce4cbSVladimir Kotal         }
1568*61dce4cbSVladimir Kotal 
1569*61dce4cbSVladimir Kotal         if (!isHistoryEnabled() && isHistoryBasedReindex()) {
1570*61dce4cbSVladimir Kotal             LOGGER.log(Level.INFO, "History based reindex is on, however history is off. " +
1571*61dce4cbSVladimir Kotal                     "History has to be enabled for history based reindex.");
1572*61dce4cbSVladimir Kotal         }
1573*61dce4cbSVladimir Kotal 
1574*61dce4cbSVladimir Kotal         if (!isHistoryCache() && isHistoryBasedReindex()) {
1575*61dce4cbSVladimir Kotal             LOGGER.log(Level.INFO, "History based reindex is on, however history cache is off. " +
1576*61dce4cbSVladimir Kotal                     "History cache has to be enabled for history based reindex.");
1577*61dce4cbSVladimir Kotal         }
1578*61dce4cbSVladimir Kotal     }
1579b5840353SAdam Hornáček }
1580