diff --git a/eclipse-sarl/plugins/io.sarl.eclipse/OSGI-INF/l10n/bundle.properties b/eclipse-sarl/plugins/io.sarl.eclipse/OSGI-INF/l10n/bundle.properties
index 8f79cdc4f5..e04ed799a2 100644
--- a/eclipse-sarl/plugins/io.sarl.eclipse/OSGI-INF/l10n/bundle.properties
+++ b/eclipse-sarl/plugins/io.sarl.eclipse/OSGI-INF/l10n/bundle.properties
@@ -48,7 +48,8 @@ the Eclipse Foundation http://www.eclipse.org, the Xtext library https://eclipse
the Guava Libraries https://code.google.com/p/guava-libraries, and \
the Apache Software Foundation https://www.apache.org.
wizard.name.newSarlProject = SARL Project
-wizard.description.newSarlProject = Create a SARL project
+wizard.description.newSarlProject.short = Create a new SARL project
+wizard.description.newSarlProject.long = Create a new SARL project in the SARL ide.
wizard.name.newSarlScript = SARL File
wizard.description.newSarlScript = Create a SARL script
wizard.name.newAgent = SARL Agent
@@ -71,3 +72,5 @@ wizard.name.newAnnotation = SARL Annotation
wizard.description.newAnnotation = Create a SARL annotation
projectconfigurator.name = SARL Project
welcome.message = Welcome to the Eclipse IDE for SARL Developers
+action.addSarlNature = Add SARL Nature
+action.removeSarlNature = Remove SARL Nature
diff --git a/eclipse-sarl/plugins/io.sarl.eclipse/plugin.xml b/eclipse-sarl/plugins/io.sarl.eclipse/plugin.xml
index 6019d37a4b..0b4c7ad690 100644
--- a/eclipse-sarl/plugins/io.sarl.eclipse/plugin.xml
+++ b/eclipse-sarl/plugins/io.sarl.eclipse/plugin.xml
@@ -15,7 +15,7 @@
finalPerspective="io.sarl.eclipse.perspective.devel"
preferredPerspectives="io.sarl.eclipse.perspective.devel,org.eclipse.jdt.ui.JavaPerspective,org.eclipse.jdt.ui.JavaBrowsingPerspective"
project="true">
- %wizard.description.newSarlProject"
+ %wizard.description.newSarlProject.short"
@@ -239,7 +239,7 @@
@@ -360,6 +360,55 @@
label="%projectconfigurator.name">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/eclipse-sarl/plugins/io.sarl.eclipse/src/io/sarl/eclipse/natures/AddSarlNatureHandler.java b/eclipse-sarl/plugins/io.sarl.eclipse/src/io/sarl/eclipse/natures/AddSarlNatureHandler.java
new file mode 100644
index 0000000000..437f07a3f4
--- /dev/null
+++ b/eclipse-sarl/plugins/io.sarl.eclipse/src/io/sarl/eclipse/natures/AddSarlNatureHandler.java
@@ -0,0 +1,125 @@
+/*
+ * $Id$
+ *
+ * SARL is an general-purpose agent programming language.
+ * More details on http://www.sarl.io
+ *
+ * Copyright (C) 2014-2016 the original authors or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.sarl.eclipse.natures;
+
+import java.lang.reflect.InvocationTargetException;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.SubMonitor;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jface.dialogs.ProgressMonitorDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/**
+ * Action for converting the nature of a project to SARL.
+ *
+ * @author $Author: sgalland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ */
+public class AddSarlNatureHandler extends AbstractHandler {
+
+ @Inject
+ private SARLProjectConfigurator configurator;
+
+ @Override
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ final ISelection currentSelection = HandlerUtil.getCurrentSelection(event);
+ if (currentSelection instanceof IStructuredSelection) {
+ final IStructuredSelection structuredSelection = (IStructuredSelection) currentSelection;
+ final List projects = new ArrayList<>();
+ final Iterator> iterator = structuredSelection.iterator();
+ while (iterator.hasNext()) {
+ final Object obj = iterator.next();
+ if (obj instanceof IJavaProject) {
+ projects.add(((IJavaProject) obj).getProject());
+ } else if (obj instanceof IProject) {
+ projects.add((IProject) obj);
+ }
+ }
+ final Shell activeShell = HandlerUtil.getActiveShell(event);
+ convertAllWithProgress(activeShell, projects);
+ }
+ return null;
+ }
+
+ private boolean convertAllWithProgress(Shell shell, List projects) throws ExecutionException {
+ final IRunnableWithProgress op = new IRunnableWithProgress() {
+ @Override
+ public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+ monitor.beginTask(Messages.RemoveSarlNatureHandler_0, projects.size());
+ final SubMonitor mon = SubMonitor.convert(monitor);
+ try {
+ for (final IProject project : projects) {
+ doConvert(project, mon.newChild(1));
+ }
+ } catch (ExecutionException e) {
+ throw new InvocationTargetException(e);
+ } finally {
+ monitor.done();
+ }
+ }
+ };
+ try {
+ new ProgressMonitorDialog(shell).run(true, true, op);
+ } catch (InvocationTargetException exception) {
+ throw new ExecutionException(
+ MessageFormat.format(Messages.RemoveSarlNatureHandler_1, exception.getLocalizedMessage()), exception);
+ } catch (InterruptedException exception) {
+ //interrupted by user
+ return true;
+ }
+ return false;
+ }
+
+ /** Convert the given project.
+ *
+ * @param project the project to convert..
+ * @param monitor the progress monitor.
+ * @throws ExecutionException if something going wrong.
+ */
+ protected void doConvert(IProject project, IProgressMonitor monitor) throws ExecutionException {
+ monitor.setTaskName(MessageFormat.format(Messages.AddSarlNatureHandler_2, project.getName()));
+ final SubMonitor mon = SubMonitor.convert(monitor, 2);
+ if (this.configurator.canConfigure(project, Collections.emptySet(), mon.newChild(1))) {
+ this.configurator.configure(project, Collections.emptySet(), mon.newChild(1));
+ }
+ monitor.done();
+ }
+
+}
diff --git a/eclipse-sarl/plugins/io.sarl.eclipse/src/io/sarl/eclipse/natures/IProjectUnconfigurator.java b/eclipse-sarl/plugins/io.sarl.eclipse/src/io/sarl/eclipse/natures/IProjectUnconfigurator.java
new file mode 100644
index 0000000000..9997d161f7
--- /dev/null
+++ b/eclipse-sarl/plugins/io.sarl.eclipse/src/io/sarl/eclipse/natures/IProjectUnconfigurator.java
@@ -0,0 +1,56 @@
+/*
+ * $Id$
+ *
+ * SARL is an general-purpose agent programming language.
+ * More details on http://www.sarl.io
+ *
+ * Copyright (C) 2014-2016 the original authors or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.sarl.eclipse.natures;
+
+import com.google.inject.ImplementedBy;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+/**
+ * Configurator for a SARL project.
+ *
+ * @author $Author: sgalland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ */
+@ImplementedBy(SARLProjectConfigurator.class)
+public interface IProjectUnconfigurator {
+
+ /** Replies if the project can be unconfigured.
+ *
+ * @param project the project.
+ * @param monitor the progress monitor.
+ * @return true
if the project could be unconfigured.
+ */
+ boolean canUnconfigure(IProject project, IProgressMonitor monitor);
+
+ /** Unconfigure the given project.
+ *
+ * @param project the project.
+ * @param monitor the progress monitor.
+ * @throws CoreException if the project cannot be unconfigured.
+ */
+ void unconfigure(IProject project, IProgressMonitor monitor) throws CoreException;
+
+}
diff --git a/eclipse-sarl/plugins/io.sarl.eclipse/src/io/sarl/eclipse/natures/Messages.java b/eclipse-sarl/plugins/io.sarl.eclipse/src/io/sarl/eclipse/natures/Messages.java
index 4d06195e6d..b3dd6628dd 100644
--- a/eclipse-sarl/plugins/io.sarl.eclipse/src/io/sarl/eclipse/natures/Messages.java
+++ b/eclipse-sarl/plugins/io.sarl.eclipse/src/io/sarl/eclipse/natures/Messages.java
@@ -33,6 +33,10 @@
@SuppressWarnings("all")
public class Messages extends NLS {
private static final String BUNDLE_NAME = "io.sarl.eclipse.natures.messages"; //$NON-NLS-1$
+ public static String AddSarlNatureHandler_2;
+ public static String RemoveSarlNatureHandler_0;
+ public static String RemoveSarlNatureHandler_1;
+ public static String RemoveSarlNatureHandler_2;
public static String SARLProjectConfigurator_0;
static {
// initialize resource bundle
diff --git a/eclipse-sarl/plugins/io.sarl.eclipse/src/io/sarl/eclipse/natures/RemoveSarlNatureHandler.java b/eclipse-sarl/plugins/io.sarl.eclipse/src/io/sarl/eclipse/natures/RemoveSarlNatureHandler.java
new file mode 100644
index 0000000000..e1254ddc34
--- /dev/null
+++ b/eclipse-sarl/plugins/io.sarl.eclipse/src/io/sarl/eclipse/natures/RemoveSarlNatureHandler.java
@@ -0,0 +1,129 @@
+/*
+ * $Id$
+ *
+ * SARL is an general-purpose agent programming language.
+ * More details on http://www.sarl.io
+ *
+ * Copyright (C) 2014-2016 the original authors or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.sarl.eclipse.natures;
+
+import java.lang.reflect.InvocationTargetException;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.SubMonitor;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jface.dialogs.ProgressMonitorDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/**
+ * Action for removing the SARL nature to a project.
+ *
+ * @author $Author: sgalland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ */
+public class RemoveSarlNatureHandler extends AbstractHandler {
+
+ @Inject
+ private IProjectUnconfigurator configurator;
+
+ @Override
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ final ISelection currentSelection = HandlerUtil.getCurrentSelection(event);
+ if (currentSelection instanceof IStructuredSelection) {
+ final IStructuredSelection structuredSelection = (IStructuredSelection) currentSelection;
+ final List projects = new ArrayList<>();
+ final Iterator> iterator = structuredSelection.iterator();
+ while (iterator.hasNext()) {
+ final Object obj = iterator.next();
+ if (obj instanceof IJavaProject) {
+ projects.add(((IJavaProject) obj).getProject());
+ } else if (obj instanceof IProject) {
+ projects.add((IProject) obj);
+ }
+ }
+ final Shell activeShell = HandlerUtil.getActiveShell(event);
+ convertAllWithProgress(activeShell, projects);
+ }
+ return null;
+ }
+
+ private boolean convertAllWithProgress(Shell shell, List projects) throws ExecutionException {
+ final IRunnableWithProgress op = new IRunnableWithProgress() {
+ @Override
+ public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+ monitor.beginTask(Messages.RemoveSarlNatureHandler_0, projects.size());
+ final SubMonitor mon = SubMonitor.convert(monitor);
+ try {
+ for (final IProject project : projects) {
+ doConvert(project, mon.newChild(1));
+ }
+ } catch (ExecutionException e) {
+ throw new InvocationTargetException(e);
+ } finally {
+ monitor.done();
+ }
+ }
+ };
+ try {
+ new ProgressMonitorDialog(shell).run(true, true, op);
+ } catch (InvocationTargetException exception) {
+ throw new ExecutionException(
+ MessageFormat.format(Messages.RemoveSarlNatureHandler_1, exception.getLocalizedMessage()), exception);
+ } catch (InterruptedException exception) {
+ //interrupted by user
+ return true;
+ }
+ return false;
+ }
+
+ /** Convert the given project.
+ *
+ * @param project the project to convert..
+ * @param monitor the progress monitor.
+ * @throws ExecutionException if something going wrong.
+ */
+ protected void doConvert(IProject project, IProgressMonitor monitor) throws ExecutionException {
+ monitor.setTaskName(MessageFormat.format(Messages.RemoveSarlNatureHandler_2, project.getName()));
+ final SubMonitor mon = SubMonitor.convert(monitor, 2);
+ if (this.configurator.canUnconfigure(project, mon.newChild(1))) {
+ try {
+ this.configurator.unconfigure(project, mon.newChild(1));
+ } catch (CoreException exception) {
+ throw new ExecutionException(exception.getLocalizedMessage(), exception);
+ }
+ }
+ monitor.done();
+ }
+
+}
diff --git a/eclipse-sarl/plugins/io.sarl.eclipse/src/io/sarl/eclipse/natures/SARLProjectConfigurator.java b/eclipse-sarl/plugins/io.sarl.eclipse/src/io/sarl/eclipse/natures/SARLProjectConfigurator.java
index fd5b2cbefc..77c29a33e8 100644
--- a/eclipse-sarl/plugins/io.sarl.eclipse/src/io/sarl/eclipse/natures/SARLProjectConfigurator.java
+++ b/eclipse-sarl/plugins/io.sarl.eclipse/src/io/sarl/eclipse/natures/SARLProjectConfigurator.java
@@ -79,7 +79,7 @@
* @mavengroupid $GroupId$
* @mavenartifactid $ArtifactId$
*/
-public class SARLProjectConfigurator implements ProjectConfigurator {
+public class SARLProjectConfigurator implements ProjectConfigurator, IProjectUnconfigurator {
private final String fileExtension;
@@ -132,12 +132,67 @@ public Set getFoldersToIgnore(IProject project, IProgressMonitor monito
@Override
public boolean canConfigure(IProject project, Set ignoredPaths, IProgressMonitor monitor) {
- return true;
+ try {
+ return project != null && !project.hasNature(SARLEclipseConfig.NATURE_ID);
+ } catch (CoreException exception) {
+ return false;
+ } finally {
+ monitor.done();
+ }
}
@Override
public void configure(IProject project, Set ignoredPaths, IProgressMonitor monitor) {
- configureSARLProject(project, true, true, monitor);
+ try {
+ configureSARLProject(project, true, true, monitor);
+ safeRefresh(project, monitor);
+ } finally {
+ monitor.done();
+ }
+ }
+
+ @Override
+ public boolean canUnconfigure(IProject project, IProgressMonitor monitor) {
+ try {
+ return project != null && project.hasNature(SARLEclipseConfig.NATURE_ID);
+ } catch (CoreException exception) {
+ return false;
+ } finally {
+ monitor.done();
+ }
+ }
+
+ @Override
+ public void unconfigure(IProject project, IProgressMonitor monitor) throws CoreException {
+ try {
+ final SubMonitor mon = SubMonitor.convert(monitor, 4);
+ final IProjectDescription description = project.getDescription();
+ final List natures = new LinkedList<>(Arrays.asList(description.getNatureIds()));
+ natures.remove(SARLEclipseConfig.XTEXT_NATURE_ID);
+ natures.remove(SARLEclipseConfig.NATURE_ID);
+ final String[] newNatures = natures.toArray(new String[natures.size()]);
+ mon.worked(1);
+ final IStatus status = ResourcesPlugin.getWorkspace().validateNatureSet(newNatures);
+ mon.worked(1);
+ if (status.getCode() == IStatus.OK) {
+ description.setNatureIds(newNatures);
+ project.setDescription(description, mon.newChild(1));
+ safeRefresh(project, mon.newChild(1));
+ } else {
+ throw new CoreException(status);
+ }
+ } finally {
+ monitor.done();
+ }
+ }
+
+ /** Refresh the project file hierarchy.
+ *
+ * @param project the project.
+ * @param monitor the progress monitor.
+ */
+ @SuppressWarnings("static-method")
+ protected void safeRefresh(IProject project, IProgressMonitor monitor) {
try {
project.refreshLocal(IResource.DEPTH_INFINITE, monitor);
} catch (CoreException exception) {
diff --git a/eclipse-sarl/plugins/io.sarl.eclipse/src/io/sarl/eclipse/natures/messages.properties b/eclipse-sarl/plugins/io.sarl.eclipse/src/io/sarl/eclipse/natures/messages.properties
index 8d85f24ed2..e3a99f7657 100644
--- a/eclipse-sarl/plugins/io.sarl.eclipse/src/io/sarl/eclipse/natures/messages.properties
+++ b/eclipse-sarl/plugins/io.sarl.eclipse/src/io/sarl/eclipse/natures/messages.properties
@@ -1 +1,5 @@
+AddSarlNatureHandler_2=Adding SARL nature to {0}...
+RemoveSarlNatureHandler_0=Converting...
+RemoveSarlNatureHandler_1=Error during conversion: {0}
+RemoveSarlNatureHandler_2=Removing SARL nature to {0}...
SARLProjectConfigurator_0=Checking {0}