/*
* Copyright 2015 SFB 632.
*
* 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 annis.libgui;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import com.vaadin.ui.UI;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* @author Thomas Krause <krauseto@hu-berlin.de>
*/
public class Background
{
private static final Logger log = LoggerFactory.getLogger(Background.class);
public static Future<?> run(Runnable job)
{
return call(Executors.callable(job));
}
/**
* Execute the job in the background and provide a callback which is called
* when the job is finished.
*
* It is guarantied that the callback is executed inside of the UI thread.
*
* @param <T>
* @param job
* @param callback
*/
public static <T> void runWithCallback(Callable<T> job, final FutureCallback<T> callback)
{
final UI ui = UI.getCurrent();
ListeningExecutorService exec = MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor());
ListenableFuture<T> future = exec.submit(job);
if(callback != null)
{
Futures.addCallback(future, new FutureCallback<T>()
{
@Override
public void onSuccess(final T result)
{
ui.access(new Runnable()
{
@Override
public void run()
{
callback.onSuccess(result);
}
});
}
@Override
public void onFailure(final Throwable t)
{
ui.access(new Runnable()
{
@Override
public void run()
{
callback.onFailure(t);
}
});
}
});
}
}
public static <T> Future<T> call(
final Callable<T> callable)
{
if(callable != null)
{
// create a new thread for every job to ensure that Vaadin.getSession() works
// as expected
ExecutorService exec = Executors.newSingleThreadExecutor();
Future<T> result = exec.submit(new Callable<T>()
{
@Override
public T call() throws Exception
{
T result = null;
try
{
result = callable.call();
}
catch(Exception ex)
{
log.error("exception in background job", ex);
throw(ex);
}
return result;
}
});
return result;
}
return null;
}
}