Reindex tickets on server start if no index exists

Check if tickets need to be reindexed when the server starts. This is the
case if no ticket index exists. In that case the ticket index is built.

This is done during the start of the `ITicketService`.

For this the interface of `ITicketService` needed to change. The `start`
method was defined abstract and the specific ticket services had to
implement it. None does any real starting stuff in it.
The `start` method is now final. It calls a new abstract method `onStart`
which the specific ticket services need to implement. In the existing
implementations I just changed `start` to `onStart`.
diff --git a/src/main/java/com/gitblit/tickets/BranchTicketService.java b/src/main/java/com/gitblit/tickets/BranchTicketService.java
index 7bef435..8430c54 100644
--- a/src/main/java/com/gitblit/tickets/BranchTicketService.java
+++ b/src/main/java/com/gitblit/tickets/BranchTicketService.java
@@ -110,9 +110,8 @@
 	}
 
 	@Override
-	public BranchTicketService start() {
+	public void onStart() {
 		log.info("{} started", getClass().getSimpleName());
-		return this;
 	}
 
 	@Override
diff --git a/src/main/java/com/gitblit/tickets/FileTicketService.java b/src/main/java/com/gitblit/tickets/FileTicketService.java
index 1e82f0d..0567046 100644
--- a/src/main/java/com/gitblit/tickets/FileTicketService.java
+++ b/src/main/java/com/gitblit/tickets/FileTicketService.java
@@ -80,9 +80,8 @@
 	}
 
 	@Override
-	public FileTicketService start() {
+	public void onStart() {
 		log.info("{} started", getClass().getSimpleName());
-		return this;
 	}
 
 	@Override
diff --git a/src/main/java/com/gitblit/tickets/ITicketService.java b/src/main/java/com/gitblit/tickets/ITicketService.java
index 20b6505..3252a60 100644
--- a/src/main/java/com/gitblit/tickets/ITicketService.java
+++ b/src/main/java/com/gitblit/tickets/ITicketService.java
@@ -181,7 +181,24 @@
 	 * @since 1.4.0
 	 */
 	@Override
-	public abstract ITicketService start();
+	public final ITicketService start() {
+		onStart();
+		if (shouldReindex()) {
+			log.info("Re-indexing all tickets...");
+//			long startTime = System.currentTimeMillis();
+			reindex();
+//			float duration = (System.currentTimeMillis() - startTime) / 1000f;
+//			log.info("Built Lucene index over all tickets in {} secs", duration);
+		}
+		return this;
+	}
+
+	/**
+	 * Start the specific ticket service implementation.
+	 *
+	 * @since 1.9.0
+	 */
+	public abstract void onStart();
 
 	/**
 	 * Stop the service.
@@ -197,6 +214,12 @@
 	}
 
 	/**
+	 * Closes any open resources used by this service.
+	 * @since 1.4.0
+	 */
+	protected abstract void close();
+
+	/**
 	 * Creates a ticket notifier.  The ticket notifier is not thread-safe!
 	 * @since 1.4.0
 	 */
@@ -274,12 +297,6 @@
 	}
 
 	/**
-	 * Closes any open resources used by this service.
-	 * @since 1.4.0
-	 */
-	protected abstract void close();
-
-	/**
 	 * Reset all caches in the service.
 	 * @since 1.4.0
 	 */
@@ -1343,6 +1360,18 @@
 		return indexer.queryFor(query, page, pageSize, sortBy, descending);
 	}
 
