package org.codemap.marker; import static org.eclipse.core.resources.IMarker.MARKER; import static org.eclipse.core.resources.IMarker.SEVERITY; import static org.eclipse.core.resources.IResource.DEPTH_INFINITE; import java.util.HashMap; import java.util.Map; import org.codemap.CodemapCore; import org.codemap.MapPerProject; import org.codemap.commands.MarkerCommand; import org.codemap.util.Log; import org.codemap.util.Resources; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IMarkerDelta; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceChangeEvent; import org.eclipse.core.resources.IResourceChangeListener; import org.eclipse.core.resources.IResourceDelta; import org.eclipse.core.resources.IResourceDeltaVisitor; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; public class MarkerController { private static final int NO_SEVERITY = -1; private IResourceDeltaVisitor resourceDeltaVisitor = new IResourceDeltaVisitor() { @Override public boolean visit(IResourceDelta delta) throws CoreException { if (delta == null) { return false; } if (resourceOpenStateChanged(delta)) { handleProjectResourceOpenStateChange(delta.getResource()); return false; } for (IMarkerDelta markerDelta: delta.getMarkerDeltas()) { switch (markerDelta.getKind()) { case IResourceDelta.ADDED : handleAddMarker(markerDelta.getMarker()); break; case IResourceDelta.REMOVED : handleRemoveMarker(markerDelta.getMarker()); break; } } return true; } private boolean resourceOpenStateChanged(IResourceDelta delta) { return 0 != (delta.getFlags() & IResourceDelta.OPEN) && 0 == (delta.getFlags() & IResourceDelta.MOVED_FROM); } }; private IResourceChangeListener resourceChangeListener = new IResourceChangeListener() { /* * @see IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent) */ @Override public void resourceChanged(IResourceChangeEvent event) { IResourceDelta delta= event.getDelta(); if (delta == null) return; try { delta.accept(resourceDeltaVisitor); } catch (CoreException e) { Log.error(e); } } }; private Map<MapPerProject, MarkerSelection> selectionCache = new HashMap<MapPerProject, MarkerSelection>(); private MarkerCommand currentCommand; public MarkerController() { ResourcesPlugin.getWorkspace().addResourceChangeListener(resourceChangeListener); } public void dispose() { ResourcesPlugin.getWorkspace().removeResourceChangeListener(resourceChangeListener); } /** * Loads all markers on the given resource. * * @param resource the resource which contains the markers */ private void loadMarkers(IResource resource) { try { IMarker[] markers = resource.findMarkers(MARKER, true, DEPTH_INFINITE); addAllMarkers(collectIdentifiers(markers)); } catch (CoreException e) { Log.error(e); } } private void addAllMarkers(Map<String, Integer> map) { if (! isActive()) return; getMarkerSelection().addAll(map); } private Map<String, Integer> collectIdentifiers(IMarker[] markers) { Map<String, Integer> identifiers = new HashMap<String, Integer>(); int severity; for(IMarker each: markers) { if ((severity = each.getAttribute(SEVERITY, NO_SEVERITY)) == NO_SEVERITY) continue; identifiers.put(Resources.asPath(each.getResource()), severity); } return identifiers; } private void removeMarker(IMarker marker) { if (! isActive()) return; String identifier = Resources.asPath(marker.getResource()); getMarkerSelection().remove(identifier); } private void addMarker(IMarker marker) { if (! isActive()) return; int severity; if ((severity = marker.getAttribute(SEVERITY, NO_SEVERITY)) == NO_SEVERITY) return; String identifier = Resources.asPath(marker.getResource()); getMarkerSelection().add(identifier, severity); } private void handleRemoveMarker(IMarker marker) { removeMarker(marker); } private void handleAddMarker(IMarker marker) { addMarker(marker); } /** * A project has been opened or closed. Updates the breakpoints for * that project */ private void handleProjectResourceOpenStateChange(IResource project) { if (!project.isAccessible()) { handleClosedProject(project); } else { handleOpenedProject(project); } } private void handleOpenedProject(IResource project) { // FIXME: what the fuck this? IMarker[] findMarkers; try { findMarkers = project.findMarkers(IMarker.MARKER, true, IResource.DEPTH_INFINITE); } catch (CoreException e) { e.printStackTrace(); } } private void handleClosedProject(IResource project) { // FIXME: what the *** is this? // TODO: iterate over the list of markers and delete the ones from the closed project // Enumeration breakpoints= ((Vector)getBreakpoints0().clone()).elements(); // while (breakpoints.hasMoreElements()) { // IBreakpoint breakpoint= (IBreakpoint) breakpoints.nextElement(); // IResource markerResource= breakpoint.getMarker().getResource(); // if (project.getFullPath().isPrefixOf(markerResource.getFullPath())) { // fRemoved.add(breakpoint); // } // } } private boolean isActive() { if (currentCommand == null) return false; return currentCommand.isEnabled(); } public void onLayerActivated() { loadAllMarkers(); } private void loadAllMarkers() { loadMarkers(CodemapCore.getPlugin().getActiveMap().getProject()); } public void onLayerDeactivated() { clearSelection(); } private void clearSelection() { getMarkerSelection().clear(); } private MarkerSelection getMarkerSelection() { MapPerProject activeMap = CodemapCore.getPlugin().getActiveMap(); MarkerSelection selection = selectionCache.get(activeMap); if (selection == null) { selection = new MarkerSelection(); selectionCache.put(activeMap, selection); MarkersOverlay markersOverlay = new MarkersOverlay(); markersOverlay.setMarkerSelection(selection); activeMap.addSelectionLayer(markersOverlay, selection.getSelection()); } return selection; } public void setCurrentCommand(MarkerCommand markerCommand) { currentCommand = markerCommand; } }