Merge "Bug 493823 - Apache Lucene indexer is shut down too soon"
diff --git a/core/plugins/org.eclipse.dltk.core.index.lucene/src/org/eclipse/dltk/internal/core/index/lucene/LuceneManager.java b/core/plugins/org.eclipse.dltk.core.index.lucene/src/org/eclipse/dltk/internal/core/index/lucene/LuceneManager.java
index 92fcf38..25c053d 100644
--- a/core/plugins/org.eclipse.dltk.core.index.lucene/src/org/eclipse/dltk/internal/core/index/lucene/LuceneManager.java
+++ b/core/plugins/org.eclipse.dltk.core.index.lucene/src/org/eclipse/dltk/internal/core/index/lucene/LuceneManager.java
@@ -31,20 +31,12 @@
 
 import org.apache.lucene.index.IndexWriter;
 import org.apache.lucene.search.SearcherManager;
-import org.eclipse.core.resources.ISaveContext;
-import org.eclipse.core.resources.ISaveParticipant;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Platform;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.dltk.core.DLTKLanguageManager;
 import org.eclipse.dltk.core.IDLTKLanguageToolkit;
+import org.eclipse.dltk.core.IShutdownListener;
 import org.eclipse.dltk.core.index.lucene.LucenePlugin;
-import org.eclipse.dltk.core.search.indexing.IndexManager;
 import org.eclipse.dltk.internal.core.ModelManager;
 import org.eclipse.dltk.internal.core.search.DLTKWorkspaceScope;
 
@@ -77,56 +69,11 @@
 	 */
 	INSTANCE;
 
-	private final class SaveParticipant extends Job
-			implements ISaveParticipant {
-
-		public SaveParticipant() {
-			super(""); //$NON-NLS-1$
-			setSystem(true);
-			setUser(false);
-		}
+	private static final class ShutdownListener implements IShutdownListener {
 
 		@Override
-		public void doneSaving(ISaveContext context) {
-			// ignore
-		}
-
-		@Override
-		public void prepareToSave(ISaveContext context) throws CoreException {
-			// ignore
-		}
-
-		@Override
-		public void rollback(ISaveContext context) {
-			// ignore
-		}
-
-		@Override
-		public void saving(ISaveContext context) throws CoreException {
-			// Close all indexes on workspace save
-			if (context.getKind() == ISaveContext.FULL_SAVE)
-				schedule();
-		}
-
-		@Override
-		public boolean belongsTo(Object family) {
-			return family == LucenePlugin.LUCENE_JOB_FAMILY;
-		}
-
-		@Override
-		protected IStatus run(IProgressMonitor monitor) {
-			IndexManager indexManager = ModelManager.getModelManager()
-					.getIndexManager();
-			// Wait for indexer before shutting down
-			while (indexManager.awaitingJobsCount() > 0) {
-				try {
-					Thread.sleep(100);
-				} catch (InterruptedException e) {
-					Logger.logException(e);
-				}
-			}
-			shutdown();
-			return Status.OK_STATUS;
+		public void shutdown() {
+			LuceneManager.INSTANCE.shutdown();
 		}
 
 	}
@@ -248,12 +195,9 @@
 		}
 		loadMappings();
 		registerIndexContainers();
-		try {
-			ResourcesPlugin.getWorkspace().addSaveParticipant(LucenePlugin.ID,
-					new SaveParticipant());
-		} catch (CoreException e) {
-			Logger.logException(e);
-		}
+		ModelManager.getModelManager().getIndexManager()
+				.addShutdownListener(new ShutdownListener());
+
 	}
 
 	private synchronized void shutdown() {
diff --git a/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/core/search/indexing/IndexManager.java b/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/core/search/indexing/IndexManager.java
index 8644957..0d10593 100644
--- a/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/core/search/indexing/IndexManager.java
+++ b/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/core/search/indexing/IndexManager.java
@@ -25,6 +25,7 @@
 import org.eclipse.core.resources.IWorkspaceRoot;
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.ListenerList;
 import org.eclipse.core.runtime.Path;
 import org.eclipse.dltk.compiler.CharOperation;
 import org.eclipse.dltk.compiler.util.SimpleLookupTable;
@@ -33,6 +34,7 @@
 import org.eclipse.dltk.core.IDLTKLanguageToolkit;
 import org.eclipse.dltk.core.IProjectFragment;
 import org.eclipse.dltk.core.IScriptProject;
+import org.eclipse.dltk.core.IShutdownListener;
 import org.eclipse.dltk.core.ISourceElementParser;
 import org.eclipse.dltk.core.ModelException;
 import org.eclipse.dltk.core.environment.IFileHandle;
@@ -62,6 +64,7 @@
 	private boolean needToSave = false;
 	private static final CRC32 checksumCalculator = new CRC32();
 	private IPath scriptPluginLocation = null;
+	private final ListenerList shutdownListeners = new ListenerList();
 	/* can only replace a current state if its less than the new one */
 	private SimpleLookupTable indexStates = null;
 	private File savedIndexNamesFile = getScriptPluginWorkingLocation().append(
@@ -98,6 +101,10 @@
 		}
 	}
 
+	public void addShutdownListener(IShutdownListener listener) {
+		shutdownListeners.add(listener);
+	}
+
 	/*
 	 * Removes unused indexes from disk.
 	 */
@@ -854,6 +861,16 @@
 	}
 
 	@Override
+	public void shutdown() {
+		super.shutdown();
+		Object[] listeners = shutdownListeners.getListeners();
+		for (int i = 0; i < listeners.length; ++i) {
+			((IShutdownListener) listeners[i]).shutdown();
+		}
+		shutdownListeners.clear();
+	}
+
+	@Override
 	public String toString() {
 		StringBuffer buffer = new StringBuffer(10);
 		buffer.append(super.toString());