Bug 474405 - org.eclipse.dltk.ui.queryParticipants extension point isn't registered

Change-Id: I1c5a645277fde88f9c4664a175e18d9309e3299b
Signed-off-by: Dawid Pakuła <zulus@w3des.net>
diff --git a/core/plugins/org.eclipse.dltk.ui/plugin.xml b/core/plugins/org.eclipse.dltk.ui/plugin.xml
index bc92964..97c03dd 100644
--- a/core/plugins/org.eclipse.dltk.ui/plugin.xml
+++ b/core/plugins/org.eclipse.dltk.ui/plugin.xml
@@ -26,6 +26,7 @@
    <extension-point id="search" name="search" schema="schema/search.exsd"/>
    <extension-point id="highlighting" name="Semantic Highlighter" schema="schema/highlighting.exsd"/>
    <extension-point id="saveParticipants" name="Save Participants" schema="schema/saveParticipants.exsd"/>
+   <extension-point id="queryParticipants" name="Search Query Participants" schema="schema/queryParticipants.exsd"/>
    <extension
     	id="DLTKSearchResultPage"
         point="org.eclipse.search.searchResultViewPages">
diff --git a/core/plugins/org.eclipse.dltk.ui/schema/queryParticipants.exsd b/core/plugins/org.eclipse.dltk.ui/schema/queryParticipants.exsd
new file mode 100644
index 0000000..e4f6009
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.ui/schema/queryParticipants.exsd
@@ -0,0 +1,162 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.dltk.ui" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+      <appInfo>
+         <meta.schema plugin="org.eclipse.dltk.ui" id="queryParticipants" name="DLTK Query Participants"/>
+      </appInfo>
+      <documentation>
+         This extension point allows clients to contribute results to DLTK searches
+      </documentation>
+   </annotation>
+
+   <element name="extension">
+      <annotation>
+         <appInfo>
+            <meta.element />
+         </appInfo>
+      </annotation>
+      <complexType>
+         <sequence>
+            <element ref="queryParticipant" minOccurs="1" maxOccurs="unbounded"/>
+         </sequence>
+         <attribute name="point" type="string" use="required">
+            <annotation>
+               <documentation>
+                  a fully qualified identifier of the target extension point
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="id" type="string">
+            <annotation>
+               <documentation>
+                  an optional identifier of the extension instance
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string">
+            <annotation>
+               <documentation>
+                  an optional name of the extension instance
+               </documentation>
+               <appInfo>
+                  <meta.attribute translatable="true"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="queryParticipant">
+      <complexType>
+         <attribute name="class" type="string" use="required">
+            <annotation>
+               <documentation>
+                  the class that implements this query participant. The class must be public and implement &lt;code&gt;org.eclipse.dltk.ui.search.IQueryParticipant&lt;/code&gt; with a zero-argument constructor.
+               </documentation>
+               <appInfo>
+                  <meta.attribute kind="java" basedOn="org.eclipse.dltk.ui.search.IQueryParticipant"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+         <attribute name="id" type="string" use="required">
+            <annotation>
+               <documentation>
+                  the unique id of this query participant
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="language" type="string">
+            <annotation>
+               <documentation>
+                  the project language id this participant should be active for. If the participant should be active for multiple script project languages, multiple participants must be defined.
+               </documentation>
+               <appInfo>
+                  <meta.attribute kind="identifier" basedOn="org.eclipse.dltk.core.language/language/@nature"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string" use="required">
+            <annotation>
+               <documentation>
+                  a user readeable name for the participant
+               </documentation>
+               <appInfo>
+                  <meta.attribute translatable="true"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+         <attribute name="nature" type="string" use="required">
+            <annotation>
+               <documentation>
+                  the project nature id this participant should be active for. If the participant should be active for multiple project natures, multiple participants must be defined.
+               </documentation>
+               <appInfo>
+                  <meta.attribute kind="identifier" basedOn="org.eclipse.core.resources.natures/@id"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="since"/>
+      </appInfo>
+      <documentation>
+         5.3
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="examples"/>
+      </appInfo>
+      <documentation>
+         The following is an example of a query participant contribution:
+
+&lt;p&gt;
+&lt;pre&gt;
+   &lt;extension
+         point=&quot;org.eclipse.dltk.ui.queryParticipants&quot;&gt;
+      &lt;queryParticipant
+            name=&quot;Example Query Participant&quot;
+            nature=&quot;org.eclipse.dltk.core.scriptnature&quot;
+            class=&quot;org.eclipse.dltk.ui.example.TestParticipant&quot;
+            id=&quot;org.eclipse.dltk.ui.example.TestParticipant&quot;&gt;
+      &lt;/queryParticipant&gt;
+   &lt;/extension&gt;
+&lt;/pre&gt;
+&lt;/p&gt;
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="apiInfo"/>
+      </appInfo>
+      <documentation>
+         The contributed class must implement &lt;code&gt;org.eclipse.dltk.ui.search.IQueryParticipant&lt;/code&gt;
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="implementation"/>
+      </appInfo>
+      <documentation>
+         none
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="copyright"/>
+      </appInfo>
+      <documentation>
+         Copyright (c) 2001, 2015 IBM Corporation and others.&lt;br&gt;
+All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0 which accompanies this distribution, and is available at &lt;a href=&quot;http://www.eclipse.org/legal/epl-v10.html&quot;&gt;http://www.eclipse.org/legal/epl-v10.html&lt;/a&gt;
+      </documentation>
+   </annotation>
+
+</schema>
diff --git a/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/internal/ui/search/DLTKSearchQuery.java b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/internal/ui/search/DLTKSearchQuery.java
index 4466045..982140a 100644
--- a/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/internal/ui/search/DLTKSearchQuery.java
+++ b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/internal/ui/search/DLTKSearchQuery.java
@@ -85,7 +85,8 @@
 
 			int totalTicks= 1000;
 			IProject[] projects= DLTKSearchScopeFactory.getInstance().getProjects(fPatternData.getScope());
