package com.sap.furcas.ide.editor; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.WeakHashMap; import org.eclipse.emf.ecore.EObject; 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 com.sap.furcas.metamodel.FURCAS.textblocks.DocumentNode; import com.sap.furcas.metamodel.FURCAS.textblocks.TextBlock; import com.sap.furcas.runtime.textblocks.TbUtil; public class PartitionHighlighter { public static final String OTHER_PARTITION_ANNOTATION_TYPE = "com.sap.ide.cts.editor.partition_highlight"; private final IAnnotationModel fModel; private final Map<DocumentNode, Annotation> fMatchesToAnnotations; public PartitionHighlighter(IAnnotationModel model) { fModel= model; fMatchesToAnnotations= new WeakHashMap<DocumentNode, Annotation>(); } public void addHighlights(Collection<DocumentNode> matches) { HashMap<Annotation, Position> map= new HashMap<Annotation, Position>(matches.size()); for (DocumentNode match : matches) { if(match instanceof TextBlock) { TextBlock tb = (TextBlock)match; int offset= TbUtil.getAbsoluteOffsetWithoutBlanks(tb); int length= TbUtil.getLengthWithoutStartingBlanks(tb); if (offset >= 0 && length >= 0) { Position position= createPosition(tb); if (position != null) { for (EObject element : tb.getCorrespondingModelElements()) { EObject partitionable = element; if (element.eResource().equals(tb.eResource())) { continue; // show errors only for the broken elements } String elementName = (element.eClass()).getName(); String partitionName = partitionable.eResource().getURI().toString(); String text = elementName + " from partition: " + partitionName; if(text.indexOf("/_comp/") >= 0) { //The annotation text is quite long, so split it in two lines text = text.replaceFirst("\\/\\_comp\\/", "/_comp/\n\t\t\t\t\t\t"); } Annotation annotation= new Annotation(PartitionHighlighter.OTHER_PARTITION_ANNOTATION_TYPE, true, text); fMatchesToAnnotations.put(match, annotation); map.put(annotation, position); } } } } } addAnnotations(map); } private Position createPosition(TextBlock tb) { int offset= TbUtil.getAbsoluteOffsetWithoutBlanks(tb); int length= TbUtil.getLengthWithoutStartingBlanks(tb); Position position= new Position(offset, length); return position; } public void removeHighlights(DocumentNode[] matches) { HashSet<Annotation> annotations= new HashSet<Annotation>(matches.length); for (int i= 0; i < matches.length; i++) { Annotation annotation= fMatchesToAnnotations.remove(matches[i]); if (annotation != null) { annotations.add(annotation); } } removeAnnotations(annotations); } public void removeAll() { Collection<Annotation> matchSet= fMatchesToAnnotations.values(); removeAnnotations(matchSet); fMatchesToAnnotations.clear(); } private void addAnnotations(Map<Annotation, Position> annotationToPositionMap) { if (fModel instanceof IAnnotationModelExtension) { IAnnotationModelExtension ame= (IAnnotationModelExtension) fModel; ame.replaceAnnotations(new Annotation[0], annotationToPositionMap); } else { for (Iterator<Annotation> elements= annotationToPositionMap.keySet().iterator(); elements.hasNext();) { Annotation element= elements.next(); Position p= annotationToPositionMap.get(element); fModel.addAnnotation(element, p); } } } /** * Removes annotations from the given annotation model. The default implementation works for editors that * implement <code>ITextEditor</code>. * Subclasses may override this method. * @param annotations A set containing the annotations to be removed. * @see Annotation */ private void removeAnnotations(Collection<Annotation> annotations) { if (fModel instanceof IAnnotationModelExtension) { IAnnotationModelExtension ame= (IAnnotationModelExtension) fModel; Annotation[] annotationArray= new Annotation[annotations.size()]; ame.replaceAnnotations(annotations.toArray(annotationArray), Collections.EMPTY_MAP); } else { for (Iterator<Annotation> iter= annotations.iterator(); iter.hasNext();) { Annotation element= iter.next(); fModel.removeAnnotation(element); } } } }