[jbosstools-commits] JBoss Tools SVN: r24020 - in trunk: common/plugins/org.jboss.tools.common.text.xml/src/org/jboss/tools/common/text/xml and 6 other directories.
jbosstools-commits at lists.jboss.org
jbosstools-commits at lists.jboss.org
Tue Aug 10 10:13:06 EDT 2010
Author: vrubezhny
Date: 2010-08-10 10:13:05 -0400 (Tue, 10 Aug 2010)
New Revision: 24020
Added:
trunk/common/plugins/org.jboss.tools.common.text.xml/src/org/jboss/tools/common/text/xml/contentassist/ProposalSorter.java
trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/computers/
trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/computers/AbstractXmlCompletionProposalComputer.java
trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/computers/FaceletsELCompletionProposalComputer.java
trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/computers/FaceletsTagCompletionProposalComputer.java
trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/computers/JspELCompletionProposalComputer.java
trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/computers/JspTagCompletionProposalComputer.java
trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/computers/XmlELCompletionProposalComputer.java
trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/computers/XmlTagCompletionProposalComputer.java
Modified:
trunk/common/plugins/org.jboss.tools.common.text.xml/src/org/jboss/tools/common/text/xml/XMLTextViewerConfiguration.java
trunk/common/plugins/org.jboss.tools.common.text.xml/src/org/jboss/tools/common/text/xml/contentassist/SortingCompoundContentAssistProcessor.java
trunk/common/plugins/org.jboss.tools.common/src/org/jboss/tools/common/text/TextProposal.java
trunk/jst/plugins/org.jboss.tools.jst.jsp/META-INF/MANIFEST.MF
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/HTMLTextViewerConfiguration.java
trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/JSPTextViewerConfiguration.java
Log:
JBIDE-6211: Move jsp/jsf/xml source editing to the Eclipse 3.6
And it's subtasks:
JBIDE-6266: Support for the Categories in JBoss CA processors
JBIDE-6509: Some JBoss CA tagname proposals duplicate the WTP ones
Modified: trunk/common/plugins/org.jboss.tools.common/src/org/jboss/tools/common/text/TextProposal.java
===================================================================
--- trunk/common/plugins/org.jboss.tools.common/src/org/jboss/tools/common/text/TextProposal.java 2010-08-10 14:09:52 UTC (rev 24019)
+++ trunk/common/plugins/org.jboss.tools.common/src/org/jboss/tools/common/text/TextProposal.java 2010-08-10 14:13:05 UTC (rev 24020)
@@ -29,7 +29,7 @@
public static final int R_JSP_ATTRIBUTE_VALUE = 830;
public static final int R_XML_ATTRIBUTE_VALUE = 850;
public static final int R_XML_ATTRIBUTE_NAME = 910;
- public static final int R_TAG_INSERTION = 500;
+ public static final int R_TAG_INSERTION = 1210; // This value was changed from 500 to 1210 because it seems that according WTP's value was risen up to 1200 in 3.6
public static final int R_XML_ATTRIBUTE_VALUE_TEMPLATE = 91;
public static final int R_CLOSE_TAG = 1550;
Modified: trunk/common/plugins/org.jboss.tools.common.text.xml/src/org/jboss/tools/common/text/xml/XMLTextViewerConfiguration.java
===================================================================
--- trunk/common/plugins/org.jboss.tools.common.text.xml/src/org/jboss/tools/common/text/xml/XMLTextViewerConfiguration.java 2010-08-10 14:09:52 UTC (rev 24019)
+++ trunk/common/plugins/org.jboss.tools.common.text.xml/src/org/jboss/tools/common/text/xml/XMLTextViewerConfiguration.java 2010-08-10 14:13:05 UTC (rev 24020)
@@ -13,10 +13,10 @@
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
@@ -25,12 +25,15 @@
import org.eclipse.jface.text.source.SourceViewerConfiguration;
import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;
import org.eclipse.wst.sse.ui.StructuredTextViewerConfiguration;
+import org.eclipse.wst.sse.ui.contentassist.CompletionProposalInvocationContext;
import org.eclipse.wst.xml.ui.StructuredTextViewerConfigurationXML;
-import org.jboss.tools.common.text.xml.contentassist.SortingCompoundContentAssistProcessor;
+import org.eclipse.wst.xml.ui.internal.contentassist.XMLStructuredContentAssistProcessor;
+import org.jboss.tools.common.text.xml.contentassist.ProposalSorter;
/**
* @author Igels
*/
+ at SuppressWarnings("restriction")
public class XMLTextViewerConfiguration extends StructuredTextViewerConfigurationXML {
SourceViewerConfiguration initial = null;
@@ -45,15 +48,30 @@
protected IContentAssistProcessor[] getContentAssistProcessors(ISourceViewer sourceViewer, String partitionType) {
- IContentAssistProcessor[] superProcessors = super.getContentAssistProcessors(
- sourceViewer, partitionType);
+// IContentAssistProcessor[] superProcessors = super.getContentAssistProcessors(
+// sourceViewer, partitionType);
+
+ IContentAssistProcessor superProcessor = new XMLStructuredContentAssistProcessor(
+ this.getContentAssistant(), partitionType, sourceViewer) {
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ @Override
+ protected List filterAndSortProposals(List proposals,
+ IProgressMonitor monitor,
+ CompletionProposalInvocationContext context) {
+ return ProposalSorter.filterAndSortProposals(proposals, monitor, context);
+ }
+
+ };
+
List<IContentAssistProcessor> processors = new ArrayList<IContentAssistProcessor>();
- SortingCompoundContentAssistProcessor sortingCompoundProcessor = new SortingCompoundContentAssistProcessor(sourceViewer, partitionType);
- if (sortingCompoundProcessor.supportsPartitionType(partitionType)) {
- processors.add(sortingCompoundProcessor);
- }
- processors.addAll(Arrays.asList(superProcessors));
+// SortingCompoundContentAssistProcessor sortingCompoundProcessor = new SortingCompoundContentAssistProcessor(sourceViewer, partitionType);
+// if (sortingCompoundProcessor.supportsPartitionType(partitionType)) {
+// processors.add(sortingCompoundProcessor);
+// }
+// processors.addAll(Arrays.asList(superProcessors));
+ processors.add(superProcessor);
return processors.toArray(new IContentAssistProcessor[0]);
}
@@ -92,11 +110,15 @@
return total.toArray(new IHyperlinkDetector[0]);
}
+ @SuppressWarnings("deprecation")
private IHyperlinkDetector getTextEditorsExtensionsHyperlinkDetector() {
Plugin plugin = Platform.getPlugin("org.jboss.tools.common.text.ext"); //$NON-NLS-1$
return (plugin != null && plugin instanceof IAdaptable ? (IHyperlinkDetector)((IAdaptable)plugin).getAdapter(IHyperlinkDetector.class):null);
}
-
+
+ /**
+ * @deprecated
+ */
IContentAssistProcessor[] getInitialProcessors(ISourceViewer sourceViewer, String partitionType) {
if(initial == null) return null;
//method getContentAssistProcessors() is declared in StructuredTextViewerConfiguration
@@ -118,6 +140,9 @@
return null;
}
+ /**
+ * @deprecated
+ */
@SuppressWarnings("rawtypes")
private Method findDeclaredMethod(Class cls, String name, Class[] paramTypes) {
Method[] ms = cls.getDeclaredMethods();
Added: trunk/common/plugins/org.jboss.tools.common.text.xml/src/org/jboss/tools/common/text/xml/contentassist/ProposalSorter.java
===================================================================
--- trunk/common/plugins/org.jboss.tools.common.text.xml/src/org/jboss/tools/common/text/xml/contentassist/ProposalSorter.java (rev 0)
+++ trunk/common/plugins/org.jboss.tools.common.text.xml/src/org/jboss/tools/common/text/xml/contentassist/ProposalSorter.java 2010-08-10 14:13:05 UTC (rev 24020)
@@ -0,0 +1,149 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Exadel, Inc. and 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:
+ * Exadel, Inc. and Red Hat, Inc. - initial API and implementation
+ ******************************************************************************/
+package org.jboss.tools.common.text.xml.contentassist;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.text.contentassist.ICompletionProposal;
+import org.eclipse.wst.sse.ui.contentassist.CompletionProposalInvocationContext;
+import org.eclipse.wst.sse.ui.internal.contentassist.CustomCompletionProposal;
+import org.eclipse.wst.sse.ui.internal.contentassist.IRelevanceCompletionProposal;
+import org.eclipse.wst.sse.ui.internal.util.Sorter;
+
+/**
+ * The utility helper class which purpose is to filter out and sort
+ * Content Assist proposals
+ *
+ * @author Jeremy
+ */
+ at SuppressWarnings("restriction")
+public class ProposalSorter {
+
+ /**
+ * Filters and sorts the Content Assist proposals
+ *
+ */
+ public static List<ICompletionProposal> filterAndSortProposals(List<ICompletionProposal> proposals,
+ IProgressMonitor monitor, CompletionProposalInvocationContext context) {
+ if (proposals == null)
+ return null;
+ ICompletionProposal[] resultArray = (ICompletionProposal[])proposals.toArray(new ICompletionProposal[proposals.size()]);
+ Object[] sorted = createSorter().sort(resultArray);
+ System.arraycopy(sorted, 0, resultArray, 0, sorted.length);
+ resultArray = makeUnique(resultArray);
+ return Arrays.asList(resultArray);
+ }
+
+ private static Sorter createSorter() {
+ return new Sorter() {
+ public boolean compare(Object proposal1, Object proposal2) {
+
+ int pr1 = Integer.MIN_VALUE;
+ int pr2 = Integer.MIN_VALUE;
+
+ ICompletionProposal p1 = (ICompletionProposal)proposal1;
+ ICompletionProposal p2 = (ICompletionProposal)proposal2;
+
+ if (p1 instanceof IRelevanceCompletionProposal)
+ pr1 = ((IRelevanceCompletionProposal)p1).getRelevance();
+
+ if (p2 instanceof IRelevanceCompletionProposal)
+ pr2 = ((IRelevanceCompletionProposal)p2).getRelevance();
+
+
+ if (pr1 == pr2) {
+ String str1 = (p1.getDisplayString() == null ? "" : p1.getDisplayString()); //$NON-NLS-1$
+ String str2 = (p2.getDisplayString() == null ? "" : p2.getDisplayString()); //$NON-NLS-1$
+ return str2.compareTo(str1) > 0;
+ }
+
+ return (pr1 > pr2);
+ }
+ };
+ }
+
+ /**
+ * Removes duplicates of completion strings
+ *
+ * @param suggestions a list of suggestions ({@link String}).
+ * @return a list of unique completion suggestions.
+ */
+ public static ICompletionProposal[] makeUnique(ICompletionProposal[] proposals) {
+ if (proposals == null)
+ return null;
+
+ Map <String, ICompletionProposal> existingProposals = new HashMap<String, ICompletionProposal>(proposals.length);
+ ArrayList<ICompletionProposal> unique = new ArrayList<ICompletionProposal>(proposals.length);
+
+ for (ICompletionProposal proposal : proposals) {
+ if (proposal == null)
+ continue;
+
+ String replString = null;
+ String dispString = null;
+
+ if (proposal instanceof CustomCompletionProposal) {
+ replString = ((CustomCompletionProposal) proposal)
+ .getReplacementString();
+ }
+ dispString = unQuote(proposal.getDisplayString());
+ replString = getReplacementWord(replString == null ? dispString
+ : replString);
+
+ ICompletionProposal existingProposal = existingProposals.get(replString);
+ if (existingProposal == null) {
+ existingProposals.put(replString, proposal);
+ unique.add(proposal);
+ }
+ }
+ return unique.toArray(new ICompletionProposal[unique.size()]);
+ }
+
+ private static String getReplacementWord(String replacement) {
+ replacement = (replacement == null ? "" : //$NON-NLS-1$
+ replacement);
+ int index = replacement.indexOf('>');
+ if (index != -1) {
+ replacement = replacement.substring(0, index).trim();
+ if (replacement.endsWith("/")) //$NON-NLS-1$
+ replacement = replacement
+ .substring(0, replacement.length() - 1).trim();
+ }
+ index = replacement.indexOf("="); //$NON-NLS-1$
+ if (index != -1) {
+ replacement = replacement.substring(0, index).trim();
+ }
+ index = replacement.indexOf(" "); //$NON-NLS-1$
+ if (index != -1) {
+ replacement = replacement.substring(0, index).trim();
+ }
+ return replacement;
+ }
+
+ private static String unQuote(String str) {
+ str = (str == null ?
+ "" : //$NON-NLS-1$
+ str.toLowerCase());
+ if (str.startsWith("\"")) //$NON-NLS-1$
+ str = str.substring(1);
+ if (str.endsWith("\"")) //$NON-NLS-1$
+ str = str.substring(0, str.length() - 1);
+ str = str.trim().toLowerCase();
+
+ return str;
+ }
+
+}
Property changes on: trunk/common/plugins/org.jboss.tools.common.text.xml/src/org/jboss/tools/common/text/xml/contentassist/ProposalSorter.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: trunk/common/plugins/org.jboss.tools.common.text.xml/src/org/jboss/tools/common/text/xml/contentassist/SortingCompoundContentAssistProcessor.java
===================================================================
--- trunk/common/plugins/org.jboss.tools.common.text.xml/src/org/jboss/tools/common/text/xml/contentassist/SortingCompoundContentAssistProcessor.java 2010-08-10 14:09:52 UTC (rev 24019)
+++ trunk/common/plugins/org.jboss.tools.common.text.xml/src/org/jboss/tools/common/text/xml/contentassist/SortingCompoundContentAssistProcessor.java 2010-08-10 14:13:05 UTC (rev 24020)
@@ -20,6 +20,7 @@
import java.util.List;
import java.util.Map;
+import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.TextPresentation;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
@@ -30,9 +31,10 @@
import org.eclipse.jface.text.contentassist.IContextInformationValidator;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.swt.graphics.Image;
+import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
-import org.eclipse.wst.sse.core.StructuredModelManager;
+import org.eclipse.wst.sse.ui.contentassist.CompletionProposalInvocationContext;
import org.eclipse.wst.sse.ui.internal.contentassist.CustomCompletionProposal;
import org.eclipse.wst.sse.ui.internal.contentassist.IRelevanceCompletionProposal;
import org.eclipse.wst.sse.ui.internal.util.Sorter;
@@ -44,7 +46,7 @@
* "org.jboss.tools.common.text.xml.contentAssistProcessor"
*
* @author jeremy
- *
+ * @deprecated
*/
@SuppressWarnings("restriction")
@@ -53,6 +55,8 @@
private String fPartitionType;
private String fErrorMessage;
+ static private Map <CompletionProposalInvocationContext, SortingCompoundContentAssistProcessor> fContextMap =
+ new HashMap<CompletionProposalInvocationContext, SortingCompoundContentAssistProcessor>();
private Map<String, Map<String, List<IContentAssistProcessor>>> fProcessorsMap;
@@ -62,6 +66,31 @@
init();
}
+ public static class SortingCompletionProposalInvocationContext extends CompletionProposalInvocationContext {
+ SortingCompoundContentAssistProcessor fSortingProcessor;
+
+ public SortingCompletionProposalInvocationContext(SortingCompoundContentAssistProcessor sortingProcessor, ITextViewer viewer,
+ int invocationOffset) {
+ super(viewer, invocationOffset);
+ this.fSortingProcessor = sortingProcessor;
+ }
+
+ }
+
+ /**
+ * <p>Creates the context that is passed to the completion proposal
+ * computers.</p>
+ *
+ * <p>Extenders may override this method</p>
+ *
+ * @param viewer the viewer that content assist is invoked on
+ * @param offset the content assist offset
+ * @return the context to be passed to the computers
+ */
+ protected CompletionProposalInvocationContext createContext(ITextViewer viewer, int offset) {
+ return new SortingCompletionProposalInvocationContext(this, viewer, offset);
+ }
+
public boolean supportsPartitionType(String partitionType) {
if (fProcessorsMap == null)
return false;
@@ -259,13 +288,25 @@
return resultArray;
}
+ public static List<ICompletionProposal> doFilterAndSortProposals(List proposals,
+ IProgressMonitor monitor, CompletionProposalInvocationContext context) {
+ if (proposals == null)
+ return null;
+ ICompletionProposal[] resultArray = (ICompletionProposal[])proposals.toArray(new ICompletionProposal[proposals.size()]);
+ Object[] sorted = createSorter().sort(resultArray);
+ System.arraycopy(sorted, 0, resultArray, 0, sorted.length);
+ resultArray = makeUnique(resultArray);
+ return Arrays.asList(resultArray);
+ }
+
+
/**
* Removes duplicates of completion strings
*
* @param suggestions a list of suggestions ({@link String}).
* @return a list of unique completion suggestions.
*/
- public ICompletionProposal[] makeUnique(ICompletionProposal[] proposals) {
+ public static ICompletionProposal[] makeUnique(ICompletionProposal[] proposals) {
if (proposals == null)
return null;
@@ -296,7 +337,7 @@
return unique.toArray(new ICompletionProposal[unique.size()]);
}
- private String getReplacementWord(String replacement) {
+ private static String getReplacementWord(String replacement) {
replacement = (replacement == null ? "" : //$NON-NLS-1$
replacement);
int index = replacement.indexOf('>');
@@ -317,7 +358,7 @@
return replacement;
}
- private String unQuote(String str) {
+ private static String unQuote(String str) {
str = (str == null ?
"" : //$NON-NLS-1$
str.toLowerCase());
@@ -331,7 +372,7 @@
}
- protected Sorter createSorter() {
+ protected static Sorter createSorter() {
return new Sorter() {
public boolean compare(Object proposal1, Object proposal2) {
Modified: trunk/jst/plugins/org.jboss.tools.jst.jsp/META-INF/MANIFEST.MF
===================================================================
--- trunk/jst/plugins/org.jboss.tools.jst.jsp/META-INF/MANIFEST.MF 2010-08-10 14:09:52 UTC (rev 24019)
+++ trunk/jst/plugins/org.jboss.tools.jst.jsp/META-INF/MANIFEST.MF 2010-08-10 14:13:05 UTC (rev 24020)
@@ -8,6 +8,7 @@
Bundle-Localization: plugin
Export-Package: org.jboss.tools.jst.jsp,
org.jboss.tools.jst.jsp.contentassist,
+ org.jboss.tools.jst.jsp.contentassist.computers,
org.jboss.tools.jst.jsp.contentassist.xpl,
org.jboss.tools.jst.jsp.drop.treeviewer.model,
org.jboss.tools.jst.jsp.drop.treeviewer.ui,
@@ -49,6 +50,7 @@
org.eclipse.jface.databinding,
org.jboss.tools.jst.web.kb,
org.eclipse.core.databinding.property;bundle-version="1.2.0",
- org.eclipse.emf.ecore;bundle-version="2.5.0"
+ org.eclipse.emf.ecore;bundle-version="2.5.0",
+ org.eclipse.wst.dtd.core
Bundle-Version: 3.2.0.qualifier
Bundle-RequiredExecutionEnvironment: J2SE-1.5
Modified: trunk/jst/plugins/org.jboss.tools.jst.jsp/plugin.properties
===================================================================
--- trunk/jst/plugins/org.jboss.tools.jst.jsp/plugin.properties 2010-08-10 14:09:52 UTC (rev 24019)
+++ trunk/jst/plugins/org.jboss.tools.jst.jsp/plugin.properties 2010-08-10 14:13:05 UTC (rev 24020)
@@ -13,3 +13,6 @@
javaStringELHover= EL in Java String
javaStringELHoverDescription= Shows the Javadoc of the selected EL-operand.
+
+proposalCategory.xmlEL= JBoss JSF/SEAM EL Proposals
+proposalCategory.xmlTag= JBoss JSF/SEAM Tag Proposals
\ No newline at end of file
Modified: trunk/jst/plugins/org.jboss.tools.jst.jsp/plugin.xml
===================================================================
--- trunk/jst/plugins/org.jboss.tools.jst.jsp/plugin.xml 2010-08-10 14:09:52 UTC (rev 24019)
+++ trunk/jst/plugins/org.jboss.tools.jst.jsp/plugin.xml 2010-08-10 14:13:05 UTC (rev 24020)
@@ -508,26 +508,27 @@
//added by estherbin
//fix http://jira.jboss.com/jira/browse/JBIDE-1791
-->
- <contentAssistProcessor
+ <!-- contentAssistProcessor
class="org.eclipse.wst.css.ui.internal.contentassist.CSSContentAssistProcessor"
id="org.eclipse.wst.css.ui.internal.contentassist.CSSContentAssistProcessor">
<contenttype id="org.eclipse.wst.html.core.htmlsource">
<partitiontype id="org.eclipse.wst.css.STYLE" />
</contenttype>
- </contentAssistProcessor>
+ </contentAssistProcessor -->
<!--
// Fix for JBIDE-5068
-->
- <contentAssistProcessor
+ <!-- contentAssistProcessor
class="org.eclipse.jst.jsp.ui.internal.contentassist.JSPJavaContentAssistProcessor"
id="org.eclipse.jst.jsp.ui.internal.contentassist.JSPJavaContentAssistProcessor">
<contenttype id="org.eclipse.jst.jsp.core.jspsource">
<partitiontype id="org.eclipse.jst.jsp.SCRIPT.JAVA" />
</contenttype>
- </contentAssistProcessor>
+ </contentAssistProcessor -->
-
+ <!-- This is to be replaced by org.eclipse.wst.sse.ui.completionProposal ext. point -->
+ <!--
<contentAssistProcessor
class="org.jboss.tools.jst.jsp.contentassist.JspContentAssistProcessor"
id="org.jboss.tools.jst.jsp.contentassist.JspContentAssistProcessor">
@@ -614,7 +615,7 @@
<partitiontype id="org.eclipse.wst.css.STYLE" />
</contenttype>
</contentAssistProcessor>
-
+ -->
</extension>
<extension
point="org.eclipse.ui.popupMenus">
@@ -669,4 +670,200 @@
point="org.eclipse.core.runtime.preferences">
<initializer class="org.jboss.tools.jst.jsp.preferences.VpePreferencesInitializer"/>
</extension>
+
+ <extension
+ point="org.eclipse.wst.sse.ui.completionProposal">
+ <proposalCategory
+ icon="images/ca/icons_JSF_EL.gif"
+ id="org.jboss.tools.jst.jsp.proposalCategory.xmlEL"
+ name="%proposalCategory.xmlEL">
+ </proposalCategory>
+ <proposalComputer
+ activate="false"
+ categoryId="org.jboss.tools.jst.jsp.proposalCategory.xmlEL"
+ class="org.jboss.tools.jst.jsp.contentassist.computers.XmlELCompletionProposalComputer"
+ id="org.jboss.tools.jst.jsp.proposalComputer.xmlEL">
+ <contentType id="org.eclipse.wst.xml.core.xmlsource">
+ <partitionType id="org.eclipse.wst.xml.XML_DEFAULT" />
+ <partitionType id="org.eclipse.wst.xml.XML_CDATA" />
+ <partitionType id="org.eclipse.wst.xml.XML_PI" />
+ <partitionType id="org.eclipse.wst.xml.XML_DECL" />
+ <partitionType id="org.eclipse.wst.xml.XML_COMMENT" />
+ <partitionType id="org.eclipse.wst.xml.dtd.internal_subset" />
+ <partitionType id="org.eclipse.wst.sse.ST_DEFAULT" />
+ <partitionType id="org.eclipse.wst.sse.UNKNOWN_PARTITION_TYPE" />
+ </contentType>
+ <contentType id="org.jboss.tools.seam.xml.ui.pages20xmlsource">
+ <partitionType id="org.eclipse.wst.xml.XML_DEFAULT" />
+ <partitionType id="org.eclipse.wst.xml.XML_CDATA" />
+ <partitionType id="org.eclipse.wst.xml.XML_PI" />
+ <partitionType id="org.eclipse.wst.xml.XML_DECL" />
+ <partitionType id="org.eclipse.wst.xml.XML_COMMENT" />
+ <partitionType id="org.eclipse.wst.xml.dtd.internal_subset" />
+ <partitionType id="org.eclipse.wst.sse.ST_DEFAULT" />
+ <partitionType id="org.eclipse.wst.sse.UNKNOWN_PARTITION_TYPE" />
+ </contentType>
+ <contentType id="org.eclipse.jst.jsf.facesconfig.facesConfigFile">
+ <partitionType id="org.eclipse.wst.xml.XML_DEFAULT" />
+ <partitionType id="org.eclipse.wst.xml.XML_CDATA" />
+ <partitionType id="org.eclipse.wst.xml.XML_PI" />
+ <partitionType id="org.eclipse.wst.xml.XML_DECL" />
+ <partitionType id="org.eclipse.wst.xml.XML_COMMENT" />
+ <partitionType id="org.eclipse.wst.xml.dtd.internal_subset" />
+ <partitionType id="org.eclipse.wst.sse.ST_DEFAULT" />
+ <partitionType id="org.eclipse.wst.sse.UNKNOWN_PARTITION_TYPE" />
+ </contentType>
+ <contentType id="org.jboss.tools.common.model.ui.xml">
+ <partitionType id="org.eclipse.wst.xml.XML_DEFAULT" />
+ <partitionType id="org.eclipse.wst.xml.XML_CDATA" />
+ <partitionType id="org.eclipse.wst.xml.XML_PI" />
+ <partitionType id="org.eclipse.wst.xml.XML_DECL" />
+ <partitionType id="org.eclipse.wst.xml.XML_COMMENT" />
+ <partitionType id="org.eclipse.wst.xml.dtd.internal_subset" />
+ <partitionType id="org.eclipse.wst.sse.ST_DEFAULT" />
+ <partitionType id="org.eclipse.wst.sse.UNKNOWN_PARTITION_TYPE" />
+ </contentType>
+ <contentType id="org.eclipse.jst.jee.ee5webDD">
+ <partitionType id="org.eclipse.wst.xml.XML_DEFAULT" />
+ <partitionType id="org.eclipse.wst.xml.XML_CDATA" />
+ <partitionType id="org.eclipse.wst.xml.XML_PI" />
+ <partitionType id="org.eclipse.wst.xml.XML_DECL" />
+ <partitionType id="org.eclipse.wst.xml.XML_COMMENT" />
+ <partitionType id="org.eclipse.wst.xml.dtd.internal_subset" />
+ <partitionType id="org.eclipse.wst.sse.ST_DEFAULT" />
+ <partitionType id="org.eclipse.wst.sse.UNKNOWN_PARTITION_TYPE" />
+ </contentType>
+ </proposalComputer>
+ <proposalComputer
+ activate="false"
+ categoryId="org.jboss.tools.jst.jsp.proposalCategory.xmlEL"
+ class="org.jboss.tools.jst.jsp.contentassist.computers.JspELCompletionProposalComputer"
+ id="org.jboss.tools.jst.jsp.proposalComputer.jspEL">
+ <contentType id="org.eclipse.jst.jsp.core.jspsource">
+ <partitionType id="org.eclipse.wst.xml.XML_DEFAULT" />
+ <partitionType id="org.eclipse.wst.html.HTML_DEFAULT" />
+ <partitionType id="org.eclipse.jst.jsp.DEFAULT_JSP" />
+ <partitionType id="org.eclipse.jst.jsp.JSP_DIRECTIVE" />
+ <partitionType id="org.eclipse.jst.jsp.SCRIPT.DELIMITER" />
+ <partitionType id="org.eclipse.jst.jsp.SCRIPT.JSP_EL" />
+ <partitionType id="org.eclipse.jst.jsp.SCRIPT.JSP_EL2" />
+ <partitionType id="org.eclipse.wst.css.STYLE" />
+ </contentType>
+ </proposalComputer>
+ <proposalComputer
+ activate="false"
+ categoryId="org.jboss.tools.jst.jsp.proposalCategory.xmlEL"
+ class="org.jboss.tools.jst.jsp.contentassist.computers.FaceletsELCompletionProposalComputer"
+ id="org.jboss.tools.jst.jsp.proposalComputer.xhtmlEL">
+ <contentType id="org.eclipse.wst.html.core.htmlsource">
+ <partitionType id="org.eclipse.wst.html.HTML_DEFAULT" />
+ <partitionType id="org.eclipse.jst.jsp.SCRIPT.JSP_EL" />
+ <partitionType id="org.eclipse.jst.jsp.SCRIPT.JSP_EL2" />
+ <partitionType id="org.eclipse.wst.css.STYLE" />
+ </contentType>
+ <contentType id="jsf.facelet">
+ <partitionType id="org.eclipse.wst.html.HTML_DEFAULT" />
+ <partitionType id="org.eclipse.jst.jsp.SCRIPT.JSP_EL" />
+ <partitionType id="org.eclipse.jst.jsp.SCRIPT.JSP_EL2" />
+ <partitionType id="org.eclipse.wst.css.STYLE" />
+ </contentType>
+ </proposalComputer>
+
+ <proposalCategory
+ icon="images/ca/icons_JSF_EL.gif"
+ id="org.jboss.tools.jst.jsp.proposalCategory.xmlTag"
+ name="%proposalCategory.xmlTag">
+ </proposalCategory>
+ <proposalComputer
+ activate="false"
+ categoryId="org.jboss.tools.jst.jsp.proposalCategory.xmlTag"
+ class="org.jboss.tools.jst.jsp.contentassist.computers.XmlTagCompletionProposalComputer"
+ id="org.jboss.tools.jst.jsp.proposalComputer.xmlTag">
+ <contentType id="org.eclipse.wst.xml.core.xmlsource">
+ <partitionType id="org.eclipse.wst.xml.XML_DEFAULT" />
+ <partitionType id="org.eclipse.wst.xml.XML_CDATA" />
+ <partitionType id="org.eclipse.wst.xml.XML_PI" />
+ <partitionType id="org.eclipse.wst.xml.XML_DECL" />
+ <partitionType id="org.eclipse.wst.xml.XML_COMMENT" />
+ <partitionType id="org.eclipse.wst.xml.dtd.internal_subset" />
+ <partitionType id="org.eclipse.wst.sse.ST_DEFAULT" />
+ <partitionType id="org.eclipse.wst.sse.UNKNOWN_PARTITION_TYPE" />
+ </contentType>
+ <contentType id="org.jboss.tools.seam.xml.ui.pages20xmlsource">
+ <partitionType id="org.eclipse.wst.xml.XML_DEFAULT" />
+ <partitionType id="org.eclipse.wst.xml.XML_CDATA" />
+ <partitionType id="org.eclipse.wst.xml.XML_PI" />
+ <partitionType id="org.eclipse.wst.xml.XML_DECL" />
+ <partitionType id="org.eclipse.wst.xml.XML_COMMENT" />
+ <partitionType id="org.eclipse.wst.xml.dtd.internal_subset" />
+ <partitionType id="org.eclipse.wst.sse.ST_DEFAULT" />
+ <partitionType id="org.eclipse.wst.sse.UNKNOWN_PARTITION_TYPE" />
+ </contentType>
+ <contentType id="org.eclipse.jst.jsf.facesconfig.facesConfigFile">
+ <partitionType id="org.eclipse.wst.xml.XML_DEFAULT" />
+ <partitionType id="org.eclipse.wst.xml.XML_CDATA" />
+ <partitionType id="org.eclipse.wst.xml.XML_PI" />
+ <partitionType id="org.eclipse.wst.xml.XML_DECL" />
+ <partitionType id="org.eclipse.wst.xml.XML_COMMENT" />
+ <partitionType id="org.eclipse.wst.xml.dtd.internal_subset" />
+ <partitionType id="org.eclipse.wst.sse.ST_DEFAULT" />
+ <partitionType id="org.eclipse.wst.sse.UNKNOWN_PARTITION_TYPE" />
+ </contentType>
+ <contentType id="org.jboss.tools.common.model.ui.xml">
+ <partitionType id="org.eclipse.wst.xml.XML_DEFAULT" />
+ <partitionType id="org.eclipse.wst.xml.XML_CDATA" />
+ <partitionType id="org.eclipse.wst.xml.XML_PI" />
+ <partitionType id="org.eclipse.wst.xml.XML_DECL" />
+ <partitionType id="org.eclipse.wst.xml.XML_COMMENT" />
+ <partitionType id="org.eclipse.wst.xml.dtd.internal_subset" />
+ <partitionType id="org.eclipse.wst.sse.ST_DEFAULT" />
+ <partitionType id="org.eclipse.wst.sse.UNKNOWN_PARTITION_TYPE" />
+ </contentType>
+ <contentType id="org.eclipse.jst.jee.ee5webDD">
+ <partitionType id="org.eclipse.wst.xml.XML_DEFAULT" />
+ <partitionType id="org.eclipse.wst.xml.XML_CDATA" />
+ <partitionType id="org.eclipse.wst.xml.XML_PI" />
+ <partitionType id="org.eclipse.wst.xml.XML_DECL" />
+ <partitionType id="org.eclipse.wst.xml.XML_COMMENT" />
+ <partitionType id="org.eclipse.wst.xml.dtd.internal_subset" />
+ <partitionType id="org.eclipse.wst.sse.ST_DEFAULT" />
+ <partitionType id="org.eclipse.wst.sse.UNKNOWN_PARTITION_TYPE" />
+ </contentType>
+ </proposalComputer>
+ <proposalComputer
+ activate="false"
+ categoryId="org.jboss.tools.jst.jsp.proposalCategory.xmlTag"
+ class="org.jboss.tools.jst.jsp.contentassist.computers.JspTagCompletionProposalComputer"
+ id="org.jboss.tools.jst.jsp.proposalComputer.jspTag">
+ <contentType id="org.eclipse.jst.jsp.core.jspsource">
+ <partitionType id="org.eclipse.wst.xml.XML_DEFAULT" />
+ <partitionType id="org.eclipse.wst.html.HTML_DEFAULT" />
+ <partitionType id="org.eclipse.jst.jsp.DEFAULT_JSP" />
+ <partitionType id="org.eclipse.jst.jsp.JSP_DIRECTIVE" />
+ <partitionType id="org.eclipse.jst.jsp.SCRIPT.DELIMITER" />
+ <partitionType id="org.eclipse.jst.jsp.SCRIPT.JSP_EL" />
+ <partitionType id="org.eclipse.jst.jsp.SCRIPT.JSP_EL2" />
+ <partitionType id="org.eclipse.wst.css.STYLE" />
+ </contentType>
+ </proposalComputer>
+ <proposalComputer
+ activate="false"
+ categoryId="org.jboss.tools.jst.jsp.proposalCategory.xmlTag"
+ class="org.jboss.tools.jst.jsp.contentassist.computers.FaceletsTagCompletionProposalComputer"
+ id="org.jboss.tools.jst.jsp.proposalComputer.xhtmltag">
+ <contentType id="org.eclipse.wst.html.core.htmlsource">
+ <partitionType id="org.eclipse.wst.html.HTML_DEFAULT" />
+ <partitionType id="org.eclipse.jst.jsp.SCRIPT.JSP_EL" />
+ <partitionType id="org.eclipse.jst.jsp.SCRIPT.JSP_EL2" />
+ <partitionType id="org.eclipse.wst.css.STYLE" />
+ </contentType>
+ <contentType id="jsf.facelet">
+ <partitionType id="org.eclipse.wst.html.HTML_DEFAULT" />
+ <partitionType id="org.eclipse.jst.jsp.SCRIPT.JSP_EL" />
+ <partitionType id="org.eclipse.jst.jsp.SCRIPT.JSP_EL2" />
+ <partitionType id="org.eclipse.wst.css.STYLE" />
+ </contentType>
+ </proposalComputer>
+ </extension>
+
</plugin>
Modified: trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/HTMLTextViewerConfiguration.java
===================================================================
--- trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/HTMLTextViewerConfiguration.java 2010-08-10 14:09:52 UTC (rev 24019)
+++ trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/HTMLTextViewerConfiguration.java 2010-08-10 14:13:05 UTC (rev 24020)
@@ -12,7 +12,6 @@
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
import java.util.List;
import org.eclipse.core.runtime.CoreException;
@@ -20,6 +19,7 @@
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.text.ITextHover;
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
@@ -31,15 +31,17 @@
import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;
import org.eclipse.wst.html.core.text.IHTMLPartitions;
import org.eclipse.wst.html.ui.StructuredTextViewerConfigurationHTML;
+import org.eclipse.wst.html.ui.internal.contentassist.HTMLStructuredContentAssistProcessor;
+import org.eclipse.wst.sse.ui.contentassist.CompletionProposalInvocationContext;
import org.eclipse.wst.sse.ui.internal.ExtendedConfigurationBuilder;
import org.eclipse.wst.sse.ui.internal.SSEUIPlugin;
import org.eclipse.wst.sse.ui.internal.format.StructuredFormattingStrategy;
import org.eclipse.wst.sse.ui.internal.taginfo.AnnotationHoverProcessor;
import org.eclipse.wst.sse.ui.internal.taginfo.ProblemAnnotationHoverProcessor;
import org.eclipse.wst.sse.ui.internal.taginfo.TextHoverManager;
+import org.jboss.tools.common.text.xml.contentassist.ProposalSorter;
import org.jboss.tools.jst.jsp.format.HTMLFormatProcessor;
import org.jboss.tools.jst.jsp.jspeditor.info.ChainTextHover;
-import org.osgi.framework.Bundle;
@SuppressWarnings("restriction")
public class HTMLTextViewerConfiguration extends
@@ -58,16 +60,28 @@
protected IContentAssistProcessor[] getContentAssistProcessors(
ISourceViewer sourceViewer, String partitionType) {
-
- IContentAssistProcessor[] superProcessors = super.getContentAssistProcessors(
- sourceViewer, partitionType);
+// IContentAssistProcessor[] superProcessors = super.getContentAssistProcessors(
+// sourceViewer, partitionType);
+ IContentAssistProcessor superProcessor = new HTMLStructuredContentAssistProcessor(
+ this.getContentAssistant(), partitionType, sourceViewer) {
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ @Override
+ protected List filterAndSortProposals(List proposals,
+ IProgressMonitor monitor,
+ CompletionProposalInvocationContext context) {
+ return ProposalSorter.filterAndSortProposals(proposals, monitor, context);
+ }
+
+ };
List<IContentAssistProcessor> processors = new ArrayList<IContentAssistProcessor>();
processors.addAll(
Arrays.asList(
configurationDelegate.getContentAssistProcessors(
sourceViewer,
partitionType)));
- processors.addAll(Arrays.asList(superProcessors));
+// processors.addAll(Arrays.asList(superProcessors));
+ processors.add(superProcessor);
return processors.toArray(new IContentAssistProcessor[0]);
}
@@ -101,11 +115,16 @@
return formatter;
}
+ /**
+ * @deprecated
+ */
public IContentAssistProcessor[] getContentAssistProcessorsForPartitionType(
ISourceViewer sourceViewer, String partitionType) {
// IContentAssistProcessor[] results = super.getContentAssistProcessors(
// sourceViewer, partitionType);
// added by Maksim Areshkau
+ // TODO: create a CA computer and move it to
+ // org.eclipse.wst.sse.ui.completionProposal extension point
if ("org.eclipse.wst.html.HTML_DEFAULT".equalsIgnoreCase(partitionType)) { //$NON-NLS-1$
List<IContentAssistProcessor> contAssists = getVpeTestExtensions();
return contAssists.toArray(new IContentAssistProcessor[0]);
@@ -124,7 +143,7 @@
* @param partitionType
* @return
*/
- @SuppressWarnings("unchecked")
+ @SuppressWarnings({ "unchecked", "rawtypes" })
private ITextHover[] createDocumentationHovers(String partitionType) {
List extendedTextHover = ExtendedConfigurationBuilder.getInstance()
.getConfigurations(
@@ -183,6 +202,8 @@
}
/**
+ * @deprecated
+ *
* Returns all extensions of {@value #VPE_TEST_EXTENTION_POINT_ID}
*/
public List<IContentAssistProcessor> getVpeTestExtensions() {
Modified: trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/JSPTextViewerConfiguration.java
===================================================================
--- trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/JSPTextViewerConfiguration.java 2010-08-10 14:09:52 UTC (rev 24019)
+++ trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/JSPTextViewerConfiguration.java 2010-08-10 14:13:05 UTC (rev 24020)
@@ -14,18 +14,23 @@
import java.util.Arrays;
import java.util.List;
+import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jst.jsp.core.text.IJSPPartitions;
import org.eclipse.jst.jsp.ui.StructuredTextViewerConfigurationJSP;
+import org.eclipse.jst.jsp.ui.internal.contentassist.JSPStructuredContentAssistProcessor;
import org.eclipse.jst.jsp.ui.internal.style.jspel.LineStyleProviderForJSPEL;
import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;
+import org.eclipse.wst.sse.ui.contentassist.CompletionProposalInvocationContext;
import org.eclipse.wst.sse.ui.internal.provisional.style.LineStyleProvider;
+import org.jboss.tools.common.text.xml.contentassist.ProposalSorter;
/**
* @author Igels
*/
+ at SuppressWarnings("restriction")
public class JSPTextViewerConfiguration extends StructuredTextViewerConfigurationJSP implements ITextViewerConfiguration {
private TextViewerConfigurationDelegate configurationDelegate;
@@ -78,15 +83,29 @@
}
protected IContentAssistProcessor[] getContentAssistProcessors(ISourceViewer sourceViewer, String partitionType) {
- IContentAssistProcessor[] superProcessors = super.getContentAssistProcessors(
- sourceViewer, partitionType);
+// IContentAssistProcessor[] superProcessors = super.getContentAssistProcessors(
+// sourceViewer, partitionType);
+ IContentAssistProcessor superProcessor = new JSPStructuredContentAssistProcessor(
+ this.getContentAssistant(), partitionType, sourceViewer) {
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ @Override
+ protected List filterAndSortProposals(List proposals,
+ IProgressMonitor monitor,
+ CompletionProposalInvocationContext context) {
+ return ProposalSorter.filterAndSortProposals(proposals, monitor, context);
+ }
+
+ };
+
List<IContentAssistProcessor> processors = new ArrayList<IContentAssistProcessor>();
processors.addAll(
Arrays.asList(
configurationDelegate.getContentAssistProcessors(
sourceViewer,
partitionType)));
- processors.addAll(Arrays.asList(superProcessors));
+// processors.addAll(Arrays.asList(superProcessors));
+ processors.add(superProcessor);
return processors.toArray(new IContentAssistProcessor[0]);
}
@@ -100,6 +119,9 @@
fPreferenceStore.getBoolean(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_HYPERLINKS_ENABLED));
}
+ /**
+ * @deprecated
+ */
public IContentAssistProcessor[] getContentAssistProcessorsForPartitionType(
ISourceViewer sourceViewer, String partitionType) {
// TODO Auto-generated method stub
Added: trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/computers/AbstractXmlCompletionProposalComputer.java
===================================================================
--- trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/computers/AbstractXmlCompletionProposalComputer.java (rev 0)
+++ trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/computers/AbstractXmlCompletionProposalComputer.java 2010-08-10 14:13:05 UTC (rev 24020)
@@ -0,0 +1,682 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Exadel, Inc. and 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:
+ * Exadel, Inc. and Red Hat, Inc. - initial API and implementation
+ ******************************************************************************/
+package org.jboss.tools.jst.jsp.contentassist.computers;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.filebuffers.FileBuffers;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.contentassist.ICompletionProposal;
+import org.eclipse.wst.sse.core.StructuredModelManager;
+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
+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.contentassist.CompletionProposalInvocationContext;
+import org.eclipse.wst.sse.ui.internal.contentassist.ContentAssistUtils;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
+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.contentassist.AbstractXMLModelQueryCompletionProposalComputer;
+import org.eclipse.wst.xml.ui.internal.contentassist.ContentAssistRequest;
+import org.jboss.tools.common.el.core.resolver.ELContext;
+import org.jboss.tools.jst.web.kb.IPageContext;
+import org.jboss.tools.jst.web.kb.KbQuery;
+import org.jboss.tools.jst.web.kb.KbQuery.Type;
+import org.jboss.tools.jst.web.kb.internal.KbProject;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * Abstract base class for XML proposal computers
+ *
+ * @since 3.2.0
+ * @author Jeremy
+ *
+ */
+ at SuppressWarnings("restriction")
+abstract public class AbstractXmlCompletionProposalComputer extends AbstractXMLModelQueryCompletionProposalComputer {
+ protected static final ICompletionProposal[] EMPTY_PROPOSAL_LIST = new ICompletionProposal[0];
+ private static final String[] EMPTY_TAGS = new String[0];
+
+ protected CompletionProposalInvocationContext fCurrentContext;
+
+ protected ELContext fContext;
+
+ /**
+ * <p>Determine if the document is XHTML or not, then compute the proposals</p>
+ *
+ * @see org.eclipse.wst.xml.ui.internal.contentassist.AbstractXMLCompletionProposalComputer#computeCompletionProposals(org.eclipse.wst.sse.ui.contentassist.CompletionProposalInvocationContext, org.eclipse.core.runtime.IProgressMonitor)
+ */
+ @SuppressWarnings("rawtypes")
+ public List computeCompletionProposals(
+ CompletionProposalInvocationContext context,
+ IProgressMonitor monitor) {
+
+ this.fCurrentContext = context;
+
+ this.fContext = createContext();
+
+ IFile resource = fContext == null ? null : fContext.getResource();
+ KbProject.checkKBBuilderInstalled(resource);
+
+ //compute the completion proposals
+ return super.computeCompletionProposals(context, monitor);
+ }
+
+ /**
+ * Calculates and adds the tag proposals to the Content Assist Request object
+ *
+ * @param contentAssistRequest Content Assist Request object
+ * @param childPosition the
+ */
+
+ abstract protected void addTagInsertionProposals(
+ ContentAssistRequest contentAssistRequest, int childPosition, CompletionProposalInvocationContext context);
+
+ /**
+ * Calculates and adds the tag attribute value proposals to the Content Assist Request object
+ *
+ * @param contentAssistRequest Content Assist Request object
+ * @param childPosition the
+ */
+ abstract protected void addAttributeValueProposals(
+ ContentAssistRequest contentAssistRequest,
+ CompletionProposalInvocationContext context);
+
+ /**
+ * Creates and fulfills the <code>org.jboss.tools.common.el.core.resolver.ELContext</code>
+ * instance
+ *
+ * @return
+ */
+ abstract protected ELContext createContext();
+
+ /**
+ * Returns the <code>org.jboss.tools.jst.web.kb.KbQuery</code> instance. The prefix and URI for the tags
+ * are calculated from the current node
+ *
+ * @param type One of the <code>org.jboss.tools.jst.web.kb.KbQuery.Type</code> values
+ * @param query The value for query
+ * @param stringQuery the full text of the query value
+ *
+ * @return The <code>org.jboss.tools.jst.web.kb.KbQuery</code> instance
+ */
+ abstract protected KbQuery createKbQuery(Type type, String query, String stringQuery);
+
+ /**
+ * Returns the <code>org.jboss.tools.jst.web.kb.KbQuery</code> instance
+ *
+ * @param type One of the <code>org.jboss.tools.jst.web.kb.KbQuery.Type</code> values
+ * @param query The value for query
+ * @param prefix the prefix for the tag
+ * @param uri the URI for the tag
+ *
+ * @return The <code>org.jboss.tools.jst.web.kb.KbQuery</code> instance
+ */
+ abstract protected KbQuery createKbQuery(Type type, String query, String stringQuery, String prefix, String uri);
+
+ /* Utility functions */
+ Node findNodeForOffset(IDOMNode node, int offset) {
+ if(node == null) return null;
+ if (!node.contains(offset)) return null;
+
+ if (node.hasChildNodes()) {
+ // Try to find the node in children
+ NodeList children = node.getChildNodes();
+ for (int i = 0; children != null && i < children.getLength(); i++) {
+ IDOMNode child = (IDOMNode)children.item(i);
+ if (child.contains(offset)) {
+ return findNodeForOffset(child, offset);
+ }
+ }
+ }
+ // Not found in children or nave no children
+ if (node.hasAttributes()) {
+ // Try to find in the node attributes
+ NamedNodeMap attributes = node.getAttributes();
+
+ for (int i = 0; attributes != null && i < attributes.getLength(); i++) {
+ IDOMNode attr = (IDOMNode)attributes.item(i);
+ if (attr.contains(offset)) {
+ return attr;
+ }
+ }
+ }
+ // Return the node itself
+ return node;
+ }
+
+ Node findNodeForOffset(Node node, int offset) {
+ return (node instanceof IDOMNode) ? findNodeForOffset((IDOMNode)node, offset) : null;
+ }
+
+ /**
+ * this is the position the cursor should be in after the proposal is
+ * applied
+ *
+ * @param proposedText
+ * @return the position the cursor should be in after the proposal is
+ * applied
+ */
+ protected static int getCursorPositionForProposedText(String proposedText) {
+ int cursorAdjustment;
+ cursorAdjustment = proposedText.indexOf("\"\"") + 1; //$NON-NLS-1$
+ // otherwise, after the first tag
+ if (cursorAdjustment == 0) {
+ cursorAdjustment = proposedText.indexOf('>') + 1;
+ }
+ if (cursorAdjustment == 0) {
+ cursorAdjustment = proposedText.length();
+ }
+
+ return cursorAdjustment;
+ }
+
+ /**
+ * Returns array of the parent tags
+ *
+ * @return
+ */
+ public String[] getParentTags(boolean includeThisTag) {
+ List<String> parentTags = new ArrayList<String>();
+
+ IStructuredModel sModel = StructuredModelManager
+ .getModelManager()
+ .getExistingModelForRead(getDocument());
+ try {
+ if (sModel == null)
+ return EMPTY_TAGS;
+
+ Document xmlDocument = (sModel instanceof IDOMModel)
+ ? ((IDOMModel) sModel).getDocument()
+ : null;
+
+ if (xmlDocument == null)
+ return EMPTY_TAGS;
+
+
+ Node n = null;
+ if (includeThisTag) {
+ n = findNodeForOffset(xmlDocument, getOffset());
+ } else {
+ // Get Fixed Structured Document Region
+ IStructuredDocumentRegion sdFixedRegion = this.getStructuredDocumentRegion(getOffset());
+ if (sdFixedRegion == null)
+ return EMPTY_TAGS;
+
+ n = findNodeForOffset(xmlDocument, sdFixedRegion.getStartOffset());
+ }
+ if (n == null)
+ return EMPTY_TAGS;
+
+ // Find the first parent tag
+ if (!(n instanceof Element)) {
+ if (n instanceof Attr) {
+ n = ((Attr) n).getOwnerElement();
+ } else {
+ n = n.getParentNode();
+ }
+ } else if (!includeThisTag) {
+ n = n.getParentNode();
+ }
+
+ // Store all the parents
+ while (n != null && n instanceof Element) {
+ String tagName = getTagName(n);
+ parentTags.add(0, tagName);
+ n = n.getParentNode();
+ }
+
+ return (String[])parentTags.toArray(new String[parentTags.size()]);
+ } finally {
+ if (sModel != null) {
+ sModel.releaseFromRead();
+ }
+ }
+ }
+
+ protected String getTagName(Node tag) {
+ return tag.getNodeName();
+ }
+
+ /**
+ * Returns name of the parent attribute/tag name
+ *
+ * @return
+ */
+ protected String getParent(boolean returnAttributeName, boolean returnThisElement) {
+ IStructuredModel sModel = StructuredModelManager
+ .getModelManager()
+ .getExistingModelForRead(getDocument());
+ try {
+ if (sModel == null)
+ return null;
+
+ Document xmlDocument = (sModel instanceof IDOMModel)
+ ? ((IDOMModel) sModel).getDocument()
+ : null;
+
+ if (xmlDocument == null)
+ return null;
+
+ Node n = null;
+ if (returnAttributeName) {
+ n = findNodeForOffset(xmlDocument, getOffset());
+ } else {
+ // Get Fixed Structured Document Region
+ IStructuredDocumentRegion sdFixedRegion = this.getStructuredDocumentRegion(getOffset());
+ if (sdFixedRegion == null)
+ return null;
+
+ n = findNodeForOffset(xmlDocument, sdFixedRegion.getStartOffset());
+ }
+
+ if (n == null)
+ return null;
+
+ // Find the first parent tag
+ if (!(n instanceof Element)) {
+ if (n instanceof Attr) {
+ if (returnAttributeName) {
+ String parentAttrName = n.getNodeName();
+ return parentAttrName;
+ }
+ n = ((Attr) n).getOwnerElement();
+ } else {
+ n = n.getParentNode();
+ }
+ } else {
+ if (!returnThisElement)
+ n = n.getParentNode();
+ }
+ if (n == null)
+ return null;
+
+ String parentTagName = getTagName(n);
+ return parentTagName;
+ } finally {
+ if (sModel != null) {
+ sModel.releaseFromRead();
+ }
+ }
+ }
+
+ /**
+ * Returns URI for the current/parent tag
+ * @return
+ */
+ public String getTagPrefix() {
+ IStructuredModel sModel = StructuredModelManager
+ .getModelManager()
+ .getExistingModelForRead(getDocument());
+ try {
+ if (sModel == null)
+ return null;
+
+ Document xmlDocument = (sModel instanceof IDOMModel)
+ ? ((IDOMModel) sModel).getDocument()
+ : null;
+
+ if (xmlDocument == null)
+ return null;
+
+ // Get Fixed Structured Document Region
+ IStructuredDocumentRegion sdFixedRegion = this.getStructuredDocumentRegion(getOffset());
+ if (sdFixedRegion == null)
+ return null;
+
+ Node n = findNodeForOffset(xmlDocument, sdFixedRegion.getStartOffset());
+ if (n == null)
+ return null;
+
+
+ if (!(n instanceof Element) && !(n instanceof Attr))
+ return null;
+
+ if (n instanceof Attr) {
+ n = ((Attr) n).getOwnerElement();
+ }
+
+ if (n == null)
+ return null;
+
+ String nodePrefix = ((Element)n).getPrefix();
+ return nodePrefix;
+ } finally {
+ if (sModel != null) {
+ sModel.releaseFromRead();
+ }
+ }
+ }
+
+ /**
+ * Returns URI for the current/parent tag
+ * @return
+ */
+ abstract public String getTagUri();
+
+ /**
+ * Returns URI string for the prefix specified using the namespaces collected for
+ * the {@link IPageContext} context.
+ *
+ * @Override org.jboss.tools.jst.jsp.contentassist.AbstractXMLContentAssistProcessor#getUri(String)
+ */
+ abstract protected String getUri(String prefix);
+
+ /**
+ * Returns the document position where the CA is invoked
+ * @return
+ */
+ protected int getOffset() {
+ return fCurrentContext.getInvocationOffset();
+ }
+
+
+ /**
+ * Returns the document
+ *
+ * @return
+ */
+ protected IDocument getDocument() {
+ return fCurrentContext.getDocument();
+ }
+
+ /**
+ * Returns IFile resource of the document
+ *
+ * @return
+ */
+ protected IFile getResource() {
+ IStructuredModel sModel = StructuredModelManager.getModelManager().getExistingModelForRead(getDocument());
+ try {
+ if (sModel != null) {
+ String baseLocation = sModel.getBaseLocation();
+ IPath location = new Path(baseLocation).makeAbsolute();
+ return FileBuffers.getWorkspaceFileAtLocation(location);
+ }
+ }
+ finally {
+ if (sModel != null) {
+ sModel.releaseFromRead();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the <code>org.jboss.tools.common.el.core.resolver.ELContext</code> instance
+ *
+ * @return
+ */
+ protected ELContext getContext() {
+ return this.fContext;
+ }
+
+ /**
+ * The reason of overriding is that the method returns wrong region in case of incomplete tag (a tag with no '>'-closing char)
+ * In this case we have to return that previous incomplete tag instead of the current tag)
+ */
+ public IStructuredDocumentRegion getStructuredDocumentRegion(int pos) {
+ IStructuredDocumentRegion sdRegion = null;
+
+ int lastOffset = pos;
+ IStructuredDocument doc = (IStructuredDocument) getDocument();
+ if (doc == null)
+ return null;
+
+ do {
+ sdRegion = doc.getRegionAtCharacterOffset(lastOffset);
+ if (sdRegion != null) {
+ ITextRegion region = sdRegion.getRegionAtCharacterOffset(lastOffset);
+ if (region != null && region.getType() == DOMRegionContext.XML_TAG_OPEN &&
+ sdRegion.getStartOffset(region) == lastOffset) {
+ // The offset is at the beginning of the region
+ if ((sdRegion.getStartOffset(region) == sdRegion.getStartOffset()) && (sdRegion.getPrevious() != null) && (!sdRegion.getPrevious().isEnded())) {
+ // Is the region also the start of the node? If so, the
+ // previous IStructuredDocumentRegion is
+ // where to look for a useful region.
+// sdRegion = sdRegion.getPrevious();
+ sdRegion = null;
+ }
+ else {
+ // Is there no separating whitespace from the previous region?
+ // If not,
+ // then that region is the important one
+ ITextRegion previousRegion = sdRegion.getRegionAtCharacterOffset(lastOffset - 1);
+ if ((previousRegion != null) && (previousRegion != region) && (previousRegion.getTextLength() == previousRegion.getLength())) {
+// sdRegion = sdRegion.getPrevious();
+ sdRegion = null;
+ }
+ }
+ }
+ }
+ lastOffset--;
+ } while (sdRegion == null && lastOffset >= 0);
+ return sdRegion;
+ }
+
+ /**
+ * The reason of overriding is that the method returns wrong region in case of incomplete tag (a tag with no '>'-closing char)
+ * In this case we have to return that previous incomplete tag instead of the current tag)
+ */
+ protected ITextRegion getCompletionRegion(int documentPosition, Node domnode) {
+ if (domnode == null) {
+ return null;
+ }
+ // Get the original WTP Structured Document Region
+ IStructuredDocumentRegion sdNormalRegion = ContentAssistUtils.getStructuredDocumentRegion(fCurrentContext.getViewer(), documentPosition);
+ // Get Fixed Structured Document Region
+ IStructuredDocumentRegion sdFixedRegion = this.getStructuredDocumentRegion(documentPosition);
+
+ // If original and fixed regions are different we have to replace domnode with its parent node
+ if (sdFixedRegion != null && !sdFixedRegion.equals(sdNormalRegion)) {
+ Node prevnode = domnode.getParentNode();
+ if (prevnode != null) {
+ domnode = prevnode;
+ }
+ }
+
+ return getSuperCompletionRegion(documentPosition, domnode);
+ }
+
+ /**
+ * Return the region whose content's require completion. This is something
+ * of a misnomer as sometimes the user wants to be prompted for contents
+ * of a non-existant ITextRegion, such as for enumerated attribute values
+ * following an '=' sign.
+ */
+ private ITextRegion getSuperCompletionRegion(int documentPosition, Node domnode) {
+ if (domnode == null) {
+ return null;
+ }
+
+ ITextRegion region = null;
+ int offset = documentPosition;
+ IStructuredDocumentRegion flatNode = null;
+ IDOMNode node = (IDOMNode) domnode;
+
+ if (node.getNodeType() == Node.DOCUMENT_NODE) {
+ if (node.getStructuredDocument().getLength() == 0) {
+ return null;
+ }
+ ITextRegion result = node.getStructuredDocument().getRegionAtCharacterOffset(offset).getRegionAtCharacterOffset(offset);
+ while (result == null) {
+ offset--;
+ result = node.getStructuredDocument().getRegionAtCharacterOffset(offset).getRegionAtCharacterOffset(offset);
+ }
+ return result;
+ }
+
+ IStructuredDocumentRegion startTag = node.getStartStructuredDocumentRegion();
+ IStructuredDocumentRegion endTag = node.getEndStructuredDocumentRegion();
+
+ // Determine if the offset is within the start
+ // IStructuredDocumentRegion, end IStructuredDocumentRegion, or
+ // somewhere within the Node's XML content.
+ if ((startTag != null) && (startTag.getStartOffset() <= offset) && (offset < startTag.getStartOffset() + startTag.getLength())) {
+ flatNode = startTag;
+ }
+ else if ((endTag != null) && (endTag.getStartOffset() <= offset) && (offset < endTag.getStartOffset() + endTag.getLength())) {
+ flatNode = endTag;
+ }
+
+ if (flatNode != null) {
+ // the offset is definitely within the start or end tag, continue
+ // on and find the region
+ region = getCompletionRegion(offset, flatNode);
+ }
+ else {
+ // the docPosition is neither within the start nor the end, so it
+ // must be content
+ flatNode = node.getStructuredDocument().getRegionAtCharacterOffset(offset);
+ // (pa) ITextRegion refactor
+ // if (flatNode.contains(documentPosition)) {
+ if ((flatNode.getStartOffset() <= documentPosition) && (flatNode.getEndOffset() >= documentPosition)) {
+ // we're interesting in completing/extending the previous
+ // IStructuredDocumentRegion if the current
+ // IStructuredDocumentRegion isn't plain content or if it's
+ // preceded by an orphan '<'
+ if ((offset == flatNode.getStartOffset()) &&
+ (flatNode.getPrevious() != null) &&
+ (((flatNode.getRegionAtCharacterOffset(documentPosition) != null) &&
+ (flatNode.getRegionAtCharacterOffset(documentPosition).getType() != DOMRegionContext.XML_CONTENT)) ||
+ (flatNode.getPrevious().getLastRegion().getType() == DOMRegionContext.XML_TAG_OPEN) ||
+ (flatNode.getPrevious().getLastRegion().getType() == DOMRegionContext.XML_END_TAG_OPEN))) {
+
+ // Is the region also the start of the node? If so, the
+ // previous IStructuredDocumentRegion is
+ // where to look for a useful region.
+ region = flatNode.getPrevious().getLastRegion();
+ }
+ else if (flatNode.getEndOffset() == documentPosition) {
+ region = flatNode.getLastRegion();
+ }
+ else {
+ region = flatNode.getFirstRegion();
+ }
+ }
+ else {
+ // catch end of document positions where the docPosition isn't
+ // in a IStructuredDocumentRegion
+ region = flatNode.getLastRegion();
+ }
+ }
+
+ return region;
+ }
+
+
+ protected ITextRegion getCompletionRegion(int offset, IStructuredDocumentRegion sdRegion) {
+ ITextRegion region = getSuperCompletionRegion(offset, sdRegion);
+ if (region != null && region.getType() == DOMRegionContext.UNDEFINED) {
+ // FIX: JBIDE-2332 CA with proposal list for comonent's atributes doesn't work before double quotes.
+ // Sometimes, especially if we have a broken XML node, the region returned has UNDEFINED type.
+ // If so, we're try to use the prevoius region, which probably will be the region of type XML_TAG_NAME.
+
+ ITextRegion previousRegion = sdRegion.getRegionAtCharacterOffset(offset - 1);
+ if ((previousRegion != null) && (previousRegion != region) && (previousRegion.getTextLength() < previousRegion.getLength())) {
+ region = previousRegion;
+ }
+ }
+ return region;
+ }
+
+ private ITextRegion getSuperCompletionRegion(int offset, IStructuredDocumentRegion sdRegion) {
+ ITextRegion region = sdRegion.getRegionAtCharacterOffset(offset);
+ if (region == null) {
+ return null;
+ }
+
+ if (sdRegion.getStartOffset(region) == offset) {
+ // The offset is at the beginning of the region
+ if ((sdRegion.getStartOffset(region) == sdRegion.getStartOffset()) && (sdRegion.getPrevious() != null) && (!sdRegion.getPrevious().isEnded())) {
+ // Is the region also the start of the node? If so, the
+ // previous IStructuredDocumentRegion is
+ // where to look for a useful region.
+ region = sdRegion.getPrevious().getRegionAtCharacterOffset(offset - 1);
+ }
+ else {
+ // Is there no separating whitespace from the previous region?
+ // If not,
+ // then that region is the important one
+ ITextRegion previousRegion = sdRegion.getRegionAtCharacterOffset(offset - 1);
+ if ((previousRegion != null) && (previousRegion != region) && (previousRegion.getTextLength() == previousRegion.getLength())) {
+ region = previousRegion;
+ }
+ }
+ }
+ else {
+ // The offset is NOT at the beginning of the region
+ if (offset > sdRegion.getStartOffset(region) + region.getTextLength()) {
+ // Is the offset within the whitespace after the text in this
+ // region?
+ // If so, use the next region
+ ITextRegion nextRegion = sdRegion.getRegionAtCharacterOffset(sdRegion.getStartOffset(region) + region.getLength());
+ if (nextRegion != null) {
+ region = nextRegion;
+ }
+ }
+ else {
+ // Is the offset within the important text for this region?
+ // If so, then we've already got the right one.
+ }
+ }
+
+ // valid WHITE_SPACE region handler (#179924)
+ if ((region != null) && (region.getType() == DOMRegionContext.WHITE_SPACE)) {
+ ITextRegion previousRegion = sdRegion.getRegionAtCharacterOffset(sdRegion.getStartOffset(region) - 1);
+ if (previousRegion != null) {
+ region = previousRegion;
+ }
+ }
+
+ return region;
+ }
+
+
+
+ /**
+ * Calculates and adds the tag name proposals to the Content Assist Request object
+ *
+ * @param contentAssistRequest
+ * @param childPosition
+ */
+ abstract protected void addTagNameProposals(ContentAssistRequest contentAssistRequest, int childPosition,
+ CompletionProposalInvocationContext context);
+
+
+ /**
+ * Calculates and adds the EL proposals in attribute value to the Content Assist Request object
+ *
+ * @param contentAssistRequest
+ */
+ abstract protected void addAttributeValueELProposals(ContentAssistRequest contentAssistRequest,
+ CompletionProposalInvocationContext context);
+
+ /**
+ * Calculates and adds the EL proposals in text to the Content Assist Request object
+ *
+ * @param contentAssistRequest
+ */
+ abstract protected void addTextELProposals(ContentAssistRequest contentAssistRequest,
+ CompletionProposalInvocationContext context);
+
+}
Property changes on: trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/computers/AbstractXmlCompletionProposalComputer.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/computers/FaceletsELCompletionProposalComputer.java
===================================================================
--- trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/computers/FaceletsELCompletionProposalComputer.java (rev 0)
+++ trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/computers/FaceletsELCompletionProposalComputer.java 2010-08-10 14:13:05 UTC (rev 24020)
@@ -0,0 +1,266 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Exadel, Inc. and 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:
+ * Exadel, Inc. and Red Hat, Inc. - initial API and implementation
+ ******************************************************************************/
+package org.jboss.tools.jst.jsp.contentassist.computers;
+
+import java.util.List;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.wst.html.core.internal.contentmodel.HTMLCMDocument;
+import org.eclipse.wst.html.core.internal.provisional.HTMLCMProperties;
+import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
+import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
+import org.eclipse.wst.sse.ui.contentassist.CompletionProposalInvocationContext;
+import org.eclipse.wst.sse.ui.internal.contentassist.ContentAssistUtils;
+import org.eclipse.wst.xml.core.internal.contentmodel.CMDocument;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.core.internal.ssemodelquery.ModelQueryAdapter;
+import org.eclipse.wst.xml.ui.internal.contentassist.ContentAssistRequest;
+import org.jboss.tools.common.el.core.ca.ELTextProposal;
+import org.jboss.tools.common.el.core.resolver.ELContext;
+import org.jboss.tools.common.text.TextProposal;
+import org.jboss.tools.jst.jsp.contentassist.AbstractXMLContentAssistProcessor.TextRegion;
+import org.jboss.tools.jst.jsp.contentassist.AutoContentAssistantProposal;
+import org.jboss.tools.jst.jsp.contentassist.AutoELContentAssistantProposal;
+import org.jboss.tools.jst.jsp.messages.JstUIMessages;
+import org.jboss.tools.jst.web.kb.IFaceletPageContext;
+import org.jboss.tools.jst.web.kb.KbQuery;
+import org.jboss.tools.jst.web.kb.KbQuery.Type;
+import org.jboss.tools.jst.web.kb.PageContextFactory;
+import org.jboss.tools.jst.web.kb.PageProcessor;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentType;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+
+/**
+ * EL Proposal computer for XHTML pages
+ *
+ * @author Jeremy
+ *
+ */
+ at SuppressWarnings("restriction")
+public class FaceletsELCompletionProposalComputer extends JspELCompletionProposalComputer {
+ private static final String JSFC_ATTRIBUTE_NAME = "jsfc"; //$NON-NLS-1$
+ private boolean replaceJsfcTags;
+
+ /** <code>true</code> if the document the proposal request is on is XHTML */
+ protected boolean isXHTML = false;
+
+ /**
+ * <p>Determine if the document is XHTML or not, then compute the proposals</p>
+ * @TODO: move the XHTML determination to XHTML computer
+ *
+ * @see org.eclipse.wst.xml.ui.internal.contentassist.AbstractXMLCompletionProposalComputer#computeCompletionProposals(org.eclipse.wst.sse.ui.contentassist.CompletionProposalInvocationContext, org.eclipse.core.runtime.IProgressMonitor)
+ */
+ @SuppressWarnings("rawtypes")
+ public List computeCompletionProposals(
+ CompletionProposalInvocationContext context,
+ IProgressMonitor monitor) {
+
+ try {
+ //determine if the content is XHTML or not
+ IndexedRegion treeNode = ContentAssistUtils.getNodeAt(context.getViewer(),
+ context.getInvocationOffset());
+ IDOMNode node = (IDOMNode) treeNode;
+ boolean isXHTMLNode = isXHTMLNode(node);
+ if(this.isXHTML != isXHTMLNode) {
+ this.isXHTML = isXHTMLNode;
+ }
+
+ //compute the completion proposals
+ return super.computeCompletionProposals(context, monitor);
+ } finally {
+ fCurrentContext = null;
+ }
+ }
+
+ /**
+ * Determine if this Document is an XHTML Document. Operates solely off of
+ * the Document Type declaration
+ */
+ @SuppressWarnings("deprecation")
+ private static boolean isXHTMLNode(Node node) {
+ if (node == null) {
+ return false;
+ }
+
+ Document doc = null;
+ if (node.getNodeType() != Node.DOCUMENT_NODE)
+ doc = node.getOwnerDocument();
+ else
+ doc = ((Document) node);
+
+ if (doc instanceof IDOMDocument) {
+ return ((IDOMDocument) doc).isXMLType();
+ }
+
+ if (doc instanceof INodeNotifier) {
+ ModelQueryAdapter adapter = (ModelQueryAdapter) ((INodeNotifier) doc).getAdapterFor(ModelQueryAdapter.class);
+ CMDocument cmdoc = null;
+ if (adapter != null && adapter.getModelQuery() != null)
+ cmdoc = adapter.getModelQuery().getCorrespondingCMDocument(doc);
+ if (cmdoc != null) {
+ // treat as XHTML unless we've got the in-code HTML content
+ // model
+ if (cmdoc instanceof HTMLCMDocument)
+ return false;
+ if (cmdoc.supports(HTMLCMProperties.IS_XHTML))
+ return Boolean.TRUE.equals(cmdoc.getProperty(HTMLCMProperties.IS_XHTML));
+ }
+ }
+ // this should never be reached
+ DocumentType docType = doc.getDoctype();
+ return docType != null && docType.getPublicId() != null && docType.getPublicId().indexOf("-//W3C//DTD XHTML ") == 0; //$NON-NLS-1$
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.jboss.tools.jst.jsp.contentassist.AbstractXMLContentAssistProcessor#createContext()
+ */
+ @Override
+ protected ELContext createContext() {
+ return PageContextFactory.createPageContext(getResource(), PageContextFactory.FACELETS_PAGE_CONTEXT_TYPE);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.jboss.tools.jst.jsp.contentassist.JspContentAssistProcessor#getContext()
+ */
+ @Override
+ public IFaceletPageContext getContext() {
+ return (IFaceletPageContext)super.getContext();
+ }
+
+ @Override
+ protected void addTagInsertionProposals(
+ ContentAssistRequest contentAssistRequest, int childPosition, CompletionProposalInvocationContext context) {
+
+ // 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;
+ }
+
+ addELPredicateProposals(contentAssistRequest, TextProposal.R_TAG_INSERTION, true);
+ }
+
+ @Override
+ protected void addTextELProposals(ContentAssistRequest contentAssistRequest, CompletionProposalInvocationContext context) {
+ if (!isELCAToBeShown())
+ return;
+
+ TextRegion prefix = getELPrefix(contentAssistRequest);
+ if (prefix == null || !prefix.isELStarted()) {
+ AutoContentAssistantProposal proposal = new AutoContentAssistantProposal(true, "#{}", //$NON-NLS-1$
+ contentAssistRequest.getReplacementBeginPosition(),
+ 0, 2, JSF_EL_PROPOSAL_IMAGE, JstUIMessages.JspContentAssistProcessor_NewELExpression, null,
+ JstUIMessages.FaceletPageContectAssistProcessor_NewELExpressionTextInfo, TextProposal.R_TAG_INSERTION + 1);
+
+ contentAssistRequest.addProposal(proposal);
+ return;
+ }
+ String matchString = "#{" + prefix.getText(); //$NON-NLS-1$
+ String query = matchString;
+ String stringQuery = matchString;
+
+ int beginChangeOffset = prefix.getStartOffset() + prefix.getOffset();
+
+ KbQuery kbQuery = createKbQuery(Type.TEXT, query, stringQuery);
+ TextProposal[] proposals = PageProcessor.getInstance().getProposals(kbQuery, getContext());
+ if (proposals == null || proposals.length == 0)
+ return;
+
+ for (TextProposal textProposal : proposals) {
+ int replacementOffset = beginChangeOffset;
+ int replacementLength = prefix.getLength();
+ String replacementString = prefix.getText().substring(0, replacementLength) + textProposal.getReplacementString();
+ int cursorPosition = replacementString.length();
+
+ if (!prefix.isELClosed()) {
+ replacementString += "}"; //$NON-NLS-1$
+ }
+
+ 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
+ int relevance = textProposal.getRelevance();
+ if (relevance == TextProposal.R_NONE) {
+ relevance = TextProposal.R_JSP_JSF_EL_VARIABLE_ATTRIBUTE_VALUE;
+ }
+
+ AutoContentAssistantProposal proposal = null;
+ if (textProposal instanceof ELTextProposal) {
+ IJavaElement[] javaElements = ((ELTextProposal)textProposal).getAllJavaElements();
+
+ proposal = new AutoELContentAssistantProposal(replacementString,
+ replacementOffset, replacementLength, cursorPosition, image, displayString,
+ null, javaElements, relevance);
+ } else {
+ String additionalProposalInfo = (textProposal.getContextInfo() == null ? "" : textProposal.getContextInfo()); //$NON-NLS-1$
+
+ proposal = new AutoContentAssistantProposal(replacementString,
+ replacementOffset, replacementLength, cursorPosition, image, displayString,
+ null, additionalProposalInfo, relevance);
+ }
+
+ contentAssistRequest.addProposal(proposal);
+ }
+
+ if (prefix.isELStarted() && !prefix.isELClosed()) {
+ AutoContentAssistantProposal proposal = new AutoContentAssistantProposal("}", //$NON-NLS-1$
+ getOffset(), 0, 1, JSF_EL_PROPOSAL_IMAGE, JstUIMessages.JspContentAssistProcessor_CloseELExpression,
+ null, JstUIMessages.JspContentAssistProcessor_CloseELExpressionInfo, TextProposal.R_XML_ATTRIBUTE_VALUE_TEMPLATE);
+
+ contentAssistRequest.addProposal(proposal);
+ }
+ }
+
+ @Override
+ protected String getTagName(Node tag) {
+ String tagName = tag.getNodeName();
+ if(replaceJsfcTags) {
+ // Only HTML tags
+ if(tagName.indexOf(':')>0) {
+ return tagName;
+ }
+ if (!(tag instanceof Element))
+ return tagName;
+
+ Element element = (Element)tag;
+
+ NamedNodeMap attributes = element.getAttributes();
+ Node jsfC = attributes.getNamedItem(JSFC_ATTRIBUTE_NAME);
+ if(jsfC==null || (!(jsfC instanceof Attr))) {
+ return tagName;
+ }
+ Attr jsfCAttribute = (Attr)jsfC;
+ String jsfTagName = jsfCAttribute.getValue();
+ if(jsfTagName==null || jsfTagName.indexOf(':')<1) {
+ return tagName;
+ }
+ tagName = jsfTagName;
+ }
+ return tagName;
+ }
+
+}
Property changes on: trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/computers/FaceletsELCompletionProposalComputer.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/computers/FaceletsTagCompletionProposalComputer.java
===================================================================
--- trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/computers/FaceletsTagCompletionProposalComputer.java (rev 0)
+++ trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/computers/FaceletsTagCompletionProposalComputer.java 2010-08-10 14:13:05 UTC (rev 24020)
@@ -0,0 +1,230 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Exadel, Inc. and 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:
+ * Exadel, Inc. and Red Hat, Inc. - initial API and implementation
+ ******************************************************************************/
+package org.jboss.tools.jst.jsp.contentassist.computers;
+
+import java.util.List;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.wst.html.core.internal.contentmodel.HTMLCMDocument;
+import org.eclipse.wst.html.core.internal.provisional.HTMLCMProperties;
+import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
+import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
+import org.eclipse.wst.sse.ui.contentassist.CompletionProposalInvocationContext;
+import org.eclipse.wst.sse.ui.internal.contentassist.ContentAssistUtils;
+import org.eclipse.wst.xml.core.internal.contentmodel.CMDocument;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.core.internal.ssemodelquery.ModelQueryAdapter;
+import org.eclipse.wst.xml.ui.internal.contentassist.ContentAssistRequest;
+import org.jboss.tools.common.el.core.resolver.ELContext;
+import org.jboss.tools.jst.web.kb.IFaceletPageContext;
+import org.jboss.tools.jst.web.kb.PageContextFactory;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentType;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+
+/**
+ * Tag Proposal computer for XHTML pages
+ *
+ * @author Jeremy
+ *
+ */
+ at SuppressWarnings("restriction")
+public class FaceletsTagCompletionProposalComputer extends JspTagCompletionProposalComputer {
+ private static final String JSFC_ATTRIBUTE_NAME = "jsfc"; //$NON-NLS-1$
+ private boolean replaceJsfcTags;
+
+ /** <code>true</code> if the document the proposal request is on is XHTML */
+ protected boolean isXHTML = false;
+
+ /**
+ * <p>Determine if the document is XHTML or not, then compute the proposals</p>
+ * @TODO: move the XHTML determination to XHTML computer
+ *
+ * @see org.eclipse.wst.xml.ui.internal.contentassist.AbstractXMLCompletionProposalComputer#computeCompletionProposals(org.eclipse.wst.sse.ui.contentassist.CompletionProposalInvocationContext, org.eclipse.core.runtime.IProgressMonitor)
+ */
+ @SuppressWarnings("rawtypes")
+ public List computeCompletionProposals(
+ CompletionProposalInvocationContext context,
+ IProgressMonitor monitor) {
+
+ try {
+ //determine if the content is XHTML or not
+ IndexedRegion treeNode = ContentAssistUtils.getNodeAt(context.getViewer(),
+ context.getInvocationOffset());
+ IDOMNode node = (IDOMNode) treeNode;
+ boolean isXHTMLNode = isXHTMLNode(node);
+ if(this.isXHTML != isXHTMLNode) {
+ this.isXHTML = isXHTMLNode;
+ }
+
+ //compute the completion proposals
+ return super.computeCompletionProposals(context, monitor);
+ } finally {
+ fCurrentContext = null;
+ }
+ }
+
+ /**
+ * Determine if this Document is an XHTML Document. Operates solely off of
+ * the Document Type declaration
+ */
+ @SuppressWarnings("deprecation")
+ private static boolean isXHTMLNode(Node node) {
+ if (node == null) {
+ return false;
+ }
+
+ Document doc = null;
+ if (node.getNodeType() != Node.DOCUMENT_NODE)
+ doc = node.getOwnerDocument();
+ else
+ doc = ((Document) node);
+
+ if (doc instanceof IDOMDocument) {
+ return ((IDOMDocument) doc).isXMLType();
+ }
+
+ if (doc instanceof INodeNotifier) {
+ ModelQueryAdapter adapter = (ModelQueryAdapter) ((INodeNotifier) doc).getAdapterFor(ModelQueryAdapter.class);
+ CMDocument cmdoc = null;
+ if (adapter != null && adapter.getModelQuery() != null)
+ cmdoc = adapter.getModelQuery().getCorrespondingCMDocument(doc);
+ if (cmdoc != null) {
+ // treat as XHTML unless we've got the in-code HTML content
+ // model
+ if (cmdoc instanceof HTMLCMDocument)
+ return false;
+ if (cmdoc.supports(HTMLCMProperties.IS_XHTML))
+ return Boolean.TRUE.equals(cmdoc.getProperty(HTMLCMProperties.IS_XHTML));
+ }
+ }
+ // this should never be reached
+ DocumentType docType = doc.getDoctype();
+ return docType != null && docType.getPublicId() != null && docType.getPublicId().indexOf("-//W3C//DTD XHTML ") == 0; //$NON-NLS-1$
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.jboss.tools.jst.jsp.contentassist.AbstractXMLContentAssistProcessor#createContext()
+ */
+ @Override
+ protected ELContext createContext() {
+ return PageContextFactory.createPageContext(getResource(), PageContextFactory.FACELETS_PAGE_CONTEXT_TYPE);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.jboss.tools.jst.jsp.contentassist.JspContentAssistProcessor#getContext()
+ */
+ @Override
+ public IFaceletPageContext getContext() {
+ return (IFaceletPageContext)super.getContext();
+ }
+
+ /**
+ * 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,
+ CompletionProposalInvocationContext context) {
+
+ // 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, context);
+ }
+
+ /**
+ * Calculates and adds the EL proposals to the Content Assist Request object
+ */
+ @Override
+ protected void addTextELProposals(ContentAssistRequest contentAssistRequest,
+ CompletionProposalInvocationContext context) {
+ // No EL proposals are to be added here
+ }
+
+ /* (non-Javadoc)
+ * @see org.jboss.tools.jst.jsp.contentassist.JspContentAssistProcessor#addAttributeNameProposals(org.eclipse.wst.xml.ui.internal.contentassist.ContentAssistRequest)
+ */
+ @Override
+ protected void addAttributeNameProposals(
+ ContentAssistRequest contentAssistRequest,
+ CompletionProposalInvocationContext context) {
+ super.addAttributeNameProposals(contentAssistRequest, context);
+ if (isExistingAttribute(JSFC_ATTRIBUTE_NAME)) {
+ this.replaceJsfcTags = true;
+ super.addAttributeNameProposals(contentAssistRequest, context);
+ this.replaceJsfcTags = false;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.jboss.tools.jst.jsp.contentassist.JspContentAssistProcessor#addAttributeValueProposals(org.eclipse.wst.xml.ui.internal.contentassist.ContentAssistRequest)
+ */
+ @Override
+ protected void addAttributeValueProposals(ContentAssistRequest contentAssistRequest,
+ CompletionProposalInvocationContext context) {
+ super.addAttributeValueProposals(contentAssistRequest, context);
+ if (isExistingAttribute(JSFC_ATTRIBUTE_NAME)) {
+ this.replaceJsfcTags = true;
+ super.addAttributeValueProposals(contentAssistRequest, context);
+ this.replaceJsfcTags = false;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.jboss.tools.jst.jsp.contentassist.AbstractXMLContentAssistProcessor#getTagName(org.w3c.dom.Node)
+ */
+ @Override
+ protected String getTagName(Node tag) {
+ String tagName = tag.getNodeName();
+ if(replaceJsfcTags) {
+ // Only HTML tags
+ if(tagName.indexOf(':')>0) {
+ return tagName;
+ }
+ if (!(tag instanceof Element))
+ return tagName;
+
+ Element element = (Element)tag;
+
+ NamedNodeMap attributes = element.getAttributes();
+ Node jsfC = attributes.getNamedItem(JSFC_ATTRIBUTE_NAME);
+ if(jsfC==null || (!(jsfC instanceof Attr))) {
+ return tagName;
+ }
+ Attr jsfCAttribute = (Attr)jsfC;
+ String jsfTagName = jsfCAttribute.getValue();
+ if(jsfTagName==null || jsfTagName.indexOf(':')<1) {
+ return tagName;
+ }
+ tagName = jsfTagName;
+ }
+ return tagName;
+ }
+
+}
Property changes on: trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/computers/FaceletsTagCompletionProposalComputer.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/computers/JspELCompletionProposalComputer.java
===================================================================
--- trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/computers/JspELCompletionProposalComputer.java (rev 0)
+++ trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/computers/JspELCompletionProposalComputer.java 2010-08-10 14:13:05 UTC (rev 24020)
@@ -0,0 +1,135 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Exadel, Inc. and 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:
+ * Exadel, Inc. and Red Hat, Inc. - initial API and implementation
+ ******************************************************************************/
+package org.jboss.tools.jst.jsp.contentassist.computers;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.Region;
+import org.eclipse.wst.sse.ui.contentassist.CompletionProposalInvocationContext;
+import org.eclipse.wst.xml.ui.internal.contentassist.ContentAssistRequest;
+import org.jboss.tools.common.el.core.model.ELExpression;
+import org.jboss.tools.common.el.core.parser.ELParserFactory;
+import org.jboss.tools.common.el.core.parser.ELParserUtil;
+import org.jboss.tools.common.el.core.resolver.ELCompletionEngine;
+import org.jboss.tools.common.el.core.resolver.ELContext;
+import org.jboss.tools.common.el.core.resolver.ELContextImpl;
+import org.jboss.tools.common.el.core.resolver.ELResolution;
+import org.jboss.tools.common.el.core.resolver.ELResolutionImpl;
+import org.jboss.tools.common.el.core.resolver.ElVarSearcher;
+import org.jboss.tools.common.el.core.resolver.Var;
+import org.jboss.tools.common.text.TextProposal;
+import org.jboss.tools.jst.web.kb.IPageContext;
+import org.jboss.tools.jst.web.kb.PageContextFactory;
+import org.jboss.tools.jst.web.kb.taglib.INameSpace;
+
+/**
+ * EL Proposal computer for JSP pages
+ *
+ * @author Jeremy
+ *
+ */
+ at SuppressWarnings("restriction")
+public class JspELCompletionProposalComputer extends XmlELCompletionProposalComputer {
+
+ /*
+ * (non-Javadoc)
+ * @see org.jboss.tools.jst.jsp.contentassist.AbstractXMLContentAssistProcessor#createContext()
+ */
+ @Override
+ protected ELContext createContext() {
+ return PageContextFactory.createPageContext(getResource(), PageContextFactory.JSP_PAGE_CONTEXT_TYPE);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.jboss.tools.jst.jsp.contentassist.JspContentAssistProcessor#getContext()
+ */
+ @Override
+ public IPageContext getContext() {
+ return (IPageContext)super.getContext();
+ }
+
+ /**
+ * Returns URI string for the prefix specified using the namespaces collected for
+ * the {@link IPageContext} context.
+ * Important: The context must be created using createContext() method before using this method.
+ *
+ * @param prefix
+ * @return
+ */
+ @Override
+ public String getUri(String prefix) {
+ if (prefix == null)
+ return null;
+
+ Map<String, List<INameSpace>> nameSpaces = getContext().getNameSpaces(getOffset());
+ if (nameSpaces == null || nameSpaces.isEmpty())
+ return null;
+
+ for (List<INameSpace> nameSpace : nameSpaces.values()) {
+ for (INameSpace n : nameSpace) {
+ if (prefix.equals(n.getPrefix())) {
+ return n.getURI();
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ protected void addTextELProposals(
+ ContentAssistRequest contentAssistRequest,
+ CompletionProposalInvocationContext context) {
+ // Do not return any EL proposals for the TEXT regions
+ }
+
+ protected void setVars(ELContextImpl context, IFile file) {
+ ELCompletionEngine fakeEngine = new ELCompletionEngine() {
+
+ public ELResolution resolveELOperand(IFile file,
+ ELExpression operand, boolean returnEqualedVariablesOnly,
+ List<Var> vars, ElVarSearcher varSearcher)
+ throws BadLocationException, StringIndexOutOfBoundsException {
+ return new ELResolutionImpl(operand);
+ }
+
+ public ELParserFactory getParserFactory() {
+ return ELParserUtil.getJbossFactory();
+ }
+
+ public List<TextProposal> getProposals(ELContext context, String el, int offset) {
+ return Collections.emptyList();
+ }
+
+ public ELResolution resolve(ELContext context, ELExpression operand, int offset) {
+ return new ELResolutionImpl(operand);
+ }
+
+ public List<TextProposal> getProposals(ELContext context, int offset) {
+ return Collections.emptyList();
+ }
+ };
+ ElVarSearcher varSearcher = new ElVarSearcher(file, fakeEngine);
+ List<Var> vars = varSearcher.findAllVars(file, getOffset());
+
+ if (vars != null) {
+ for (Var var : vars) {
+ context.addVar(new Region(getOffset(), 0), var);
+ }
+ }
+ }
+
+
+}
Property changes on: trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/computers/JspELCompletionProposalComputer.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/computers/JspTagCompletionProposalComputer.java
===================================================================
--- trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/computers/JspTagCompletionProposalComputer.java (rev 0)
+++ trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/computers/JspTagCompletionProposalComputer.java 2010-08-10 14:13:05 UTC (rev 24020)
@@ -0,0 +1,158 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Exadel, Inc. and 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:
+ * Exadel, Inc. and Red Hat, Inc. - initial API and implementation
+ ******************************************************************************/
+package org.jboss.tools.jst.jsp.contentassist.computers;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.Region;
+import org.eclipse.wst.sse.ui.contentassist.CompletionProposalInvocationContext;
+import org.eclipse.wst.xml.ui.internal.contentassist.ContentAssistRequest;
+import org.jboss.tools.common.el.core.model.ELExpression;
+import org.jboss.tools.common.el.core.parser.ELParserFactory;
+import org.jboss.tools.common.el.core.parser.ELParserUtil;
+import org.jboss.tools.common.el.core.resolver.ELCompletionEngine;
+import org.jboss.tools.common.el.core.resolver.ELContext;
+import org.jboss.tools.common.el.core.resolver.ELContextImpl;
+import org.jboss.tools.common.el.core.resolver.ELResolution;
+import org.jboss.tools.common.el.core.resolver.ELResolutionImpl;
+import org.jboss.tools.common.el.core.resolver.ElVarSearcher;
+import org.jboss.tools.common.el.core.resolver.Var;
+import org.jboss.tools.common.text.TextProposal;
+import org.jboss.tools.jst.web.kb.IPageContext;
+import org.jboss.tools.jst.web.kb.PageContextFactory;
+import org.jboss.tools.jst.web.kb.taglib.INameSpace;
+
+/**
+ * Tag Proposal computer for JSP pages
+ *
+ * @author Jeremy
+ *
+ */
+ at SuppressWarnings("restriction")
+public class JspTagCompletionProposalComputer extends XmlTagCompletionProposalComputer {
+ /*
+ * (non-Javadoc)
+ * @see org.jboss.tools.jst.jsp.contentassist.AbstractXMLContentAssistProcessor#createContext()
+ */
+ @Override
+ protected ELContext createContext() {
+ return PageContextFactory.createPageContext(getResource(), PageContextFactory.JSP_PAGE_CONTEXT_TYPE);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.jboss.tools.jst.jsp.contentassist.JspContentAssistProcessor#getContext()
+ */
+ @Override
+ public IPageContext getContext() {
+ return (IPageContext)super.getContext();
+ }
+
+ /**
+ * Returns URI string for the prefix specified using the namespaces collected for
+ * the {@link IPageContext} context.
+ * Important: The context must be created using createContext() method before using this method.
+ *
+ * @param prefix
+ * @return
+ */
+ @Override
+ public String getUri(String prefix) {
+ if (prefix == null)
+ return null;
+
+ Map<String, List<INameSpace>> nameSpaces = getContext().getNameSpaces(getOffset());
+ if (nameSpaces == null || nameSpaces.isEmpty())
+ return null;
+
+ for (List<INameSpace> nameSpace : nameSpaces.values()) {
+ for (INameSpace n : nameSpace) {
+ if (prefix.equals(n.getPrefix())) {
+ return n.getURI();
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * 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,
+ CompletionProposalInvocationContext context) {
+
+ // 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, context);
+ }
+
+ /**
+ * Calculates and adds the EL proposals to the Content Assist Request object
+ */
+ @Override
+ protected void addTextELProposals(ContentAssistRequest contentAssistRequest,
+ CompletionProposalInvocationContext context) {
+ // No EL proposals are to be added here
+ }
+
+ protected void setVars(ELContextImpl context, IFile file) {
+ ELCompletionEngine fakeEngine = new ELCompletionEngine() {
+
+ public ELResolution resolveELOperand(IFile file,
+ ELExpression operand, boolean returnEqualedVariablesOnly,
+ List<Var> vars, ElVarSearcher varSearcher)
+ throws BadLocationException, StringIndexOutOfBoundsException {
+ return new ELResolutionImpl(operand);
+ }
+
+ public ELParserFactory getParserFactory() {
+ return ELParserUtil.getJbossFactory();
+ }
+
+ public List<TextProposal> getProposals(ELContext context, String el, int offset) {
+ return Collections.emptyList();
+ }
+
+ public ELResolution resolve(ELContext context, ELExpression operand, int offset) {
+ return new ELResolutionImpl(operand);
+ }
+
+ public List<TextProposal> getProposals(ELContext context, int offset) {
+ return Collections.emptyList();
+ }
+ };
+ ElVarSearcher varSearcher = new ElVarSearcher(file, fakeEngine);
+ List<Var> vars = varSearcher.findAllVars(file, getOffset());
+
+ if (vars != null) {
+ for (Var var : vars) {
+ context.addVar(new Region(getOffset(), 0), var);
+ }
+ }
+ }
+
+}
Property changes on: trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/computers/JspTagCompletionProposalComputer.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/computers/XmlELCompletionProposalComputer.java
===================================================================
--- trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/computers/XmlELCompletionProposalComputer.java (rev 0)
+++ trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/computers/XmlELCompletionProposalComputer.java 2010-08-10 14:13:05 UTC (rev 24020)
@@ -0,0 +1,1090 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Exadel, Inc. and 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:
+ * Exadel, Inc. and Red Hat, Inc. - initial API and implementation
+ ******************************************************************************/
+package org.jboss.tools.jst.jsp.contentassist.computers;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.filebuffers.FileBuffers;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.contentassist.ICompletionProposal;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.wst.dtd.core.internal.contentmodel.DTDImpl.DTDBaseAdapter;
+import org.eclipse.wst.dtd.core.internal.contentmodel.DTDImpl.DTDElementReferenceContentAdapter;
+import org.eclipse.wst.html.core.internal.contentmodel.HTMLPropertyDeclaration;
+import org.eclipse.wst.sse.core.StructuredModelManager;
+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
+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.contentassist.CompletionProposalInvocationContext;
+import org.eclipse.wst.sse.ui.internal.contentassist.ContentAssistUtils;
+import org.eclipse.wst.xml.core.internal.contentmodel.CMAttributeDeclaration;
+import org.eclipse.wst.xml.core.internal.contentmodel.CMNode;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
+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.contentassist.ContentAssistRequest;
+import org.eclipse.wst.xml.ui.internal.contentassist.XMLContentModelGenerator;
+import org.eclipse.wst.xml.ui.internal.contentassist.XMLRelevanceConstants;
+import org.jboss.tools.common.el.core.ca.ELTextProposal;
+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.el.core.resolver.ELResolver;
+import org.jboss.tools.common.el.core.resolver.ELResolverFactoryManager;
+import org.jboss.tools.common.text.TextProposal;
+import org.jboss.tools.jst.jsp.JspEditorPlugin;
+import org.jboss.tools.jst.jsp.contentassist.AbstractXMLContentAssistProcessor.TextRegion;
+import org.jboss.tools.jst.jsp.contentassist.AutoContentAssistantProposal;
+import org.jboss.tools.jst.jsp.contentassist.AutoELContentAssistantProposal;
+import org.jboss.tools.jst.jsp.messages.JstUIMessages;
+import org.jboss.tools.jst.web.kb.IPageContext;
+import org.jboss.tools.jst.web.kb.KbQuery;
+import org.jboss.tools.jst.web.kb.KbQuery.Type;
+import org.jboss.tools.jst.web.kb.PageContextFactory;
+import org.jboss.tools.jst.web.kb.PageProcessor;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * EL Proposal computer for XML pages
+ *
+ * @author Jeremy
+ *
+ */
+ at SuppressWarnings("restriction")
+public class XmlELCompletionProposalComputer extends AbstractXmlCompletionProposalComputer {
+ protected static final ICompletionProposal[] EMPTY_PROPOSAL_LIST = new ICompletionProposal[0];
+ private static final String[] EMPTY_TAGS = new String[0];
+ protected static final Image JSF_EL_PROPOSAL_IMAGE = JspEditorPlugin.getDefault().getImage(JspEditorPlugin.CA_JSF_EL_IMAGE_PATH);
+
+ @Override
+ protected XMLContentModelGenerator getContentGenerator() {
+ return new XMLContentModelGenerator();
+ }
+
+ @Override
+ protected boolean validModelQueryNode(CMNode node) {
+ boolean isValid = false;
+ if(node instanceof DTDElementReferenceContentAdapter) {
+ DTDElementReferenceContentAdapter content = (DTDElementReferenceContentAdapter)node;
+ if(content.getCMDocument() instanceof DTDBaseAdapter) {
+ DTDBaseAdapter dtd = (DTDBaseAdapter)content.getCMDocument();
+ //this maybe a little hacky, but it works, if you have a better idea go for it
+ String spec = dtd.getSpec();
+ isValid = spec.indexOf("html") != -1; //$NON-NLS-1$
+ }
+ } else if(node instanceof HTMLPropertyDeclaration) {
+ HTMLPropertyDeclaration propDec = (HTMLPropertyDeclaration)node;
+ isValid = !propDec.isJSP();
+ } else if (node instanceof CMAttributeDeclaration) {
+ isValid = true;
+ }
+ return isValid;
+ }
+
+
+ /**
+ * Calculates and adds the tag proposals to the Content Assist Request object
+ *
+ * @param contentAssistRequest Content Assist Request object
+ * @param childPosition the
+ */
+
+ @Override
+ protected void addTagInsertionProposals(
+ ContentAssistRequest contentAssistRequest, int childPosition, CompletionProposalInvocationContext context) {
+
+ // 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;
+ }
+
+ addELPredicateProposals(contentAssistRequest, TextProposal.R_TAG_INSERTION, true);
+ }
+
+ @Override
+ protected void addAttributeValueProposals(
+ ContentAssistRequest contentAssistRequest,
+ CompletionProposalInvocationContext context) {
+
+ fCurrentContext = context;
+
+ // 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;
+ }
+
+ addELPredicateProposals(contentAssistRequest, TextProposal.R_JSP_ATTRIBUTE_VALUE, false);
+ }
+
+ protected void addTagNameProposals(ContentAssistRequest contentAssistRequest, int childPosition,
+ CompletionProposalInvocationContext context) {
+ }
+
+ @SuppressWarnings("unused")
+ @Override
+ protected void addAttributeValueELProposals(ContentAssistRequest contentAssistRequest,
+ CompletionProposalInvocationContext context) {
+
+ if (!isELCAToBeShown())
+ return;
+
+ TextRegion prefix = getELPrefix(contentAssistRequest);
+ if (prefix == null) {
+ return;
+ }
+
+ if(!prefix.isELStarted()) {
+ AutoContentAssistantProposal proposal = new AutoContentAssistantProposal(true,
+ "#{}" + (prefix.isAttributeValue() && prefix.hasOpenQuote() && !prefix.hasCloseQuote() ? String.valueOf(prefix.getQuoteChar()) : ""), //$NON-NLS-1$ //$NON-NLS-2$
+ getOffset(), 0, 2, JSF_EL_PROPOSAL_IMAGE, JstUIMessages.JspContentAssistProcessor_NewELExpression,
+ null, JstUIMessages.JspContentAssistProcessor_NewELExpressionAttrInfo, TextProposal.R_XML_ATTRIBUTE_VALUE_TEMPLATE);
+
+ contentAssistRequest.addProposal(proposal);
+ 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());
+
+ if (proposals == null || proposals.length == 0)
+ return;
+
+ for (TextProposal textProposal : proposals) {
+ int replacementOffset = beginChangeOffset;
+ int replacementLength = prefix.getLength();
+ String replacementString = prefix.getText().substring(0, replacementLength) + textProposal.getReplacementString();
+
+ char quoteChar = prefix.isAttributeValue() && prefix.hasOpenQuote() ? prefix.getQuoteChar() : '"';
+// if (prefix.isAttributeValue() && !prefix.hasOpenQuote()) {
+// replacementString = String.valueOf(quoteChar) + replacementString;
+// }
+ 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
+
+ int relevance = textProposal.getRelevance();
+ if (relevance == TextProposal.R_NONE) {
+ relevance = TextProposal.R_JSP_JSF_EL_VARIABLE_ATTRIBUTE_VALUE;
+ }
+
+ AutoContentAssistantProposal proposal = null;
+ if (textProposal instanceof ELTextProposal) {
+ IJavaElement[] javaElements = ((ELTextProposal)textProposal).getAllJavaElements();
+
+ proposal = new AutoELContentAssistantProposal(replacementString,
+ replacementOffset, replacementLength, cursorPosition, image, displayString,
+ null, javaElements, relevance);
+ } else {
+ String additionalProposalInfo = (textProposal.getContextInfo() == null ? "" : textProposal.getContextInfo()); //$NON-NLS-1$
+
+ proposal = new AutoContentAssistantProposal(replacementString,
+ replacementOffset, replacementLength, cursorPosition, image, displayString,
+ null, additionalProposalInfo, relevance);
+ }
+ contentAssistRequest.addProposal(proposal);
+ }
+
+ if (prefix.isELStarted() && !prefix.isELClosed()) {
+ AutoContentAssistantProposal proposal = new AutoContentAssistantProposal(
+ "}" + (prefix.isAttributeValue() && prefix.hasOpenQuote() && !prefix.hasCloseQuote() ? String.valueOf(prefix.getQuoteChar()) : ""), //$NON-NLS-1$ //$NON-NLS-2$
+ getOffset(), 0, 0, JSF_EL_PROPOSAL_IMAGE, JstUIMessages.JspContentAssistProcessor_CloseELExpression,
+ null, JstUIMessages.JspContentAssistProcessor_CloseELExpressionInfo, TextProposal.R_XML_ATTRIBUTE_VALUE + 1); //
+
+ contentAssistRequest.addProposal(proposal);
+ }
+ }
+
+ @SuppressWarnings("unused")
+ @Override
+ protected void addTextELProposals(ContentAssistRequest contentAssistRequest,
+ CompletionProposalInvocationContext context) {
+ if (!isELCAToBeShown())
+ return;
+
+ TextRegion prefix = getELPrefix(contentAssistRequest);
+ if (prefix == null || !prefix.isELStarted()) {
+ AutoContentAssistantProposal proposal = new AutoContentAssistantProposal(true, "#{}", //$NON-NLS-1$
+ contentAssistRequest.getReplacementBeginPosition(),
+ 0, 2, JSF_EL_PROPOSAL_IMAGE, JstUIMessages.JspContentAssistProcessor_NewELExpression, null,
+ JstUIMessages.FaceletPageContectAssistProcessor_NewELExpressionTextInfo, TextProposal.R_TAG_INSERTION + 1);
+
+ contentAssistRequest.addProposal(proposal);
+ 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.TEXT, query, stringQuery);
+ TextProposal[] proposals = PageProcessor.getInstance().getProposals(kbQuery, getContext());
+
+ if (proposals == null || proposals.length == 0)
+ return;
+
+ for (TextProposal textProposal : proposals) {
+ int replacementOffset = beginChangeOffset;
+ int replacementLength = prefix.getLength();
+ String replacementString = prefix.getText().substring(0, replacementLength) + textProposal.getReplacementString();
+ int cursorPosition = replacementString.length();
+
+ if (!prefix.isELClosed()) {
+ replacementString += "}"; //$NON-NLS-1$
+ }
+
+ 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
+ int relevance = textProposal.getRelevance();
+ if (relevance == TextProposal.R_NONE) {
+ relevance = TextProposal.R_JSP_JSF_EL_VARIABLE_ATTRIBUTE_VALUE;
+ }
+
+ AutoContentAssistantProposal proposal = null;
+ if (textProposal instanceof ELTextProposal) {
+ IJavaElement[] javaElements = ((ELTextProposal)textProposal).getAllJavaElements();
+
+ proposal = new AutoELContentAssistantProposal(replacementString,
+ replacementOffset, replacementLength, cursorPosition, image, displayString,
+ null, javaElements, relevance);
+ } else {
+ String additionalProposalInfo = (textProposal.getContextInfo() == null ? "" : textProposal.getContextInfo()); //$NON-NLS-1$
+
+ proposal = new AutoContentAssistantProposal(replacementString,
+ replacementOffset, replacementLength, cursorPosition, image, displayString,
+ null, additionalProposalInfo, relevance);
+ }
+ contentAssistRequest.addProposal(proposal);
+ }
+
+ if (prefix.isELStarted() && !prefix.isELClosed()) {
+ AutoContentAssistantProposal proposal = new AutoContentAssistantProposal("}", //$NON-NLS-1$
+ getOffset(), 0, 1, JSF_EL_PROPOSAL_IMAGE, JstUIMessages.JspContentAssistProcessor_CloseELExpression,
+ null, JstUIMessages.JspContentAssistProcessor_CloseELExpressionInfo, TextProposal.R_XML_ATTRIBUTE_VALUE_TEMPLATE);
+
+ contentAssistRequest.addProposal(proposal);
+ }
+ }
+
+ /**
+ * Calculates and adds EL predicate proposals based on the last word typed
+ * To be used only outside the EL.
+ *
+ * @param contentAssistRequest
+ */
+ @SuppressWarnings("unused")
+ protected void addELPredicateProposals(ContentAssistRequest contentAssistRequest, int baseRelevance, boolean shiftRelevanceAgainstTagNameProposals) {
+ if (!isELCAToBeShown())
+ return;
+
+ // 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 relevanceShift = -2; // Fix for JBIDE-5987: Relevance for predicate proposals is shifted down by default to show EL proposals lower than attr-value proposals
+ if (shiftRelevanceAgainstTagNameProposals) {
+ relevanceShift += prefix.getText() != null && prefix.getText().trim().length() > 0 ? (XMLRelevanceConstants.R_STRICTLY_VALID_TAG_INSERTION - baseRelevance + 2): -2;
+ }
+
+ int beginChangeOffset = prefix.getStartOffset() + prefix.getOffset();
+
+ KbQuery kbQuery = createKbQuery(Type.ATTRIBUTE_VALUE, query, stringQuery);
+ TextProposal[] proposals = PageProcessor.getInstance().getProposals(kbQuery, getContext());
+
+ if (proposals == null || proposals.length == 0)
+ return;
+
+ for (TextProposal textProposal : proposals) {
+ 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
+
+ int relevance = textProposal.getRelevance();
+ if (relevance == TextProposal.R_NONE) {
+ relevance = baseRelevance;
+ }
+ relevance += relevanceShift;
+
+ AutoContentAssistantProposal proposal = null;
+ if (textProposal instanceof ELTextProposal) {
+ IJavaElement[] javaElements = ((ELTextProposal)textProposal).getAllJavaElements();
+
+ proposal = new AutoELContentAssistantProposal(replacementString,
+ replacementOffset, replacementLength, cursorPosition, image, displayString,
+ null, javaElements, relevance);
+ } else {
+ String additionalProposalInfo = (textProposal.getContextInfo() == null ? "" : textProposal.getContextInfo()); //$NON-NLS-1$
+
+ proposal = new AutoContentAssistantProposal(replacementString,
+ replacementOffset, replacementLength, cursorPosition, image, displayString,
+ null, additionalProposalInfo, relevance);
+ }
+ contentAssistRequest.addProposal(proposal);
+ }
+ }
+
+ /**
+ * Checks is we need to show EL proposals
+ *
+ * @return
+ */
+ protected boolean isELCAToBeShown() {
+ ELResolver[] resolvers = getContext().getElResolvers();
+ return (resolvers != null && resolvers.length > 0);
+ }
+
+ protected ELContext createContext() {
+ return PageContextFactory.createPageContext(getResource(), PageContextFactory.XML_PAGE_CONTEXT_TYPE);
+ }
+
+ protected KbQuery createKbQuery(Type type, String query, String stringQuery) {
+ return createKbQuery(type, query, stringQuery, getTagPrefix(), getTagUri());
+ }
+
+ protected KbQuery createKbQuery(Type type, String query, String stringQuery, String prefix, String uri) {
+ KbQuery kbQuery = new KbQuery();
+
+ String[] parentTags = getParentTags(type == Type.ATTRIBUTE_NAME || type == Type.ATTRIBUTE_VALUE);
+ String parent = getParent(type == Type.ATTRIBUTE_VALUE, type == Type.ATTRIBUTE_NAME);
+ String queryValue = query;
+ String queryStringValue = stringQuery;
+
+ kbQuery.setPrefix(prefix);
+ kbQuery.setUri(uri);
+ kbQuery.setParentTags(parentTags);
+ kbQuery.setParent(parent);
+ kbQuery.setMask(true);
+ kbQuery.setType(type);
+ kbQuery.setOffset(fCurrentContext.getInvocationOffset());
+ kbQuery.setValue(queryValue);
+ kbQuery.setStringQuery(queryStringValue);
+
+ return kbQuery;
+ }
+
+ /**
+ * this is the position the cursor should be in after the proposal is
+ * applied
+ *
+ * @param proposedText
+ * @return the position the cursor should be in after the proposal is
+ * applied
+ */
+ protected static int getCursorPositionForProposedText(String proposedText) {
+ int cursorAdjustment;
+ cursorAdjustment = proposedText.indexOf("\"\"") + 1; //$NON-NLS-1$
+ // otherwise, after the first tag
+ if (cursorAdjustment == 0) {
+ cursorAdjustment = proposedText.indexOf('>') + 1;
+ }
+ if (cursorAdjustment == 0) {
+ cursorAdjustment = proposedText.length();
+ }
+
+ return cursorAdjustment;
+ }
+
+ /**
+ * Returns array of the <code>org.jboss.tools.common.el.core.resolver.ELResolver</code>
+ * instances.
+ *
+ * @param resource
+ * @return
+ */
+ protected ELResolver[] getELResolvers(IResource resource) {
+ if (resource == null)
+ return null;
+
+ ELResolverFactoryManager elrfm = ELResolverFactoryManager.getInstance();
+ return elrfm.getResolvers(resource);
+ }
+
+ /**
+ * Returns array of the parent tags
+ *
+ * @return
+ */
+ public String[] getParentTags(boolean includeThisTag) {
+ List<String> parentTags = new ArrayList<String>();
+
+ IStructuredModel sModel = StructuredModelManager
+ .getModelManager()
+ .getExistingModelForRead(getDocument());
+ try {
+ if (sModel == null)
+ return EMPTY_TAGS;
+
+ Document xmlDocument = (sModel instanceof IDOMModel)
+ ? ((IDOMModel) sModel).getDocument()
+ : null;
+
+ if (xmlDocument == null)
+ return EMPTY_TAGS;
+
+
+ Node n = null;
+ if (includeThisTag) {
+ n = findNodeForOffset(xmlDocument, getOffset());
+ } else {
+ // Get Fixed Structured Document Region
+ IStructuredDocumentRegion sdFixedRegion = this.getStructuredDocumentRegion(getOffset());
+ if (sdFixedRegion == null)
+ return EMPTY_TAGS;
+
+ n = findNodeForOffset(xmlDocument, sdFixedRegion.getStartOffset());
+ }
+ if (n == null)
+ return EMPTY_TAGS;
+
+ // Find the first parent tag
+ if (!(n instanceof Element)) {
+ if (n instanceof Attr) {
+ n = ((Attr) n).getOwnerElement();
+ } else {
+ n = n.getParentNode();
+ }
+ } else if (!includeThisTag) {
+ n = n.getParentNode();
+ }
+
+ // Store all the parents
+ while (n != null && n instanceof Element) {
+ String tagName = getTagName(n);
+ parentTags.add(0, tagName);
+ n = n.getParentNode();
+ }
+
+ return (String[])parentTags.toArray(new String[parentTags.size()]);
+ } finally {
+ if (sModel != null) {
+ sModel.releaseFromRead();
+ }
+ }
+ }
+
+ protected String getTagName(Node tag) {
+ return tag.getNodeName();
+ }
+
+ /**
+ * Returns name of the parent attribute/tag name
+ *
+ * @return
+ */
+ protected String getParent(boolean returnAttributeName, boolean returnThisElement) {
+ IStructuredModel sModel = StructuredModelManager
+ .getModelManager()
+ .getExistingModelForRead(getDocument());
+ try {
+ if (sModel == null)
+ return null;
+
+ Document xmlDocument = (sModel instanceof IDOMModel)
+ ? ((IDOMModel) sModel).getDocument()
+ : null;
+
+ if (xmlDocument == null)
+ return null;
+
+ Node n = null;
+ if (returnAttributeName) {
+ n = findNodeForOffset(xmlDocument, getOffset());
+ } else {
+ // Get Fixed Structured Document Region
+ IStructuredDocumentRegion sdFixedRegion = this.getStructuredDocumentRegion(getOffset());
+ if (sdFixedRegion == null)
+ return null;
+
+ n = findNodeForOffset(xmlDocument, sdFixedRegion.getStartOffset());
+ }
+
+ if (n == null)
+ return null;
+
+ // Find the first parent tag
+ if (!(n instanceof Element)) {
+ if (n instanceof Attr) {
+ if (returnAttributeName) {
+ String parentAttrName = n.getNodeName();
+ return parentAttrName;
+ }
+ n = ((Attr) n).getOwnerElement();
+ } else {
+ n = n.getParentNode();
+ }
+ } else {
+ if (!returnThisElement)
+ n = n.getParentNode();
+ }
+ if (n == null)
+ return null;
+
+ String parentTagName = getTagName(n);
+ return parentTagName;
+ } finally {
+ if (sModel != null) {
+ sModel.releaseFromRead();
+ }
+ }
+ }
+
+ /**
+ * Returns URI for the current/parent tag
+ * @return
+ */
+ public String getTagPrefix() {
+ IStructuredModel sModel = StructuredModelManager
+ .getModelManager()
+ .getExistingModelForRead(getDocument());
+ try {
+ if (sModel == null)
+ return null;
+
+ Document xmlDocument = (sModel instanceof IDOMModel)
+ ? ((IDOMModel) sModel).getDocument()
+ : null;
+
+ if (xmlDocument == null)
+ return null;
+
+ // Get Fixed Structured Document Region
+ IStructuredDocumentRegion sdFixedRegion = this.getStructuredDocumentRegion(getOffset());
+ if (sdFixedRegion == null)
+ return null;
+
+ Node n = findNodeForOffset(xmlDocument, sdFixedRegion.getStartOffset());
+ if (n == null)
+ return null;
+
+
+ if (!(n instanceof Element) && !(n instanceof Attr))
+ return null;
+
+ if (n instanceof Attr) {
+ n = ((Attr) n).getOwnerElement();
+ }
+
+ if (n == null)
+ return null;
+
+ String nodePrefix = ((Element)n).getPrefix();
+ return nodePrefix;
+ } finally {
+ if (sModel != null) {
+ sModel.releaseFromRead();
+ }
+ }
+ }
+
+ /**
+ * Returns URI for the current/parent tag
+ * @return
+ */
+ public String getTagUri() {
+ String nodePrefix = getTagPrefix();
+ return getUri(nodePrefix);
+ }
+
+ /**
+ * Returns URI string for the prefix specified using the namespaces collected for
+ * the {@link IPageContext} context.
+ *
+ * @Override org.jboss.tools.jst.jsp.contentassist.AbstractXMLContentAssistProcessor#getUri(String)
+ */
+ protected String getUri(String prefix) {
+ return null;
+ }
+
+ /**
+ * Returns the document position where the CA is invoked
+ * @return
+ */
+ protected int getOffset() {
+ return fCurrentContext.getInvocationOffset();
+ }
+
+
+ /**
+ * Returns the document
+ *
+ * @return
+ */
+ protected IDocument getDocument() {
+ return fCurrentContext.getDocument();
+ }
+
+ /**
+ * Returns IFile resource of the document
+ *
+ * @return
+ */
+ protected IFile getResource() {
+ IStructuredModel sModel = StructuredModelManager.getModelManager().getExistingModelForRead(getDocument());
+ try {
+ if (sModel != null) {
+ String baseLocation = sModel.getBaseLocation();
+ IPath location = new Path(baseLocation).makeAbsolute();
+ return FileBuffers.getWorkspaceFileAtLocation(location);
+ }
+ }
+ finally {
+ if (sModel != null) {
+ sModel.releaseFromRead();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the <code>org.jboss.tools.common.el.core.resolver.ELContext</code> instance
+ *
+ * @return
+ */
+ protected ELContext getContext() {
+ return this.fContext;
+ }
+
+
+ /**
+ * Returns EL Prefix Text Region Information Object
+ *
+ * @return
+ */
+ protected TextRegion getELPrefix(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.trim().endsWith(String.valueOf(quoteChar))) {
+ hasCloseQuote = true;
+ }
+ }
+
+ int inValueOffset = getOffset() - 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 : inValueOffset - ie.getStartPosition(), ie == null ? "" : ie.getText(), //$NON-NLS-1$
+ isELStarted, isELClosed,
+ isAttributeValue, hasOpenQuote, hasCloseQuote, quoteChar);
+
+ return tr;
+ }
+
+ /**
+ * Returns EL Predicate Text Region Information Object
+ *
+ *
+ * @return
+ */
+ protected TextRegion getELPredicatePrefix(ContentAssistRequest request) {
+ if (request == null || request.getRegion() == null)
+ return null;
+
+ IStructuredDocumentRegion documentRegion = request.getDocumentRegion();
+ ITextRegion completionRegion = request.getRegion();
+ String regionType = completionRegion.getType();
+
+ if (DOMRegionContext.XML_END_TAG_OPEN.equals(regionType) || DOMRegionContext.XML_TAG_OPEN.equals(regionType)) {
+ documentRegion = documentRegion.getPrevious();
+ completionRegion = getCompletionRegion(request.getDocumentRegion().getStartOffset() + request.getRegion().getStart() - 1, request.getParent());
+ }
+ if (!DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE.equals(completionRegion.getType()) &&
+ !DOMRegionContext.XML_CONTENT.equals(completionRegion.getType()) &&
+ !DOMRegionContext.BLOCK_TEXT.equals(completionRegion.getType())) {
+ return null;
+ }
+ String text = documentRegion.getFullText(completionRegion);
+ int startOffset = documentRegion.getStartOffset() + completionRegion.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.trim().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);
+ }
+
+ /**
+ * The reason of overriding is that the method returns wrong region in case of incomplete tag (a tag with no '>'-closing char)
+ * In this case we have to return that previous incomplete tag instead of the current tag)
+ */
+ public IStructuredDocumentRegion getStructuredDocumentRegion(int pos) {
+ IStructuredDocumentRegion sdRegion = null;
+
+ int lastOffset = pos;
+ IStructuredDocument doc = (IStructuredDocument) getDocument();
+ if (doc == null)
+ return null;
+
+ do {
+ sdRegion = doc.getRegionAtCharacterOffset(lastOffset);
+ if (sdRegion != null) {
+ ITextRegion region = sdRegion.getRegionAtCharacterOffset(lastOffset);
+ if (region != null && region.getType() == DOMRegionContext.XML_TAG_OPEN &&
+ sdRegion.getStartOffset(region) == lastOffset) {
+ // The offset is at the beginning of the region
+ if ((sdRegion.getStartOffset(region) == sdRegion.getStartOffset()) && (sdRegion.getPrevious() != null) && (!sdRegion.getPrevious().isEnded())) {
+ // Is the region also the start of the node? If so, the
+ // previous IStructuredDocumentRegion is
+ // where to look for a useful region.
+// sdRegion = sdRegion.getPrevious();
+ sdRegion = null;
+ }
+ else {
+ // Is there no separating whitespace from the previous region?
+ // If not,
+ // then that region is the important one
+ ITextRegion previousRegion = sdRegion.getRegionAtCharacterOffset(lastOffset - 1);
+ if ((previousRegion != null) && (previousRegion != region) && (previousRegion.getTextLength() == previousRegion.getLength())) {
+// sdRegion = sdRegion.getPrevious();
+ sdRegion = null;
+ }
+ }
+ }
+ }
+ lastOffset--;
+ } while (sdRegion == null && lastOffset >= 0);
+ return sdRegion;
+ }
+
+ /**
+ * The reason of overriding is that the method returns wrong region in case of incomplete tag (a tag with no '>'-closing char)
+ * In this case we have to return that previous incomplete tag instead of the current tag)
+ */
+ protected ITextRegion getCompletionRegion(int documentPosition, Node domnode) {
+ if (domnode == null) {
+ return null;
+ }
+ // Get the original WTP Structured Document Region
+ IStructuredDocumentRegion sdNormalRegion = ContentAssistUtils.getStructuredDocumentRegion(fCurrentContext.getViewer(), documentPosition);
+ // Get Fixed Structured Document Region
+ IStructuredDocumentRegion sdFixedRegion = this.getStructuredDocumentRegion(documentPosition);
+
+ // If original and fixed regions are different we have to replace domnode with its parent node
+ if (sdFixedRegion != null && !sdFixedRegion.equals(sdNormalRegion)) {
+ Node prevnode = domnode.getParentNode();
+ if (prevnode != null) {
+ domnode = prevnode;
+ }
+ }
+
+ return getSuperCompletionRegion(documentPosition, domnode);
+ }
+
+ /**
+ * Return the region whose content's require completion. This is something
+ * of a misnomer as sometimes the user wants to be prompted for contents
+ * of a non-existant ITextRegion, such as for enumerated attribute values
+ * following an '=' sign.
+ */
+ private ITextRegion getSuperCompletionRegion(int documentPosition, Node domnode) {
+ if (domnode == null) {
+ return null;
+ }
+
+ ITextRegion region = null;
+ int offset = documentPosition;
+ IStructuredDocumentRegion flatNode = null;
+ IDOMNode node = (IDOMNode) domnode;
+
+ if (node.getNodeType() == Node.DOCUMENT_NODE) {
+ if (node.getStructuredDocument().getLength() == 0) {
+ return null;
+ }
+ ITextRegion result = node.getStructuredDocument().getRegionAtCharacterOffset(offset).getRegionAtCharacterOffset(offset);
+ while (result == null) {
+ offset--;
+ result = node.getStructuredDocument().getRegionAtCharacterOffset(offset).getRegionAtCharacterOffset(offset);
+ }
+ return result;
+ }
+
+ IStructuredDocumentRegion startTag = node.getStartStructuredDocumentRegion();
+ IStructuredDocumentRegion endTag = node.getEndStructuredDocumentRegion();
+
+ // Determine if the offset is within the start
+ // IStructuredDocumentRegion, end IStructuredDocumentRegion, or
+ // somewhere within the Node's XML content.
+ if ((startTag != null) && (startTag.getStartOffset() <= offset) && (offset < startTag.getStartOffset() + startTag.getLength())) {
+ flatNode = startTag;
+ }
+ else if ((endTag != null) && (endTag.getStartOffset() <= offset) && (offset < endTag.getStartOffset() + endTag.getLength())) {
+ flatNode = endTag;
+ }
+
+ if (flatNode != null) {
+ // the offset is definitely within the start or end tag, continue
+ // on and find the region
+ region = getCompletionRegion(offset, flatNode);
+ }
+ else {
+ // the docPosition is neither within the start nor the end, so it
+ // must be content
+ flatNode = node.getStructuredDocument().getRegionAtCharacterOffset(offset);
+ // (pa) ITextRegion refactor
+ // if (flatNode.contains(documentPosition)) {
+ if ((flatNode.getStartOffset() <= documentPosition) && (flatNode.getEndOffset() >= documentPosition)) {
+ // we're interesting in completing/extending the previous
+ // IStructuredDocumentRegion if the current
+ // IStructuredDocumentRegion isn't plain content or if it's
+ // preceded by an orphan '<'
+ if ((offset == flatNode.getStartOffset()) &&
+ (flatNode.getPrevious() != null) &&
+ (((flatNode.getRegionAtCharacterOffset(documentPosition) != null) &&
+ (flatNode.getRegionAtCharacterOffset(documentPosition).getType() != DOMRegionContext.XML_CONTENT)) ||
+ (flatNode.getPrevious().getLastRegion().getType() == DOMRegionContext.XML_TAG_OPEN) ||
+ (flatNode.getPrevious().getLastRegion().getType() == DOMRegionContext.XML_END_TAG_OPEN))) {
+
+ // Is the region also the start of the node? If so, the
+ // previous IStructuredDocumentRegion is
+ // where to look for a useful region.
+ region = flatNode.getPrevious().getLastRegion();
+ }
+ else if (flatNode.getEndOffset() == documentPosition) {
+ region = flatNode.getLastRegion();
+ }
+ else {
+ region = flatNode.getFirstRegion();
+ }
+ }
+ else {
+ // catch end of document positions where the docPosition isn't
+ // in a IStructuredDocumentRegion
+ region = flatNode.getLastRegion();
+ }
+ }
+
+ return region;
+ }
+
+
+ protected ITextRegion getCompletionRegion(int offset, IStructuredDocumentRegion sdRegion) {
+ ITextRegion region = getSuperCompletionRegion(offset, sdRegion);
+ if (region != null && region.getType() == DOMRegionContext.UNDEFINED) {
+ // FIX: JBIDE-2332 CA with proposal list for comonent's atributes doesn't work before double quotes.
+ // Sometimes, especially if we have a broken XML node, the region returned has UNDEFINED type.
+ // If so, we're try to use the prevoius region, which probably will be the region of type XML_TAG_NAME.
+
+ ITextRegion previousRegion = sdRegion.getRegionAtCharacterOffset(offset - 1);
+ if ((previousRegion != null) && (previousRegion != region) && (previousRegion.getTextLength() < previousRegion.getLength())) {
+ region = previousRegion;
+ }
+ }
+ return region;
+ }
+
+ private ITextRegion getSuperCompletionRegion(int offset, IStructuredDocumentRegion sdRegion) {
+ ITextRegion region = sdRegion.getRegionAtCharacterOffset(offset);
+ if (region == null) {
+ return null;
+ }
+
+ if (sdRegion.getStartOffset(region) == offset) {
+ // The offset is at the beginning of the region
+ if ((sdRegion.getStartOffset(region) == sdRegion.getStartOffset()) && (sdRegion.getPrevious() != null) && (!sdRegion.getPrevious().isEnded())) {
+ // Is the region also the start of the node? If so, the
+ // previous IStructuredDocumentRegion is
+ // where to look for a useful region.
+ region = sdRegion.getPrevious().getRegionAtCharacterOffset(offset - 1);
+ }
+ else {
+ // Is there no separating whitespace from the previous region?
+ // If not,
+ // then that region is the important one
+ ITextRegion previousRegion = sdRegion.getRegionAtCharacterOffset(offset - 1);
+ if ((previousRegion != null) && (previousRegion != region) && (previousRegion.getTextLength() == previousRegion.getLength())) {
+ region = previousRegion;
+ }
+ }
+ }
+ else {
+ // The offset is NOT at the beginning of the region
+ if (offset > sdRegion.getStartOffset(region) + region.getTextLength()) {
+ // Is the offset within the whitespace after the text in this
+ // region?
+ // If so, use the next region
+ ITextRegion nextRegion = sdRegion.getRegionAtCharacterOffset(sdRegion.getStartOffset(region) + region.getLength());
+ if (nextRegion != null) {
+ region = nextRegion;
+ }
+ }
+ else {
+ // Is the offset within the important text for this region?
+ // If so, then we've already got the right one.
+ }
+ }
+
+ // valid WHITE_SPACE region handler (#179924)
+ if ((region != null) && (region.getType() == DOMRegionContext.WHITE_SPACE)) {
+ ITextRegion previousRegion = sdRegion.getRegionAtCharacterOffset(sdRegion.getStartOffset(region) - 1);
+ if (previousRegion != null) {
+ region = previousRegion;
+ }
+ }
+
+ return region;
+ }
+
+}
Property changes on: trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/computers/XmlELCompletionProposalComputer.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/computers/XmlTagCompletionProposalComputer.java
===================================================================
--- trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/computers/XmlTagCompletionProposalComputer.java (rev 0)
+++ trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/computers/XmlTagCompletionProposalComputer.java 2010-08-10 14:13:05 UTC (rev 24020)
@@ -0,0 +1,683 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Exadel, Inc. and 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:
+ * Exadel, Inc. and Red Hat, Inc. - initial API and implementation
+ ******************************************************************************/
+package org.jboss.tools.jst.jsp.contentassist.computers;
+
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.text.contentassist.ICompletionProposal;
+import org.eclipse.jface.text.contentassist.IContextInformation;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.wst.dtd.core.internal.contentmodel.DTDImpl.DTDBaseAdapter;
+import org.eclipse.wst.dtd.core.internal.contentmodel.DTDImpl.DTDElementReferenceContentAdapter;
+import org.eclipse.wst.html.core.internal.contentmodel.HTMLPropertyDeclaration;
+import org.eclipse.wst.sse.core.StructuredModelManager;
+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
+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.contentassist.CompletionProposalInvocationContext;
+import org.eclipse.wst.xml.core.internal.contentmodel.CMAttributeDeclaration;
+import org.eclipse.wst.xml.core.internal.contentmodel.CMNode;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
+import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext;
+import org.eclipse.wst.xml.ui.internal.contentassist.ContentAssistRequest;
+import org.eclipse.wst.xml.ui.internal.contentassist.XMLContentModelGenerator;
+import org.eclipse.wst.xml.ui.internal.editor.XMLEditorPluginImageHelper;
+import org.eclipse.wst.xml.ui.internal.editor.XMLEditorPluginImages;
+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.el.core.resolver.ELResolver;
+import org.jboss.tools.common.el.core.resolver.ELResolverFactoryManager;
+import org.jboss.tools.common.text.TextProposal;
+import org.jboss.tools.jst.jsp.contentassist.AutoContentAssistantProposal;
+import org.jboss.tools.jst.web.kb.IPageContext;
+import org.jboss.tools.jst.web.kb.KbQuery;
+import org.jboss.tools.jst.web.kb.KbQuery.Type;
+import org.jboss.tools.jst.web.kb.PageContextFactory;
+import org.jboss.tools.jst.web.kb.PageProcessor;
+import org.jboss.tools.jst.web.kb.taglib.INameSpace;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * Tag Proposal computer for XML pages
+ *
+ * @author Jeremy
+ *
+ */
+ at SuppressWarnings("restriction")
+public class XmlTagCompletionProposalComputer extends AbstractXmlCompletionProposalComputer {
+ protected static final ICompletionProposal[] EMPTY_PROPOSAL_LIST = new ICompletionProposal[0];
+
+ @Override
+ protected XMLContentModelGenerator getContentGenerator() {
+ return new ELXMLContentModelGenerator();
+ }
+
+ @Override
+ protected boolean validModelQueryNode(CMNode node) {
+ boolean isValid = false;
+ if(node instanceof DTDElementReferenceContentAdapter) {
+ DTDElementReferenceContentAdapter content = (DTDElementReferenceContentAdapter)node;
+ if(content.getCMDocument() instanceof DTDBaseAdapter) {
+ DTDBaseAdapter dtd = (DTDBaseAdapter)content.getCMDocument();
+ //this maybe a little hacky, but it works, if you have a better idea go for it
+ String spec = dtd.getSpec();
+ isValid = spec.indexOf("html") != -1; //$NON-NLS-1$
+ }
+ } else if(node instanceof HTMLPropertyDeclaration) {
+ HTMLPropertyDeclaration propDec = (HTMLPropertyDeclaration)node;
+ isValid = !propDec.isJSP();
+ } else if (node instanceof CMAttributeDeclaration) {
+ isValid = true;
+ }
+ return isValid;
+ }
+
+
+ /**
+ * Calculates and adds the tag proposals to the Content Assist Request object
+ *
+ * @param contentAssistRequest Content Assist Request object
+ * @param childPosition the
+ */
+
+ @Override
+ protected void addTagInsertionProposals(
+ ContentAssistRequest contentAssistRequest, int childPosition, CompletionProposalInvocationContext context) {
+
+ // 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, context);
+ }
+
+ @Override
+ protected void addAttributeNameProposals(ContentAssistRequest contentAssistRequest,
+ CompletionProposalInvocationContext context) {
+ String matchString = contentAssistRequest.getMatchString();
+ String query = matchString;
+ if (query == null)
+ query = ""; //$NON-NLS-1$
+ String stringQuery = matchString;
+
+ KbQuery kbQuery = createKbQuery(Type.ATTRIBUTE_NAME, query, stringQuery);
+ TextProposal[] proposals = PageProcessor.getInstance().getProposals(kbQuery, getContext());
+
+ for (int i = 0; proposals != null && i < proposals.length; i++) {
+ TextProposal textProposal = proposals[i];
+
+ if (isExistingAttribute(textProposal.getLabel()))
+ continue;
+
+ String replacementString = textProposal.getReplacementString() + "=\"\""; //$NON-NLS-1$
+
+ int replacementOffset = contentAssistRequest.getReplacementBeginPosition();
+ int replacementLength = contentAssistRequest.getReplacementLength();
+ int cursorPosition = getCursorPositionForProposedText(replacementString);
+ Image image = textProposal.getImage();
+ if (image == null) {
+ image = XMLEditorPluginImageHelper.getInstance().getImage(XMLEditorPluginImages.IMG_OBJ_ATTRIBUTE);
+ }
+
+ String displayString = textProposal.getLabel() == null ?
+ replacementString :
+ textProposal.getLabel();
+ IContextInformation contextInformation = null;
+ String additionalProposalInfo = textProposal.getContextInfo();
+ int relevance = textProposal.getRelevance();
+
+ AutoContentAssistantProposal proposal = new AutoContentAssistantProposal(true, replacementString,
+ replacementOffset, replacementLength, cursorPosition, image, displayString,
+ contextInformation, additionalProposalInfo, relevance);
+
+ contentAssistRequest.addProposal(proposal);
+ }
+ }
+
+ /*
+ * Checks if the specified attribute exists
+ *
+ * @param attrName Name of attribute to check
+ */
+ protected boolean isExistingAttribute(String attrName) {
+ IStructuredModel sModel = StructuredModelManager.getModelManager()
+ .getExistingModelForRead(getDocument());
+ try {
+ if (sModel == null)
+ return false;
+
+ Document xmlDocument = (sModel instanceof IDOMModel) ? ((IDOMModel) sModel)
+ .getDocument()
+ : null;
+
+ if (xmlDocument == null)
+ return false;
+
+ // Get Fixed Structured Document Region
+ IStructuredDocumentRegion sdFixedRegion = this.getStructuredDocumentRegion(getOffset());
+ if (sdFixedRegion == null)
+ return false;
+
+ Node n = findNodeForOffset(xmlDocument, sdFixedRegion.getStartOffset());
+ if (n == null)
+ return false;
+
+ // Find the first parent tag
+ if (!(n instanceof Element)) {
+ if (n instanceof Attr) {
+ n = ((Attr) n).getOwnerElement();
+ } else {
+ return false;
+ }
+ }
+
+ if (n == null)
+ return false;
+
+ String existingAttributeName = ((Element)n).getAttribute(attrName);
+ return (existingAttributeName != null && existingAttributeName.length() > 0);
+ } finally {
+ if (sModel != null) {
+ sModel.releaseFromRead();
+ }
+ }
+ }
+
+ @Override
+ protected void addAttributeValueProposals(
+ ContentAssistRequest contentAssistRequest,
+ CompletionProposalInvocationContext context) {
+
+ fCurrentContext = context;
+
+ // 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;
+ }
+
+ String matchString = contentAssistRequest.getMatchString();
+ String query = matchString;
+ if (query == null)
+ query = ""; //$NON-NLS-1$
+ String stringQuery = matchString;
+
+ 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 = contentAssistRequest.getReplacementBeginPosition();
+ int replacementLength = contentAssistRequest.getReplacementLength();
+ if(textProposal.getStart() >= 0 && textProposal.getEnd() >= 0) {
+ replacementOffset += textProposal.getStart() + 1;
+ replacementLength = textProposal.getEnd() - textProposal.getStart();
+ }
+ String replacementString = "\"" + textProposal.getReplacementString() + "\""; //$NON-NLS-1$ //$NON-NLS-2$
+ if(textProposal.getStart() >= 0 && textProposal.getEnd() >= 0) {
+ replacementString = textProposal.getReplacementString();
+ }
+ int cursorPosition = getCursorPositionForProposedText(replacementString);
+ Image image = textProposal.getImage();
+ String displayString = textProposal.getLabel() == null ?
+ replacementString :
+ textProposal.getLabel();
+ IContextInformation contextInformation = null;
+ String additionalProposalInfo = textProposal.getContextInfo();
+ int relevance = textProposal.getRelevance();
+ if (relevance == TextProposal.R_NONE) {
+ relevance = TextProposal.R_JSP_ATTRIBUTE_VALUE;
+ }
+
+ AutoContentAssistantProposal proposal = new AutoContentAssistantProposal(replacementString,
+ replacementOffset, replacementLength, cursorPosition, image, displayString,
+ contextInformation, additionalProposalInfo, relevance);
+
+ contentAssistRequest.addProposal(proposal);
+ }
+ }
+
+ protected void addTagNameProposals(ContentAssistRequest contentAssistRequest, int childPosition,
+ CompletionProposalInvocationContext context) {
+ addTagNameProposals(contentAssistRequest, childPosition, false, context);
+ }
+ /**
+ * Calculates and adds the tag name proposals to the Content Assist Request object
+ *
+ * @param contentAssistRequest Content Assist Request object
+ * @param childPosition the
+ */
+ protected void addTagNameProposals(
+ ContentAssistRequest contentAssistRequest,
+ int childPosition, boolean insertTagOpenningCharacter,
+ CompletionProposalInvocationContext context) {
+
+ String mainPrefix = getTagPrefix();
+ String mainURI = getTagUri();
+
+ String query = contentAssistRequest.getMatchString();
+ addTagNameProposalsForPrefix(contentAssistRequest, childPosition, query, mainPrefix, mainURI, TextProposal.R_TAG_INSERTION, insertTagOpenningCharacter);
+
+ if (query == null || query.length() == 0 || query.contains(":")) //$NON-NLS-1$
+ return;
+
+ // Make an additional proposals to allow prefixed tags to be entered with no prefix typed
+ ELContext elContext = getContext();
+ if (elContext instanceof IPageContext) {
+ IPageContext pageContext = (IPageContext)elContext;
+ Map<String, List<INameSpace>> nsMap = pageContext.getNameSpaces(contentAssistRequest.getReplacementBeginPosition());
+ if (nsMap == null) return;
+
+ for (List<INameSpace> namespaces : nsMap.values()) {
+ if (namespaces == null) continue;
+
+ for (INameSpace namespace : namespaces) {
+ String possiblePrefix = namespace.getPrefix();
+ if (possiblePrefix == null || possiblePrefix.length() == 0)
+ continue; // Don't query proposals for the default value here
+
+ String possibleURI = namespace.getURI();
+ String possibleQuery = namespace.getPrefix() + ":" + query; //$NON-NLS-1$
+ addTagNameProposalsForPrefix(contentAssistRequest, childPosition,
+ possibleQuery, possiblePrefix, possibleURI,
+ TextProposal.R_TAG_INSERTION - 1,
+ insertTagOpenningCharacter);
+ }
+ }
+ }
+ }
+
+ private void addTagNameProposalsForPrefix(
+ ContentAssistRequest contentAssistRequest,
+ int childPosition,
+ String query,
+ String prefix,
+ String uri,
+ int defaultRelevance,
+ boolean insertTagOpenningCharacter) {
+ if (query == null)
+ query = ""; //$NON-NLS-1$
+ String stringQuery = "<" + query; //$NON-NLS-1$
+
+ KbQuery kbQuery = createKbQuery(Type.TAG_NAME, query, stringQuery, prefix, uri);
+ TextProposal[] proposals = PageProcessor.getInstance().getProposals(kbQuery, getContext());
+
+ for (int i = 0; proposals != null && i < proposals.length; i++) {
+ TextProposal textProposal = proposals[i];
+
+ String replacementString = textProposal.getReplacementString();
+ String closingTag = textProposal.getLabel();
+ if (closingTag != null && closingTag.startsWith("<")) { //$NON-NLS-1$
+ closingTag = closingTag.substring(1);
+ }
+
+ if (!insertTagOpenningCharacter && replacementString.startsWith("<")) { //$NON-NLS-1$
+ // Because the tag starting char is already in the text
+ replacementString = replacementString.substring(1);
+ }
+ if (!replacementString.endsWith("/>")) { //$NON-NLS-1$
+ replacementString += "</" + closingTag + ">"; //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+
+ int replacementOffset = contentAssistRequest.getReplacementBeginPosition();
+ int replacementLength = contentAssistRequest.getReplacementLength();
+ int cursorPosition = getCursorPositionForProposedText(replacementString);
+ Image image = textProposal.getImage();
+ if (image == null) {
+ image = XMLEditorPluginImageHelper.getInstance().getImage(XMLEditorPluginImages.IMG_OBJ_TAG_GENERIC);
+ }
+
+ String displayString = closingTag;
+ IContextInformation contextInformation = null;
+ String additionalProposalInfo = textProposal.getContextInfo();
+ int relevance = textProposal.getRelevance();
+ if (relevance == TextProposal.R_NONE) {
+ relevance = defaultRelevance == TextProposal.R_NONE? TextProposal.R_TAG_INSERTION : defaultRelevance;
+ }
+
+ AutoContentAssistantProposal proposal = new AutoContentAssistantProposal(true, replacementString,
+ replacementOffset, replacementLength, cursorPosition, image, displayString,
+ contextInformation, additionalProposalInfo, relevance);
+
+ contentAssistRequest.addProposal(proposal);
+ }
+ }
+
+ @Override
+ protected void addAttributeValueELProposals(ContentAssistRequest contentAssistRequest,
+ CompletionProposalInvocationContext context) {
+ // No EL proposals are to be added here
+ }
+
+
+ protected void addTextELProposals(ContentAssistRequest contentAssistRequest,
+ CompletionProposalInvocationContext context) {
+ // No EL proposals are to be added here
+ }
+
+ protected ELContext createContext() {
+ return PageContextFactory.createPageContext(getResource(), PageContextFactory.XML_PAGE_CONTEXT_TYPE);
+ }
+
+ protected KbQuery createKbQuery(Type type, String query, String stringQuery) {
+ return createKbQuery(type, query, stringQuery, getTagPrefix(), getTagUri());
+ }
+
+ protected KbQuery createKbQuery(Type type, String query, String stringQuery, String prefix, String uri) {
+ KbQuery kbQuery = new KbQuery();
+
+ String[] parentTags = getParentTags(type == Type.ATTRIBUTE_NAME || type == Type.ATTRIBUTE_VALUE);
+ String parent = getParent(type == Type.ATTRIBUTE_VALUE, type == Type.ATTRIBUTE_NAME);
+ String queryValue = query;
+ String queryStringValue = stringQuery;
+
+ kbQuery.setPrefix(prefix);
+ kbQuery.setUri(uri);
+ kbQuery.setParentTags(parentTags);
+ kbQuery.setParent(parent);
+ kbQuery.setMask(true);
+ kbQuery.setType(type);
+ kbQuery.setOffset(fCurrentContext.getInvocationOffset());
+ kbQuery.setValue(queryValue);
+ kbQuery.setStringQuery(queryStringValue);
+
+ return kbQuery;
+ }
+
+
+ /**
+ * this is the position the cursor should be in after the proposal is
+ * applied
+ *
+ * @param proposedText
+ * @return the position the cursor should be in after the proposal is
+ * applied
+ */
+ protected static int getCursorPositionForProposedText(String proposedText) {
+ int cursorAdjustment;
+ cursorAdjustment = proposedText.indexOf("\"\"") + 1; //$NON-NLS-1$
+ // otherwise, after the first tag
+ if (cursorAdjustment == 0) {
+ cursorAdjustment = proposedText.indexOf('>') + 1;
+ }
+ if (cursorAdjustment == 0) {
+ cursorAdjustment = proposedText.length();
+ }
+
+ return cursorAdjustment;
+ }
+
+ /**
+ * Returns array of the <code>org.jboss.tools.common.el.core.resolver.ELResolver</code>
+ * instances.
+ *
+ * @param resource
+ * @return
+ */
+ protected ELResolver[] getELResolvers(IResource resource) {
+ if (resource == null)
+ return null;
+
+ ELResolverFactoryManager elrfm = ELResolverFactoryManager.getInstance();
+ return elrfm.getResolvers(resource);
+ }
+
+ /**
+ * Returns URI for the current/parent tag
+ * @return
+ */
+ public String getTagUri() {
+ String nodePrefix = getTagPrefix();
+ return getUri(nodePrefix);
+ }
+
+ /**
+ * Returns URI string for the prefix specified using the namespaces collected for
+ * the {@link IPageContext} context.
+ *
+ * @Override org.jboss.tools.jst.jsp.contentassist.AbstractXMLContentAssistProcessor#getUri(String)
+ */
+ protected String getUri(String prefix) {
+ return null;
+ }
+
+ /**
+ * Returns EL Prefix Text Region Information Object
+ *
+ * @return
+ */
+ protected TextRegion getELPrefix(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.trim().endsWith(String.valueOf(quoteChar))) {
+ hasCloseQuote = true;
+ }
+ }
+
+ int inValueOffset = getOffset() - 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 : inValueOffset - ie.getStartPosition(), ie == null ? "" : ie.getText(), //$NON-NLS-1$
+ isELStarted, isELClosed,
+ isAttributeValue, hasOpenQuote, hasCloseQuote, quoteChar);
+
+ return tr;
+ }
+
+ /**
+ * Returns EL Predicate Text Region Information Object
+ *
+ *
+ * @return
+ */
+ protected TextRegion getELPredicatePrefix(ContentAssistRequest request) {
+ if (request == null || request.getRegion() == null)
+ return null;
+
+ IStructuredDocumentRegion documentRegion = request.getDocumentRegion();
+ ITextRegion completionRegion = request.getRegion();
+ String regionType = completionRegion.getType();
+
+ if (DOMRegionContext.XML_END_TAG_OPEN.equals(regionType) || DOMRegionContext.XML_TAG_OPEN.equals(regionType)) {
+ documentRegion = documentRegion.getPrevious();
+ completionRegion = getCompletionRegion(request.getDocumentRegion().getStartOffset() + request.getRegion().getStart() - 1, request.getParent());
+ }
+ if (!DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE.equals(completionRegion.getType()) &&
+ !DOMRegionContext.XML_CONTENT.equals(completionRegion.getType()) &&
+ !DOMRegionContext.BLOCK_TEXT.equals(completionRegion.getType())) {
+ return null;
+ }
+ String text = documentRegion.getFullText(completionRegion);
+ int startOffset = documentRegion.getStartOffset() + completionRegion.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.trim().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);
+ }
+
+ public static class ELXMLContentModelGenerator extends XMLContentModelGenerator {
+
+ }
+
+ public static class TextRegion {
+ private int startOffset;
+ private int offset;
+ private int length;
+ private String text;
+ private boolean isELStarted;
+ private boolean isELClosed;
+ private boolean isAttributeValue;
+ private boolean hasOpenQuote;
+ private boolean hasCloseQuote;
+ private char quoteChar;
+
+ TextRegion(int startOffset, int offset, int length, String text, boolean isELStarted, boolean isELClosed) {
+ this(startOffset, offset, length, text, isELStarted, isELClosed, false, false, false, (char)0);
+ }
+
+ public TextRegion(int startOffset, int offset, int length, String text, boolean isELStarted, boolean isELClosed,
+ boolean isAttributeValue, boolean hasOpenQuote, boolean hasCloseQuote, char quoteChar) {
+ this.startOffset = startOffset;
+ this.offset = offset;
+ this.length = length;
+ this.text = text;
+ this.isELStarted = isELStarted;
+ this.isELClosed = isELClosed;
+ this.isAttributeValue = isAttributeValue;
+ this.hasOpenQuote = hasOpenQuote;
+ this.hasCloseQuote = hasCloseQuote;
+ this.quoteChar = quoteChar;
+ }
+
+ public int getStartOffset() {
+ return startOffset;
+ }
+
+ public int getOffset() {
+ return offset;
+ }
+
+ public int getLength() {
+ return length;
+ }
+
+ public String getText() {
+ StringBuffer sb = new StringBuffer(length);
+ sb = sb.append(text.substring(0, length));
+ sb.setLength(length);
+ return sb.toString();
+ }
+
+ public boolean isELStarted() {
+ return isELStarted;
+ }
+
+ public boolean isELClosed() {
+ return isELClosed;
+ }
+
+ public boolean isAttributeValue() {
+ return isAttributeValue;
+ }
+
+ public char getQuoteChar() {
+ return quoteChar;
+ }
+
+ public boolean hasOpenQuote() {
+ return hasOpenQuote;
+ }
+
+ public boolean hasCloseQuote() {
+ return hasCloseQuote;
+ }
+ }
+
+}
+
Property changes on: trunk/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/contentassist/computers/XmlTagCompletionProposalComputer.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
More information about the jbosstools-commits
mailing list