/*******************************************************************************
* Copyright (c) 2009-2011 Red Hat, Inc.
* Distributed under license by Red Hat, Inc. All rights reserved.
* This program is 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:
* Red Hat, Inc. - initial API and implementation
******************************************************************************/
package org.jboss.tools.common.text.xml.info;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.jface.text.IInformationControlCreator;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextHover;
import org.eclipse.jface.text.ITextHoverExtension;
import org.eclipse.jface.text.ITextHoverExtension2;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.wst.sse.ui.internal.Logger;
import org.eclipse.wst.sse.ui.internal.taginfo.AnnotationHoverProcessor;
import org.eclipse.wst.sse.ui.internal.taginfo.DebugInfoHoverProcessor;
import org.jboss.tools.common.text.xml.XmlEditorPlugin;
import org.jboss.tools.common.text.xml.xpl.MarkerProblemAnnotationHoverProcessor;
/**
* Provides the best hover help documentation (by using other hover help
* processors) Priority of hover help processors is: ProblemHoverProcessor,
* FaceletTagInfoProcessor, TagInfoProcessor, AnnotationHoverProcessor
*
* The processors are acquired in order of their priorities. If a hover doesn'n returns an information
* (i.e. returns null as a display string) the next processor will be acquired.
*
* @author Victor Rubezhny
*
*/
@SuppressWarnings("restriction")
public class ChainTextHover implements ITextHover, ITextHoverExtension, ITextHoverExtension2 {
private ITextHover fBestMatchHover; // current best match text hover
private ITextHover[] fTagInfoHovers; // documentation/information hover
private List<ITextHover> fTextHovers; // list of text hovers to consider in best
// match
public ChainTextHover(ITextHover infoTagHover) {
this(new ITextHover[]{infoTagHover});
}
public ChainTextHover(ITextHover[] infoTagHovers) {
fTagInfoHovers = infoTagHovers;
}
/**
* Create a list of text hovers applicable to this best match hover
* processor
*
* @return List of ITextHover - in abstract class this is empty list
*/
private List<ITextHover> createTextHoversList() {
List<ITextHover> hoverList = new ArrayList<ITextHover>();
// if currently debugging, then add the debug hover to the list of
// best match
if (Logger.isTracing(DebugInfoHoverProcessor.TRACEFILTER)) {
hoverList.add(new DebugInfoHoverProcessor());
}
// hoverList.add(new ProblemAnnotationHoverProcessor());
hoverList.add(new MarkerProblemAnnotationHoverProcessor());
int lastToolsIndex = hoverList.size();
for (int i = 0; i < fTagInfoHovers.length; i++) {
if (fTagInfoHovers[i].getClass().getName().startsWith("org.jboss.tools.")) { //$NON-NLS-1$
hoverList.add(lastToolsIndex,fTagInfoHovers[i]);
lastToolsIndex++;
} else {
hoverList.add(fTagInfoHovers[i]);
}
}
hoverList.add(new AnnotationHoverProcessor());
return hoverList;
}
public IInformationControlCreator getHoverControlCreator() {
IInformationControlCreator creator = null;
if (fBestMatchHover instanceof ITextHoverExtension) {
creator = ((ITextHoverExtension) fBestMatchHover).getHoverControlCreator();
}
return creator;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.text.ITextHover#getHoverInfo(org.eclipse.jface.text.ITextViewer,
* org.eclipse.jface.text.IRegion)
*/
public String getHoverInfo(ITextViewer viewer, IRegion hoverRegion) {
String displayInfo = null;
// already have a best match hover picked out from getHoverRegion call
if (fBestMatchHover != null) {
displayInfo = fBestMatchHover.getHoverInfo(viewer, hoverRegion);
}
// either had no best match hover or best match hover returned null
if (displayInfo == null) {
// go through the list of text hovers and return first display string
Iterator<ITextHover> i = getTextHovers().iterator();
while ((i.hasNext()) && (displayInfo == null)) {
ITextHover hover = (ITextHover) i.next();
if(hover instanceof ITextHoverExtension2) {
Object displayInfoObject = ((ITextHoverExtension2)hover).getHoverInfo2(viewer, hoverRegion);
if(displayInfoObject!=null) {
displayInfo = displayInfoObject.toString();
}
} else {
displayInfo = hover.getHoverInfo(viewer, hoverRegion);
}
}
}
return displayInfo;
}
public Object getHoverInfo2(ITextViewer viewer, IRegion hoverRegion) {
Object objectInfo = null;
// already have a best match hover picked out from getHoverRegion call
if (fBestMatchHover != null) {
if (fBestMatchHover instanceof ITextHoverExtension2) {
objectInfo = ((ITextHoverExtension2) fBestMatchHover).getHoverInfo2(viewer, hoverRegion);
} else {
objectInfo = fBestMatchHover.getHoverInfo(viewer, hoverRegion);
}
}
if (objectInfo == null) {
// go through the list of text hovers and return first display string
Iterator<ITextHover> i = getTextHovers().iterator();
while ((i.hasNext()) && (objectInfo == null)) {
ITextHover hover = (ITextHover) i.next();
if(hover instanceof ITextHoverExtension2) {
objectInfo = ((ITextHoverExtension2)hover).getHoverInfo2(viewer, hoverRegion);
} else {
objectInfo = hover.getHoverInfo(viewer, hoverRegion);
}
}
}
// either had no best match hover or best match hover returned null
return objectInfo;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.text.ITextHover#getHoverRegion(org.eclipse.jface.text.ITextViewer,
* int)
*/
public IRegion getHoverRegion(ITextViewer viewer, int offset) {
IRegion hoverRegion = null;
// go through list of text hovers and return first hover region
ITextHover hover = null;
Iterator<ITextHover> i = getTextHovers().iterator();
while ((i.hasNext()) && (hoverRegion == null)) {
hover = i.next();
hoverRegion = hover.getHoverRegion(viewer, offset);
}
// store the text hover processor that found region
if (hoverRegion != null)
fBestMatchHover = hover;
else
fBestMatchHover = null;
return hoverRegion;
}
private List<ITextHover> getTextHovers() {
if (fTextHovers == null) {
fTextHovers = createTextHoversList();
}
return fTextHovers;
}
}