Author: vrubezhny
Date: 2010-01-20 10:11:52 -0500 (Wed, 20 Jan 2010)
New Revision: 19826
Modified:
trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/AbstractXMLContentAssistProcessor.java
trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/AutoContentAssistantProposal.java
trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/FaceletPageContectAssistProcessor.java
trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/JspContentAssistProcessor.java
trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/XmlContentAssistProcessor.java
Log:
JBIDE-3290: sorting/filtering is not updating correctly in code completion of source page
in VPE
Predicate EL proposals are added for attribute value regions in XML/XHTML/JSP editors and
for text regions in XML/XHTML editors. The predicative proposals, when applied, change
the word/part of word right before cursor to EL expression by inserting '#{'
character sequence before the word/part of word beginning and '} ' character
sequence right after proposed text.
Modified:
trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/AbstractXMLContentAssistProcessor.java
===================================================================
---
trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/AbstractXMLContentAssistProcessor.java 2010-01-20
14:51:57 UTC (rev 19825)
+++
trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/AbstractXMLContentAssistProcessor.java 2010-01-20
15:11:52 UTC (rev 19826)
@@ -996,6 +996,74 @@
}
/**
+ * Returns EL Predicate Text Region Information Object
+ *
+ *
+ * @return
+ */
+ protected TextRegion getELPredicatePrefix(ContentAssistRequest request) {
+ if (!DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE.equals(request.getRegion().getType())
&&
+ !DOMRegionContext.XML_CONTENT.equals(request.getRegion().getType()) &&
+ !DOMRegionContext.BLOCK_TEXT.equals(request.getRegion().getType()))
+ return null;
+
+ String text = request.getDocumentRegion().getFullText(request.getRegion());
+ int startOffset = request.getDocumentRegion().getStartOffset() +
request.getRegion().getStart();
+
+ boolean isAttributeValue = false;
+ boolean hasOpenQuote = false;
+ boolean hasCloseQuote = false;
+ char quoteChar = (char)0;
+ if (DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE.equals(request.getRegion().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 = getOffset() - startOffset;
+ if (inValueOffset<0 || // There is no a word part before cursor
+ (text != null && text.length() < inValueOffset)) { // probably, the
attribute value ends before the document position
+ return null;
+ }
+
+ String matchString = getELPredicateMatchString(text, inValueOffset);
+ if (matchString == null)
+ return null;
+
+ TextRegion tr = new TextRegion(startOffset, getOffset() - matchString.length() -
startOffset,
+ matchString.length(), matchString, false, false,
+ isAttributeValue, hasOpenQuote, hasCloseQuote, quoteChar);
+
+ return tr;
+ }
+
+ /**
+ * Returns predicate string for the EL-related query.
+ * The predicate string is the word/part of word right before the cursor position,
including the '.' and '_' characters,
+ * which is to be replaced by the EL CA proposal ('#{' and '}' character
sequences are to be inserted too)
+ *
+ * @param text
+ * @param offset
+ * @return
+ */
+ protected String getELPredicateMatchString(String text, int offset) {
+ int beginningOffset = offset - 1;
+ while(beginningOffset >=0 &&
+ (Character.isJavaIdentifierPart(text.charAt(beginningOffset)) ||
+ '.' == text.charAt(beginningOffset) ||
+ '_' == text.charAt(beginningOffset))) {
+ beginningOffset--;
+ }
+ beginningOffset++; // move it to point the first valid character
+ return text.substring(beginningOffset, offset);
+ }
+
+ /**
* Returns EL Prefix Text Region Information Object
*
* @deprecated
Modified:
trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/AutoContentAssistantProposal.java
===================================================================
---
trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/AutoContentAssistantProposal.java 2010-01-20
14:51:57 UTC (rev 19825)
+++
trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/AutoContentAssistantProposal.java 2010-01-20
15:11:52 UTC (rev 19826)
@@ -21,8 +21,12 @@
import org.eclipse.jface.viewers.StyledString;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
+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.CustomCompletionProposal;
import org.eclipse.wst.sse.ui.internal.contentassist.IRelevanceConstants;
+import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext;
/**
* @author Igels
@@ -129,6 +133,28 @@
private int fOriginalReplacementLength;
+ /**
+ * Returns true in case of the region at specified offset is a node name region
+ *
+ * @param document
+ * @param offset
+ * @return
+ */
+ private boolean isTagName(IDocument document, int offset) {
+ if (!(document instanceof IStructuredDocument))
+ return false;
+
+ int lastOffset = offset;
+ IStructuredDocumentRegion sdRegion =
((IStructuredDocument)document).getRegionAtCharacterOffset(offset);
+ while (sdRegion == null && lastOffset >= 0) {
+ lastOffset--;
+ sdRegion = ((IStructuredDocument)document).getRegionAtCharacterOffset(lastOffset);
+ }
+
+ ITextRegion region = sdRegion == null ? null :
sdRegion.getRegionAtCharacterOffset(offset);
+
+ return DOMRegionContext.XML_TAG_NAME.equals(region == null ? null : region.getType());
+ }
// Fix for JBIDE-5125 >>>
@Override
@@ -138,10 +164,14 @@
if (offset < fReplacementOffset)
return false;
boolean validated = startsWith(document, offset, getReplacementString());
- if (!validated && getReplacementString() != null &&
getReplacementString().indexOf(":") != -1) { //$NON-NLS-1$
+ if (!validated && isTagName(document, fReplacementOffset) &&
getReplacementString() != null && getReplacementString().indexOf(":") !=
-1) { //$NON-NLS-1$
String replacementString =
getReplacementString().substring(getReplacementString().indexOf(":") + 1);
//$NON-NLS-1$
validated = startsWith(document, offset, replacementString);
}
+ if (!validated && getReplacementString() != null &&
getReplacementString().startsWith("#{")) { //$NON-NLS-1$
+ String replacementString =
getReplacementString().substring(getReplacementString().indexOf("#{") + 2);
//$NON-NLS-1$
+ validated = startsWith(document, offset, replacementString);
+ }
// it would be better to use "originalCursorPosition" instead of
// getReplacementOffset(), but we don't have that info.
int newLength = offset - getReplacementOffset();
Modified:
trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/FaceletPageContectAssistProcessor.java
===================================================================
---
trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/FaceletPageContectAssistProcessor.java 2010-01-20
14:51:57 UTC (rev 19825)
+++
trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/FaceletPageContectAssistProcessor.java 2010-01-20
15:11:52 UTC (rev 19826)
@@ -55,6 +55,29 @@
}
/**
+ * Calculates and adds the tag proposals to the Content Assist Request object
+ * The method is to be overridden here because xhtml allows to use EL-s inside a text
region
+ *
+ * @param contentAssistRequest Content Assist Request object
+ * @param childPosition the
+ */
+
+ @Override
+ protected void addTagInsertionProposals(
+ ContentAssistRequest contentAssistRequest, int childPosition) {
+
+ // Need to check if an EL Expression is opened here.
+ // If it is true we don't need to start any new tag proposals
+ TextRegion prefix = getELPrefix(contentAssistRequest);
+ if (prefix != null && prefix.isELStarted()) {
+ return;
+ }
+
+ addTagNameProposals(contentAssistRequest, childPosition, true);
+ addAttributeValueELPredicateProposals(contentAssistRequest);
+ }
+
+ /**
* Calculates and adds the EL proposals to the Content Assist Request object
*/
@Override
Modified:
trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/JspContentAssistProcessor.java
===================================================================
---
trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/JspContentAssistProcessor.java 2010-01-20
14:51:57 UTC (rev 19825)
+++
trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/JspContentAssistProcessor.java 2010-01-20
15:11:52 UTC (rev 19826)
@@ -150,6 +150,28 @@
}
/**
+ * Calculates and adds the tag proposals to the Content Assist Request object
+ * The method is to be overridden here because jsp disallows to use EL-s inside a text
region
+ *
+ * @param contentAssistRequest Content Assist Request object
+ * @param childPosition the
+ */
+
+ @Override
+ protected void addTagInsertionProposals(
+ ContentAssistRequest contentAssistRequest, int childPosition) {
+
+ // Need to check if an EL Expression is opened here.
+ // If it is true we don't need to start any new tag proposals
+ TextRegion prefix = getELPrefix(contentAssistRequest);
+ if (prefix != null && prefix.isELStarted()) {
+ return;
+ }
+
+ addTagNameProposals(contentAssistRequest, childPosition, true);
+ }
+
+ /**
* Calculates and adds the attribute name proposals to the Content Assist Request
object
*
* @param contentAssistRequest Content Assist Request object
Modified:
trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/XmlContentAssistProcessor.java
===================================================================
---
trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/XmlContentAssistProcessor.java 2010-01-20
14:51:57 UTC (rev 19825)
+++
trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/XmlContentAssistProcessor.java 2010-01-20
15:11:52 UTC (rev 19826)
@@ -105,6 +105,7 @@
}
addTagNameProposals(contentAssistRequest, childPosition, true);
+ addAttributeValueELPredicateProposals(contentAssistRequest);
}
private void addTagNameProposalsForPrefix(
@@ -283,8 +284,77 @@
contentAssistRequest.addProposal(proposal);
}
+
+ addAttributeValueELPredicateProposals(contentAssistRequest);
}
+ /**
+ * Calculates and adds EL predicate proposals based on the last word typed
+ * To be used only outside the EL.
+ *
+ * @param contentAssistRequest
+ */
+ protected void addAttributeValueELPredicateProposals(ContentAssistRequest
contentAssistRequest) {
+ // Need to check if the cursor is placed right after a word part.
+ // If there is no word part found then just quit
+ TextRegion prefix = getELPredicatePrefix(contentAssistRequest);
+ if (prefix == null || prefix.isELStarted()) {
+ return;
+ }
+ String matchString = "#{" + prefix.getText(); //$NON-NLS-1$
+ String query = matchString;
+ if (query == null)
+ query = ""; //$NON-NLS-1$
+ String stringQuery = matchString;
+
+ int beginChangeOffset = prefix.getStartOffset() + prefix.getOffset();
+
+ KbQuery kbQuery = createKbQuery(Type.ATTRIBUTE_VALUE, query, stringQuery);
+ TextProposal[] proposals = PageProcessor.getInstance().getProposals(kbQuery,
getContext());
+
+ for (int i = 0; proposals != null && i < proposals.length; i++) {
+ TextProposal textProposal = proposals[i];
+
+ int replacementOffset = beginChangeOffset;
+ int replacementLength = prefix.getLength();
+ String replacementString = "#{" + prefix.getText().substring(0,
replacementLength) + textProposal.getReplacementString(); //$NON-NLS-1$
+
+ char quoteChar = prefix.isAttributeValue() && prefix.hasOpenQuote() ?
prefix.getQuoteChar() : '"';
+ int cursorPosition = replacementString.length();
+
+ if (!prefix.isELClosed()) {
+ replacementString += "}"; //$NON-NLS-1$
+ }
+
+ if (prefix.isAttributeValue() && prefix.hasOpenQuote() &&
!prefix.hasCloseQuote()) {
+ replacementString += String.valueOf(quoteChar);
+ }
+
+ Image image = textProposal.getImage();
+
+ // JBIDE-512, JBIDE-2541 related changes ===>>>
+// String displayString = prefix.getText().substring(0, replacementLength) +
textProposal.getReplacementString();
+ String displayString = textProposal.getLabel();
+ if (displayString == null)
+ displayString = textProposal.getReplacementString() == null ? replacementString :
textProposal.getReplacementString();
+ // <<<=== JBIDE-512, JBIDE-2541 related changes
+
+ IContextInformation contextInformation = null;
+ String additionalProposalInfo = (textProposal.getContextInfo() == null ? ""
: textProposal.getContextInfo()); //$NON-NLS-1$
+ int relevance = textProposal.getRelevance();
+ if (relevance == TextProposal.R_NONE) {
+ relevance = TextProposal.R_JSP_JSF_EL_VARIABLE_ATTRIBUTE_VALUE;
+ }
+
+ AutoContentAssistantProposal proposal = new
AutoContentAssistantProposal(replacementString,
+ replacementOffset, replacementLength, cursorPosition, image, displayString,
+ contextInformation, additionalProposalInfo, relevance);
+
+ contentAssistRequest.addProposal(proposal);
+ }
+ }
+
+
@Override
protected void addAttributeValueELProposals(ContentAssistRequest contentAssistRequest)
{
if (!isJsfProject())