+
+	/**
+	 * Checks tickets should get re-indexed.
+	 *
+	 * @return true if tickets should get re-indexed, false otherwise.
+	 */
+	private boolean shouldReindex()
+	{
+		return indexer.shouldReindex();
+	}
+
+
 	/**
 	 * Destroys an existing index and reindexes all tickets.
 	 * This operation may be expensive and time-consuming.
diff --git a/src/main/java/com/gitblit/tickets/NullTicketService.java b/src/main/java/com/gitblit/tickets/NullTicketService.java
index 3947b94..050c699 100644
--- a/src/main/java/com/gitblit/tickets/NullTicketService.java
+++ b/src/main/java/com/gitblit/tickets/NullTicketService.java
@@ -61,9 +61,8 @@
 	}
 
 	@Override
-	public NullTicketService start() {
+	public void onStart() {
 		log.info("{} started", getClass().getSimpleName());
-		return this;
 	}
 
 	@Override
diff --git a/src/main/java/com/gitblit/tickets/RedisTicketService.java b/src/main/java/com/gitblit/tickets/RedisTicketService.java
index 0f9ad17..4e63231 100644
--- a/src/main/java/com/gitblit/tickets/RedisTicketService.java
+++ b/src/main/java/com/gitblit/tickets/RedisTicketService.java
@@ -83,12 +83,11 @@
 	}
 
 	@Override
-	public RedisTicketService start() {
+	public void onStart() {
 		log.info("{} started", getClass().getSimpleName());
 		if (!isReady()) {
 			log.warn("{} is not ready!", getClass().getSimpleName());
 		}
-		return this;
 	}
 
 	@Override
diff --git a/src/main/java/com/gitblit/tickets/TicketIndexer.java b/src/main/java/com/gitblit/tickets/TicketIndexer.java
index bc08fc8..7c16448 100644
--- a/src/main/java/com/gitblit/tickets/TicketIndexer.java
+++ b/src/main/java/com/gitblit/tickets/TicketIndexer.java
@@ -227,6 +227,18 @@
 	}
 
 	/**
+	 * Checks if a tickets index exists, that is compatible with Lucene.INDEX_VERSION
+	 * and the Lucene codec version.
+	 *
+	 * @return true if no tickets index is found, false otherwise.
+	 *
+	 * @since 1.9.0
+	 */
+	boolean shouldReindex() {
+		return ! this.indexStore.hasIndex();
+	}
+
+	/**
 	 * Bulk Add/Update tickets in the Lucene index
 	 *
 	 * @param tickets
@@ -665,4 +677,4 @@
 		int i = Integer.parseInt(val);
 		return i;
 	}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/com/gitblit/utils/LuceneIndexStore.java b/src/main/java/com/gitblit/utils/LuceneIndexStore.java
index 0ccfd2e..c05e201 100644
--- a/src/main/java/com/gitblit/utils/LuceneIndexStore.java
+++ b/src/main/java/com/gitblit/utils/LuceneIndexStore.java
@@ -92,7 +92,7 @@
 	{
 		return indexFolder.exists() &&
 				indexFolder.isDirectory() &&
-				(indexFolder.list().length > 1);
+				(indexFolder.list().length > 1);  // Must have more than 'write.lock'
 	}
 
 }
diff --git a/src/test/java/com/gitblit/tests/BranchTicketServiceTest.java b/src/test/java/com/gitblit/tests/BranchTicketServiceTest.java
index 0a5de19..0e9d887 100644
--- a/src/test/java/com/gitblit/tests/BranchTicketServiceTest.java
+++ b/src/test/java/com/gitblit/tests/BranchTicketServiceTest.java
@@ -59,7 +59,7 @@
 		IUserManager userManager = new UserManager(runtimeManager, pluginManager).start();
 		IRepositoryManager repositoryManager = new RepositoryManager(runtimeManager, pluginManager, userManager).start();
 
-		BranchTicketService service = new BranchTicketService(
+		BranchTicketService service = (BranchTicketService) new BranchTicketService(
 				runtimeManager,
 				pluginManager,
 				notificationManager,
diff --git a/src/test/java/com/gitblit/tests/FileTicketServiceTest.java b/src/test/java/com/gitblit/tests/FileTicketServiceTest.java
index 1fb2eed..c4a63c4 100644
--- a/src/test/java/com/gitblit/tests/FileTicketServiceTest.java
+++ b/src/test/java/com/gitblit/tests/FileTicketServiceTest.java
@@ -58,7 +58,7 @@
 		IUserManager userManager = new UserManager(runtimeManager, pluginManager).start();
 		IRepositoryManager repositoryManager = new RepositoryManager(runtimeManager, pluginManager, userManager).start();
 
-		FileTicketService service = new FileTicketService(
+		FileTicketService service = (FileTicketService) new FileTicketService(
 				runtimeManager,
 				pluginManager,
 				notificationManager,
diff --git a/src/test/java/com/gitblit/tests/RedisTicketServiceTest.java b/src/test/java/com/gitblit/tests/RedisTicketServiceTest.java
index 48011ad..5f3cb94 100644
--- a/src/test/java/com/gitblit/tests/RedisTicketServiceTest.java
+++ b/src/test/java/com/gitblit/tests/RedisTicketServiceTest.java
@@ -66,7 +66,7 @@
 		IUserManager userManager = new UserManager(runtimeManager, pluginManager).start();
 		IRepositoryManager repositoryManager = new RepositoryManager(runtimeManager, pluginManager, userManager).start();
 
-		RedisTicketService service = new RedisTicketService(
+		RedisTicketService service = (RedisTicketService) new RedisTicketService(
 				runtimeManager,
 				pluginManager,
 				notificationManager,
diff --git a/src/test/java/com/gitblit/tests/UITicketTest.java b/src/test/java/com/gitblit/tests/UITicketTest.java
index 54aa1e1..e89c32f 100644
--- a/src/test/java/com/gitblit/tests/UITicketTest.java
+++ b/src/test/java/com/gitblit/tests/UITicketTest.java
@@ -83,7 +83,7 @@
 		IUserManager userManager = new UserManager(runtimeManager, pluginManager).start();
 		IRepositoryManager repositoryManager = new RepositoryManager(runtimeManager, pluginManager, userManager).start();
 
-		BranchTicketService service = new BranchTicketService(
+		BranchTicketService service = (BranchTicketService) new BranchTicketService(
 				runtimeManager,
 				pluginManager,
 				notificationManager,