ar.com.tadp.xml.rinzo.core.MultipleLinesTextHover.java Source code

Java tutorial

Introduction

Here is the source code for ar.com.tadp.xml.rinzo.core.MultipleLinesTextHover.java

Source

/*****************************************************************************
  * This file is part of Rinzo
 *
 * Author: Claudio Cancinos
 * WWW: https://sourceforge.net/projects/editorxml
 * Copyright (C): 2008, Claudio Cancinos
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this program; If not, see <http://www.gnu.org/licenses/>
 ****************************************************************************/
package ar.com.tadp.xml.rinzo.core;

import java.util.Iterator;

import org.apache.commons.lang.StringUtils;
import org.eclipse.core.runtime.Assert;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextHover;
import org.eclipse.jface.text.ITextHoverExtension2;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.ISourceViewerExtension2;

import ar.com.tadp.xml.rinzo.core.model.XMLNode;
import ar.com.tadp.xml.rinzo.core.model.tags.AttributeDefinition;

/**
 * This implementation of {@link org.eclipse.jface.text.ITextHover}. displays
 * 
 * @author ccancinos
 */
public class MultipleLinesTextHover implements ITextHover {
    /** This hover's source viewer */
    private ISourceViewer sourceViewer;
    private RinzoXMLEditor editor;

    /**
     * Creates a new annotation hover.
     *
     * @param sourceViewer this hover's annotation model
     * @param editor 
     */
    public MultipleLinesTextHover(ISourceViewer sourceViewer, RinzoXMLEditor editor) {
        this.editor = editor;
        Assert.isNotNull(sourceViewer);
        this.sourceViewer = sourceViewer;
    }

    /**
     * {@inheritDoc}
     *
     * @deprecated As of 3.4, replaced by {@link ITextHoverExtension2#getHoverInfo2(ITextViewer, IRegion)}
     */
    public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) {
        if (hoverRegion.getLength() == 0) {
            return null;
        }
        String annotationMessage = this.getAnnotationMessage(textViewer, hoverRegion);
        if (!StringUtils.isEmpty(annotationMessage)) {
            return annotationMessage;
        }

        try {
            XMLNode activeNode = this.editor.getModel().getTree().getActiveNode(hoverRegion.getOffset());
            if (activeNode.isTag() || activeNode.isEndTag() || activeNode.isEmptyTag()) {
                int startName = activeNode.getOffset();
                int endName = activeNode.getFullTagName().length();

                if (startName <= hoverRegion.getOffset() && ((startName + endName) >= hoverRegion.getOffset())) {
                    if (activeNode.isEndTag()) {
                        activeNode = activeNode.getCorrespondingNode();
                    }
                    return activeNode.getTypeDefinition().getComment() + "<br>" + "<b>XPath:</b> "
                            + activeNode.getXPath();
                }

                AttributeDefinition attribute = activeNode.getTypeDefinition().getAttribute(
                        this.sourceViewer.getDocument().get(hoverRegion.getOffset(), hoverRegion.getLength()));
                if (attribute != null) {
                    return attribute.getComment() + "<br>" + "<b>XPath:</b> " + activeNode.getXPath() + "[@"
                            + attribute.getName() + "]";
                }
            }
        } catch (Exception e1) {
            //DO NOTHING
        }
        return null;
    }

    private String getAnnotationMessage(ITextViewer textViewer, IRegion hoverRegion) {
        IAnnotationModel model = getAnnotationModel(sourceViewer);
        if (model == null) {
            return null;
        }

        Iterator e = model.getAnnotationIterator();
        StringBuffer buffer = new StringBuffer();
        while (e.hasNext()) {
            Annotation a = (Annotation) e.next();
            if (isIncluded(a)) {
                Position p = model.getPosition(a);
                if (p != null && p.overlapsWith(hoverRegion.getOffset(), hoverRegion.getLength())) {
                    String msg = a.getText();
                    if (msg != null && msg.trim().length() > 0 && !msg.trim().endsWith("changed lines")
                            && !msg.trim().endsWith("changed line")) {
                        buffer.append("-" + msg);
                        buffer.append("<br>");
                    }
                }
            }
        }

        return buffer.toString();
    }

    /*
     * @see org.eclipse.jface.text.ITextHover#getHoverRegion(org.eclipse.jface.text.ITextViewer, int)
     */
    public IRegion getHoverRegion(ITextViewer textViewer, int offset) {
        return findWord(textViewer.getDocument(), offset);
    }

    /**
     * Tells whether the annotation should be included in
     * the computation.
     *
     * @param annotation the annotation to test
     * @return <code>true</code> if the annotation is included in the computation
     */
    protected boolean isIncluded(Annotation annotation) {
        return true;
    }

    private IAnnotationModel getAnnotationModel(ISourceViewer viewer) {
        if (viewer instanceof ISourceViewerExtension2) {
            ISourceViewerExtension2 extension = (ISourceViewerExtension2) viewer;
            return extension.getVisualAnnotationModel();
        }
        return viewer.getAnnotationModel();
    }

    private IRegion findWord(IDocument document, int offset) {
        int start = -2;
        int end = -1;

        try {
            int pos = offset;
            char c;

            while (pos >= 0) {
                c = document.getChar(pos);
                if (!Character.isUnicodeIdentifierPart(c) && c != '-') {
                    break;
                }
                --pos;
            }

            start = pos;
            pos = offset;
            int length = document.getLength();

            while (pos < length) {
                c = document.getChar(pos);
                if (!Character.isUnicodeIdentifierPart(c) && c != '-') {
                    break;
                }
                ++pos;
            }

            end = pos;
        } catch (BadLocationException x) {
        }

        if (start >= -1 && end > -1) {
            if (start == offset && end == offset) {
                return new Region(offset, 0);
            } else if (start == offset) {
                return new Region(start, end - start);
            } else {
                return new Region(start + 1, end - start - 1);
            }
        }

        return null;
    }
}