/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* See LICENSE.txt included in this distribution for the specific
* language governing permissions and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at LICENSE.txt.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
/**
* This class is used to create / update the index databases. Currently we use
* one index database per project.
*
* @author Trond Norbye
* @author Lubos Kosco , update for lucene 3.0.0
*/
public class IndexDatabase {
private boolean interrupted;
private boolean dirty;
private boolean running;
/**
* Create a new instance of the Index Database. Use this constructor if
* you don't use any projects
*
* @throws java.io.IOException if an error occurs while creating directories
*/
this(null);
}
/**
* Create a new instance of an Index Database for a given project
* @param project the project to create the database for
* @throws IOException if an errror occurs while creating directories
*/
lockfact = new SimpleFSLockFactory();
initialize();
}
/**
* Update the index database for all of the projects. Print progress to
* standard out.
* @param executor An executor to run the job
* @throws IOException if an error occurs
*/
}
/**
* Update the index database for all of the projects
* @param executor An executor to run the job
* @param listener where to signal the changes to the database
* @throws IOException if an error occurs
*/
throws IOException
{
if (config.hasProjects()) {
}
} else {
}
for (IndexDatabase d : dbs) {
final IndexDatabase db = d;
}
public void run() {
try {
} catch (Throwable e) {
}
}
});
}
}
/**
* Update the index database for a number of sub-directories
* @param executor An executor to run the job
* @param listener where to signal the changes to the database
* @param paths
*/
{
} else {
try {
db = new IndexDatabase();
} else {
}
if (idx != -1) {
}
if (idx == -1) {
}
} else {
}
} catch (IOException e) {
}
}
public void run() {
try {
} catch (Throwable e) {
}
}
});
}
}
}
@SuppressWarnings("PMD.CollapsibleIfStatements")
synchronized (this) {
}
// to avoid race conditions, just recheck..
throw new FileNotFoundException("Failed to create root directory '"
}
}
throw new FileNotFoundException("Failed to create root directory '"
}
}
if (!config.isUsingLuceneLocking()) {
}
analyzerGuru = new AnalyzerGuru();
if (config.isGenerateHtml()) {
}
}
}
/**
* By default the indexer will traverse all directories in the project.
* If you add directories with this function update will just process
* the specified directories.
*
* @param dir The directory to scan
* @return <code>true</code> if the file is added, false oth
*/
@SuppressWarnings("PMD.UseStringBufferForStringAppends")
}
return true;
}
return false;
}
/**
* Update the content of this index database
* @throws IOException if an error occurs
* @throws HistoryException if an error occurs when accessing the history
*/
synchronized (lock) {
if (running) {
throw new IOException("Indexer already running");
}
running = true;
interrupted = false;
}
}
}
try {
//TODO we might need to add writer.commit after certain phases of
// index generation, right now it will only happen in the end
//iwc.setRAMBufferSizeMB(256.0); //TODO check what is the sweet spot
//writer.setMaxFieldLength(RuntimeEnvironment.getInstance().getIndexWordLimit());
if (directories.isEmpty()) {
} else {
}
}
} else {
}
try {
//TODO below should be optional, since it traverses the tree once more to get total count! :(
int file_cnt = 0;
if (config.isPrintProgress()) {
}
}
{
removeFile();
}
} finally {
}
}
} finally {
}
synchronized (lock) {
running = false;
}
}
if (!isInterrupted() && isDirty()) {
if (config.isOptimizeDatabase()) {
optimize();
}
+ "'used for timestamping the index database");
}
} else if (!timestamp.createNewFile()) {
+ "', used for timestamping the index database");
}
}
}
/**
* Optimize all index databases
* @param executor An executor to run the job
* @throws IOException if an error occurs
*/
if (config.hasProjects()) {
}
} else {
}
for (IndexDatabase d : dbs) {
final IndexDatabase db = d;
public void run() {
try {
} catch (Throwable e) {
+ e.getMessage());
}
}
});
}
}
}
/**
* Optimize the index database
*/
public void optimize() {
synchronized (lock) {
if (running) {
return ;
}
running = true;
}
@SuppressWarnings("resource")
@SuppressWarnings("resource")
try {
synchronized (lock) {
}
dirty = false;
}
} catch (IOException e) {
} finally {
synchronized (lock) {
running = false;
}
}
}
/**
* Generate a spelling suggestion for the definitions stored in defs
*/
@SuppressWarnings("resource")
public void createSpellingSuggestions() {
try {
//TODO below seems only to index "defs" , possible bug ?
iwc, false);
} catch (IOException e) {
+ this + ": " + e.getMessage());
} finally {
}
}
private boolean isDirty() {
synchronized (lock) {
return dirty;
}
}
private void setDirty() {
synchronized (lock) {
try {
}
dirty = true;
}
} catch (IOException e) {
}
}
}
/**
* Remove a stale file (uidIter.term().text()) from the index database
* (and the xref file)
* @throws java.io.IOException if an error occurs
*/
}
}
// Remove the parent directory if it's empty
}
setDirty();
}
}
/**
* Add a file to the Lucene index (and generate a xref file)
* @param file The file to add
* @param path The path to the file (from source root)
* @throws java.io.IOException if an error occurs
*/
@SuppressWarnings("resource")
final InputStream in =
try {
}
Document d;
try {
} catch (Exception e) {
"Skipped file ''{0}'' because the analyzer didn''t " +
"understand it.", path);
return;
}
// If mkdirs() returns false, the failure is most likely
// because the file already exists. But to check for the
// file first and only add it if it doesn't exists would
// only increase the file IO...
}
}
setDirty();
}
} finally {
}
}
/**
* Check if I should accept this file into the index database
* @param file the file to check
* @return true if the file should be included, false otherwise
*/
if (!includedNames.isEmpty() &&
// the filter should not affect directory names
return false;
}
return false;
}
return false;
}
try {
{
return false;
}
// below will only let go files and directories, anything else is
// considered special and is not added
return false;
}
} catch (IOException exp) {
}
if (file.isDirectory()) {
// always accept directories so that their files can be examined
return true;
}
// versioned files should always be accepted
return true;
}
// this is an unversioned file, check if it should be indexed
}
try {
return false;
}
// Now, let's verify that it's not a link back up the chain...
return false;
}
}
} catch (IOException ex) {
}
return false;
}
/**
* Check if I should accept the path containing a symlink
* @param absolutePath the path with a symlink to check
* @param canonicalPath the canonical path to the file
* @return true if the file should be accepted, false otherwise
*/
throws IOException
{
// Always accept local symlinks
if (isLocal(canonicalPath)) {
return true;
}
{
return true;
}
}
}
return false;
}
/**
* Check if a file is local to the current project. If we don't have
* projects, check if the file is in the source root.
*
* @param path the path to a file
* @return true if the file is local to the current repository
*/
boolean local = false;
if (config.hasProjects()) {
// File is under the current project, so it's local.
local = true;
}
} else {
// File is under source root, and we don't have projects, so
// consider it local.
local = true;
}
}
return local;
}
/**
* Generate indexes recursively
* @param dir the root indexDirectory to generate indexes for
* @param path the path
* @param count_only if true will just traverse the source root and count files
* @param cur_count current count during the traversal of the tree
* @param est_total estimate total files to process
* @return number of files indexed
*/
@SuppressWarnings("boxing")
{
int lcur_count=cur_count;
if (isInterrupted()) {
return lcur_count;
}
return lcur_count;
}
return lcur_count;
}
}
});
if (file.isDirectory()) {
} else {
lcur_count++;
if (count_only) {
continue;
}
{
new Object[] { lcur_count,
}
// construct uid for doc
{
removeFile();
}
{
continue;
}
}
try {
} catch (Exception e) {
}
}
}
}
return lcur_count;
}
/**
* Interrupt the index generation (and the index generation will stop as
* soon as possible)
*/
public void interrupt() {
synchronized (lock) {
interrupted = true;
}
}
private boolean isInterrupted() {
synchronized (lock) {
return interrupted;
}
}
/**
* Register an object to receive events when modifications is done to the
* index database.
*
* @param listener the object to receive the events
*/
}
/**
* Remove an object from the lists of objects to receive events when
* modifications is done to the index database
*
* @param listener the object to remove
*/
}
/**
* List all files in all of the index databases
* @throws IOException if an error occurs
*/
}
/**
* List all files in some of the index databases
* @param subFiles Subdirectories for the various projects to list the files
* for (or null or an empty list to dump all projects)
* @throws IOException if an error occurs
*/
if (config.hasProjects()) {
}
} else {
+ path + "'");
} else {
}
}
}
} else {
}
}
/**
* Print a listing of all of the files in this index database to stdout.
*
* @throws IOException If an IO error occurs while reading from the database
*/
@SuppressWarnings("resource")
try {
}
} finally {
}
}
}
final int limit = 4;
if (config.hasProjects()) {
}
} else {
} else {
}
}
}
} else {
}
}
@SuppressWarnings("resource")
try {
}
} else {
break;
}
}
} finally {
}
}
/**
* Get an indexReader for the Index database where a given file
* @param path the file to get the database for
* @return The index database where the file should be located or null if
* it cannot be located.
*/
if (config.hasProjects()) {
if (p == null) {
return null;
}
}
try {
@SuppressWarnings("resource")
}
}
return ret;
}
/**
* Get the latest definitions for a file from the index.
*
* @param file the file whose definitions to find
* @return definitions for the file, or {@code null} if they could not
* be found
* @throws IOException if an error happens when accessing the index
* @throws ParseException if an error happens when building the Lucene query
* @throws ClassNotFoundException if the class for the stored definitions
* instance cannot be found
*/
// No index, no definitions...
return null;
}
try {
try {
// No hits, no definitions...
return null;
}
// Only use the definitions if we found an exact match.
}
}
} finally {
}
} finally {
}
// Didn't find any definitions.
return null;
}
/**
* {@inheritDoc}
*/
return false;
}
return false;
}
}
/**
* {@inheritDoc}
*/
public int hashCode() {
int hash = 7;
return hash;
}
/**
* {@inheritDoc}
*/
}
}