[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