/******************************************************************************* * Copyright (c) 2016 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is 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: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.windup.ui.util; import java.io.File; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicBoolean; import javax.inject.Inject; import javax.inject.Singleton; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.IJobChangeEvent; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.core.runtime.jobs.JobChangeAdapter; import org.eclipse.e4.core.di.annotations.Creatable; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.jboss.tools.windup.runtime.WindupRmiClient; import org.jboss.tools.windup.ui.WindupUIPlugin; import org.jboss.tools.windup.ui.internal.Messages; import org.jboss.tools.windup.ui.util.FutureUtils.AbstractDelegatingMonitorJob; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @Singleton @Creatable public class WindupLauncher { private static Logger logger = LoggerFactory.getLogger(WindupLauncher.class); // TODO: Move to preference item. public static final long WINDUP_START_DURATION_TIMEOUT = 45000; public static final long WINDUP_STOP_DURATION_TIMEOUT = 35000; @Inject private WindupRmiClient windupClient; public void shutdown(WinupServerCallback callback) { Display.getDefault().syncExec(() -> { Job job = new Job(Messages.WindupShuttingDown) { @Override protected IStatus run(IProgressMonitor monitor) { IStatus result = Status.OK_STATUS; try { monitor.beginTask(Messages.WindupShuttingDown, 3); shutdown(monitor); } catch (ExecutionException | TimeoutException | InterruptedException e) { WindupUIPlugin.log(e); result = new Status(IStatus.ERROR, WindupUIPlugin.PLUGIN_ID, e.getMessage(), e); } finally { monitor.done(); } if (monitor.isCanceled()) { result = Status.CANCEL_STATUS; } return result; } }; job.setUser(true); job.addJobChangeListener(new JobChangeAdapter() { public void done(IJobChangeEvent event) { callback.serverShutdown(event.getResult()); } }); job.schedule(); }); } private void shutdown(IProgressMonitor monitor) throws InterruptedException, ExecutionException, TimeoutException { logger.info("Shutting Windup down."); //$NON-NLS-1$ monitor.worked(1); windupClient.shutdownWindup(); monitor.worked(1); Future<IStatus> future = WindupLauncher.getTerminateWindupFuture(windupClient); FutureUtils.waitForFuture(WINDUP_STOP_DURATION_TIMEOUT, future, monitor); monitor.worked(1); } public static Future<IStatus> getTerminateWindupFuture(WindupRmiClient windupClient) { return new Future<IStatus>() { private AtomicBoolean cancelled = new AtomicBoolean(false); @Override public boolean cancel(boolean mayInterruptIfRunning) { cancelled.set(true); return true; } @Override public boolean isCancelled() { return cancelled.get(); } @Override public boolean isDone() { return !windupClient.isWindupServerRunning(); } @Override public IStatus get() throws InterruptedException, ExecutionException { return null; } @Override public IStatus get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { return null; } }; } public void start(WinupServerCallback callback) { Display.getDefault().syncExec(() -> { logger.info("Start Windup Server."); //$NON-NLS-1$ String windupHome = windupClient.getWindupHome().toString(); boolean executable = new File(windupHome).setExecutable(true); if (!executable) { logger.info("Windup not executable."); //$NON-NLS-1$ callback.windupNotExecutable(); return; } Job job = createStartWindupJob(); IStatus status = FutureUtils.runWithProgress(job, WINDUP_START_DURATION_TIMEOUT, 5, callback.getShell(), Messages.WindupStartingDetail); callback.serverStart(status); }); } public Job createStartWindupJob() { Job job = new AbstractDelegatingMonitorJob(Messages.WindupStartingTitle) { @Override protected IStatus doRun(IProgressMonitor monitor) { Future<IStatus> future = new Future<IStatus>() { private AtomicBoolean cancelled = new AtomicBoolean(false); @Override public boolean cancel(boolean mayInterruptIfRunning) { cancelled.set(true); return true; } @Override public boolean isCancelled() { return cancelled.get(); } @Override public boolean isDone() { return windupClient.updateWindupServer(); } @Override public IStatus get() throws InterruptedException, ExecutionException { return null; } @Override public IStatus get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { return null; } }; try { monitor.subTask(Messages.WindupRunStartScipt); windupClient.startWindup(monitor); FutureUtils.waitForFuture(WINDUP_START_DURATION_TIMEOUT, future, monitor); } catch (ExecutionException | TimeoutException | InterruptedException e) { WindupUIPlugin.log(e); } finally { monitor.done(); } monitor.done(); return Status.OK_STATUS; } }; job.setUser(true); return job; } public static interface WinupServerCallback { void serverShutdown(IStatus status); void serverStart(IStatus status); void windupNotExecutable(); Shell getShell(); } }