package cideplus.ui.presentation; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.runtime.CoreException; import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.ITextSelection; import org.eclipse.jface.text.Position; import org.eclipse.jface.text.source.IAnnotationModel; import org.eclipse.ui.IWorkbenchActionConstants; import org.eclipse.ui.texteditor.IDocumentProvider; import org.eclipse.ui.texteditor.ITextEditor; import org.eclipse.ui.texteditor.MarkerUtilities; import cideplus.FeaturerPlugin; import cideplus.model.Feature; import cideplus.model.ast.utils.ASTUtils; import cideplus.ui.configuration.FeaturesConfigurationUtil; import cideplus.utils.PluginUtils; public class FeaturesMarker { public static final String TYPE = "cideplus.markers.featuresMarker"; public static IMarker createMarker(IResource resource, final int offset, final int length, int featureId) throws CoreException { Map<String, Object> attributes = createMarkerAttributes(offset, length, featureId); IMarker marker = resource.createMarker(TYPE); marker.setAttributes(attributes); if (FeaturerPlugin.DEBUG_MARKERS) printAllRelatedMarkers(resource, false); IWorkbenchActionConstants a; SelectAnnotationRulerAction sra; return marker; } public static IMarker createMarker(IResource resource, ITextSelection selection, int featureId) throws CoreException { IMarker marker = createMarker(resource, selection.getOffset(), selection.getLength(), featureId); return marker; } public static IMarker createMarker(ASTNode node, int featureId) throws CoreException { IResource resource = ASTUtils.getCorrespondingResource(node); if (resource != null) { IMarker marker = createMarker(resource, node.getStartPosition(), node.getLength(), featureId); return marker; } return null; } public static void addAnnotation(IMarker marker, int offset, int length) { ITextEditor editor = PluginUtils.getCurrentTextEditor(); //The DocumentProvider enables to get the document currently loaded in the editor IDocumentProvider idp = editor.getDocumentProvider(); //This is the document we want to connect to. This is taken from the current editor input. IDocument document = idp.getDocument(editor.getEditorInput()); //The IannotationModel enables to add/remove/change annoatation to a Document loaded in an Editor IAnnotationModel iamf = idp.getAnnotationModel(editor.getEditorInput()); //Note: The annotation type id specify that you want to create one of your annotations FeatureAnnotation annotation = new FeatureAnnotation(marker); //Finally add the new annotation to the model iamf.connect(document); iamf.addAnnotation(annotation, new Position(offset, length)); iamf.disconnect(document); } public static void addAnnotation(IMarker marker, ITextSelection selection) { addAnnotation(marker, selection.getOffset(), selection.getLength()); } /* returns a list of a resource's markers */ public static List<IMarker> findMarkers(IResource resource) { try { return Arrays.asList(resource.findMarkers(TYPE, true, IResource.DEPTH_ZERO)); } catch (CoreException e) { return new ArrayList<IMarker>(); } } /* Returns the marker associated with the given feature in the AST node */ public static IMarker getCorrespondingMarker(ASTNode node, int featureId) { int nodeStart = node.getStartPosition(); int nodeLength = node.getLength(); IResource resource = ASTUtils.getCorrespondingResource(node); List<IMarker> markers = findAllRelatedMarkers(resource); if (FeaturerPlugin.DEBUG_AST_MARKER) { System.out.println("Getting corresponding marker..."); for (IMarker marker : markers) printMarkerInline(marker); System.out.println("---"); System.out.println("nodeStart: " + nodeStart); System.out.println("nodeLength: " + nodeLength); } Iterator<IMarker> it = markers.iterator(); while (it.hasNext()) { IMarker marker = it.next(); // for (IMarker marker : markers) { int markerStart = marker.getAttribute("charStart", -1); int markerLength = marker.getAttribute("charEnd", -1) - markerStart; if (marker.getAttribute("featureId", -1) == featureId) { if (FeaturerPlugin.DEBUG_AST_MARKER) { System.out.println(" markerStart: " + markerStart); System.out.println(" markerLength: " + markerLength); } if (markerStart == nodeStart && markerLength == nodeLength) return marker; } } return null; } /** * Returns a list of markers that are linked to the resource or any sub resource of the resource */ public static List<IMarker> findAllRelatedMarkers(IResource resource) { try { return Arrays.asList(resource.findMarkers(TYPE, true, IResource.DEPTH_INFINITE)); } catch (CoreException e) { return new ArrayList<IMarker>(); } } /** * Returns a list of markers that are linked to the resource or any sub resource of the resource * * @return the list of markers */ public static List<IMarker> findAllMarkers() { IWorkspaceRoot root = PluginUtils.getWorkspaceRoot(); try { return Arrays.asList(root.findMarkers(TYPE, true, IResource.DEPTH_INFINITE)); } catch (CoreException e) { return new ArrayList<IMarker>(); } } /** * Creates an attributes map for a text marker that references a range in text. In order to the marker * appear automatically in the vertical ruler, the <code>lineNumber</code> or the <code>charStart</code>/<code>charEnd</code> * attributes must be set. * * @param offset The offset of the range being referenced * @param length The length of the range being referenced * @param featureId The ID of the feature this marker is tracking * @return The attribute map. * @author ppires */ private static Map<String, Object> createMarkerAttributes(int offset, int length, int featureId) { Map<String, Object> attributes = new HashMap<String, Object>(); IDocument document = PluginUtils.getCurrentDocument(); // Getting the feature name to show when // hovering an annotation in vertical ruler String infoMessage = null; try { // ISelection selection = PluginUtils.getCurrentSelection(); // System.out.println("selection class: " + selection.getClass()); // FIXME: getCurrentProject() pega o projeto de acordo com o arquivo // aberto no editor. Esse project deve ser pegado de acordo com a selection // do package explorer. // IProject p = PluginUtils.getCurrentSelectedProject(); // IProject project = PluginUtils.getCurrentProject(); IProject project = PluginUtils.getCurrentSelectedProject(); Feature feature = FeaturesConfigurationUtil.getFeature(project, featureId); String featureName = feature.getName(); // String code = document.get(offset, length); // infoMessage = "(" + featureName + ") " + code; infoMessage = " Feature: " + featureName; } catch (CoreException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } // Setting the line number attribute if (document != null) { try { int lineNumber = document.getLineOfOffset(offset) + 1; MarkerUtilities.setLineNumber(attributes, lineNumber); } catch (BadLocationException e) { e.printStackTrace(); } } // Setting the charStart and charEnd attributes. MarkerUtilities.setCharStart(attributes, offset); MarkerUtilities.setCharEnd(attributes, offset + length); MarkerUtilities.setMessage(attributes, infoMessage); attributes.put("featureId", new Integer(featureId)); attributes.put("length", new Integer(length)); // attributes.put(IMarker.MESSAGE, "A sample marker message!"); return attributes; } public static void printAllRelatedMarkers(IResource resource, boolean inline) { System.out.println("========================================"); System.out.println("Printing all markers related to " + resource.getName()); System.out.println("========================================"); for (IMarker marker : findAllRelatedMarkers(resource)) { if (inline) printMarkerInline(marker); else { printMarker(marker); System.out.println(System.getProperty("line.separator")); } } System.out.println("========================================"); } public static void printAllMarkers(boolean inline) { for (IMarker marker : findAllMarkers()) { if (inline) printMarkerInline(marker); else { printMarker(marker); System.out.println(System.getProperty("line.separator")); } } } public static void printMarkerInline(IMarker marker) { int charStart = marker.getAttribute("charStart", -1); int charEnd = marker.getAttribute("charEnd", -1); int lineNumber = marker.getAttribute("lineNumber", -1); int featureId = marker.getAttribute("featureId", -1); System.out.print(" - start: " + charStart); System.out.print(" / length: " + (charEnd - charStart)); System.out.print(" / line: " + lineNumber); System.out.print(" / featureId: " + featureId); System.out.println(" / markerId: " + marker.getId()); } public static void printMarker(IMarker marker) { try { int start = (Integer) marker.getAttribute("charStart"); int end = (Integer) marker.getAttribute("charEnd"); System.out.println("type: " + marker.getType()); System.out.println("resource: " + marker.getResource().getName()); System.out.println("char start: " + start); System.out.println("length: " + (end - start)); System.out.println("feature id: " + marker.getAttribute("featureId")); System.out.println("message: " + marker.getAttribute("message")); } catch (CoreException e) { System.out.println("Caught Exception getting marker att..."); e.printStackTrace(); } } }