-			final SearchParticipantRecord[] participantDescriptors= SearchParticipantsExtensionPoint.getInstance().getSearchParticipants(projects);
+			final SearchParticipantRecord[] participantDescriptors = SearchParticipantsExtensionPoint
+					.getInstance().getSearchParticipants(this.fPatternData.getScope().getLanguageToolkit(), projects);
 			final int[] ticks= new int[participantDescriptors.length];
 			for (int i= 0; i < participantDescriptors.length; i++) {
 				final int iPrime= i;
diff --git a/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/internal/ui/search/SearchMessages.java b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/internal/ui/search/SearchMessages.java
index 3443112..7f2e559 100644
--- a/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/internal/ui/search/SearchMessages.java
+++ b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/internal/ui/search/SearchMessages.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -130,6 +130,7 @@
 	public static String DLTKSearchQuery_error_participant_search;
 	public static String SearchParticipant_error_noID;
 	public static String SearchParticipant_error_noNature;
+	public static String SearchParticipant_error_noLanguage;
 	public static String SearchParticipant_error_noClass;
 	public static String SearchParticipant_error_classCast;
 	public static String MatchFilter_WriteFilter_name;
diff --git a/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/internal/ui/search/SearchMessages.properties b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/internal/ui/search/SearchMessages.properties
index ef25519..0bbae47 100644
--- a/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/internal/ui/search/SearchMessages.properties
+++ b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/internal/ui/search/SearchMessages.properties
@@ -241,6 +241,7 @@
 
 SearchParticipant_error_noID=Missing id attribute on search participant extension {0}
 SearchParticipant_error_noNature=Missing nature attribute on search participant {0}
+SearchParticipant_error_noLanguage=Missing language attribute on search participant {0}
 SearchParticipant_error_noClass=Missing class attribute on search participant {0}
 SearchParticipant_error_classCast=Search participant doesn't implement IQueryParticipant
 
diff --git a/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/internal/ui/search/SearchParticipantDescriptor.java b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/internal/ui/search/SearchParticipantDescriptor.java
index 1a85be5..b08bd1c 100644
--- a/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/internal/ui/search/SearchParticipantDescriptor.java
+++ b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/internal/ui/search/SearchParticipantDescriptor.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -18,21 +18,21 @@
 import org.eclipse.dltk.ui.DLTKUIPlugin;
 import org.eclipse.dltk.ui.search.IQueryParticipant;
 
-
 /**
  */
 public class SearchParticipantDescriptor {
-		private static final String CLASS= "class"; //$NON-NLS-1$
-		private static final String NATURE= "nature"; //$NON-NLS-1$
-		private static final String ID= "id"; //$NON-NLS-1$
-		
-		private IConfigurationElement fConfigurationElement;
-		private boolean fEnabled; //	
-		
-		protected SearchParticipantDescriptor(IConfigurationElement configElement) {
-			fConfigurationElement= configElement;
-			fEnabled= true;
-		}
+	private static final String CLASS = "class"; //$NON-NLS-1$
+	private static final String NATURE = "nature"; //$NON-NLS-1$
+	private static final String LANGUAGE = "language"; //$NON-NLS-1$
+	private static final String ID = "id"; //$NON-NLS-1$
+
+	private IConfigurationElement fConfigurationElement;
+	private boolean fEnabled; //
+
+	protected SearchParticipantDescriptor(IConfigurationElement configElement) {
+		fConfigurationElement = configElement;
+		fEnabled = true;
+	}
 
 	/**
 	 * checks whether a participant has all the proper attributes.
@@ -41,20 +41,38 @@
 	 */
 	protected IStatus checkSyntax() {
 		if (fConfigurationElement.getAttribute(ID) == null) {
-			String format= SearchMessages.SearchParticipant_error_noID; 
-			String message= Messages.format(format,  new String[] { fConfigurationElement.getDeclaringExtension().getUniqueIdentifier() });
-			return new Status(IStatus.ERROR, DLTKUIPlugin.getPluginId(), 0, message, null);
+			String format = SearchMessages.SearchParticipant_error_noID;
+			String message = Messages
+					.format(format,
+							new String[] { fConfigurationElement
+									.getDeclaringExtension()
+									.getUniqueIdentifier() });
+			return new Status(IStatus.ERROR, DLTKUIPlugin.getPluginId(), 0,
+					message, null);
 		}
+
+		if (fConfigurationElement.getAttribute(LANGUAGE) == null) {
+			String format = SearchMessages.SearchParticipant_error_noLanguage;
+			String message = Messages.format(format,
+					new String[] { fConfigurationElement.getAttribute(ID) });
+			return new Status(IStatus.ERROR, DLTKUIPlugin.getPluginId(), 0,
+					message, null);
+		}
+
 		if (fConfigurationElement.getAttribute(NATURE) == null) {
-			String format= SearchMessages.SearchParticipant_error_noNature; 
-			String message= Messages.format(format,  new String[] { fConfigurationElement.getAttribute(ID)});
-			return new Status(IStatus.ERROR, DLTKUIPlugin.getPluginId(), 0, message, null);
+			String format = SearchMessages.SearchParticipant_error_noNature;
+			String message = Messages.format(format,
+					new String[] { fConfigurationElement.getAttribute(ID) });
+			return new Status(IStatus.ERROR, DLTKUIPlugin.getPluginId(), 0,
+					message, null);
 		}
 
 		if (fConfigurationElement.getAttribute(CLASS) == null) {
-			String format= SearchMessages.SearchParticipant_error_noClass; 
-			String message= Messages.format(format,  new String[] { fConfigurationElement.getAttribute(ID)});
-			return new Status(IStatus.ERROR, DLTKUIPlugin.getPluginId(), 0, message, null);
+			String format = SearchMessages.SearchParticipant_error_noClass;
+			String message = Messages.format(format,
+					new String[] { fConfigurationElement.getAttribute(ID) });
+			return new Status(IStatus.ERROR, DLTKUIPlugin.getPluginId(), 0,
+					message, null);
 		}
 		return Status.OK_STATUS;
 	}
@@ -62,20 +80,23 @@
 	public String getID() {
 		return fConfigurationElement.getAttribute(ID);
 	}
-	
+
 	public void disable() {
-		fEnabled= false;
+		fEnabled = false;
 	}
-	
+
 	public boolean isEnabled() {
 		return fEnabled;
 	}
-	
+
 	protected IQueryParticipant create() throws CoreException {
 		try {
-			return (IQueryParticipant) fConfigurationElement.createExecutableExtension(CLASS);
+			return (IQueryParticipant) fConfigurationElement
+					.createExecutableExtension(CLASS);
 		} catch (ClassCastException e) {
-			throw new CoreException(new Status(IStatus.ERROR, DLTKUIPlugin.getPluginId(), 0, SearchMessages.SearchParticipant_error_classCast, e)); 
+			throw new CoreException(new Status(IStatus.ERROR,
+					DLTKUIPlugin.getPluginId(), 0,
+					SearchMessages.SearchParticipant_error_classCast, e));
 		}
 	}
 
@@ -83,5 +104,8 @@
 		return fConfigurationElement.getAttribute(NATURE);
 	}
 
+	protected String getLanguage() {
+		return fConfigurationElement.getAttribute(LANGUAGE);
+	}
 
 }
