Author: vrubezhny
Date: 2010-03-10 07:57:29 -0500 (Wed, 10 Mar 2010)
New Revision: 20729
Added:
trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/jspeditor/info/JavaStringELInfoHover.java
Modified:
trunk/jst/plugins/org.jboss.tools.jst.jsp/plugin.properties
trunk/jst/plugins/org.jboss.tools.jst.jsp/plugin.xml
trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/jspeditor/info/FaceletTagInfoHoverProcessor.java
Log:
JBIDE-4947: Tool tip for EL in XHTML/JSP/XML editors.
Tool tips are added for JSP/XHTML/Java editors
Modified: trunk/jst/plugins/org.jboss.tools.jst.jsp/plugin.properties
===================================================================
--- trunk/jst/plugins/org.jboss.tools.jst.jsp/plugin.properties 2010-03-10 12:48:01 UTC
(rev 20728)
+++ trunk/jst/plugins/org.jboss.tools.jst.jsp/plugin.properties 2010-03-10 12:57:29 UTC
(rev 20729)
@@ -8,4 +8,7 @@
occurrenceStructureProvidersExtensionPoint= Occurrence Structure Providers
defaultOccurrenceStructureProviderName= Default Occurrence Provider
-Bundle-Name.0 = Jsp Editor Plug-in
\ No newline at end of file
+Bundle-Name.0 = Jsp Editor Plug-in
+
+javaStringELHover= EL in Java String
+javaStringELHoverDescription= Shows the Javadoc of the selected EL-operand.
Modified: trunk/jst/plugins/org.jboss.tools.jst.jsp/plugin.xml
===================================================================
--- trunk/jst/plugins/org.jboss.tools.jst.jsp/plugin.xml 2010-03-10 12:48:01 UTC (rev
20728)
+++ trunk/jst/plugins/org.jboss.tools.jst.jsp/plugin.xml 2010-03-10 12:57:29 UTC (rev
20729)
@@ -112,9 +112,24 @@
<documentationTextHover
class="org.jboss.tools.jst.jsp.jspeditor.info.FaceletTagInfoHoverProcessor"
target="org.eclipse.wst.html.HTML_DEFAULT" />
-
+ <documentationTextHover
class="org.jboss.tools.jst.jsp.jspeditor.info.FaceletTagInfoHoverProcessor"
target="org.eclipse.wst.xml.XML_DEFAULT" />
+ <documentationTextHover
class="org.jboss.tools.jst.jsp.jspeditor.info.FaceletTagInfoHoverProcessor"
target="org.eclipse.wst.sse.ST_DEFAULT" />
+ <documentationTextHover
class="org.jboss.tools.jst.jsp.jspeditor.info.FaceletTagInfoHoverProcessor"
target="org.eclipse.jst.jsp.SCRIPT.JSP_EL" />
+ <documentationTextHover
class="org.jboss.tools.jst.jsp.jspeditor.info.FaceletTagInfoHoverProcessor"
target="org.eclipse.jst.jsp.SCRIPT.JSP_EL2" />
+
</extension>
+ <extension
+ point="org.eclipse.jdt.ui.javaEditorTextHovers">
+ <hover
+ label="%javaStringELHover"
+ description="%javaStringELHoverDescription"
+
class="org.jboss.tools.jst.jsp.jspeditor.info.JavaStringELInfoHover"
+ id="org.jboss.tools.jst.jsp.jspeditor.info.JavaStringELInfoHover"
+ activate="true">
+ </hover>
+ </extension>
+
<extension point="org.eclipse.ui.preferencePages">
<!-- Additional JSP/HTML PREFERENCE PAGES -->
<page
Modified:
trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/jspeditor/info/FaceletTagInfoHoverProcessor.java
===================================================================
---
trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/jspeditor/info/FaceletTagInfoHoverProcessor.java 2010-03-10
12:48:01 UTC (rev 20728)
+++
trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/jspeditor/info/FaceletTagInfoHoverProcessor.java 2010-03-10
12:57:29 UTC (rev 20729)
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2009 Red Hat, Inc.
+ * Copyright (c) 2010 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,
@@ -18,22 +18,36 @@
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.Region;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
+import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
+import org.eclipse.wst.sse.ui.internal.contentassist.ContentAssistUtils;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext;
import org.eclipse.wst.xml.ui.internal.taginfo.XMLTagInfoHoverProcessor;
+import org.jboss.tools.common.el.core.model.ELInstance;
+import org.jboss.tools.common.el.core.model.ELInvocationExpression;
+import org.jboss.tools.common.el.core.model.ELModel;
+import org.jboss.tools.common.el.core.model.ELUtil;
+import org.jboss.tools.common.el.core.parser.ELParser;
+import org.jboss.tools.common.el.core.parser.ELParserUtil;
import org.jboss.tools.common.el.core.resolver.ELContext;
import org.jboss.tools.common.text.TextProposal;
import org.jboss.tools.jst.jsp.contentassist.Utils;
+import
org.jboss.tools.jst.jsp.contentassist.AbstractXMLContentAssistProcessor.TextRegion;
import org.jboss.tools.jst.web.kb.IPageContext;
import org.jboss.tools.jst.web.kb.KbQuery;
import org.jboss.tools.jst.web.kb.PageContextFactory;
import org.jboss.tools.jst.web.kb.PageProcessor;
import org.jboss.tools.jst.web.kb.KbQuery.Type;
import org.jboss.tools.jst.web.kb.taglib.INameSpace;
+import org.w3c.dom.Node;
/**
*
@@ -63,7 +77,30 @@
if (fContext == null)
return null;
- return super.computeHoverHelp(textViewer, documentPosition);
+ IStructuredDocumentRegion flatNode = ((IStructuredDocument)
textViewer.getDocument()).getRegionAtCharacterOffset(fDocumentPosition);
+ ITextRegion region = null;
+
+ if (flatNode != null) {
+ region = flatNode.getRegionAtCharacterOffset(fDocumentPosition);
+ }
+
+ String hoverHelp = null;
+ if (region != null) {
+ TextRegion elPrefix = getELPrefix(flatNode, region, fDocumentPosition);
+ if (elPrefix != null && elPrefix.isELStarted()) {
+ IndexedRegion treeNode = ContentAssistUtils.getNodeAt(textViewer,
fDocumentPosition);
+ if (treeNode == null) {
+ return null;
+ }
+ Node node = (Node) treeNode;
+
+ while ((node != null) && (node.getNodeType() == Node.TEXT_NODE) &&
(node.getParentNode() != null)) {
+ node = node.getParentNode();
+ }
+ return computeELHelp((IDOMNode) treeNode, (IDOMNode) node, flatNode, region,
elPrefix);
+ }
+ }
+ return hoverHelp != null ? hoverHelp : super.computeHoverHelp(textViewer,
documentPosition);
}
@Override
@@ -80,7 +117,7 @@
String[] parentTags = Utils.getParentTags(xmlnode, true, true);
String parent = Utils.getParent(xmlnode, true, true, true);
- KbQuery kbQuery = Utils.createKbQuery(Type.ATTRIBUTE_NAME, fDocumentPosition, query,
query, //$NON-NLS-1$
+ KbQuery kbQuery = Utils.createKbQuery(Type.ATTRIBUTE_NAME, fDocumentPosition, query,
query,
prefix, uri, parentTags, parent, false);
TextProposal[] proposals = PageProcessor.getInstance().getProposals(kbQuery,
fContext);
@@ -133,7 +170,79 @@
return null;
}
+
+ protected String computeELHelp(IDOMNode xmlnode, IDOMNode parentNode,
+ IStructuredDocumentRegion flatNode, ITextRegion region, TextRegion elPrefix) {
+ if (fContext == null)
+ return null;
+
+ String query = "#{" + elPrefix.getText(); //$NON-NLS-1$
+ String prefix = getPrefix(query);
+ String uri = getUri(prefix);
+ String[] parentTags = Utils.getParentTags(xmlnode, false, true);
+ String parent = Utils.getParent(xmlnode, false, false, true);
+
+ KbQuery kbQuery = Utils.createKbQuery(Type.TEXT, fDocumentPosition, query, query,
+ prefix, uri, parentTags, parent, false);
+
+ TextProposal[] proposals = PageProcessor.getInstance().getProposals(kbQuery,
fContext);
+ if (proposals == null)
+ return null;
+
+ for(TextProposal proposal : proposals) {
+ String label = proposal == null ? null : proposal.getLabel();
+ label = (label == null || label.indexOf(':') == -1) ? label :
label.substring(0, label.indexOf(':')).trim();
+ if (label != null && query.endsWith(label) &&
+ proposal != null && proposal.getContextInfo() != null &&
+ proposal.getContextInfo().trim().length() > 0) {
+ return proposal.getContextInfo();
+ }
+ }
+
+ return null;
+ }
+
/**
+ * Returns the region to hover the text over based on the offset.
+ * Overrides the base method enabling the TEXT regions to the supported
+ *
+ * @param textViewer
+ * @param offset
+ *
+ * @return IRegion region to hover over if offset is within tag name,
+ * attribute name, or attribute value and if offset is not over
+ * invalid whitespace. otherwise, returns <code>null</code>
+ *
+ * @see org.eclipse.jface.text.ITextHover#getHoverRegion(ITextViewer, int)
+ */
+ @Override
+ public IRegion getHoverRegion(ITextViewer textViewer, int offset) {
+ if ((textViewer == null) || (textViewer.getDocument() == null)) {
+ return null;
+ }
+
+ IStructuredDocumentRegion flatNode = ((IStructuredDocument)
textViewer.getDocument()).getRegionAtCharacterOffset(offset);
+ ITextRegion region = null;
+
+ if (flatNode != null) {
+ region = flatNode.getRegionAtCharacterOffset(offset);
+ }
+
+ if (region != null) {
+ // Supply hoverhelp for text
+ String regionType = region.getType();
+ if (DOMRegionContext.XML_CONTENT.equals(regionType) ||
+ DOMRegionContext.BLOCK_TEXT.equals(regionType) ||
+ DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE.equals(regionType)) {
+ TextRegion elPrefix = getELPrefix(flatNode, region, offset);
+ if (elPrefix != null && elPrefix.isELStarted()) {
+ return new Region(elPrefix.getStartOffset() + elPrefix.getOffset() +
elPrefix.getLength(), 0);
+ }
+ }
+ }
+ return super.getHoverRegion(textViewer, offset);
+ }
+ /**
* Returns IFile resource of the document
*
* @return
@@ -190,4 +299,61 @@
}
return null;
}
+
+ /**
+ * Returns EL Prefix Text Region Information Object
+ *
+ * @return
+ */
+ private TextRegion getELPrefix(IStructuredDocumentRegion sdRegion, ITextRegion region,
int offset) {
+ if (sdRegion == null || region == null)
+ return null;
+
+ String text = sdRegion.getFullText(region);
+ int startOffset = sdRegion.getStartOffset() + region.getStart();
+
+ boolean isAttributeValue = false;
+ boolean hasOpenQuote = false;
+ boolean hasCloseQuote = false;
+ char quoteChar = (char)0;
+ if (DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE.equals(region.getType())) {
+ isAttributeValue = true;
+ if (text.startsWith("\"") || text.startsWith("'"))
{//$NON-NLS-1$ //$NON-NLS-2$
+ quoteChar = text.charAt(0);
+ hasOpenQuote = true;
+ }
+ if (hasOpenQuote && text.endsWith(String.valueOf(quoteChar))) {
+ hasCloseQuote = true;
+ }
+ }
+
+ int inValueOffset = offset - startOffset;
+ if (text != null && text.length() < inValueOffset) { // probably, the
attribute value ends before the document position
+ return null;
+ }
+ if (inValueOffset<0) {
+ return null;
+ }
+
+// String matchString = text.substring(0, inValueOffset);
+
+ ELParser p = ELParserUtil.getJbossFactory().createParser();
+ ELModel model = p.parse(text);
+
+ ELInstance is = ELUtil.findInstance(model, inValueOffset);// ELInstance
+ ELInvocationExpression ie = ELUtil.findExpression(model, inValueOffset);//
ELExpression
+
+ boolean isELStarted = (model != null && is != null &&
(model.toString().startsWith("#{") || //$NON-NLS-1$
+ model.toString().startsWith("${"))); //$NON-NLS-1$
+ boolean isELClosed = (model != null && is != null &&
model.toString().endsWith("}")); //$NON-NLS-1$
+
+// boolean insideEL = startOffset + model.toString().length()
+ TextRegion tr = new TextRegion(startOffset, ie == null ? inValueOffset :
ie.getStartPosition(),
+ ie == null ? 0 : ie.getLength(), ie == null ? "" : ie.getText(),
//$NON-NLS-1$
+ isELStarted, isELClosed,
+ isAttributeValue, hasOpenQuote, hasCloseQuote, quoteChar);
+
+ return tr;
+ }
+
}
Added:
trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/jspeditor/info/JavaStringELInfoHover.java
===================================================================
---
trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/jspeditor/info/JavaStringELInfoHover.java
(rev 0)
+++
trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/jspeditor/info/JavaStringELInfoHover.java 2010-03-10
12:57:29 UTC (rev 20729)
@@ -0,0 +1,209 @@
+/*******************************************************************************
+ * Copyright (c) 2010 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.jst.jsp.jspeditor.info;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jdt.core.ITypeRoot;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.ui.text.FastJavaPartitionScanner;
+import org.eclipse.jdt.internal.ui.text.JavaWordFinder;
+import org.eclipse.jdt.internal.ui.text.java.hover.AbstractJavaEditorTextHover;
+import org.eclipse.jdt.ui.text.IJavaPartitions;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DefaultInformationControl;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IInformationControl;
+import org.eclipse.jface.text.IInformationControlCreator;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.wst.sse.ui.internal.derived.HTMLTextPresenter;
+import org.jboss.tools.common.el.core.model.ELInvocationExpression;
+import org.jboss.tools.common.el.core.model.ELModel;
+import org.jboss.tools.common.el.core.model.ELUtil;
+import org.jboss.tools.common.el.core.parser.ELParser;
+import org.jboss.tools.common.el.core.parser.ELParserUtil;
+import org.jboss.tools.common.el.core.resolver.ELContext;
+import org.jboss.tools.common.text.TextProposal;
+import org.jboss.tools.jst.jsp.JspEditorPlugin;
+import org.jboss.tools.jst.jsp.contentassist.Utils;
+import org.jboss.tools.jst.web.kb.KbQuery;
+import org.jboss.tools.jst.web.kb.PageContextFactory;
+import org.jboss.tools.jst.web.kb.PageProcessor;
+import org.jboss.tools.jst.web.kb.KbQuery.Type;
+
+/**
+ *
+ * @author Victor Rubezhny
+ *
+ */
+@SuppressWarnings("restriction")
+public class JavaStringELInfoHover extends AbstractJavaEditorTextHover {
+
+ /*
+ * @see ITextHover#getHoverRegion(ITextViewer, int)
+ */
+ public IRegion getHoverRegion(ITextViewer textViewer, int offset) {
+ return JavaWordFinder.findWord(textViewer.getDocument(), offset);
+ }
+
+ /*
+ * @see JavaElementHover
+ */
+ public String getHoverInfo(ITextViewer textViewer, IRegion region) {
+ // find a region of __java_string, if we're in it - use it
+ IDocument document = textViewer == null ? null : textViewer.getDocument();
+ if (document == null)
+ return null;
+
+ int rangeStart = -1;
+ int rangeLength = 0;
+ IToken rangeToken = null;
+ FastJavaPartitionScanner scanner = new FastJavaPartitionScanner();
+ scanner.setRange(document, 0, document.getLength());
+ while(true) {
+ IToken token = scanner.nextToken();
+ if(token == null || token.isEOF()) break;
+ int start = scanner.getTokenOffset();
+ int length = scanner.getTokenLength();
+ int end = start + length;
+ if(start <= region.getOffset() && end >= region.getOffset()) {
+ rangeStart = start;
+ rangeLength = length;
+ rangeToken = token;
+ break;
+ }
+ if(start > region.getOffset()) break;
+ }
+
+ if (rangeToken == null || rangeStart == -1 || rangeLength <=0 ||
+ !IJavaPartitions.JAVA_STRING.equals(rangeToken.getData()))
+ return null;
+
+ // OK. We've found JAVA_STRING token
+ // Check that the position is in the EL
+ if (!checkStartPosition(document, region.getOffset()))
+ return null;
+
+ // Calculate and prepare KB-query parameters
+ String text = null;
+ try {
+ text = document.get(rangeStart, rangeLength);
+ } catch (BadLocationException e) {
+ JspEditorPlugin.getPluginLog().logError(e);
+ }
+ int inValueOffset = region.getOffset() - rangeStart;
+
+ ELParser p = ELParserUtil.getJbossFactory().createParser();
+ ELModel model = p.parse(text);
+
+ ELInvocationExpression ie = ELUtil.findExpression(model, inValueOffset);//
ELExpression
+ if (ie == null)
+ return null;
+
+ String query = "#{" + ie.getText(); //$NON-NLS-1$
+
+ KbQuery kbQuery = Utils.createKbQuery(Type.ATTRIBUTE_VALUE, region.getOffset() +
region.getLength(),
+ query, query, "", "", null, null, false); //$NON-NLS-1$
//$NON-NLS-2$
+
+ ITypeRoot input= getEditorInputJavaElement();
+ if (input == null)
+ return null;
+
+ IFile file = null;
+
+ try {
+ IResource resource = input.getCorrespondingResource();
+ if (resource instanceof IFile)
+ file = (IFile) resource;
+ } catch (JavaModelException e) {
+ // Ignore. It is probably because of Java element's resource is not found
+ }
+
+ ELContext context = PageContextFactory.createPageContext(file,
JavaCore.JAVA_SOURCE_CONTENT_TYPE);
+
+ TextProposal[] proposals = PageProcessor.getInstance().getProposals(kbQuery, context);
+ if (proposals == null)
+ return null;
+
+ for(TextProposal proposal : proposals) {
+ String label = proposal == null ? null : proposal.getLabel();
+ label = (label == null || label.indexOf(':') == -1) ? label :
label.substring(0, label.indexOf(':')).trim();
+ if (label != null && query.endsWith(label) &&
+ proposal != null && proposal.getContextInfo() != null &&
+ proposal.getContextInfo().trim().length() > 0) {
+ return proposal.getContextInfo();
+ }
+ }
+
+ return null;
+ }
+
+ /*
+ * Checks if the EL start starting characters are present
+ * @param viewer
+ * @param offset
+ * @return
+ * @throws BadLocationException
+ */
+ private boolean checkStartPosition(IDocument document, int offset) {
+ try {
+ while (--offset >= 0) {
+ if ('}' == document.getChar(offset))
+ return false;
+
+
+ if ('"' == document.getChar(offset) &&
+ (offset - 1) >= 0 && '\\' != document.getChar(offset - 1)) {
+ return false;
+ }
+
+
+ if ('{' == document.getChar(offset) &&
+ (offset - 1) >= 0 &&
+ ('#' == document.getChar(offset - 1) ||
+ '$' == document.getChar(offset - 1))) {
+ return true;
+ }
+ }
+ } catch (BadLocationException e) {
+ JspEditorPlugin.getPluginLog().logError(e);
+ }
+ return false;
+ }
+
+ /*
+ * @see org.eclipse.jface.text.ITextHoverExtension#getHoverControlCreator()
+ * @since 3.0
+ */
+ public IInformationControlCreator getHoverControlCreator() {
+ return new IInformationControlCreator() {
+ public IInformationControl createInformationControl(Shell parent) {
+ return new DefaultInformationControl(parent, new HTMLTextPresenter(true));
+ }
+ };
+ }
+
+ /*
+ * @see
org.eclipse.jface.text.ITextHoverExtension2#getInformationPresenterControlCreator()
+ * @since 3.0
+ */
+ public IInformationControlCreator getInformationPresenterControlCreator() {
+ return new IInformationControlCreator() {
+ public IInformationControl createInformationControl(Shell parent) {
+ return new DefaultInformationControl(parent, new HTMLTextPresenter(true));
+ }
+ };
+ }
+}
Property changes on:
trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/jspeditor/info/JavaStringELInfoHover.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain