Indexer.java revision 1238
0N/A/*
0N/A * CDDL HEADER START
0N/A *
0N/A * The contents of this file are subject to the terms of the
0N/A * Common Development and Distribution License (the "License").
0N/A * You may not use this file except in compliance with the License.
0N/A *
0N/A * See LICENSE.txt included in this distribution for the specific
0N/A * language governing permissions and limitations under the License.
0N/A *
0N/A * When distributing Covered Code, include this CDDL HEADER in each
0N/A * file and include the License file at LICENSE.txt.
0N/A * If applicable, add the following below this CDDL HEADER, with the
0N/A * fields enclosed by brackets "[]" replaced with your own identifying
0N/A * information: Portions Copyright [yyyy] [name of copyright owner]
0N/A *
0N/A * CDDL HEADER END
0N/A */
0N/A
0N/A/*
119N/A * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
0N/A *
0N/A * Portions Copyright 2011 Jens Elkner.
0N/A */
65N/Apackage org.opensolaris.opengrok.index;
0N/A
125N/Aimport java.io.File;
125N/Aimport java.io.IOException;
125N/Aimport java.lang.reflect.Field;
125N/Aimport java.net.InetAddress;
58N/Aimport java.text.ParseException;
77N/Aimport java.util.ArrayList;
125N/Aimport java.util.Collections;
125N/Aimport java.util.Comparator;
125N/Aimport java.util.HashMap;
125N/Aimport java.util.HashSet;
261N/Aimport java.util.List;
261N/Aimport java.util.Map;
126N/Aimport java.util.concurrent.ExecutorService;
58N/Aimport java.util.concurrent.Executors;
8N/Aimport java.util.concurrent.TimeUnit;
30N/Aimport java.util.logging.Level;
0N/Aimport java.util.logging.LogManager;
77N/Aimport java.util.logging.Logger;
0N/Aimport org.opensolaris.opengrok.Info;
0N/Aimport org.opensolaris.opengrok.OpenGrokLogger;
0N/Aimport org.opensolaris.opengrok.analysis.AnalyzerGuru;
0N/Aimport org.opensolaris.opengrok.configuration.Configuration;
0N/Aimport org.opensolaris.opengrok.configuration.Project;
0N/Aimport org.opensolaris.opengrok.configuration.RuntimeEnvironment;
0N/Aimport org.opensolaris.opengrok.history.HistoryException;
65N/Aimport org.opensolaris.opengrok.history.HistoryGuru;
65N/Aimport org.opensolaris.opengrok.history.Repository;
65N/Aimport org.opensolaris.opengrok.history.RepositoryFactory;
65N/Aimport org.opensolaris.opengrok.history.RepositoryInfo;
0N/Aimport org.opensolaris.opengrok.util.Getopt;
30N/A
58N/A/**
260N/A * Creates and updates an inverted source index
112N/A * as well as generates Xref, file stats etc., if specified
0N/A * in the options
0N/A */
0N/A@SuppressWarnings({"PMD.AvoidPrintStackTrace", "PMD.SystemPrintln"})
260N/Apublic final class Indexer {
0N/A
0N/A private static final String ON = "on";
0N/A private static final String OFF = "off";
0N/A private static Indexer index = new Indexer();
0N/A private static final Logger log = Logger.getLogger(Indexer.class.getName());
11N/A
0N/A private static final String DERBY_EMBEDDED_DRIVER =
240N/A "org.apache.derby.jdbc.EmbeddedDriver";
58N/A
58N/A private static final String DERBY_CLIENT_DRIVER =
58N/A "org.apache.derby.jdbc.ClientDriver";
58N/A
77N/A public static Indexer getInstance() {
207N/A return index;
207N/A }
261N/A
260N/A /**
77N/A * Program entry point
260N/A * @param argv argument vector
112N/A */
77N/A @SuppressWarnings("PMD.UseStringBufferForStringAppends")
77N/A public static void main(String argv[]) {
77N/A boolean runIndex = true;
77N/A boolean update = true;
260N/A boolean optimizedChanged = false;
77N/A ArrayList<String> zapCache = new ArrayList<String>();
77N/A CommandLineOptions cmdOptions = new CommandLineOptions();
77N/A
0N/A if (argv.length == 0) {
77N/A System.err.println(cmdOptions.getUsage());
111N/A System.exit(1);
111N/A } else {
111N/A boolean searchRepositories = false;
111N/A ArrayList<String> subFiles = new ArrayList<String>();
111N/A ArrayList<String> repositories = new ArrayList<String>();
111N/A HashSet<String> allowedSymlinks = new HashSet<String>();
111N/A String configFilename = null;
111N/A String configHost = null;
111N/A boolean addProjects = false;
111N/A boolean refreshHistory = false;
111N/A String defaultProject = null;
111N/A boolean listFiles = false;
77N/A boolean listRepos = false;
77N/A boolean createDict = false;
77N/A int noThreads = 2 + (2 * Runtime.getRuntime().availableProcessors());
207N/A
207N/A // Parse command line options:
77N/A Getopt getopt = new Getopt(argv, cmdOptions.getCommandString());
77N/A
207N/A try {
207N/A getopt.parse();
77N/A } catch (ParseException ex) {
77N/A System.err.println("OpenGrok: " + ex.getMessage());
99N/A System.err.println(cmdOptions.getUsage());
77N/A System.exit(1);
77N/A }
77N/A
77N/A try {
77N/A Configuration cfg = null;
77N/A int cmd;
77N/A
77N/A // We need to read the configuration file first, since we
0N/A // will try to overwrite options..
77N/A while ((cmd = getopt.getOpt()) != -1) {
77N/A if (cmd == 'R') {
77N/A cfg = Configuration.read(new File(getopt.getOptarg()));
77N/A break;
77N/A }
77N/A }
77N/A
77N/A if (cfg == null) {
77N/A cfg = new Configuration();
77N/A }
77N/A
111N/A String databaseDriver = cfg.getDatabaseDriver();
111N/A String databaseURL = cfg.getDatabaseUrl();
77N/A
77N/A // Now we can handle all the other options..
77N/A getopt.reset();
240N/A while ((cmd = getopt.getOpt()) != -1) {
173N/A switch (cmd) {
173N/A case 'x':
173N/A createDict = true;
173N/A runIndex = false;
254N/A break;
173N/A
173N/A case 'q':
173N/A cfg.setVerbose(false);
254N/A OpenGrokLogger.setOGConsoleLogLevel(Level.WARNING);
173N/A break;
173N/A case 'e':
173N/A cfg.setGenerateHtml(false);
253N/A break;
253N/A case 'P':
253N/A addProjects = true;
253N/A break;
253N/A case 'p':
253N/A defaultProject = getopt.getOptarg();
253N/A break;
253N/A case 'c':
253N/A cfg.setCtags(getopt.getOptarg());
253N/A break;
253N/A case 'w':
253N/A {
99N/A String webapp = getopt.getOptarg();
77N/A if (webapp.charAt(0) != '/' && !webapp.startsWith("http")) {
77N/A webapp = "/" + webapp;
77N/A }
77N/A if (webapp.endsWith("/")) {
77N/A cfg.setUrlPrefix(webapp + "s?");
0N/A } else {
0N/A cfg.setUrlPrefix(webapp + "/s?");
77N/A }
125N/A }
77N/A break;
77N/A case 'W':
205N/A configFilename = getopt.getOptarg();
205N/A break;
205N/A case 'U':
112N/A configHost = getopt.getOptarg();
112N/A break;
112N/A case 'R':
77N/A // already handled
106N/A break;
119N/A case 'N':
106N/A allowedSymlinks.add(getopt.getOptarg());
119N/A break;
106N/A case 'n':
119N/A runIndex = false;
119N/A break;
119N/A case 'H':
119N/A refreshHistory = true;
106N/A break;
106N/A case 'h':
106N/A repositories.add(getopt.getOptarg());
99N/A break;
99N/A case 'D':
99N/A cfg.setHistoryCacheInDB(true);
99N/A break;
99N/A case 'j':
99N/A databaseDriver = getopt.getOptarg();
99N/A // Should be a full class name, but we also accept
99N/A // the shorthands "client" and "embedded". Expand
99N/A // the shorthands here.
125N/A if ("client".equals(databaseDriver)) {
125N/A databaseDriver = DERBY_CLIENT_DRIVER;
125N/A } else if ("embedded".equals(databaseDriver)) {
125N/A databaseDriver = DERBY_EMBEDDED_DRIVER;
125N/A }
125N/A break;
125N/A case 'u':
125N/A databaseURL = getopt.getOptarg();
125N/A break;
126N/A case 'r':
125N/A {
125N/A if (getopt.getOptarg().equalsIgnoreCase(ON)) {
125N/A cfg.setRemoteScmSupported(true);
126N/A } else if (getopt.getOptarg().equalsIgnoreCase(OFF)) {
126N/A cfg.setRemoteScmSupported(false);
126N/A } else {
126N/A System.err.println("ERROR: You should pass either \"on\" or \"off\" as argument to -r");
126N/A System.err.println(" Ex: \"-r on\" will allow retrival for remote SCM systems");
126N/A System.err.println(" \"-r off\" will ignore SCM for remote systems");
126N/A }
126N/A }
126N/A break;
126N/A case 'O':
126N/A {
126N/A boolean oldval = cfg.isOptimizeDatabase();
126N/A if (getopt.getOptarg().equalsIgnoreCase(ON)) {
126N/A cfg.setOptimizeDatabase(true);
126N/A } else if (getopt.getOptarg().equalsIgnoreCase(OFF)) {
126N/A cfg.setOptimizeDatabase(false);
126N/A } else {
126N/A System.err.println("ERROR: You should pass either \"on\" or \"off\" as argument to -O");
126N/A System.err.println(" Ex: \"-O on\" will optimize the database as part of the index generation");
210N/A System.err.println(" \"-O off\" disable optimization of the index database");
210N/A }
210N/A if (oldval != cfg.isOptimizeDatabase()) {
210N/A optimizedChanged = true;
210N/A }
210N/A }
210N/A break;
126N/A case 'v':
126N/A cfg.setVerbose(true);
126N/A OpenGrokLogger.setOGConsoleLogLevel(Level.INFO);
126N/A break;
144N/A case 'C':
144N/A cfg.setPrintProgress(true);
144N/A break;
261N/A
261N/A case 's':
261N/A {
261N/A File sourceRoot = new File(getopt.getOptarg());
261N/A if (!sourceRoot.isDirectory()) {
261N/A System.err.println("ERROR: Source root must be a directory");
261N/A System.exit(1);
261N/A }
77N/A cfg.setSourceRoot(sourceRoot.getCanonicalPath());
99N/A break;
0N/A }
0N/A case 'd':
0N/A {
77N/A File dataRoot = new File(getopt.getOptarg());
77N/A if (!dataRoot.exists() && !dataRoot.mkdirs()) {
205N/A System.err.println("ERROR: Cannot create data root");
77N/A System.exit(1);
77N/A }
77N/A if (!dataRoot.isDirectory()) {
77N/A System.err.println("ERROR: Data root must be a directory");
77N/A System.exit(1);
58N/A }
58N/A cfg.setDataRoot(dataRoot.getCanonicalPath());
77N/A break;
260N/A }
0N/A case 'i':
0N/A cfg.getIgnoredNames().add(getopt.getOptarg());
77N/A break;
58N/A case 'I':
58N/A cfg.getIncludedNames().add(getopt.getOptarg());
58N/A break;
0N/A case 'S':
0N/A searchRepositories = true;
0N/A break;
58N/A case 'Q':
0N/A if (getopt.getOptarg().equalsIgnoreCase(ON)) {
0N/A cfg.setQuickContextScan(true);
0N/A } else if (getopt.getOptarg().equalsIgnoreCase(OFF)) {
0N/A cfg.setQuickContextScan(false);
58N/A } else {
0N/A System.err.println("ERROR: You should pass either \"on\" or \"off\" as argument to -Q");
260N/A System.err.println(" Ex: \"-Q on\" will just scan a \"chunk\" of the file and insert \"[..all..]\"");
0N/A System.err.println(" \"-Q off\" will try to build a more accurate list by reading the complete file.");
0N/A }
58N/A
77N/A break;
58N/A case 'm': {
58N/A try {
260N/A cfg.setIndexWordLimit(Integer.parseInt(getopt.getOptarg()));
0N/A } catch (NumberFormatException exp) {
0N/A System.err.println("ERROR: Failed to parse argument to \"-m\": " + exp.getMessage());
0N/A System.exit(1);
77N/A }
99N/A break;
0N/A }
0N/A case 'a':
77N/A if (getopt.getOptarg().equalsIgnoreCase(ON)) {
11N/A cfg.setAllowLeadingWildcard(true);
99N/A } else if (getopt.getOptarg().equalsIgnoreCase(OFF)) {
99N/A cfg.setAllowLeadingWildcard(false);
99N/A } else {
99N/A System.err.println("ERROR: You should pass either \"on\" or \"off\" as argument to -a");
11N/A System.err.println(" Ex: \"-a on\" will allow a search to start with a wildcard");
58N/A System.err.println(" \"-a off\" will disallow a search to start with a wildcard");
11N/A System.exit(1);
99N/A }
99N/A
99N/A break;
11N/A
77N/A case 'A':
58N/A {
77N/A String[] arg = getopt.getOptarg().split(":");
70N/A if (arg.length != 2) {
70N/A System.err.println("ERROR: You must specify: -A extension:class");
58N/A System.err.println(" Ex: -A foo:org.opensolaris.opengrok.analysis.c.CAnalyzer");
77N/A System.err.println(" will use the C analyzer for all files ending with .foo");
70N/A System.err.println(" Ex: -A c:-");
58N/A System.err.println(" will disable the c-analyzer for for all files ending with .c");
58N/A System.exit(1);
77N/A }
77N/A
99N/A arg[0] = arg[0].substring(arg[0].lastIndexOf('.') + 1).toUpperCase();
99N/A if (arg[1].equals("-")) {
99N/A AnalyzerGuru.addExtension(arg[0], null);
99N/A break;
77N/A }
77N/A
77N/A try {
77N/A AnalyzerGuru.addExtension(
77N/A arg[0],
77N/A AnalyzerGuru.findFactory(arg[1]));
77N/A } catch (Exception e) {
77N/A log.log(Level.SEVERE, "Unable to use {0} as a FileAnalyzerFactory", arg[1]);
77N/A log.log(Level.SEVERE, "Stack: ",e.fillInStackTrace());
77N/A System.exit(1);
58N/A }
77N/A }
77N/A break;
77N/A case 'L':
77N/A cfg.setWebappLAF(getopt.getOptarg());
77N/A break;
77N/A case 'T':
77N/A try {
77N/A noThreads = Integer.parseInt(getopt.getOptarg());
77N/A } catch (NumberFormatException exp) {
99N/A System.err.println("ERROR: Failed to parse argument to \"-T\": " + exp.getMessage());
58N/A System.exit(1);
99N/A }
99N/A break;
99N/A case 'z':
99N/A try {
58N/A cfg.setScanningDepth(Integer.parseInt(getopt.getOptarg()));
99N/A } catch (NumberFormatException exp) {
99N/A System.err.println("ERROR: Failed to parse argument to \"-z\": " + exp.getMessage());
99N/A System.exit(1);
99N/A }
58N/A break;
112N/A case 'l':
58N/A if (getopt.getOptarg().equalsIgnoreCase(ON)) {
203N/A cfg.setUsingLuceneLocking(true);
240N/A } else if (getopt.getOptarg().equalsIgnoreCase(OFF)) {
240N/A cfg.setUsingLuceneLocking(false);
58N/A } else {
58N/A System.err.println("ERROR: You should pass either \"on\" or \"off\" as argument to -l");
207N/A System.err.println(" Ex: \"-l on\" will enable locks in Lucene");
207N/A System.err.println(" \"-l off\" will disable locks in Lucene");
207N/A }
207N/A break;
207N/A case 'B':
207N/A cfg.setUserPage(getopt.getOptarg());
207N/A break;
207N/A case 'X':
58N/A cfg.setUserPageSuffix(getopt.getOptarg());
261N/A break;
261N/A case 'V':
207N/A System.out.println(Info.getFullVersion());
207N/A System.exit(0);
261N/A break;
261N/A case 'k':
261N/A zapCache.add(getopt.getOptarg());
261N/A break;
261N/A case 'K':
261N/A listRepos = true;
261N/A break;
261N/A case '?':
261N/A System.err.println(cmdOptions.getUsage());
261N/A System.exit(0);
261N/A break;
261N/A case 't':
261N/A try {
261N/A int tmp = Integer.parseInt(getopt.getOptarg());
261N/A cfg.setTabSize(tmp);
261N/A } catch (NumberFormatException exp) {
261N/A System.err.println("ERROR: Failed to parse argument to \"-t\": " + exp.getMessage());
261N/A System.exit(1);
261N/A }
261N/A break;
207N/A default:
207N/A System.err.println("Internal Error - Unimplemented cmdline option: " + (char) cmd);
207N/A System.exit(1);
58N/A }
58N/A }
58N/A
99N/A List<Class<? extends Repository>> repositoryClasses =
99N/A RepositoryFactory.getRepositoryClasses();
99N/A for (Class<? extends Repository> clazz : repositoryClasses) {
58N/A try {
58N/A Field f = clazz.getDeclaredField("CMD_PROPERTY_KEY");
58N/A Object key = f.get(null);
58N/A if (key != null) {
58N/A cfg.setRepoCmd(clazz.getCanonicalName(),
58N/A System.getProperty(key.toString()));
58N/A }
58N/A } catch (Exception e) {
58N/A // don't care
58N/A }
58N/A }
58N/A int optind = getopt.getOptind();
58N/A if (optind != -1) {
58N/A while (optind < argv.length) {
58N/A subFiles.add(argv[optind]);
58N/A ++optind;
99N/A }
99N/A }
99N/A
58N/A //logging starts here
58N/A if (cfg.isVerbose()) {
0N/A String fn=LogManager.getLogManager().getProperty("java.util.logging.FileHandler.pattern");
260N/A if (fn!=null) {System.out.println("Logging filehandler pattern: "+fn);}
260N/A }
260N/A
0N/A if (cfg.isHistoryCacheInDB()) {
0N/A // The default database driver is Derby's client driver.
0N/A if (databaseDriver == null) {
0N/A databaseDriver = DERBY_CLIENT_DRIVER;
260N/A }
260N/A
260N/A // The default URL depends on the database driver.
0N/A if (databaseURL == null) {
StringBuilder defaultURL = new StringBuilder();
defaultURL.append("jdbc:derby:");
if (databaseDriver.equals(DERBY_EMBEDDED_DRIVER)) {
defaultURL.append(cfg.getDataRoot())
.append(File.separator);
} else {
defaultURL.append("//localhost/");
}
defaultURL.append("cachedb;create=true");
databaseURL = defaultURL.toString();
}
}
cfg.setDatabaseDriver(databaseDriver);
cfg.setDatabaseUrl(databaseURL);
// automatically allow symlinks that are directly in source root
String file = cfg.getSourceRoot();
if (file != null) {
File sourceRootFile = new File(file);
File[] projectDirs = sourceRootFile.listFiles();
if (projectDirs != null) {
for (File projectDir : projectDirs) {
if (!projectDir.getCanonicalPath().equals(projectDir.getAbsolutePath())) {
allowedSymlinks.add(projectDir.getAbsolutePath());
}
}
}
}
allowedSymlinks.addAll(cfg.getAllowedSymlinks());
cfg.setAllowedSymlinks(allowedSymlinks);
//Set updated configuration in RuntimeEnvironment
RuntimeEnvironment env = RuntimeEnvironment.getInstance();
env.setConfiguration(cfg);
getInstance().prepareIndexer(env, searchRepositories, addProjects,
defaultProject, configFilename, refreshHistory,
listFiles, createDict, subFiles, repositories,
zapCache, listRepos);
if (listRepos || !zapCache.isEmpty()) {
return;
}
if (runIndex || (optimizedChanged && env.isOptimizeDatabase())) {
IndexChangedListener progress = new DefaultIndexChangedListener();
getInstance().doIndexerExecution(update, noThreads, subFiles,
progress);
}
getInstance().sendToConfigHost(env, configHost);
} catch (IndexerException ex) {
OpenGrokLogger.getLogger().log(Level.SEVERE, "Exception running indexer", ex);
System.err.println(cmdOptions.getUsage());
System.exit(1);
} catch (IOException ioe) {
System.err.println("Got IOException " + ioe);
OpenGrokLogger.getLogger().log(Level.SEVERE, "Exception running indexer", ioe);
System.exit(1);
}
}
}
// PMD wants us to use length() > 0 && charAt(0) instead of startsWith()
// for performance. We prefer clarity over performance here, so silence it.
@SuppressWarnings("PMD.SimplifyStartsWith")
public void prepareIndexer(RuntimeEnvironment env,
boolean searchRepositories,
boolean addProjects,
String defaultProject,
String configFilename,
boolean refreshHistory,
boolean listFiles,
boolean createDict,
List<String> subFiles,
List<String> repositories,
List<String> zapCache,
boolean listRepoPathes) throws IndexerException, IOException {
if (env.getDataRootPath() == null) {
throw new IndexerException("ERROR: Please specify a DATA ROOT path");
}
if (env.getSourceRootFile() == null) {
throw new IndexerException("ERROR: please specify a SRC_ROOT with option -s !");
}
if (!env.validateExuberantCtags()) {
throw new IndexerException("Didn't find Exuberant Ctags");
}
if (zapCache == null) {
throw new IndexerException("Internal error, zapCache shouldn't be null");
}
if (searchRepositories || listRepoPathes || !zapCache.isEmpty()) {
log.log(Level.INFO,"Scanning for repositories...");
long start = System.currentTimeMillis();
HistoryGuru.getInstance().addRepositories(env.getSourceRootPath());
long time = (System.currentTimeMillis() - start) / 1000;
log.log(Level.INFO, "Done scanning for repositories ({0}s)", time);
if (listRepoPathes || !zapCache.isEmpty()) {
List<RepositoryInfo> repos = env.getRepositories();
String prefix = env.getSourceRootPath();
if (listRepoPathes) {
if (repos.isEmpty()) {
System.out.println("No repositories found.");
return;
}
System.out.println("Repositories in " + prefix + ":");
for (RepositoryInfo info : env.getRepositories()) {
String dir = info.getDirectoryName();
System.out.println(dir.substring(prefix.length()));
}
}
if (!zapCache.isEmpty()) {
HashSet<String> toZap = new HashSet<String>(zapCache.size() << 1);
boolean all = false;
for (String repo : zapCache) {
if ("*".equals(repo)) {
all = true;
break;
}
if (repo.startsWith(prefix)) {
repo = repo.substring(prefix.length());
}
toZap.add(repo);
}
if (all) {
toZap.clear();
for (RepositoryInfo info : env.getRepositories()) {
toZap.add(info.getDirectoryName()
.substring(prefix.length()));
}
}
try {
HistoryGuru.getInstance().removeCache(toZap);
} catch (HistoryException e) {
log.warning("Clearing history cache faild: "
+ e.getLocalizedMessage());
}
}
return;
}
}
if (addProjects) {
File files[] = env.getSourceRootFile().listFiles();
List<Project> projects = env.getProjects();
// Keep a copy of the old project list so that we can preserve
// the customization of existing projects.
Map<String, Project> oldProjects = new HashMap<String, Project>();
for (Project p : projects) {
oldProjects.put(p.getPath(), p);
}
projects.clear();
// Add a project for each top-level directory in source root.
for (File file : files) {
String name = file.getName();
String path = "/" + name;
if (oldProjects.containsKey(path)) {
// This is an existing object. Reuse the old project,
// possibly with customizations, instead of creating a
// new with default values.
projects.add(oldProjects.get(path));
} else if (!name.startsWith(".") && file.isDirectory()) {
// Found a new directory with no matching project, so
// create a new project with default properties.
Project p = new Project();
p.setDescription(name);
p.setPath(path);
p.setTabSize(env.getConfiguration().getTabSize());
projects.add(p);
}
}
// The projects should be sorted...
Collections.sort(projects, new Comparator<Project>() {
@Override
public int compare(Project p1, Project p2) {
String s1 = p1.getDescription();
String s2 = p2.getDescription();
int ret;
if (s1 == null) {
ret = (s2 == null) ? 0 : 1;
} else {
ret = s1.compareTo(s2);
}
return ret;
}
});
}
if (defaultProject != null) {
for (Project p : env.getProjects()) {
if (p.getPath().equals(defaultProject)) {
env.setDefaultProject(p);
break;
}
}
}
if (configFilename != null) {
log.log(Level.INFO, "Writing configuration to {0}", configFilename);
env.writeConfiguration(new File(configFilename));
log.info("Done...");
}
if (refreshHistory) {
log.log(Level.INFO, "Generating history cache for all repositories ...");
HistoryGuru.getInstance().createCache();
log.info("Done...");
} else if (repositories != null && !repositories.isEmpty()) {
log.log(Level.INFO, "Generating history cache for specified repositories ...");
HistoryGuru.getInstance().createCache(repositories);
log.info("Done...");
}
if (listFiles) {
IndexDatabase.listAllFiles(subFiles);
}
if (createDict) {
IndexDatabase.listFrequentTokens(subFiles);
}
}
public void doIndexerExecution(final boolean update, int noThreads, List<String> subFiles,
IndexChangedListener progress)
throws IOException {
RuntimeEnvironment env = RuntimeEnvironment.getInstance().register();
log.info("Starting indexing");
ExecutorService executor = Executors.newFixedThreadPool(noThreads);
if (subFiles == null || subFiles.isEmpty()) {
if (update) {
IndexDatabase.updateAll(executor, progress);
} else if (env.isOptimizeDatabase()) {
IndexDatabase.optimizeAll(executor);
}
} else {
List<IndexDatabase> dbs = new ArrayList<IndexDatabase>();
for (String path : subFiles) {
Project project = Project.getProject(path);
if (project == null && env.hasProjects()) {
log.log(Level.WARNING, "Could not find a project for \"{0}\"", path);
} else {
IndexDatabase db;
if (project == null) {
db = new IndexDatabase();
} else {
db = new IndexDatabase(project);
}
int idx = dbs.indexOf(db);
if (idx != -1) {
db = dbs.get(idx);
}
if (db.addDirectory(path)) {
if (idx == -1) {
dbs.add(db);
}
} else {
log.log(Level.WARNING, "Directory does not exist \"{0}\"", path);
}
}
}
for (final IndexDatabase db : dbs) {
final boolean optimize = env.isOptimizeDatabase();
db.addIndexChangedListener(progress);
executor.submit(new Runnable() {
@Override
public void run() {
try {
if (update) {
db.update();
} else if (optimize) {
db.optimize();
}
} catch (Exception e) {
if (update) {
OpenGrokLogger.getLogger().log(Level.WARNING, "An error occured while updating index", e);
} else {
OpenGrokLogger.getLogger().log(Level.WARNING, "An error occured while optimizing index", e);
}
log.log(Level.SEVERE,"Stack trace: ",e.fillInStackTrace());
}
}
});
}
}
executor.shutdown();
while (!executor.isTerminated()) {
try {
// Wait forever
executor.awaitTermination(999,TimeUnit.DAYS);
} catch (InterruptedException exp) {
OpenGrokLogger.getLogger().log(Level.WARNING, "Received interrupt while waiting for executor to finish", exp);
}
}
}
public void sendToConfigHost(RuntimeEnvironment env, String configHost) {
if (configHost != null) {
String[] cfg = configHost.split(":");
log.log(Level.INFO, "Send configuration to: {0}", configHost);
if (cfg.length == 2) {
try {
InetAddress host = InetAddress.getByName(cfg[0]);
RuntimeEnvironment.getInstance().writeConfiguration(host, Integer.parseInt(cfg[1]));
} catch (Exception ex) {
log.log(Level.SEVERE, "Failed to send configuration to " + configHost+" (is web application server running with opengrok deployed?)", ex);
}
} else {
log.severe("Syntax error: ");
for (String s : cfg) {
log.log(Level.SEVERE, "[{0}]", s);
}
}
log.info("Configuration update routine done, check log output for errors.");
}
}
private Indexer() {
}
}