diff --git a/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/internal/ui/search/SearchParticipantsExtensionPoint.java b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/internal/ui/search/SearchParticipantsExtensionPoint.java
index 8951312..962e1b5 100644
--- a/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/internal/ui/search/SearchParticipantsExtensionPoint.java
+++ b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/internal/ui/search/SearchParticipantsExtensionPoint.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -9,9 +9,6 @@
  *******************************************************************************/
 /*
  * Created on Apr 13, 2004
- * 
- * TODO To change the template for this generated file go to Window -
- * Preferences - Script - Code Generation - Code and Comments
  */
 package org.eclipse.dltk.internal.ui.search;
 
@@ -24,24 +21,26 @@
 import org.eclipse.core.runtime.IConfigurationElement;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Platform;
+import org.eclipse.dltk.core.IDLTKLanguageToolkit;
 import org.eclipse.dltk.ui.DLTKUIPlugin;
 import org.eclipse.dltk.ui.search.ScriptSearchPage;
 
 
 public class SearchParticipantsExtensionPoint {
 
-	private Set fActiveParticipants= null;
+	private Set<SearchParticipantDescriptor> fActiveParticipants = null;
 	private static SearchParticipantsExtensionPoint fgInstance;
 
 	public boolean hasAnyParticipants() {
 		return Platform.getExtensionRegistry().getConfigurationElementsFor(ScriptSearchPage.PARTICIPANT_EXTENSION_POINT).length > 0;
 	}
 
-	private synchronized Set getAllParticipants() {
+	private synchronized Set<SearchParticipantDescriptor> getAllParticipants() {
 		if (fActiveParticipants != null)
 			return fActiveParticipants;
 		IConfigurationElement[] allParticipants= Platform.getExtensionRegistry().getConfigurationElementsFor(ScriptSearchPage.PARTICIPANT_EXTENSION_POINT);
-		fActiveParticipants= new HashSet(allParticipants.length);
+		fActiveParticipants = new HashSet<SearchParticipantDescriptor>(
+				allParticipants.length);
 		for (int i= 0; i < allParticipants.length; i++) {
 			SearchParticipantDescriptor descriptor= new SearchParticipantDescriptor(allParticipants[i]);
 			IStatus status= descriptor.checkSyntax();
@@ -54,12 +53,15 @@
 		return fActiveParticipants;
 	}
 
-	private void collectParticipants(Set participants, IProject[] projects) {
-		Iterator activeParticipants= getAllParticipants().iterator();
-		Set seenParticipants= new HashSet();
+	private void collectParticipants(IDLTKLanguageToolkit language,
+			Set<SearchParticipantRecord> participants,
+			IProject[] projects) {
+		Iterator<SearchParticipantDescriptor> activeParticipants = getAllParticipants()
+				.iterator();
+		Set<String> seenParticipants = new HashSet<String>();
 		while (activeParticipants.hasNext()) {
-			SearchParticipantDescriptor participant= (SearchParticipantDescriptor) activeParticipants.next();
-			if (participant.isEnabled()) {
+			SearchParticipantDescriptor participant = activeParticipants.next();
+			if (participant.isEnabled() && language.getNatureId().equals(participant.getLanguage())) {
 				String id= participant.getID();
 				for (int i= 0; i < projects.length; i++) {
 					if (seenParticipants.contains(id))
@@ -80,11 +82,12 @@
 
 
 
-	public SearchParticipantRecord[] getSearchParticipants(IProject[] concernedProjects) throws CoreException {
-		Set participantSet= new HashSet();
-		collectParticipants(participantSet, concernedProjects);
-		SearchParticipantRecord[] participants= new SearchParticipantRecord[participantSet.size()];
-		return (SearchParticipantRecord[]) participantSet.toArray(participants);
+	public SearchParticipantRecord[] getSearchParticipants(
+			IDLTKLanguageToolkit language, IProject[] concernedProjects)
+					throws CoreException {
+		Set<SearchParticipantRecord> participantSet = new HashSet<SearchParticipantRecord>();
+		collectParticipants(language, participantSet, concernedProjects);
+		return participantSet.toArray(new SearchParticipantRecord[participantSet.size()]);
 	}
 
 	public static synchronized SearchParticipantsExtensionPoint getInstance() {