package net.sourceforge.pmd.eclipse.ui.views;
import java.util.ArrayList;
import java.util.List;
import net.sourceforge.pmd.eclipse.runtime.builder.MarkerUtil;
import net.sourceforge.pmd.eclipse.ui.model.FileRecord;
import net.sourceforge.pmd.eclipse.util.Util;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IMarkerDelta;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
/**
* Provides the ViolationOutlinePages with Content
*
* @author SebastianRaffel ( 08.05.2005 )
*/
public class ViolationOutlineContentProvider implements
IStructuredContentProvider, IResourceChangeListener {
private RefreshableTablePage tablePage;
private TableViewer tableViewer;
private FileRecord resource;
/**
* Constructor
*
* @param page
*/
public ViolationOutlineContentProvider(RefreshableTablePage page) {
tablePage = page;
tableViewer = page.tableViewer();
}
/* @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) */
public Object[] getElements(Object inputElement) {
if (inputElement instanceof FileRecord) {
return ((FileRecord) inputElement).findMarkers();
}
return Util.EMPTY_ARRAY;
}
/* @see org.eclipse.jface.viewers.IContentProvider#dispose() */
public void dispose() {
}
/* @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object) */
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
if (resource != null) {
resource.getResource().getWorkspace().removeResourceChangeListener(this);
}
// we create a new FileRecord
resource = (FileRecord) newInput;
if (resource != null) {
resource.getResource().getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.POST_CHANGE);
}
tableViewer = (TableViewer) viewer;
}
/* @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent) */
public void resourceChanged(IResourceChangeEvent event) {
if (resource == null || !resource.getResource().exists()) return;
List<IMarkerDelta> markerDeltas = MarkerUtil.markerDeltasIn(event);
if (markerDeltas.isEmpty()) return;
// we search for removed, added or changed Markers
final List<IMarker> additions = new ArrayList<IMarker>();
final List<IMarker> removals = new ArrayList<IMarker>();
final List<IMarker> changes = new ArrayList<IMarker>();
for (IMarkerDelta delta : markerDeltas) {
if (!delta.getResource().equals(resource.getResource()))
continue;
IMarker marker = delta.getMarker();
switch (delta.getKind()) {
case IResourceDelta.ADDED:
additions.add(marker);
break;
case IResourceDelta.REMOVED:
removals.add(marker);
break;
case IResourceDelta.CHANGED:
changes.add(marker);
break;
}
}
// updating the table MUST be in sync
tableViewer.getControl().getDisplay().syncExec(new Runnable() {
public void run() {
updateViewer(additions, removals, changes);
}
});
}
/**
* Applies found updates on the table,
* adapted from Philippe Herlin
*
* @param additions
* @param removals
* @param changes
*/
protected void updateViewer(List<IMarker> additions, List<IMarker> removals, List<IMarker> changes) {
// perform removals
if (removals.size() > 0) {
tableViewer.cancelEditing();
tableViewer.remove(removals.toArray());
}
// perform additions
if (additions.size() > 0) {
tableViewer.add(additions.toArray());
}
// perform changes
if (changes.size() > 0) {
tableViewer.update(changes.toArray(), null);
}
tablePage.refresh();
}
}