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}