/******************************************************************************* * Copyright (c) 2007 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: * Robert Fuhrer (rfuhrer@watson.ibm.com) - initial API and implementation *******************************************************************************/ package org.eclipse.imp.editor.internal; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import org.eclipse.imp.editor.UniversalEditor; import org.eclipse.imp.parser.IMessageHandlerExtension; import org.eclipse.jface.text.Position; import org.eclipse.jface.text.source.Annotation; import org.eclipse.jface.text.source.IAnnotationModel; import org.eclipse.jface.text.source.IAnnotationModelExtension; import org.eclipse.ui.texteditor.IDocumentProvider; import org.eclipse.ui.texteditor.ITextEditor; /** * An implementation of the IMessageHandler interface that creates editor annotations * directly from messages. Used for live parsing within a source editor (cf. building, * which uses the class MarkerCreator to create markers). * @author rmfuhrer */ public class AnnotationCreator implements IMessageHandlerExtension { private static class PositionedMessage { public final String message; public final Position pos; public PositionedMessage(String msg, Position pos) { this.message= msg; this.pos= pos; } } private final ITextEditor fEditor; private final String fAnnotationType; private final List<PositionedMessage> fMessages= new LinkedList<PositionedMessage>(); private final List<Annotation> fAnnotations= new LinkedList<Annotation>(); public AnnotationCreator(ITextEditor textEditor, String annotationType) { fEditor= textEditor; if (annotationType == null) fAnnotationType = UniversalEditor.PARSE_ANNOTATION_TYPE; else fAnnotationType= annotationType; } public void clearMessages() { removeAnnotations(); fMessages.clear(); } public void startMessageGroup(String groupName) { } public void endMessageGroup() { } public void handleSimpleMessage(String message, int startOffset, int endOffset, int startCol, int endCol, int startLine, int endLine) { Position pos= new Position(startOffset, endOffset - startOffset + 1); fMessages.add(new PositionedMessage(message, pos)); } public void endMessages() { IAnnotationModel model= fEditor.getDocumentProvider().getAnnotationModel(fEditor.getEditorInput()); if (model instanceof IAnnotationModelExtension) { IAnnotationModelExtension modelExt= (IAnnotationModelExtension) model; Annotation[] oldAnnotations= fAnnotations.toArray(new Annotation[fAnnotations.size()]); Map<Annotation, Position> newAnnotations= new HashMap<Annotation, Position>(fMessages.size()); for(PositionedMessage pm: fMessages) { Annotation anno= new Annotation(fAnnotationType, false, pm.message); newAnnotations.put(anno, pm.pos); fAnnotations.add(anno); } modelExt.replaceAnnotations(oldAnnotations, newAnnotations); } else if (model != null) { // model could be null if, e.g., we're directly browsing a file version in a src repo for(Iterator i= model.getAnnotationIterator(); i.hasNext(); ) { Annotation a= (Annotation) i.next(); if (a.getType().equals(fAnnotationType)) { model.removeAnnotation(a); } } for(PositionedMessage pm: fMessages) { Annotation annotation= new Annotation(fAnnotationType, false, pm.message); model.addAnnotation(annotation, pm.pos); fAnnotations.add(annotation); } } // System.out.println("Annotation model updated."); fMessages.clear(); } private void removeAnnotations() { final IDocumentProvider docProvider= fEditor.getDocumentProvider(); if (docProvider == null) { return; } IAnnotationModel model= docProvider.getAnnotationModel(fEditor.getEditorInput()); if (model == null) return; if (model instanceof IAnnotationModelExtension) { IAnnotationModelExtension modelExt= (IAnnotationModelExtension) model; Annotation[] oldAnnotations= fAnnotations.toArray(new Annotation[fAnnotations.size()]); modelExt.replaceAnnotations(oldAnnotations, Collections.EMPTY_MAP); } else { for(Iterator i= model.getAnnotationIterator(); i.hasNext(); ) { Annotation a= (Annotation) i.next(); if (a.getType().equals(fAnnotationType)) { model.removeAnnotation(a); } } } // System.out.println("Annotations removed."); fAnnotations.clear(); } }