/*******************************************************************************
* Copyright 2005-2007, CHISEL Group, University of Victoria, Victoria, BC, Canada
* and IBM Corporation. All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* The Chisel Group, University of Victoria
*******************************************************************************/
package net.sourceforge.tagsea.parsed.core.internal.resources;
import java.util.HashMap;
import net.sourceforge.tagsea.parsed.ParsedWaypointPlugin;
import net.sourceforge.tagsea.parsed.core.IDocumentRegistry;
import net.sourceforge.tagsea.parsed.parser.IWaypointParseProblemCollector;
import net.sourceforge.tagsea.parsed.parser.WaypointParseProblem;
import org.eclipse.core.filebuffers.FileBuffers;
import org.eclipse.core.filebuffers.IFileBuffer;
import org.eclipse.core.filebuffers.ITextFileBuffer;
import org.eclipse.core.filebuffers.LocationKind;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentListener;
import org.eclipse.jface.text.IRegion;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
/**
* Listens to the creation/deletion of file buffers and registers listeners to adapt to document changes.
* Invokes a parse on a buffer created unless it was created during a ParseFileOperation.
* @author Del Myers
*
*/
public class DocumentRegistry extends FileBufferAdapter implements IWaypointParseProblemCollector, IDocumentRegistry {
public static final DocumentRegistry INSTANCE = new DocumentRegistry();
private HashMap<IDocument, IFile> documentFileMap;
private HashMap<IDocument, ITextFileBuffer> documentBufferMap;
private IDocumentListener documentListener;
private boolean connected;
private ProblemAnnotator annotator;
private ListenerList documentListeners;
/**
*
*/
private DocumentRegistry() {
this.documentFileMap = new HashMap<IDocument,IFile>();
documentListener = new DocumentWaypointUpdater(this);
documentBufferMap = new HashMap<IDocument, ITextFileBuffer>();
annotator = new ProblemAnnotator();
connected = false;
this.documentListeners = new ListenerList(ListenerList.EQUALITY);
}
public void bufferCreated(IFileBuffer buffer) {
internalBufferCreated(buffer);
}
private void internalBufferCreated(IFileBuffer buffer) {
if (buffer instanceof ITextFileBuffer) {
ITextFileBuffer textBuffer = (ITextFileBuffer) buffer;
IDocument document = textBuffer.getDocument();
IPath location = textBuffer.getLocation();
IResource resource = ResourcesPlugin.getWorkspace().getRoot().findMember(location);
if (resource != null && resource.isAccessible() && resource instanceof IFile) {
documentFileMap.put(document, (IFile)resource);
documentBufferMap.put(document, textBuffer);
document.addDocumentListener(documentListener);
for (Object o : documentListeners.getListeners()) {
((IDocumentLifecycleListener)o).documentCreated(textBuffer);
}
}
}
}
public void ignoreDocument(IDocument document) {
document.removeDocumentListener(documentListener);
}
public void watchDocument(IDocument document) {
document.addDocumentListener(documentListener);
}
public synchronized void bufferDisposed(IFileBuffer buffer) {
internalBufferDisposed(buffer);
}
private void internalBufferDisposed(IFileBuffer buffer) {
if (buffer instanceof ITextFileBuffer) {
ITextFileBuffer textBuffer = (ITextFileBuffer) buffer;
IDocument document = textBuffer.getDocument();
document.removeDocumentListener(documentListener);
IFile file = documentFileMap.remove(document);
documentBufferMap.remove(document);
annotator.cleanDocument(document, (IFile)ResourcesPlugin.getWorkspace().getRoot().findMember(textBuffer.getLocation()));
if (file != null) {
for (Object o : documentListeners.getListeners()) {
((IDocumentLifecycleListener)o).documentDisposed(textBuffer);
}
}
}
}
public synchronized IFile getFileForDocument(IDocument document) {
return documentFileMap.get(document);
}
public synchronized ITextFileBuffer getBufferForDocument(IDocument document) {
return documentBufferMap.get(document);
}
/**
* Convenience method for connecting this registry to the buffer manager. Also initializes all documents.
*/
public synchronized void connect() {
if (connected) return;
Display.getDefault().syncExec(new Runnable(){
public void run() {
IWorkbenchWindow[] windows = ParsedWaypointPlugin.getDefault().getWorkbench().getWorkbenchWindows();
for (IWorkbenchWindow window : windows) {
for (IWorkbenchPage page : window.getPages()) {
for (IEditorReference editor : page.getEditorReferences()) {
IEditorInput input;
try {
input = editor.getEditorInput();
} catch (PartInitException e) {
continue;
}
if (input instanceof IFileEditorInput) {
IFile file = ((IFileEditorInput)input).getFile();
IPath filePath = file.getFullPath();
IFileBuffer buffer = FileBuffers.getTextFileBufferManager().getTextFileBuffer(filePath, LocationKind.IFILE);
if (buffer != null) {
internalBufferCreated(buffer);
}
}
}
}
}
}
});
FileBuffers.getTextFileBufferManager().addFileBufferListener(this);
connected = true;
}
/**
* @param marker
* @return
*/
public WaypointParseProblem getProblemForMarker(IMarker marker) {
return annotator.getProblemForMarker(marker);
}
public void accept(WaypointParseProblem problem) {
IDocument document = problem.getDocument();
IFile file = getFileForDocument(document);
if (file == null) return;
annotator.createAnnotation(problem, file);
}
public WaypointParseProblem[] problems() {
return null;
}
/**
* @param document
* @param r
*/
public void clearProblems(IDocument document, IRegion r) {
IFile file = getFileForDocument(document);
if (file == null) return;
annotator.cleanDocument(document, file, r);
}
public void clearProblems(IDocument document) {
IFile file = getFileForDocument(document);
if (file == null) return;
annotator.cleanDocument(document, file);
}
public void addDocumentLifecycleListener(IDocumentLifecycleListener listener) {
documentListeners.add(listener);
}
public void removeDocumentLifecycleListener(
IDocumentLifecycleListener listener) {
documentListeners.remove(listener);
}
}