/*
* ==========================================================================%%#
* EasyPmd
* ===========================================================================%%
* Copyright (C) 2009 - 2016 Gianluca Costa
* ===========================================================================%%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* ==========================================================================%##
*/
package info.gianlucacosta.easypmd.ide.editor;
import org.openide.cookies.LineCookie;
import org.openide.filesystems.FileChangeAdapter;
import org.openide.filesystems.FileChangeListener;
import org.openide.filesystems.FileEvent;
import org.openide.filesystems.FileObject;
import org.openide.loaders.DataObject;
import org.openide.text.Annotation;
import org.openide.text.Line;
import org.openide.util.lookup.ServiceProvider;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
/**
* Default implementation of AnnotationService
*/
@ServiceProvider(service = AnnotationService.class)
public class DefaultAnnotationService implements AnnotationService {
private final Map<FileObject, ScanMessageAnnotationList> attachedAnnotations = new HashMap<>();
private final Map<FileObject, FileChangeListener> registeredFileChangeListeners = new HashMap<>();
@Override
public void attachAnnotationsTo(DataObject dataObject, ScanMessageAnnotationList annotations) {
final FileObject fileObject = dataObject.getPrimaryFile();
if (attachedAnnotations.containsKey(fileObject)) {
throw new IllegalArgumentException("EasyPmd annotations have already been attached to this file.\nYou must detach them before attaching new ones.");
}
LineCookie lineCookie = dataObject.getLookup().lookup(LineCookie.class);
Line.Set lineSet = lineCookie.getLineSet();
for (ScanMessageAnnotation annotation : annotations) {
annotation.attach(lineSet);
}
attachedAnnotations.put(fileObject, annotations);
registerFileEventHandlers(fileObject);
}
private void registerFileEventHandlers(final FileObject fileObject) {
FileChangeListener fileChangeListener = new FileChangeAdapter() {
@Override
public void fileChanged(FileEvent ev) { //This is triggered only when the user SAVES the file
detachAnnotationsFrom(fileObject);
}
@Override
public void fileDeleted(FileEvent ev) {
detachAnnotationsFrom(fileObject);
}
};
fileObject.addFileChangeListener(fileChangeListener);
registeredFileChangeListeners.put(fileObject, fileChangeListener);
}
@Override
public void detachAnnotationsFrom(FileObject fileObject) {
ScanMessageAnnotationList fileAnnotations = attachedAnnotations.get(fileObject);
if (fileAnnotations == null) {
return;
}
for (Annotation annotation : fileAnnotations) {
annotation.detach();
}
attachedAnnotations.remove(fileObject);
unregisterFileEventHandlers(fileObject);
}
private void unregisterFileEventHandlers(FileObject fileObject) {
FileChangeListener fileChangeListener = registeredFileChangeListeners.get(fileObject);
fileObject.removeFileChangeListener(fileChangeListener);
registeredFileChangeListeners.remove(fileObject);
}
@Override
public void detachAllAnnotations() {
Collection<FileObject> fileObjects = new ArrayList<>(attachedAnnotations.keySet());
for (FileObject fileObject : fileObjects) {
detachAnnotationsFrom(fileObject);
}
}
}