diff --git a/eclipse/tern.eclipse.ide.core/plugin.properties b/eclipse/tern.eclipse.ide.core/plugin.properties
index 44e62c2ad..8e1e58b7c 100644
--- a/eclipse/tern.eclipse.ide.core/plugin.properties
+++ b/eclipse/tern.eclipse.ide.core/plugin.properties
@@ -14,6 +14,7 @@ providerName=Angelo ZERR
# Extension point
ternServerTypes.name=Tern Server Types.
ternConsoleConnectors.name=Tern Console Connectors.
+ternServerAdapters.name=Tern Nature Adapters
# Nature
ternNature.name=Tern Nature
diff --git a/eclipse/tern.eclipse.ide.core/plugin.xml b/eclipse/tern.eclipse.ide.core/plugin.xml
index c11ceba9d..aeefb7482 100644
--- a/eclipse/tern.eclipse.ide.core/plugin.xml
+++ b/eclipse/tern.eclipse.ide.core/plugin.xml
@@ -18,6 +18,8 @@
schema="schema/ternServerTypes.exsd" />
+
diff --git a/eclipse/tern.eclipse.ide.core/schema/ternNatureAdapters.exsd b/eclipse/tern.eclipse.ide.core/schema/ternNatureAdapters.exsd
new file mode 100644
index 000000000..ce47bb0b3
--- /dev/null
+++ b/eclipse/tern.eclipse.ide.core/schema/ternNatureAdapters.exsd
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+ Extension point to provide Natures that are to be treated as the Tern ones.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ a fully-qualified name of the target extension point
+
+
+
+
+
+
+ an optional id
+
+
+
+
+
+
+ an optional name
+
+
+
+
+
+
+
+
+
+
+
+ ID of the Nature to be treated as the Tern one
+
+
+
+
+
+
+ an optional name
+
+
+
+
+
+
+
+
+
+
+
+ 2.0
+
+
+
+
+
+
+
+
+
+
+ This plugin itself does not have any predefined builders.
+
+
+
+
+
diff --git a/eclipse/tern.eclipse.ide.core/src/tern/eclipse/ide/core/IDETernProject.java b/eclipse/tern.eclipse.ide.core/src/tern/eclipse/ide/core/IDETernProject.java
index b4f069d87..59351dce8 100644
--- a/eclipse/tern.eclipse.ide.core/src/tern/eclipse/ide/core/IDETernProject.java
+++ b/eclipse/tern.eclipse.ide.core/src/tern/eclipse/ide/core/IDETernProject.java
@@ -23,7 +23,10 @@
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.text.BadLocationException;
@@ -79,6 +82,8 @@ public class IDETernProject extends TernProject {
private static final QualifiedName TERN_PROJECT = new QualifiedName(
TernCorePlugin.PLUGIN_ID + ".sessionprops", "TernProject");
+ private static final String EXTENSION_TERN_PROJECT_DESCRIBERS = "ternNatureAdapters";
+
private final IProject project;
private ITernServer ternServer;
@@ -91,6 +96,8 @@ public class IDETernProject extends TernProject {
private final List listeners;
+ private static List ternNatureAdapters;
+
IDETernProject(IProject project) throws CoreException {
super(project.getLocation().toFile());
this.project = project;
@@ -184,11 +191,18 @@ public boolean isTernServerDisposed() {
*/
public static boolean hasTernNature(IProject project) {
try {
- return project.hasNature(TernNature.ID);
+ if (project.hasNature(TernNature.ID))
+ return true;
+
+ loadTernProjectDescribers();
+ for (String adaptToNature : ternNatureAdapters) {
+ if (project.hasNature(adaptToNature))
+ return true;
+ }
} catch (CoreException e) {
Trace.trace(Trace.SEVERE, "Error tern nature", e);
- return false;
}
+ return false;
}
@Override
@@ -240,7 +254,48 @@ private void loadIDEInfos() {
}
}
+
+ private static void loadTernProjectDescribers() {
+ if (ternNatureAdapters != null)
+ return;
+
+ Trace.trace(Trace.EXTENSION_POINT,
+ "->- Loading .ternProjectDescribers extension point ->-");
+
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+ IConfigurationElement[] cf = registry.getConfigurationElementsFor(
+ TernCorePlugin.PLUGIN_ID, EXTENSION_TERN_PROJECT_DESCRIBERS);
+ List list = new ArrayList(
+ cf.length);
+ addTernNatureAdapters(cf, list);
+ ternNatureAdapters = list;
+
+ Trace.trace(Trace.EXTENSION_POINT,
+ "-<- Done loading .ternProjectDescribers extension point -<-");
+ }
+
+ /**
+ * Load the tern project describers.
+ */
+ private static synchronized void addTernNatureAdapters(
+ IConfigurationElement[] cf, List list) {
+ for (IConfigurationElement ce : cf) {
+ try {
+ list.add(ce.getAttribute("id"));
+ Trace.trace(
+ Trace.EXTENSION_POINT,
+ " Loaded project describer: "
+ + ce.getAttribute("id"));
+ } catch (Throwable t) {
+ Trace.trace(
+ Trace.SEVERE,
+ " Could not load project describers: "
+ + ce.getAttribute("id"), t);
+ }
+ }
+ }
+
/**
* Returns the resource of the given path and type.
*
diff --git a/eclipse/tern.eclipse.ide.ui/META-INF/MANIFEST.MF b/eclipse/tern.eclipse.ide.ui/META-INF/MANIFEST.MF
index 1f8c38466..de3e94deb 100644
--- a/eclipse/tern.eclipse.ide.ui/META-INF/MANIFEST.MF
+++ b/eclipse/tern.eclipse.ide.ui/META-INF/MANIFEST.MF
@@ -16,7 +16,8 @@ Require-Bundle: org.eclipse.ui,
org.eclipse.ui.editors,
org.eclipse.jface.text,
org.eclipse.ui.workbench.texteditor,
- tern.eclipse;bundle-version="0.2.0"
+ tern.eclipse;bundle-version="0.2.0",
+ org.eclipse.core.expressions
Bundle-ActivationPolicy: lazy
Bundle-Activator: tern.eclipse.ide.ui.TernUIPlugin
Import-Package: org.json.simple
diff --git a/eclipse/tern.eclipse.ide.ui/plugin.xml b/eclipse/tern.eclipse.ide.ui/plugin.xml
index 63c13d2c9..bc311eb77 100644
--- a/eclipse/tern.eclipse.ide.ui/plugin.xml
+++ b/eclipse/tern.eclipse.ide.ui/plugin.xml
@@ -13,6 +13,22 @@
###############################################################################
-->
+
+
+
+
+
+
+
+
+
+
@@ -40,8 +56,7 @@
-
+
@@ -85,8 +100,7 @@
id="tern.eclipse.ide.internal.ui.properties.TernMainPropertyPage">
-
+
@@ -97,8 +111,7 @@
id="tern.eclipse.ide.internal.ui.properties.TernTypeDefinitionsPropertyPage">
-
+
@@ -109,8 +122,7 @@
id="tern.eclipse.ide.internal.ui.properties.TernPluginsPropertyPage">
-
+
@@ -121,8 +133,7 @@
id="tern.eclipse.ide.internal.ui.properties.TernScriptPathsPropertyPage">
-
+
@@ -133,8 +144,7 @@
id="tern.eclipse.ide.internal.ui.properties.TernConsolePropertyPage">
-
+
diff --git a/eclipse/tern.eclipse.ide.ui/src/tern/eclipse/ide/ui/internal/TernIDEStartup.java b/eclipse/tern.eclipse.ide.ui/src/tern/eclipse/ide/ui/internal/TernIDEStartup.java
new file mode 100644
index 000000000..e148edf0d
--- /dev/null
+++ b/eclipse/tern.eclipse.ide.ui/src/tern/eclipse/ide/ui/internal/TernIDEStartup.java
@@ -0,0 +1,17 @@
+package tern.eclipse.ide.ui.internal;
+
+import org.eclipse.ui.IStartup;
+
+/**
+ * Need this to make TernNatureTester work from early start
+ *
+ * @author Victor Rubezhny
+ */
+public class TernIDEStartup implements IStartup {
+
+ @Override
+ public void earlyStartup() {
+ // Nothing really to do here, but need this to make TernNatureTester work from early start
+ }
+
+}
diff --git a/eclipse/tern.eclipse.ide.ui/src/tern/eclipse/ide/ui/internal/TernNatureTester.java b/eclipse/tern.eclipse.ide.ui/src/tern/eclipse/ide/ui/internal/TernNatureTester.java
new file mode 100644
index 000000000..1f210ed2b
--- /dev/null
+++ b/eclipse/tern.eclipse.ide.ui/src/tern/eclipse/ide/ui/internal/TernNatureTester.java
@@ -0,0 +1,49 @@
+package tern.eclipse.ide.ui.internal;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IAdaptable;
+
+import tern.eclipse.ide.core.IDETernProject;
+
+/**
+ * Property Tester for a IProject receiver object
+ *
+ * Property to be tested: "isTernProject"
+ *
+ * @author Victor Rubezhny
+ */
+public class TernNatureTester extends org.eclipse.core.expressions.PropertyTester {
+ private static final String IS_TERN_PROJECT_PROPERTY = "isTernProject";
+
+ public TernNatureTester() {
+ // Default constructor is required for property tester
+ }
+
+ /**
+ * Tests if the receiver object is a project is a Tern project
+ *
+ * @return true if the receiver object is a Project that has a nature that is treated as Tern nature,
+ * otherwise false is returned
+ */
+ @Override
+ public boolean test(Object receiver, String property, Object[] args,
+ Object expectedValue) {
+
+ if (IS_TERN_PROJECT_PROPERTY.equals(property))
+ return testIsTernProject(receiver);
+
+ return false;
+ }
+
+ private boolean testIsTernProject(Object receiver) {
+ if (receiver instanceof IAdaptable) {
+ IProject project = (IProject)((IAdaptable)receiver).getAdapter(IProject.class);
+ if (project != null) {
+ return IDETernProject.hasTernNature(project);
+ }
+ }
+
+ return false;
+ }
+
+}