Configuration.java revision 1289
58N/A/*
58N/A * CDDL HEADER START
58N/A *
58N/A * The contents of this file are subject to the terms of the
58N/A * Common Development and Distribution License (the "License").
58N/A * You may not use this file except in compliance with the License.
58N/A *
58N/A * See LICENSE.txt included in this distribution for the specific
58N/A * language governing permissions and limitations under the License.
58N/A *
58N/A * When distributing Covered Code, include this CDDL HEADER in each
58N/A * file and include the License file at LICENSE.txt.
58N/A * If applicable, add the following below this CDDL HEADER, with the
58N/A * fields enclosed by brackets "[]" replaced with your own identifying
58N/A * information: Portions Copyright [yyyy] [name of copyright owner]
58N/A *
58N/A * CDDL HEADER END
58N/A */
58N/A
58N/A/*
77N/A * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
58N/A */
58N/Apackage org.opensolaris.opengrok.configuration;
58N/A
58N/Aimport java.beans.XMLDecoder;
234N/Aimport java.beans.XMLEncoder;
234N/Aimport java.io.BufferedInputStream;
234N/Aimport java.io.BufferedOutputStream;
234N/Aimport java.io.BufferedReader;
639N/Aimport java.io.ByteArrayInputStream;
639N/Aimport java.io.ByteArrayOutputStream;
234N/Aimport java.io.File;
234N/Aimport java.io.FileInputStream;
234N/Aimport java.io.FileOutputStream;
234N/Aimport java.io.FileReader;
639N/Aimport java.io.IOException;
639N/Aimport java.io.InputStream;
58N/Aimport java.io.OutputStream;
667N/Aimport java.util.ArrayList;
1016N/Aimport java.util.Collections;
58N/Aimport java.util.Date;
1016N/Aimport java.util.HashMap;
664N/Aimport java.util.HashSet;
112N/Aimport java.util.List;
58N/Aimport java.util.Map;
58N/Aimport java.util.Set;
77N/A
77N/Aimport org.opensolaris.opengrok.history.RepositoryInfo;
77N/Aimport org.opensolaris.opengrok.index.Filter;
77N/Aimport org.opensolaris.opengrok.index.IgnoredNames;
58N/Aimport org.opensolaris.opengrok.util.IOUtils;
418N/A
58N/A/**
773N/A * Placeholder class for all configuration variables. Due to the multithreaded
773N/A * nature of the web application, each thread will use the same instance of the
58N/A * configuration object for each page request. Class and methods should have
773N/A * package scope, but that didn't work with the XMLDecoder/XMLEncoder.
773N/A */
773N/Apublic final class Configuration {
773N/A private String ctags;
58N/A
773N/A /** Should the history log be cached? */
773N/A private boolean historyCache;
773N/A /**
773N/A * The maximum time in milliseconds {@code HistoryCache.get()} can take
58N/A * before its result is cached.
58N/A */
58N/A private int historyCacheTime;
664N/A
58N/A /** Should the history cache be stored in a database? */
65N/A private boolean historyCacheInDB;
894N/A
77N/A private List<Project> projects;
99N/A private String sourceRoot;
99N/A private String dataRoot;
125N/A private List<RepositoryInfo> repositories;
112N/A private String urlPrefix;
129N/A private boolean generateHtml;
129N/A /** Default project will be used, when no project is selected and no project is in cookie, so basically only the first time you open the first page, or when you clear your web cookies */
129N/A private Project defaultProject;
318N/A private int indexWordLimit;
318N/A private boolean verbose;
144N/A //if below is set, then we count how many files per project we need to process and print percentage of completion per project
173N/A private boolean printProgress;
253N/A private boolean allowLeadingWildcard;
296N/A private IgnoredNames ignoredNames;
335N/A private Filter includedNames;
480N/A private String userPage;
816N/A private String userPageSuffix;
816N/A private String bugPage;
833N/A private String bugPattern;
833N/A private String reviewPage;
993N/A private String reviewPattern;
1016N/A private String webappLAF;
993N/A private boolean remoteScmSupported;
993N/A private boolean optimizeDatabase;
993N/A private boolean useLuceneLocking;
993N/A private boolean compressXref;
993N/A private boolean indexVersionedFilesOnly;
993N/A private int hitsPerPage;
993N/A private int cachePages;
993N/A private String databaseDriver;
937N/A private String databaseUrl;
58N/A private int scanningDepth;
58N/A private Set<String> allowedSymlinks;
816N/A private boolean obfuscatingEMailAddresses;
58N/A private boolean chattyStatusPage;
58N/A private final Map<String,String> cmds;
773N/A private int tabSize;
58N/A
664N/A /**
58N/A * Get the default tab size (number of space characters per tab character)
850N/A * to use for each project. If {@code <= 0} tabs are read/write as is.
99N/A * @return current tab size set.
870N/A * @see Project#getTabSize()
870N/A * @see org.opensolaris.opengrok.analysis.ExpandTabsReader
99N/A */
101N/A public int getTabSize() {
106N/A return tabSize;
112N/A }
129N/A
129N/A /**
129N/A * Set the default tab size (number of space characters per tab character)
875N/A * to use for each project. If {@code <= 0} tabs are read/write as is.
318N/A * @param tabSize tabsize to set.
144N/A * @see Project#setTabSize(int)
173N/A * @see org.opensolaris.opengrok.analysis.ExpandTabsReader
253N/A */
296N/A public void setTabSize(int tabSize) {
335N/A this.tabSize = tabSize;
480N/A }
816N/A
816N/A public int getScanningDepth() {
993N/A return scanningDepth;
1016N/A }
58N/A
937N/A public void setScanningDepth(int scanningDepth) {
58N/A this.scanningDepth = scanningDepth;
58N/A }
58N/A
937N/A /** Creates a new instance of Configuration */
58N/A public Configuration() {
58N/A //defaults for an opengrok instance configuration
58N/A setHistoryCache(true);
937N/A setHistoryCacheTime(30);
816N/A setHistoryCacheInDB(false);
816N/A setProjects(new ArrayList<Project>());
816N/A setRepositories(new ArrayList<RepositoryInfo>());
816N/A setUrlPrefix("/source/s?");
816N/A //setUrlPrefix("../s?"); // TODO generate relative search paths, get rid of -w <webapp> option to indexer !
816N/A setCtags(System.getProperty("org.opensolaris.opengrok.analysis.Ctags", "ctags"));
816N/A //below can cause an outofmemory error, since it is defaulting to NO LIMIT
816N/A setIndexWordLimit(Integer.MAX_VALUE);
816N/A setVerbose(false);
816N/A setPrintProgress(false);
816N/A setGenerateHtml(true);
816N/A setQuickContextScan(true);
816N/A setIgnoredNames(new IgnoredNames());
816N/A setIncludedNames(new Filter());
816N/A setUserPage("http://www.opensolaris.org/viewProfile.jspa?username=");
773N/A setBugPage("http://bugs.opensolaris.org/bugdatabase/view_bug.do?bug_id=");
773N/A setBugPattern("\\b([12456789][0-9]{6})\\b");
773N/A setReviewPage("http://arc.opensolaris.org/caselog/PSARC/");
773N/A setReviewPattern("\\b(\\d{4}/\\d{3})\\b"); // in form e.g. PSARC 2008/305
773N/A setWebappLAF("default");
773N/A setRemoteScmSupported(false);
58N/A setOptimizeDatabase(true);
58N/A setUsingLuceneLocking(false);
58N/A setCompressXref(true);
773N/A setIndexVersionedFilesOnly(false);
773N/A setHitsPerPage(25);
773N/A setCachePages(5);
773N/A setScanningDepth(3); // default depth of scanning for repositories
773N/A setAllowedSymlinks(new HashSet<String>());
58N/A setTabSize(4);
58N/A cmds = new HashMap<String, String>();
58N/A }
773N/A
773N/A public String getRepoCmd(String clazzName) {
773N/A return cmds.get(clazzName);
773N/A }
773N/A
773N/A public String setRepoCmd(String clazzName, String cmd) {
773N/A if (clazzName == null) {
773N/A return null;
773N/A }
58N/A if (cmd == null || cmd.length() == 0) {
58N/A return cmds.remove(clazzName);
58N/A }
773N/A return cmds.put(clazzName, cmd);
773N/A }
773N/A
773N/A // just to satisfy bean/de|encoder stuff
773N/A public Map<String, String> getCmds() {
773N/A return Collections.unmodifiableMap(cmds);
773N/A }
58N/A
58N/A public void setCmds(Map<String, String> cmds) {
58N/A this.cmds.clear();
773N/A this.cmds.putAll(cmds);
773N/A }
773N/A
773N/A public String getCtags() {
773N/A return ctags;
773N/A }
773N/A
773N/A public void setCtags(String ctags) {
773N/A this.ctags = ctags;
773N/A }
773N/A
773N/A public int getCachePages() {
773N/A return cachePages;
773N/A }
773N/A
773N/A public void setCachePages(int cachePages) {
773N/A this.cachePages = cachePages;
773N/A }
773N/A
773N/A public int getHitsPerPage() {
773N/A return hitsPerPage;
773N/A }
773N/A
937N/A public void setHitsPerPage(int hitsPerPage) {
58N/A this.hitsPerPage = hitsPerPage;
58N/A }
58N/A
937N/A /**
58N/A * Should the history log be cached?
58N/A * @return {@code true} if a {@code HistoryCache} implementation should
58N/A * be used, {@code false} otherwise
937N/A */
58N/A public boolean isHistoryCache() {
58N/A return historyCache;
58N/A }
937N/A
58N/A /**
58N/A * Set whether history should be cached.
58N/A * @param historyCache if {@code true} enable history cache
937N/A */
58N/A public void setHistoryCache(boolean historyCache) {
58N/A this.historyCache = historyCache;
58N/A }
937N/A
58N/A /**
58N/A * How long can a history request take before it's cached? If the time
58N/A * is exceeded, the result is cached. This setting only affects
937N/A * {@code FileHistoryCache}.
664N/A *
58N/A * @return the maximum time in milliseconds a history request can take
58N/A * before it's cached
937N/A */
664N/A public int getHistoryCacheTime() {
58N/A return historyCacheTime;
58N/A }
937N/A
58N/A /**
58N/A * Set the maximum time a history request can take before it's cached.
58N/A * This setting is only respected if {@code FileHistoryCache} is used.
937N/A *
58N/A * @param historyCacheTime maximum time in milliseconds
58N/A */
58N/A public void setHistoryCacheTime(int historyCacheTime) {
937N/A this.historyCacheTime = historyCacheTime;
65N/A }
65N/A
65N/A /**
937N/A * Should the history cache be stored in a database? If yes,
65N/A * {@code JDBCHistoryCache} will be used to cache the history; otherwise,
65N/A * {@code FileHistoryCache} is used.
65N/A *
937N/A * @return whether the history cache should be stored in a database
77N/A */
77N/A public boolean isHistoryCacheInDB() {
77N/A return historyCacheInDB;
937N/A }
77N/A
77N/A /**
77N/A * Set whether the history cache should be stored in a database, and
99N/A * {@code JDBCHistoryCache} should be used instead of {@code
99N/A * FileHistoryCache}.
99N/A *
99N/A * @param historyCacheInDB whether the history cached should be stored in
99N/A * a database
99N/A */
99N/A public void setHistoryCacheInDB(boolean historyCacheInDB) {
99N/A this.historyCacheInDB = historyCacheInDB;
99N/A }
99N/A
99N/A public List<Project> getProjects() {
99N/A return projects;
99N/A }
99N/A
99N/A public void setProjects(List<Project> projects) {
99N/A this.projects = projects;
937N/A }
125N/A
125N/A public String getSourceRoot() {
125N/A return sourceRoot;
937N/A }
125N/A
125N/A public void setSourceRoot(String sourceRoot) {
125N/A this.sourceRoot = sourceRoot;
106N/A }
106N/A
937N/A public String getDataRoot() {
106N/A return dataRoot;
106N/A }
106N/A
937N/A public void setDataRoot(String dataRoot) {
106N/A this.dataRoot = dataRoot;
106N/A }
106N/A
112N/A public List<RepositoryInfo> getRepositories() {
112N/A return repositories;
112N/A }
112N/A
112N/A public void setRepositories(List<RepositoryInfo> repositories) {
112N/A this.repositories = repositories;
112N/A }
112N/A
129N/A public String getUrlPrefix() {
129N/A return urlPrefix;
129N/A }
129N/A
129N/A /**
129N/A * Set the URL prefix to be used by the {@link
129N/A * org.opensolaris.opengrok.analysis.executables.JavaClassAnalyzer} as well
129N/A * as lexers (see {@link org.opensolaris.opengrok.analysis.JFlexXref})
129N/A * when they create output with html links.
129N/A * @param urlPrefix prefix to use.
129N/A */
129N/A public void setUrlPrefix(String urlPrefix) {
129N/A this.urlPrefix = urlPrefix;
129N/A }
129N/A
129N/A public void setGenerateHtml(boolean generateHtml) {
129N/A this.generateHtml = generateHtml;
129N/A }
129N/A
129N/A public boolean isGenerateHtml() {
129N/A return generateHtml;
129N/A }
129N/A
129N/A public void setDefaultProject(Project defaultProject) {
937N/A this.defaultProject = defaultProject;
318N/A }
318N/A
318N/A public Project getDefaultProject() {
318N/A return defaultProject;
318N/A }
318N/A
318N/A public int getIndexWordLimit() {
318N/A return indexWordLimit;
318N/A }
318N/A
318N/A public void setIndexWordLimit(int indexWordLimit) {
318N/A this.indexWordLimit = indexWordLimit;
318N/A }
318N/A
318N/A public boolean isVerbose() {
144N/A return verbose;
144N/A }
144N/A
144N/A public void setVerbose(boolean verbose) {
144N/A this.verbose = verbose;
144N/A }
144N/A
144N/A public boolean isPrintProgress() {
173N/A return printProgress;
173N/A }
173N/A
173N/A public void setPrintProgress(boolean printProgress) {
173N/A this.printProgress = printProgress;
173N/A }
173N/A
173N/A public void setAllowLeadingWildcard(boolean allowLeadingWildcard) {
234N/A this.allowLeadingWildcard = allowLeadingWildcard;
253N/A }
253N/A
253N/A public boolean isAllowLeadingWildcard() {
253N/A return allowLeadingWildcard;
253N/A }
253N/A
253N/A private boolean quickContextScan;
253N/A
296N/A public boolean isQuickContextScan() {
296N/A return quickContextScan;
296N/A }
296N/A
296N/A public void setQuickContextScan(boolean quickContextScan) {
296N/A this.quickContextScan = quickContextScan;
296N/A }
335N/A
335N/A public void setIgnoredNames(IgnoredNames ignoredNames) {
335N/A this.ignoredNames = ignoredNames;
335N/A }
335N/A
335N/A public IgnoredNames getIgnoredNames() {
335N/A return ignoredNames;
335N/A }
335N/A
480N/A public void setIncludedNames(Filter includedNames) {
480N/A this.includedNames = includedNames;
480N/A }
480N/A
480N/A public Filter getIncludedNames() {
480N/A return includedNames;
480N/A }
937N/A
937N/A public void setUserPage(String userPage) {
667N/A this.userPage = userPage;
667N/A }
667N/A
833N/A public String getUserPage() {
833N/A return userPage;
833N/A }
833N/A
833N/A public void setUserPageSuffix(String userPageSuffix) {
833N/A this.userPageSuffix = userPageSuffix;
833N/A }
833N/A
833N/A public String getUserPageSuffix() {
833N/A return userPageSuffix;
833N/A }
833N/A
833N/A public void setBugPage(String bugPage) {
833N/A this.bugPage = bugPage;
833N/A }
833N/A
833N/A public String getBugPage() {
1016N/A return bugPage;
1016N/A }
1016N/A
1016N/A public void setBugPattern(String bugPattern) {
1016N/A this.bugPattern = bugPattern;
1016N/A }
1016N/A
1016N/A public String getBugPattern() {
234N/A return bugPattern;
234N/A }
234N/A
234N/A public String getReviewPage() {
234N/A return reviewPage;
234N/A }
509N/A
640N/A public void setReviewPage(String reviewPage) {
640N/A this.reviewPage = reviewPage;
640N/A }
640N/A
640N/A public String getReviewPattern() {
639N/A return reviewPattern;
937N/A }
639N/A
639N/A public void setReviewPattern(String reviewPattern) {
639N/A this.reviewPattern = reviewPattern;
639N/A }
639N/A
937N/A public String getWebappLAF() {
639N/A return webappLAF;
640N/A }
640N/A
640N/A public void setWebappLAF(String webappLAF) {
234N/A this.webappLAF = webappLAF;
234N/A }
234N/A
639N/A public boolean isRemoteScmSupported() {
640N/A return remoteScmSupported;
640N/A }
640N/A
640N/A public void setRemoteScmSupported(boolean remoteScmSupported) {
640N/A this.remoteScmSupported = remoteScmSupported;
639N/A }
937N/A
937N/A public boolean isOptimizeDatabase() {
937N/A return optimizeDatabase;
639N/A }
639N/A
639N/A public void setOptimizeDatabase(boolean optimizeDatabase) {
639N/A this.optimizeDatabase = optimizeDatabase;
639N/A }
639N/A
937N/A public boolean isUsingLuceneLocking() {
639N/A return useLuceneLocking;
640N/A }
640N/A
640N/A public void setUsingLuceneLocking(boolean useLuceneLocking) {
509N/A this.useLuceneLocking = useLuceneLocking;
234N/A }
234N/A
640N/A public void setCompressXref(boolean compressXref) {
234N/A this.compressXref = compressXref;
234N/A }
639N/A
58N/A public boolean isCompressXref() {
return compressXref;
}
public boolean isIndexVersionedFilesOnly() {
return indexVersionedFilesOnly;
}
public void setIndexVersionedFilesOnly(boolean indexVersionedFilesOnly) {
this.indexVersionedFilesOnly = indexVersionedFilesOnly;
}
public Date getDateForLastIndexRun() {
File timestamp = new File(getDataRoot(), "timestamp");
return new Date(timestamp.lastModified());
}
/**
* Return string from the header include file so it can be embedded into
* page header.
*/
public String getHeaderIncludeFileContent() {
StringBuilder contents = new StringBuilder();
File hdrfile = new File(getDataRoot(), "header_include");
try {
BufferedReader input = new BufferedReader(new FileReader(hdrfile));
try {
String line = null;
while (( line = input.readLine()) != null) {
contents.append(line);
contents.append(System.getProperty("line.separator"));
}
}
catch (java.io.IOException e) {
// TODO: use logger to produce error message
return "";
}
finally {
try {
input.close();
}
catch (Exception e) {
return contents.toString();
}
}
}
catch (java.io.FileNotFoundException e) {
// TODO: use logger to produce error message
return "";
}
return contents.toString();
}
public String getDatabaseDriver() {
return databaseDriver;
}
public void setDatabaseDriver(String databaseDriver) {
this.databaseDriver = databaseDriver;
}
public String getDatabaseUrl() {
return databaseUrl;
}
public void setDatabaseUrl(String databaseUrl) {
this.databaseUrl = databaseUrl;
}
public Set<String> getAllowedSymlinks() {
return allowedSymlinks;
}
public void setAllowedSymlinks(Set<String> allowedSymlinks) {
this.allowedSymlinks = allowedSymlinks;
}
public boolean isObfuscatingEMailAddresses() {
return obfuscatingEMailAddresses;
}
public void setObfuscatingEMailAddresses(boolean obfuscate) {
this.obfuscatingEMailAddresses = obfuscate;
}
public boolean isChattyStatusPage() {
return chattyStatusPage;
}
public void setChattyStatusPage(boolean chattyStatusPage) {
this.chattyStatusPage = chattyStatusPage;
}
/**
* Write the current configuration to a file
* @param file the file to write the configuration into
* @throws IOException if an error occurs
*/
public void write(File file) throws IOException {
final FileOutputStream out = new FileOutputStream(file);
try {
this.encodeObject(out);
} finally {
IOUtils.close(out);
}
}
public String getXMLRepresentationAsString() {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
this.encodeObject(bos);
return bos.toString();
}
private void encodeObject(OutputStream out) {
XMLEncoder e = new XMLEncoder(new BufferedOutputStream(out));
e.writeObject(this);
e.close();
}
public static Configuration read(File file) throws IOException {
final FileInputStream in = new FileInputStream(file);
try {
return decodeObject(in);
} finally {
IOUtils.close(in);
}
}
public static Configuration makeXMLStringAsConfiguration(String xmlconfig) throws IOException {
final Configuration ret;
final ByteArrayInputStream in = new ByteArrayInputStream(xmlconfig.getBytes());
ret = decodeObject(in);
return ret;
}
private static Configuration decodeObject(InputStream in) throws IOException {
XMLDecoder d = new XMLDecoder(new BufferedInputStream(in));
final Object ret = d.readObject();
d.close();
if (!(ret instanceof Configuration)) {
throw new IOException("Not a valid config file");
}
return (Configuration)ret;
}
}