1 /*******************************************************************************
 
   2  * Copyright (c) 2000, 2003 IBM Corporation and others.
 
   3  * All rights reserved. This program and the accompanying materials 
 
   4  * are made available under the terms of the Common Public License v1.0
 
   5  * which accompanies this distribution, and is available at
 
   6  * http://www.eclipse.org/legal/cpl-v10.html
 
   9  *     IBM Corporation - initial API and implementation
 
  10  *******************************************************************************/
 
  11 package net.sourceforge.phpdt.internal.ui.text;
 
  13 import java.util.ArrayList;
 
  14 import java.util.HashMap;
 
  15 import java.util.Iterator;
 
  16 import java.util.List;
 
  20 //import net.sourceforge.phpdt.internal.corext.Assert;
 
  21 import org.eclipse.core.runtime.Assert;
 
  22 import net.sourceforge.phpdt.internal.ui.PHPUIMessages;
 
  23 //import net.sourceforge.phpeclipse.PHPeclipsePlugin;
 
  25 import org.eclipse.jface.preference.IPreferenceStore;
 
  26 import org.eclipse.jface.text.BadLocationException;
 
  27 import org.eclipse.jface.text.IDocument;
 
  28 import org.eclipse.jface.text.Position;
 
  29 import org.eclipse.jface.text.source.Annotation;
 
  30 import org.eclipse.jface.text.source.IAnnotationHover;
 
  31 import org.eclipse.jface.text.source.IAnnotationModel;
 
  32 import org.eclipse.jface.text.source.ISourceViewer;
 
  33 import org.eclipse.ui.editors.text.EditorsUI;
 
  34 import org.eclipse.ui.texteditor.AnnotationPreference;
 
  37  * Determines all markers for the given line and collects, concatenates, and
 
  38  * formates their messages.
 
  40 public class JavaAnnotationHover implements IAnnotationHover {
 
  41         private static class JavaAnnotationHoverType {
 
  44         public static final JavaAnnotationHoverType OVERVIEW_RULER_HOVER = new JavaAnnotationHoverType();
 
  46         public static final JavaAnnotationHoverType TEXT_RULER_HOVER = new JavaAnnotationHoverType();
 
  48         public static final JavaAnnotationHoverType VERTICAL_RULER_HOVER = new JavaAnnotationHoverType();
 
  50         // private IPreferenceStore fStore =
 
  51         // PHPeclipsePlugin.getDefault().getPreferenceStore();
 
  52         private IPreferenceStore fStore = EditorsUI.getPreferenceStore();
 
  54         private JavaAnnotationHoverType fType;
 
  56         public JavaAnnotationHover(JavaAnnotationHoverType type) {
 
  57                 Assert.isTrue(OVERVIEW_RULER_HOVER.equals(type)
 
  58                                 || TEXT_RULER_HOVER.equals(type)
 
  59                                 || VERTICAL_RULER_HOVER.equals(type));
 
  64          * Returns the distance to the ruler line.
 
  66         protected int compareRulerLine(Position position, IDocument document,
 
  69                 if (position.getOffset() > -1 && position.getLength() > -1) {
 
  71                                 int javaAnnotationLine = document.getLineOfOffset(position
 
  73                                 if (line == javaAnnotationLine)
 
  75                                 if (javaAnnotationLine <= line
 
  76                                                 && line <= document.getLineOfOffset(position
 
  78                                                                 + position.getLength()))
 
  80                         } catch (BadLocationException x) {
 
  88          * Selects a set of markers from the two lists. By default, it just returns
 
  89          * the set of exact matches.
 
  91         protected List select(List exactMatch, List including) {
 
  96          * Returns one marker which includes the ruler's line of activity.
 
  98         protected List getJavaAnnotationsForLine(ISourceViewer viewer, int line) {
 
 100                 IDocument document = viewer.getDocument();
 
 101                 IAnnotationModel model = viewer.getAnnotationModel();
 
 106                 List exact = new ArrayList();
 
 107                 List including = new ArrayList();
 
 109                 Iterator e = model.getAnnotationIterator();
 
 110                 HashMap messagesAtPosition = new HashMap();
 
 111                 while (e.hasNext()) {
 
 112                         Annotation annotation = (Annotation) e.next();
 
 114                         if (annotation.getText() == null)
 
 117                         Position position = model.getPosition(annotation);
 
 118                         if (position == null)
 
 121                         AnnotationPreference preference = getAnnotationPreference(annotation);
 
 122                         if (preference == null)
 
 125                         if (OVERVIEW_RULER_HOVER.equals(fType)) {
 
 126                                 String key = preference.getOverviewRulerPreferenceKey();
 
 127                                 if (key == null || !fStore.getBoolean(key))
 
 129                         } else if (TEXT_RULER_HOVER.equals(fType)) {
 
 130                                 String key = preference.getTextPreferenceKey();
 
 132                                         if (!fStore.getBoolean(key))
 
 135                                         key = preference.getHighlightPreferenceKey();
 
 136                                         if (key == null || !fStore.getBoolean(key))
 
 139                         } else if (VERTICAL_RULER_HOVER.equals(fType)) {
 
 140                                 String key = preference.getVerticalRulerPreferenceKey();
 
 141                                 // backward compatibility
 
 142                                 if (key != null && !fStore.getBoolean(key))
 
 146                         if (isDuplicateJavaAnnotation(messagesAtPosition, position,
 
 147                                         annotation.getText()))
 
 150                         switch (compareRulerLine(position, document, line)) {
 
 152                                 exact.add(annotation);
 
 155                                 including.add(annotation);
 
 160                 return select(exact, including);
 
 164         // * Returns one marker which includes the ruler's line of activity.
 
 166         // protected List getJavaAnnotationsForLine(ISourceViewer viewer, int line)
 
 169         // IDocument document= viewer.getDocument();
 
 170         // IAnnotationModel model= viewer.getAnnotationModel();
 
 172         // if (model == null)
 
 175         // List exact= new ArrayList();
 
 176         // List including= new ArrayList();
 
 178         // Iterator e= model.getAnnotationIterator();
 
 179         // HashMap messagesAtPosition= new HashMap();
 
 180         // while (e.hasNext()) {
 
 181         // Object o= e.next();
 
 182         // if (o instanceof IJavaAnnotation) {
 
 183         // IJavaAnnotation a= (IJavaAnnotation)o;
 
 184         // if (!a.hasOverlay()) {
 
 185         // Position position= model.getPosition((Annotation)a);
 
 186         // if (position == null)
 
 189         // if (isDuplicateJavaAnnotation(messagesAtPosition, position,
 
 193         // switch (compareRulerLine(position, document, line)) {
 
 205         // return select(exact, including);
 
 208         private boolean isDuplicateJavaAnnotation(Map messagesAtPosition,
 
 209                         Position position, String message) {
 
 210                 if (messagesAtPosition.containsKey(position)) {
 
 211                         Object value = messagesAtPosition.get(position);
 
 212                         if (message.equals(value))
 
 215                         if (value instanceof List) {
 
 216                                 List messages = (List) value;
 
 217                                 if (messages.contains(message))
 
 220                                         messages.add(message);
 
 222                                 ArrayList messages = new ArrayList();
 
 224                                 messages.add(message);
 
 225                                 messagesAtPosition.put(position, messages);
 
 228                         messagesAtPosition.put(position, message);
 
 233          * @see IVerticalRulerHover#getHoverInfo(ISourceViewer, int)
 
 235         public String getHoverInfo(ISourceViewer sourceViewer, int lineNumber) {
 
 236                 List javaAnnotations = getJavaAnnotationsForLine(sourceViewer,
 
 238                 if (javaAnnotations != null) {
 
 240                         if (javaAnnotations.size() == 1) {
 
 243                                 Annotation annotation = (Annotation) javaAnnotations.get(0);
 
 244                                 String message = annotation.getText();
 
 245                                 if (message != null && message.trim().length() > 0)
 
 246                                         return formatSingleMessage(message);
 
 250                                 List messages = new ArrayList();
 
 252                                 Iterator e = javaAnnotations.iterator();
 
 253                                 while (e.hasNext()) {
 
 254                                         Annotation annotation = (Annotation) e.next();
 
 255                                         String message = annotation.getText();
 
 256                                         if (message != null && message.trim().length() > 0)
 
 257                                                 messages.add(message.trim());
 
 260                                 if (messages.size() == 1)
 
 261                                         return formatSingleMessage((String) messages.get(0));
 
 263                                 if (messages.size() > 1)
 
 264                                         return formatMultipleMessages(messages);
 
 272          * @see IVerticalRulerHover#getHoverInfo(ISourceViewer, int)
 
 274         // public String getHoverInfo(ISourceViewer sourceViewer, int lineNumber) {
 
 275         // List javaAnnotations= getJavaAnnotationsForLine(sourceViewer,
 
 277         // if (javaAnnotations != null) {
 
 279         // if (javaAnnotations.size() == 1) {
 
 282         // IJavaAnnotation javaAnnotation= (IJavaAnnotation) javaAnnotations.get(0);
 
 283         // String message= javaAnnotation.getMessage();
 
 284         // if (message != null && message.trim().length() > 0)
 
 285         // return formatSingleMessage(message);
 
 289         // List messages= new ArrayList();
 
 291         // Iterator e= javaAnnotations.iterator();
 
 292         // while (e.hasNext()) {
 
 293         // IJavaAnnotation javaAnnotation= (IJavaAnnotation) e.next();
 
 294         // String message= javaAnnotation.getMessage();
 
 295         // if (message != null && message.trim().length() > 0)
 
 296         // messages.add(message.trim());
 
 299         // if (messages.size() == 1)
 
 300         // return formatSingleMessage((String) messages.get(0));
 
 302         // if (messages.size() > 1)
 
 303         // return formatMultipleMessages(messages);
 
 310          * Formats a message as HTML text.
 
 312         private String formatSingleMessage(String message) {
 
 313                 StringBuffer buffer = new StringBuffer();
 
 314                 HTMLPrinter.addPageProlog(buffer);
 
 315                 HTMLPrinter.addParagraph(buffer, HTMLPrinter
 
 316                                 .convertToHTMLContent(message));
 
 317                 HTMLPrinter.addPageEpilog(buffer);
 
 318                 return buffer.toString();
 
 322          * Formats several message as HTML text.
 
 324         private String formatMultipleMessages(List messages) {
 
 325                 StringBuffer buffer = new StringBuffer();
 
 326                 HTMLPrinter.addPageProlog(buffer);
 
 331                                                                 .convertToHTMLContent(PHPUIMessages
 
 332                                                                                 .getString("JavaAnnotationHover.multipleMarkersAtThisLine"))); //$NON-NLS-1$
 
 334                 HTMLPrinter.startBulletList(buffer);
 
 335                 Iterator e = messages.iterator();
 
 337                         HTMLPrinter.addBullet(buffer, HTMLPrinter
 
 338                                         .convertToHTMLContent((String) e.next()));
 
 339                 HTMLPrinter.endBulletList(buffer);
 
 341                 HTMLPrinter.addPageEpilog(buffer);
 
 342                 return buffer.toString();
 
 346          * Returns the annotation preference for the given annotation.
 
 350          * @return the annotation preference or <code>null</code> if none
 
 352         private AnnotationPreference getAnnotationPreference(Annotation annotation) {
 
 353                 return EditorsUI.getAnnotationPreferenceLookup()
 
 354                                 .getAnnotationPreference(annotation);