RuntimeEnvironment.java revision 173
824N/A/*
824N/A * CDDL HEADER START
824N/A *
824N/A * The contents of this file are subject to the terms of the
824N/A * Common Development and Distribution License (the "License").
824N/A * You may not use this file except in compliance with the License.
824N/A *
824N/A * See LICENSE.txt included in this distribution for the specific
824N/A * language governing permissions and limitations under the License.
824N/A *
824N/A * When distributing Covered Code, include this CDDL HEADER in each
824N/A * file and include the License file at LICENSE.txt.
824N/A * If applicable, add the following below this CDDL HEADER, with the
824N/A * fields enclosed by brackets "[]" replaced with your own identifying
824N/A * information: Portions Copyright [yyyy] [name of copyright owner]
824N/A *
824N/A * CDDL HEADER END
824N/A */
824N/A
824N/A/*
824N/A * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
824N/A * Use is subject to license terms.
824N/A */
824N/Apackage org.opensolaris.opengrok.configuration;
824N/A
824N/Aimport java.beans.XMLDecoder;
824N/Aimport java.beans.XMLEncoder;
824N/Aimport java.io.BufferedInputStream;
824N/Aimport java.io.BufferedOutputStream;
824N/Aimport java.io.BufferedReader;
824N/Aimport java.io.File;
824N/Aimport java.io.FileInputStream;
824N/Aimport java.io.FileOutputStream;
824N/Aimport java.io.IOException;
824N/Aimport java.io.InputStreamReader;
824N/Aimport java.net.InetAddress;
824N/Aimport java.net.ServerSocket;
824N/Aimport java.net.Socket;
824N/Aimport java.net.SocketAddress;
824N/Aimport java.net.UnknownHostException;
824N/Aimport java.util.Date;
824N/Aimport java.util.List;
824N/Aimport java.util.Map;
824N/Aimport org.opensolaris.opengrok.history.ExternalRepository;
824N/Aimport org.opensolaris.opengrok.index.IgnoredNames;
824N/A
824N/A/**
824N/A * The RuntimeEnvironment class is used as a placeholder for the current
824N/A * configuration this execution context (classloader) is using.
824N/A */
824N/Apublic class RuntimeEnvironment {
824N/A private Configuration configuration;
824N/A private ThreadLocal<Configuration> threadConfig;
824N/A
824N/A private static RuntimeEnvironment instance = new RuntimeEnvironment();
824N/A
824N/A /**
824N/A * Get the one and only instance of the RuntimeEnvironment
824N/A * @return the one and only instance of the RuntimeEnvironment
824N/A */
824N/A public static RuntimeEnvironment getInstance() {
824N/A return instance;
824N/A }
824N/A
824N/A /**
824N/A * Creates a new instance of RuntimeEnvironment. Private to ensure a
824N/A * singleton pattern.
824N/A */
824N/A private RuntimeEnvironment() {
824N/A configuration = new Configuration();
824N/A threadConfig = new ThreadLocal<Configuration>() {
824N/A @Override protected Configuration initialValue() {
824N/A return configuration;
824N/A }
824N/A };
824N/A }
824N/A
824N/A /**
824N/A * Get the path to the where the index database is stored
824N/A * @return the path to the index database
824N/A */
824N/A public String getDataRootPath() {
824N/A return threadConfig.get().getDataRoot();
824N/A }
824N/A
824N/A /**
824N/A * Get a file representing the index database
824N/A * @return the index database
824N/A */
824N/A public File getDataRootFile() {
824N/A File ret = null;
824N/A String file = getDataRootPath();
824N/A if (file != null) {
824N/A ret = new File(file);
824N/A }
824N/A
824N/A return ret;
824N/A }
824N/A
824N/A /**
824N/A * Set the path to where the index database is stored
824N/A * @param data the index database
824N/A * @throws IOException if the path cannot be resolved
824N/A */
824N/A public void setDataRoot(File data) throws IOException {
824N/A threadConfig.get().setDataRoot(data.getCanonicalPath());
824N/A }
824N/A
824N/A /**
824N/A * Set the path to where the index database is stored
824N/A * @param dataRoot the index database
824N/A */
824N/A public void setDataRoot(String dataRoot) {
824N/A threadConfig.get().setDataRoot(dataRoot);
824N/A }
824N/A
824N/A /**
824N/A * Get the path to where the sources are located
824N/A * @return path to where the sources are located
824N/A */
824N/A public String getSourceRootPath() {
824N/A return threadConfig.get().getSourceRoot();
824N/A }
824N/A
824N/A /**
824N/A * Get a file representing the directory where the sources are located
824N/A * @return A file representing the directory where the sources are located
824N/A */
824N/A public File getSourceRootFile() {
824N/A File ret = null;
824N/A String file = getSourceRootPath();
824N/A if (file != null) {
824N/A ret = new File(file);
824N/A }
824N/A
824N/A return ret;
824N/A }
824N/A
824N/A /**
824N/A * Specify the source root
824N/A * @param source the location of the sources
824N/A * @throws IOException if the name cannot be resolved
824N/A */
824N/A public void setSourceRootFile(File source) throws IOException {
824N/A threadConfig.get().setSourceRoot(source.getCanonicalPath());
824N/A }
824N/A
824N/A /**
824N/A * Specify the source root
824N/A * @param sourceRoot the location of the sources
824N/A */
824N/A public void setSourceRoot(String sourceRoot) {
824N/A threadConfig.get().setSourceRoot(sourceRoot);
}
/**
* Do we have projects?
* @return true if we have projects
*/
public boolean hasProjects() {
List<Project> proj = getProjects();
return (proj != null && proj.size() > 0);
}
/**
* Get all of the projects
* @return a list containing all of the projects (may be null)
*/
public List<Project> getProjects() {
return threadConfig.get().getProjects();
}
/**
* Set the list of the projects
* @param projects the list of projects to use
*/
public void setProjects(List<Project> projects) {
threadConfig.get().setProjects(projects);
}
/**
* Register this thread in the thread/configuration map (so that all
* subsequent calls to the RuntimeEnvironment from this thread will use
* the same configuration
*/
public void register() {
threadConfig.set(configuration);
}
/**
* Get the context name of the web application
* @return the web applications context name
*/
public String getUrlPrefix() {
return threadConfig.get().getUrlPrefix();
}
/**
* Set the web context name
* @param urlPrefix the web applications context name
*/
public void setUrlPrefix(String urlPrefix) {
threadConfig.get().setUrlPrefix(urlPrefix);
}
/**
* Get the name of the ctags program in use
* @return the name of the ctags program in use
*/
public String getCtags() {
return threadConfig.get().getCtags();
}
/**
* Specify the CTags program to use
* @param ctags the ctags program to use
*/
public void setCtags(String ctags) {
threadConfig.get().setCtags(ctags);
}
/**
* Validate that I have a Exuberant ctags program I may use
* @return true if success, false otherwise
*/
public boolean validateExuberantCtags() {
String ctags = getCtags();
//Check if exub ctags is available
Process ctagsProcess = null;
try {
ctagsProcess = Runtime.getRuntime().exec(new String[] {ctags, "--version" });
} catch (Exception e) {
}
try {
BufferedReader cin = new BufferedReader(new InputStreamReader(ctagsProcess.getInputStream()));
String ctagOut;
if (!((ctagOut = cin.readLine()) != null && ctagOut.startsWith("Exuberant Ctags"))) {
System.err.println("Error: No Exuberant Ctags found in PATH!\n" +
"(tried running " + ctags + ")\n" +
"Please use option -c to specify path to a good Exuberant Ctags program");
return false;
}
} catch (Exception e) {
System.err.println("Error: executing " + ctags + "! " +e.getLocalizedMessage() +
"\nPlease use option -c to specify path to a good Exuberant Ctags program");
return false;
}
// reap the child process..
try {
int ret;
if ((ret = ctagsProcess.exitValue()) != 0) {
System.err.println("Error: ctags returned " + ret);
return false;
}
} catch (IllegalThreadStateException exp) {
// the process is still running??? just kill it..
ctagsProcess.destroy();
return true;
}
return true;
}
/**
* Get the max time a SMC operation may use to avoid beeing cached
* @return the max time
*/
public int getHistoryReaderTimeLimit() {
return threadConfig.get().getHistoryCacheTime();
}
/**
* Specify the maximum time a SCM operation should take before it will
* be cached (in ms)
* @param historyReaderTimeLimit the max time in ms before it is cached
*/
public void setHistoryReaderTimeLimit(int historyReaderTimeLimit) {
threadConfig.get().setHistoryCacheTime(historyReaderTimeLimit);
}
/**
* Is history cache currently enabled?
* @return true if history cache is enabled
*/
public boolean useHistoryCache() {
return threadConfig.get().isHistoryCache();
}
/**
* Specify if we should use history cache or not
* @param useHistoryCache set false if you do not want to use history cache
*/
public void setUseHistoryCache(boolean useHistoryCache) {
threadConfig.get().setHistoryCache(useHistoryCache);
}
/**
* Should we generate HTML or not during the indexing phase
* @return true if HTML should be generated during the indexing phase
*/
public boolean isGenerateHtml() {
return threadConfig.get().isGenerateHtml();
}
/**
* Specify if we should generate HTML or not during the indexing phase
* @param generateHtml set this to true to pregenerate HTML
*/
public void setGenerateHtml(boolean generateHtml) {
threadConfig.get().setGenerateHtml(generateHtml);
}
public boolean isQuickContextScan() {
return threadConfig.get().isQuickContextScan();
}
public void setQuickContextScan(boolean quickContextScan) {
threadConfig.get().setQuickContextScan(quickContextScan);
}
/**
* Get the map of external SCM repositories available
* @return A map containing all available SCMs
*/
public Map<String, ExternalRepository> getRepositories() {
return threadConfig.get().getRepositories();
}
/**
* Set the map of external SCM repositories
* @param repositories the repositories to use
*/
public void setRepositories(Map<String, ExternalRepository> repositories) {
threadConfig.get().setRepositories(repositories);
}
/**
* Set the project that is specified to be the default project to use. The
* default project is the project you will search (from the web application)
* if the page request didn't contain the cookie..
* @param defaultProject The default project to use
*/
public void setDefaultProject(Project defaultProject) {
threadConfig.get().setDefaultProject(defaultProject);
}
/**
* Get the project that is specified to be the default project to use. The
* default project is the project you will search (from the web application)
* if the page request didn't contain the cookie..
* @return the default project (may be null if not specified)
*/
public Project getDefaultProject() {
return threadConfig.get().getDefaultProject();
}
/**
* Chandan wrote the following answer on the opengrok-discuss list:
* "Traditionally search engines (specially spiders) think that large files
* are junk. Large files tend to be multimedia files etc., which text
* search spiders do not want to chew. So they ignore the contents of
* the file after a cutoff length. Lucene does this by number of words,
* which is by default is 10,000."
* By default OpenGrok will increase this limit to 60000, but it may be
* overridden in the configuration file
* @return The maximum words to index
*/
public int getIndexWordLimit() {
return threadConfig.get().getIndexWordLimit();
}
/**
* Set the number of words in a file Lucene will index.
* See getIndexWordLimit for a better description.
* @param indexWordLimit the number of words to index in a single file
*/
public void setIndexWordLimit(int indexWordLimit) {
threadConfig.get().setIndexWordLimit(indexWordLimit);
}
/**
* Is the verbosity flag turned on?
* @return true if we can print extra information
*/
public boolean isVerbose() {
return threadConfig.get().isVerbose();
}
/**
* Set the verbosity flag (to add extra debug information in output)
* @param verbose new value
*/
public void setVerbose(boolean verbose) {
threadConfig.get().setVerbose(verbose);
}
/**
* Specify if a search may start with a wildcard. Note that queries
* that start with a wildcard will give a significant impact on the
* search performace.
* @param allowLeadingWildcard set to true to activate (disabled by default)
*/
public void setAllowLeadingWildcard(boolean allowLeadingWildcard) {
threadConfig.get().setAllowLeadingWildcard(allowLeadingWildcard);
}
/**
* Is leading wildcards allowed?
* @return true if a search may start with a wildcard
*/
public boolean isAllowLeadingWildcard() {
return threadConfig.get().isAllowLeadingWildcard();
}
public IgnoredNames getIgnoredNames() {
return threadConfig.get().getIgnoredNames();
}
public void setIgnoredNames(IgnoredNames ignoredNames) {
threadConfig.get().setIgnoredNames(ignoredNames);
}
/**
* Returns the user page for the history listing
* @return the URL string fragment preceeding the username
*/
public String getUserPage() {
return threadConfig.get().getUserPage();
}
/**
* Sets the user page for the history listing
* @param userPage the URL fragment preceeding the username from history
*/
public void setUserPage(String userPage) {
threadConfig.get().setUserPage(userPage);
}
/**
* Returns the bug page for the history listing
* @return the URL string fragment preceeding the bug ID
*/
public String getBugPage() {
return threadConfig.get().getBugPage();
}
/**
* Sets the bug page for the history listing
* @param bugPage the URL fragment preceeding the bug ID
*/
public void setBugPage(String bugPage) {
threadConfig.get().setBugPage(bugPage);
}
/**
* Returns the bug regex for the history listing
* @return the regex that is looked for in history comments
*/
public String getBugPattern() {
return threadConfig.get().getBugPattern();
}
/**
* Sets the bug regex for the history listing
* @param bugPattern the regex to search history comments
*/
public void setBugPattern(String bugPattern) {
threadConfig.get().setBugPattern(bugPattern);
}
public String getWebappLAF() {
return threadConfig.get().getWebappLAF();
}
public void setWebappLAF(String laf) {
threadConfig.get().setWebappLAF(laf);
}
public boolean isRemoteScmSupported() {
return threadConfig.get().isRemoteScmSupported();
}
public void setRemoteScmSupported(boolean supported) {
threadConfig.get().setRemoteScmSupported(supported);
}
/**
* Read an configuration file and set it as the current configuration.
* @param file the file to read
* @throws IOException if an error occurs
*/
public void readConfiguration(File file) throws IOException {
XMLDecoder d = new XMLDecoder(
new BufferedInputStream(new FileInputStream(file)));
Object obj = d.readObject();
d.close();
if (obj instanceof Configuration) {
configuration = (Configuration)obj;
System.out.println("Config file " + file.getName() + " successfully read");
} else {
throw new IOException("Not a valid config file");
}
}
/**
* Write the current configuration to a file
* @param file the file to write the configuration into
* @throws IOException if an error occurs
*/
public void writeConfiguration(File file) throws IOException {
XMLEncoder e = new XMLEncoder(
new BufferedOutputStream(new FileOutputStream(file)));
e.writeObject(threadConfig.get());
e.close();
}
/**
* Write the current configuration to a socket
* @param host the host address to receive the configuration
* @param port the port to use on the host
* @throws IOException if an error occurs
*/
public void writeConfiguration(InetAddress host, int port) throws IOException {
Socket sock = new Socket(host, port);
XMLEncoder e = new XMLEncoder(sock.getOutputStream());
e.writeObject(threadConfig.get());
e.close();
try {
sock.close();
} catch (Exception ex) {
;
}
}
private ServerSocket configServerSocket;
/**
* Try to stop the configuration listener thread
*/
public void stopConfigurationListenerThread() {
try {
configServerSocket.close();
} catch (Exception e) {}
}
/**
* Start a thread to listen on a socket to receive new configurations
* to use.
* @param endpoint The socket address to listen on
* @return true if the endpoint was available (and the thread was started)
*/
public boolean startConfigurationListenerThread(SocketAddress endpoint) {
boolean ret = false;
try {
configServerSocket = new ServerSocket();
configServerSocket.bind(endpoint);
ret = true;
final ServerSocket sock = configServerSocket;
Thread t = new Thread(new Runnable() {
public void run() {
Socket s = null;
while (!sock.isClosed()) {
try {
System.out.flush();
s = sock.accept();
System.out.println((new Date()).toString() + " OpenGrok: Got request from " + s.getInetAddress().getHostAddress());
String line;
BufferedInputStream in = new BufferedInputStream(s.getInputStream());
XMLDecoder d = new XMLDecoder(new BufferedInputStream(in));
Object obj = d.readObject();
d.close();
if (obj instanceof Configuration) {
configuration = (Configuration)obj;
System.out.println("Configuration updated: " + configuration.getSourceRoot());
System.out.flush();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try { s.close(); } catch (Exception ex) { }
}
}
}
});
t.start();
} catch (UnknownHostException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
if (!ret && configServerSocket != null) {
try {
configServerSocket.close();
} catch (IOException ex) {
;
}
}
return ret;
}
}