/******************************************************************************* * Copyright (c) 2014 Bruno Medeiros and other Contributors. * 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 * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Bruno Medeiros - initial API and implementation *******************************************************************************/ package melnorme.lang.ide.core.utils; import static melnorme.utilbox.core.Assert.AssertNamespace.assertNotNull; import static melnorme.utilbox.core.Assert.AssertNamespace.assertUnreachable; import java.util.ArrayList; import java.util.List; import java.util.function.Supplier; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProjectDescription; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Platform; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IDocumentExtension3; import org.eclipse.jface.text.IDocumentPartitioner; import org.osgi.framework.Bundle; import org.osgi.framework.BundleException; import melnorme.lang.ide.core.EclipseCore; import melnorme.lang.ide.core.LangCore; import melnorme.lang.tooling.common.ops.IOperationMonitor; import melnorme.lang.tooling.common.ops.IOperationMonitor.BasicOperationMonitor; import melnorme.lang.tooling.common.ops.Operation; import melnorme.utilbox.concurrency.ICancelMonitor; import melnorme.utilbox.concurrency.OperationCancellation; import melnorme.utilbox.core.CommonException; import melnorme.utilbox.misc.ArrayUtil; import melnorme.utilbox.status.IStatusMessage; import melnorme.utilbox.status.Severity; import melnorme.utilbox.status.StatusException; import melnorme.utilbox.status.StatusLevel; public class EclipseUtils { public static CommonException createCommonException(CoreException ce) { return new CommonException(ce.getMessage(), ce.getCause()); } public static final String MSG__ERROR_TRYING_TO_START_PLUGIN = "Error trying to start plugin: "; public static IWorkspaceRoot getWorkspaceRoot() { return ResourcesPlugin.getWorkspace().getRoot(); } public static IWorkspace getWorkspace() { return ResourcesPlugin.getWorkspace(); } public static void startOtherPlugin(String pluginId) { try { Bundle debugPlugin = Platform.getBundle(pluginId); if(debugPlugin == null) { throw new BundleException("Plugin not found"); } if(debugPlugin.getState() != Bundle.STARTING) { debugPlugin.start(Bundle.START_TRANSIENT); } } catch (BundleException e) { LangCore.logError(MSG__ERROR_TRYING_TO_START_PLUGIN + pluginId, e); } } public static IProject[] getOpenedProjects(String natureId) throws CoreException { final List<IProject> result = new ArrayList<IProject>(); final IProject[] projects = getWorkspaceRoot().getProjects(); for (IProject project : projects) { if (project.exists() && project.isOpen() && (natureId == null || project.hasNature(natureId))) { result.add(project); } } return ArrayUtil.createFrom(result, IProject.class); } /** Adds a nature to the given project if it doesn't exist already. */ public static void addNature(IProject project, String natureID) throws CoreException { IProjectDescription description = project.getDescription(); String[] natures = description.getNatureIds(); if(ArrayUtil.contains(natures, natureID)) return; String[] newNatures = ArrayUtil.append(natures, natureID); description.setNatureIds(newNatures); project.setDescription(description, null); } /** Remove nature from given project, if project has given nature. */ public static void removeNature(IProject project, String natureID) throws CoreException { IProjectDescription description = project.getDescription(); String[] natures = description.getNatureIds(); String[] newNatures = ArrayUtil.remove(natures, natureID); if(newNatures != natures) { description.setNatureIds(newNatures); project.setDescription(description, null); } } public static <T> T getAdapter(Object adaptable, Class<T> adapterType) { return Platform.getAdapterManager().getAdapter(adaptable, adapterType); } /* ----------------- status ----------------- */ public static int toEclipseSeverity(IStatusMessage se) { return toEclipseSeverity(se.getSeverity()); } public static int toEclipseSeverity(Severity severity) { return toEclipseSeverity(severity.toStatusLevel()); } public static int toEclipseSeverity(StatusLevel statusLevel) { switch(statusLevel) { case OK: return IStatus.OK; case INFO: return IStatus.INFO; case WARNING: return IStatus.WARNING; case ERROR: return IStatus.ERROR; } throw assertUnreachable(); } public static StatusLevel toStatusLevel(IStatus status) { switch(status.getSeverity()) { case IStatus.CANCEL: return null; case IStatus.OK: return StatusLevel.OK; case IStatus.INFO: return StatusLevel.INFO; case IStatus.WARNING: return StatusLevel.WARNING; case IStatus.ERROR: return StatusLevel.ERROR; } throw assertUnreachable(); } public static void validate(Supplier<IStatus> statusGetter) throws StatusException { IStatus status = statusGetter.get(); StatusException se = statusToStatusException3(status); if(se != null) { throw se; } } public static StatusException statusToStatusException3(IStatus status) throws StatusException { if(status.isOK() || status.getSeverity() == IStatus.CANCEL) { return null; } Severity severity = toStatusLevel(status).toSeverity(); return new StatusException(severity, status.getMessage(), status.getException()); } /* ----------------- ops ----------------- */ public static void execute_asCore(IProgressMonitor pm, Operation commonOperation) throws OperationCancellation, CoreException { try { IOperationMonitor om = EclipseUtils.om(pm); commonOperation.execute(om); } catch (CommonException ce) { throw EclipseCore.createCoreException(ce); } } public static ICancelMonitor cm(IProgressMonitor pm) { return new EclipseCancelMonitor(pm); } public static class EclipseCancelMonitor implements ICancelMonitor { protected final IProgressMonitor pm; public EclipseCancelMonitor(IProgressMonitor pm) { this.pm = assertNotNull(pm); } @Override public boolean isCancelled() { return pm.isCanceled(); } } public static IOperationMonitor om(IProgressMonitor pm) { return new BasicOperationMonitor(cm(pm)) { @Override public void setTaskLabel(String taskName) { pm.setTaskName(taskName); } }; } public static IProgressMonitor pm(ICancelMonitor cm) { if(cm instanceof EclipseCancelMonitor) { EclipseCancelMonitor ecm = (EclipseCancelMonitor) cm; return ecm.pm; } return new NullProgressMonitor() { @Override public boolean isCanceled() { return cm.isCancelled(); } }; } public static void run(CoreRunnable coreRunnable) throws CommonException { try { coreRunnable.execute(); } catch(CoreException e) { throw createCommonException(e); } } public static <R> R call(CoreCallable<R> coreCallable) throws CommonException { try { return coreCallable.execute(); } catch(CoreException e) { throw createCommonException(e); } } public static <R> R callCore(CoreCallable<R> coreCallable) throws CoreException { try { return coreCallable.execute(); } catch(CommonException e) { throw EclipseCore.createCoreException(e); } } public interface CoreRunnable { public void execute() throws CoreException, CommonException; } public interface CoreCallable<R> { public R execute() throws CoreException, CommonException; } /* ----------------- text ----------------- */ public static void setupDocumentPartitioner(IDocument document, String partitioning, IDocumentPartitioner partitioner) { assertNotNull(document); assertNotNull(partitioning); assertNotNull(partitioner); partitioner.connect(document); if (document instanceof IDocumentExtension3) { IDocumentExtension3 extension3 = (IDocumentExtension3) document; extension3.setDocumentPartitioner(partitioning, partitioner); } else { document.setDocumentPartitioner(partitioner); } } }