Author: vrubezhny
Date: 2008-10-13 13:46:26 -0400 (Mon, 13 Oct 2008)
New Revision: 10801
Added:
trunk/common/plugins/org.jboss.tools.common.text.xml/src/org/jboss/tools/common/text/xml/contentassist/SortingCompoundContentAssistProcessor.java
Modified:
trunk/common/plugins/org.jboss.tools.common.text.xml/schema/contentAssistProcessor.exsd
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/ContentAssistProcessorBuilder.java
trunk/common/plugins/org.jboss.tools.common.text.xml/src/org/jboss/tools/common/text/xml/contentassist/ContentAssistProcessorDefinition.java
Log:
https://jira.jboss.org/jira/browse/JBIDE-2118 Cleanup/unify the EL code completion used in
JSF, Java, Seam completions
Modified:
trunk/common/plugins/org.jboss.tools.common.text.xml/schema/contentAssistProcessor.exsd
===================================================================
---
trunk/common/plugins/org.jboss.tools.common.text.xml/schema/contentAssistProcessor.exsd 2008-10-13
16:37:31 UTC (rev 10800)
+++
trunk/common/plugins/org.jboss.tools.common.text.xml/schema/contentAssistProcessor.exsd 2008-10-13
17:46:26 UTC (rev 10801)
@@ -74,6 +74,26 @@
</complexType>
</element>
+ <element name="contenttype">
+ <annotation>
+ <documentation>
+ Defined the editor's content type to be assotiated with the Content
Assist Processor. The value is either one of the WTP structured model content type ID or
any other structured text content type ID
+ </documentation>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="partitiontype" minOccurs="1"
maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="id" type="string"
use="required">
+ <annotation>
+ <documentation>
+ A unique ID for this contenttype. The value is either one of the WTP
structured model content type ID or any other structured text content type ID.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
<element name="partitiontype">
<annotation>
<documentation>
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 2008-10-13
16:37:31 UTC (rev 10800)
+++
trunk/common/plugins/org.jboss.tools.common.text.xml/src/org/jboss/tools/common/text/xml/XMLTextViewerConfiguration.java 2008-10-13
17:46:26 UTC (rev 10801)
@@ -26,6 +26,7 @@
import org.eclipse.wst.xml.ui.StructuredTextViewerConfigurationXML;
import org.jboss.tools.common.text.xml.contentassist.ContentAssistProcessorBuilder;
import org.jboss.tools.common.text.xml.contentassist.ContentAssistProcessorDefinition;
+import
org.jboss.tools.common.text.xml.contentassist.SortingCompoundContentAssistProcessor;
/**
* @author Igels
@@ -43,7 +44,15 @@
}
protected IContentAssistProcessor[] getContentAssistProcessors(ISourceViewer
sourceViewer, String partitionType) {
-
+
+ SortingCompoundContentAssistProcessor sortingCompoundProcessor = new
SortingCompoundContentAssistProcessor(sourceViewer, partitionType);
+ List<IContentAssistProcessor> processors = new
ArrayList<IContentAssistProcessor>();
+
+// if (sortingCompoundProcessor.size() > 0) {
+ if (sortingCompoundProcessor.supportsPartitionType(partitionType)) {
+ processors.add(sortingCompoundProcessor);
+ }
+/*
// if we have our own processors we need
// to define them in plugin.xml file of their
// plugins using extention point
@@ -53,18 +62,17 @@
if(defs==null) return null;
- List processors = new ArrayList();
for(int i=0; i<defs.length; i++) {
IContentAssistProcessor processor = defs[i].createContentAssistProcessor();
if(!processors.contains(processor)) {
processors.add(processor);
}
}
-
+*/
IContentAssistProcessor[] in = getInitialProcessors(sourceViewer, partitionType);
if(in != null && in.length > 0) {
- //we do not need super processors - make initial processors responcible for that
+ //we do not need super processors - make initial processors responsible for that
for(int i=0; i<in.length; i++) {
if(!processors.contains(in[i])) {
processors.add(in[i]);
Modified:
trunk/common/plugins/org.jboss.tools.common.text.xml/src/org/jboss/tools/common/text/xml/contentassist/ContentAssistProcessorBuilder.java
===================================================================
---
trunk/common/plugins/org.jboss.tools.common.text.xml/src/org/jboss/tools/common/text/xml/contentassist/ContentAssistProcessorBuilder.java 2008-10-13
16:37:31 UTC (rev 10800)
+++
trunk/common/plugins/org.jboss.tools.common.text.xml/src/org/jboss/tools/common/text/xml/contentassist/ContentAssistProcessorBuilder.java 2008-10-13
17:46:26 UTC (rev 10801)
@@ -12,6 +12,8 @@
package org.jboss.tools.common.text.xml.contentassist;
import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
import java.util.List;
import org.eclipse.core.runtime.IConfigurationElement;
@@ -26,6 +28,7 @@
public static final String PL_CONTENTASSISTPROCESSOR =
"contentAssistProcessor"; //$NON-NLS-1$
public static final String TAG_CONTENTASSISTPROCESSOR =
"contentAssistProcessor"; //$NON-NLS-1$
+ public static final String TAG_CONTENT_TYPE = "contenttype"; //$NON-NLS-1$
public static final String TAG_PARTITION_TYPE = "partitiontype";
//$NON-NLS-1$
public static final String ATT_ID = "id"; //$NON-NLS-1$
@@ -37,6 +40,7 @@
private List<ContentAssistProcessorDefinition> fContentAssistProcessorDefs =
null;
private ContentAssistProcessorDefinition fCurrentDefinition = null;
+ private String fCurrentDefinitionContentType = null;
/**
* returns singleton instance of ContentAssistProcessorBuilder
@@ -94,6 +98,24 @@
}
/**
+ * Processes element which should be a configuration element specifying an
+ * open on object. Creates a new ContentAssistProcessor definitio object and adds it to
the
+ * list of ContentAssistProcessor definition objects
+ *
+ * @param element ContentAssistProcessor configuration element
+ */
+ private void processContentTypeTag(IConfigurationElement element) {
+ String theId = getId(element);
+
+ if (theId != null && fCurrentDefinition != null) {
+ fCurrentDefinitionContentType = theId;
+ }
+ else {
+ fCurrentDefinitionContentType = null;
+ }
+ }
+
+ /**
* Processes element which should be a configuration element specifying a partition
* type for the current contentAssistProcessor tag. Assumes that there is a valid
* current contentAssistProcessor tag.
@@ -104,8 +126,8 @@
// add to current HyperlinkDefinition/contentType
String theId = getId(element);
- if (theId != null) {
- fCurrentDefinition.addPartitionType(theId);
+ if (theId != null && fCurrentDefinition != null &&
fCurrentDefinitionContentType != null) {
+ fCurrentDefinition.addPartitionType(fCurrentDefinitionContentType, theId);
}
}
@@ -123,6 +145,14 @@
}
return true;
}
+ else if (tag.equals(TAG_CONTENT_TYPE)) {
+ processContentTypeTag(element);
+
+ if (fCurrentDefinition != null) {
+ readElementChildren(element);
+ }
+ return true;
+ }
else if (tag.equals(TAG_PARTITION_TYPE)) {
processPartitionTypeTag(element);
return true;
@@ -147,7 +177,36 @@
(ContentAssistProcessorDefinition[])fContentAssistProcessorDefs.toArray(new
ContentAssistProcessorDefinition[fContentAssistProcessorDefs.size()]));
}
+
/**
+ * Returns all the valid ContentTypes for partitionType
+ *
+ * @param partitionType
+ * @return if partitionType is null, null is returned
+ */
+ public Collection<String> getContentAssistProcessorContentTypes(String
partitionType) {
+ if (partitionType == null) {
+ return null;
+ }
+
+ ContentAssistProcessorDefinition[] allDefs = getContentAssistProcessorDefinitions();
+ List<ContentAssistProcessorDefinition> defs = new
ArrayList<ContentAssistProcessorDefinition>();
+ List<ContentAssistProcessorDefinition> lastDefs = new
ArrayList<ContentAssistProcessorDefinition>();
+
+ HashSet<String> validContentTypes = new HashSet<String>();
+ for (int i = 0; i < allDefs.length; ++i) {
+ Collection<String> contentTypes = allDefs[i].getContentTypes();
+
+ if (contentTypes != null) {
+ validContentTypes.addAll(contentTypes);
+ }
+ }
+
+ return validContentTypes;
+ }
+
+
+ /**
* Returns all the ContentAssistProcessor definition objects valid for partitionType
*
* @param partitionType
@@ -159,26 +218,29 @@
}
ContentAssistProcessorDefinition[] allDefs = getContentAssistProcessorDefinitions();
- List defs = new ArrayList();
- List lastDefs = new ArrayList();
+ List<ContentAssistProcessorDefinition> defs = new
ArrayList<ContentAssistProcessorDefinition>();
+ List<ContentAssistProcessorDefinition> lastDefs = new
ArrayList<ContentAssistProcessorDefinition>();
for (int i = 0; i < allDefs.length; ++i) {
- List partitions = (List) allDefs[i].getPartitionTypes();
- if (partitions != null) {
- if (partitions.isEmpty()) {
- lastDefs.add(allDefs[i]);
- }
- else {
- int j = 0;
- boolean added = false;
- while (j < partitions.size() && !added) {
- if (partitionType.equals(partitions.get(j))) {
- defs.add(allDefs[i]);
- added = true;
+ for (String contentType : allDefs[i].getContentTypes()) {
+ List<String> partitions = allDefs[i].getPartitionTypes(contentType);
+
+ if (partitions != null) {
+ if (partitions.isEmpty()) {
+ lastDefs.add(allDefs[i]);
+ }
+ else {
+ int j = 0;
+ boolean added = false;
+ while (j < partitions.size() && !added) {
+ if (partitionType.equals(partitions.get(j))) {
+ defs.add(allDefs[i]);
+ added = true;
+ }
+ else {
+ ++j;
+ }
}
- else {
- ++j;
- }
}
}
}
Modified:
trunk/common/plugins/org.jboss.tools.common.text.xml/src/org/jboss/tools/common/text/xml/contentassist/ContentAssistProcessorDefinition.java
===================================================================
---
trunk/common/plugins/org.jboss.tools.common.text.xml/src/org/jboss/tools/common/text/xml/contentassist/ContentAssistProcessorDefinition.java 2008-10-13
16:37:31 UTC (rev 10800)
+++
trunk/common/plugins/org.jboss.tools.common.text.xml/src/org/jboss/tools/common/text/xml/contentassist/ContentAssistProcessorDefinition.java 2008-10-13
17:46:26 UTC (rev 10801)
@@ -12,7 +12,10 @@
package org.jboss.tools.common.text.xml.contentassist;
import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
@@ -26,8 +29,8 @@
private String fId = null;
private String fClassName = null;
- // a list of partition types (String)
- private List fPartitionTypes = null;
+ // a list of content types (String)
+ private Map<String, List<String>> fContentTypes = null;
private IConfigurationElement fConfigurationElement = null;
@@ -41,12 +44,20 @@
fId = id;
fClassName = class1;
fConfigurationElement = configurationElement;
- fPartitionTypes = new ArrayList();
+ fContentTypes = new HashMap<String, List<String>>();
}
- public void addPartitionType(String partitionType) {
- if (!fPartitionTypes.contains(partitionType))
- fPartitionTypes.add(partitionType);
+ public void addPartitionType(String contentType, String partitionType) {
+ List<String> partitionTypes = new ArrayList<String>();
+
+ if (fContentTypes.containsKey(contentType)) {
+ partitionTypes = fContentTypes.get(contentType);
+ }
+
+ if (!partitionTypes.contains(partitionType)) {
+ partitionTypes.add(partitionType);
+ fContentTypes.put(contentType, partitionTypes);
+ }
}
/**
@@ -131,9 +142,18 @@
}
/**
- * @return Returns the fPartitionTypes.
+ * @return Returns the collection of ContentTypes.
*/
- public List getPartitionTypes() {
- return fPartitionTypes;
+ public Collection<String> getContentTypes() {
+ return fContentTypes.keySet();
}
+
+ /**
+ * @return Returns the list of Partition Types for the specified ContentType.
+ */
+ public List<String> getPartitionTypes(String contentType) {
+ return (fContentTypes == null || !fContentTypes.containsKey(contentType) ?
+ new ArrayList<String>(): fContentTypes.get(contentType));
+ }
+
}
Added:
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
(rev 0)
+++
trunk/common/plugins/org.jboss.tools.common.text.xml/src/org/jboss/tools/common/text/xml/contentassist/SortingCompoundContentAssistProcessor.java 2008-10-13
17:46:26 UTC (rev 10801)
@@ -0,0 +1,543 @@
+/*******************************************************************************
+ * Copyright (c) 2007 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
+ *
+ * Contributor:
+ * 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.Collection;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.TextPresentation;
+import org.eclipse.jface.text.contentassist.ICompletionProposal;
+import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
+import org.eclipse.jface.text.contentassist.IContextInformation;
+import org.eclipse.jface.text.contentassist.IContextInformationExtension;
+import org.eclipse.jface.text.contentassist.IContextInformationPresenter;
+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.internal.provisional.IModelManager;
+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
+import org.eclipse.wst.sse.core.internal.provisional.StructuredModelManager;
+
+/**
+ * Reads the plugin.xml file for the processors defined using the
+ * extention point
+ * "org.jboss.tools.common.text.xml.contentAssistProcessor"
+ *
+ * @author jeremy
+ *
+ */
+
+public class SortingCompoundContentAssistProcessor implements IContentAssistProcessor {
+ private ISourceViewer fSourceViewer;
+ private String fPartitionType;
+ private String fErrorMessage;
+
+
+ private static Map<String, Map<String, List<IContentAssistProcessor>>>
fProcessorsMap;
+
+ public SortingCompoundContentAssistProcessor(ISourceViewer sourceViewer, String
partitionType) {
+ this.fSourceViewer = sourceViewer;
+ this.fPartitionType = partitionType;
+ init();
+ }
+
+ public boolean supportsPartitionType(String partitionType) {
+ if (fProcessorsMap == null)
+ return false;
+
+ for (String contentType : fProcessorsMap.keySet()) {
+ Map<String, List<IContentAssistProcessor>> partitionTypes =
+ fProcessorsMap.get(contentType);
+ if (partitionTypes != null && partitionTypes.containsKey(partitionType))
+ return true;
+ }
+ return false;
+ }
+
+ void init () {
+ ContentAssistProcessorDefinition[] defs =
ContentAssistProcessorBuilder.getInstance().getContentAssistProcessorDefinitions(fPartitionType);
+
+ if(defs==null || defs.length == 0) return;
+
+ if (fProcessorsMap == null)
+ fProcessorsMap = new HashMap<String, Map<String,
List<IContentAssistProcessor>>>();
+
+ for(int i=0; i<defs.length; i++) {
+ IContentAssistProcessor processor = defs[i].createContentAssistProcessor();
+ Collection<String> contentTypes = defs[i].getContentTypes();
+ if (contentTypes != null) {
+ for (String contentType : contentTypes) {
+ Map<String, List<IContentAssistProcessor>> contentTypeProcessors =
+ fProcessorsMap.get(contentType);
+
+ if (contentTypeProcessors == null) {
+ contentTypeProcessors = new HashMap<String,
List<IContentAssistProcessor>>();
+ }
+
+ List<String> partitionTypes = defs[i].getPartitionTypes(contentType);
+ for (String partitionType : partitionTypes) {
+ List<IContentAssistProcessor> partitionTypeProcessors =
+ contentTypeProcessors.get(partitionType);
+
+ if (partitionTypeProcessors == null) {
+ partitionTypeProcessors = new ArrayList<IContentAssistProcessor>();
+ }
+
+ if(!containsAnObjectOfTheSameType(partitionTypeProcessors,processor)) {
+ partitionTypeProcessors.add(processor);
+ }
+
+ if (!contentTypeProcessors.containsKey(partitionType)) {
+ contentTypeProcessors.put(partitionType, partitionTypeProcessors);
+ }
+ }
+
+ if (!fProcessorsMap.containsKey(contentType)) {
+ fProcessorsMap.put(contentType, contentTypeProcessors);
+ }
+ }
+ }
+ }
+
+ }
+
+ boolean containsAnObjectOfTheSameType(Collection collection, Object obj) {
+ if (collection == null || obj == null)
+ return false;
+
+ String objClassName = obj.getClass().getName();
+ for (Object o : collection) {
+ if (objClassName.equals(o.getClass().getName()))
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Returns the content type of document
+ *
+ * @param document -
+ * assumes document is not null
+ * @return String content type of given document
+ */
+ protected String getContentType(ISourceViewer viewer) {
+ if (viewer == null || viewer.getDocument() == null)
+ return null;
+
+ String type = null;
+
+ IModelManager mgr = StructuredModelManager.getModelManager();
+ IStructuredModel model = null;
+ try {
+ model = mgr.getExistingModelForRead(viewer.getDocument());
+ if (model != null) {
+ type = model.getContentTypeIdentifier();
+ }
+ } finally {
+ if (model != null) {
+ model.releaseFromRead();
+ }
+ }
+ return type;
+ }
+
+ /**
+ * Returns a list of completion proposals based on the
+ * specified location within the document that corresponds
+ * to the current cursor position within the text viewer.
+ *
+ * @param viewer the viewer whose document is used to compute the proposals
+ * @param offset an offset within the document for which completions should be computed
+ * @return an array of completion proposals or <code>null</code> if no
proposals are possible
+ */
+ public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset)
{
+ fErrorMessage = null;
+
+ String contentType = getContentType(fSourceViewer);
+ if (contentType == null)
+ return new ICompletionProposal[0];
+
+ List<ICompletionProposal> ret = new LinkedList<ICompletionProposal>();
+
+ if (fProcessorsMap.get(contentType) == null)
+ return new ICompletionProposal[0];
+
+ if (fProcessorsMap.get(contentType).get(fPartitionType) == null)
+ return new ICompletionProposal[0];
+
+ List<IContentAssistProcessor> processors =
fProcessorsMap.get(contentType).get(fPartitionType);
+
+ for (IContentAssistProcessor p : processors) {
+ ICompletionProposal[] proposals = p.computeCompletionProposals(viewer, offset);
+ if (proposals != null && proposals.length > 0) {
+ ret.addAll(Arrays.asList(proposals));
+ fErrorMessage = null; // Hide previous errors
+ } else {
+ if (fErrorMessage == null && ret.isEmpty()) {
+ String errorMessage = p.getErrorMessage();
+ if (errorMessage != null) {
+ fErrorMessage = errorMessage;
+ }
+ }
+ }
+ }
+
+ ICompletionProposal[] resultArray = ret.toArray(new ICompletionProposal[ret.size()]);
+ // TODO: Need to improve the sorting algorithm
+/* Arrays.sort(resultArray, new Comparator<ICompletionProposal>() {
+ public int compare(ICompletionProposal arg0,
+ ICompletionProposal arg1) {
+ String str0 = (arg0 == null ? "" : arg0.getDisplayString()); //$NON-NLS-1$
+ String str1 = (arg1 == null ? "" : arg1.getDisplayString()); //$NON-NLS-1$
+ return str0.compareTo(str1);
+ }});
+*/
+
+ return resultArray;
+ }
+
+ /**
+ * Returns information about possible contexts based on the
+ * specified location within the document that corresponds
+ * to the current cursor position within the text viewer.
+ *
+ * @param viewer the viewer whose document is used to compute the possible contexts
+ * @param offset an offset within the document for which context information should be
computed
+ * @return an array of context information objects or <code>null</code> if
no context could be found
+ */
+ public IContextInformation[] computeContextInformation(ITextViewer viewer, int offset)
{
+ fErrorMessage = null;
+
+ String contentType = getContentType(fSourceViewer);
+ if (contentType == null)
+ return new IContextInformation[0];
+
+ List<IContextInformation> ret = new LinkedList<IContextInformation>();
+
+ if (fProcessorsMap.get(contentType) == null)
+ return new IContextInformation[0];
+
+ if (fProcessorsMap.get(contentType).get(fPartitionType) == null)
+ return new IContextInformation[0];
+
+ for (IContentAssistProcessor p : fProcessorsMap.get(contentType).get(fPartitionType))
{
+ IContextInformation[] informations = p.computeContextInformation(viewer, offset);
+ if (informations != null && informations.length > 0) {
+ for (int i = 0; i < informations.length; i++)
+ ret.add(new ContextInformation(informations[i], p));
+ fErrorMessage = null; // Hide previous errors
+ } else {
+ if (fErrorMessage == null && ret.isEmpty()) {
+ String errorMessage = p.getErrorMessage();
+ if (errorMessage != null) {
+ fErrorMessage = errorMessage;
+ }
+ }
+ }
+ }
+ return (IContextInformation[]) ret.toArray(new IContextInformation[ret.size()]);
+ }
+
+ /**
+ * Returns the characters which when entered by the user should
+ * automatically trigger the presentation of possible completions.
+ *
+ * @return the auto activation characters for completion proposal or
<code>null</code>
+ * if no auto activation is desired
+ */
+ public char[] getCompletionProposalAutoActivationCharacters() {
+ String contentType = getContentType(fSourceViewer);
+ if (contentType == null)
+ return new char[0];
+
+ List<Character> ret = new LinkedList<Character>();
+
+ if (fProcessorsMap.get(contentType) == null)
+ return new char[0];
+
+ if (fProcessorsMap.get(contentType).get(fPartitionType) == null)
+ return new char[0];
+
+ for (IContentAssistProcessor p : fProcessorsMap.get(contentType).get(fPartitionType))
{
+ char[] chars = p.getCompletionProposalAutoActivationCharacters();
+ if (chars != null)
+ for (int i = 0; i < chars.length; i++)
+ ret.add(new Character(chars[i]));
+ }
+
+ char[] chars = new char[ret.size()];
+ int i = 0;
+ for (Iterator it = ret.iterator(); it.hasNext(); i++) {
+ Character ch = (Character) it.next();
+ chars[i] = ch.charValue();
+ }
+ return chars;
+ }
+
+ /**
+ * Returns the characters which when entered by the user should
+ * automatically trigger the presentation of context information.
+ *
+ * @return the auto activation characters for presenting context information
+ * or <code>null</code> if no auto activation is desired
+ */
+ public char[] getContextInformationAutoActivationCharacters() {
+ String contentType = getContentType(fSourceViewer);
+ if (contentType == null)
+ return new char[0];
+
+ List<Character> ret = new LinkedList<Character>();
+
+ if (fProcessorsMap.get(contentType) == null)
+ return new char[0];
+
+ if (fProcessorsMap.get(contentType).get(fPartitionType) == null)
+ return new char[0];
+
+ for (IContentAssistProcessor p : fProcessorsMap.get(contentType).get(fPartitionType))
{
+ char[] chars = p.getContextInformationAutoActivationCharacters();
+ if (chars != null)
+ for (int i = 0; i < chars.length; i++)
+ ret.add(new Character(chars[i]));
+ }
+
+ char[] chars = new char[ret.size()];
+ int i = 0;
+ for (Iterator it = ret.iterator(); it.hasNext(); i++) {
+ Character ch = (Character) it.next();
+ chars[i] = ch.charValue();
+ }
+ return chars;
+ }
+
+ /**
+ * Returns the reason why this content assist processor
+ * was unable to produce any completion proposals or context information.
+ *
+ * @return an error message or <code>null</code> if no error occurred
+ */
+ public String getErrorMessage() {
+ return fErrorMessage;
+ }
+
+ /**
+ * Returns a validator used to determine when displayed context information
+ * should be dismissed. May only return <code>null</code> if the processor
is
+ * incapable of computing context information. <p>
+ *
+ * @return a context information validator, or <code>null</code> if the
processor
+ * is incapable of computing context information
+ */
+ public IContextInformationValidator getContextInformationValidator() {
+ boolean hasValidator = false;
+ boolean hasPresenter = false;
+ boolean hasExtension = false;
+
+
+ String contentType = getContentType(fSourceViewer);
+ if (contentType == null)
+ return null;
+
+ List<Character> ret = new LinkedList<Character>();
+
+ if (fProcessorsMap.get(contentType) == null)
+ return null;
+
+ if (fProcessorsMap.get(contentType).get(fPartitionType) == null)
+ return null;
+
+ for (IContentAssistProcessor p : fProcessorsMap.get(contentType).get(fPartitionType))
{
+ IContextInformationValidator v = p.getContextInformationValidator();
+ if (v != null) {
+ hasValidator = true;
+ if (v instanceof IContextInformationPresenter) {
+ hasPresenter = true;
+ }
+ }
+ }
+
+ SortingCompoundContentAssistValidator validator = null;
+ if (hasPresenter)
+ validator = new SortingCompoundContentAssistValidatorPresenter();
+ else if (hasValidator)
+ validator = new SortingCompoundContentAssistValidator();
+
+ if (validator != null)
+ for (IContentAssistProcessor p : fProcessorsMap.get(contentType).get(fPartitionType))
{
+ IContextInformationValidator v = p.getContextInformationValidator();
+ if (v != null)
+ validator.add(v);
+ }
+
+ return validator;
+ }
+
+
+ static class ContextInformation implements IContextInformation,
IContextInformationExtension {
+ private IContextInformation fInfo;
+ private IContentAssistProcessor fProcessor;
+
+ ContextInformation(IContextInformation info, IContentAssistProcessor processor) {
+ fInfo = info;
+ fProcessor = processor;
+ }
+
+ /*
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ public boolean equals(Object obj) {
+ return fInfo.equals(obj);
+ }
+
+ /*
+ * @see
org.eclipse.jface.text.contentassist.IContextInformation#getContextDisplayString()
+ */
+ public String getContextDisplayString() {
+ return fInfo.getContextDisplayString();
+ }
+
+ /*
+ * @see org.eclipse.jface.text.contentassist.IContextInformation#getImage()
+ */
+ public Image getImage() {
+ return fInfo.getImage();
+ }
+
+ /*
+ * @see
org.eclipse.jface.text.contentassist.IContextInformation#getInformationDisplayString()
+ */
+ public String getInformationDisplayString() {
+ return fInfo.getInformationDisplayString();
+ }
+
+ /*
+ * @see java.lang.Object#hashCode()
+ */
+ public int hashCode() {
+ return fInfo.hashCode();
+ }
+
+ /*
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ return fInfo.toString();
+ }
+
+ IContentAssistProcessor getProcessor() {
+ return fProcessor;
+ }
+
+ IContextInformation getContextInformation() {
+ return fInfo;
+ }
+
+ public int getContextInformationPosition() {
+ int position = -1;
+ if (fInfo instanceof IContextInformationExtension)
+ position = ((IContextInformationExtension)fInfo).getContextInformationPosition();
+ return position;
+ }
+ }
+
+ private static class SortingCompoundContentAssistValidator implements
IContextInformationValidator {
+ List fValidators = new ArrayList();
+ IContextInformationValidator fValidator;
+
+ void add(IContextInformationValidator validator) {
+ fValidators.add(validator);
+ }
+
+ /*
+ * @see
org.eclipse.jface.text.contentassist.IContextInformationValidator#install(org.eclipse.jface.text.contentassist.IContextInformation,
+ * org.eclipse.jface.text.ITextViewer, int)
+ */
+ public void install(IContextInformation info, ITextViewer viewer, int documentPosition)
{
+ // install either the validator in the info, or all validators
+ fValidator = getValidator(info);
+ IContextInformation realInfo = getContextInformation(info);
+ if (fValidator != null)
+ fValidator.install(realInfo, viewer, documentPosition);
+ else {
+ for (Iterator it = fValidators.iterator(); it.hasNext();) {
+ IContextInformationValidator v = (IContextInformationValidator) it.next();
+ v.install(realInfo, viewer, documentPosition);
+ }
+ }
+ }
+
+ IContextInformationValidator getValidator(IContextInformation info) {
+ if (info instanceof ContextInformation) {
+ ContextInformation wrap = (ContextInformation) info;
+ return wrap.getProcessor().getContextInformationValidator();
+ }
+
+ return null;
+ }
+
+ IContextInformation getContextInformation(IContextInformation info) {
+ IContextInformation realInfo = info;
+ if (info instanceof ContextInformation) {
+ ContextInformation wrap = (ContextInformation) info;
+ realInfo = wrap.getContextInformation();
+ }
+
+ return realInfo;
+ }
+
+ /*
+ * @see
org.eclipse.jface.text.contentassist.IContextInformationValidator#isContextInformationValid(int)
+ */
+ public boolean isContextInformationValid(int documentPosition) {
+ // use either the validator in the info, or all validators
+ boolean isValid = false;
+ if (fValidator != null)
+ isValid = fValidator.isContextInformationValid(documentPosition);
+ else {
+ for (Iterator it = fValidators.iterator(); it.hasNext();) {
+ IContextInformationValidator v = (IContextInformationValidator) it.next();
+ isValid |= v.isContextInformationValid(documentPosition);
+ }
+ }
+ return isValid;
+ }
+
+ }
+
+ private static class SortingCompoundContentAssistValidatorPresenter extends
SortingCompoundContentAssistValidator implements IContextInformationPresenter {
+ public boolean updatePresentation(int offset, TextPresentation presentation) {
+ // use either the validator in the info, or all validators
+ boolean presentationUpdated = false;
+ if (fValidator instanceof IContextInformationPresenter)
+ presentationUpdated = ((IContextInformationPresenter)
fValidator).updatePresentation(offset, presentation);
+ else {
+ for (Iterator it = fValidators.iterator(); it.hasNext();) {
+ IContextInformationValidator v = (IContextInformationValidator) it.next();
+ if (v instanceof IContextInformationPresenter)
+ presentationUpdated |= ((IContextInformationPresenter)
v).updatePresentation(offset, presentation);
+ }
+ }
+ return presentationUpdated;
+ }
+ }
+}