/* * DBeaver - Universal Database Manager * Copyright (C) 2010-2017 Serge Rider (serge@jkiss.org) * * 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 org.jkiss.dbeaver.ui; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.jkiss.dbeaver.Log; import org.jkiss.dbeaver.core.DBeaverCore; import org.jkiss.dbeaver.core.DBeaverUI; import org.jkiss.dbeaver.model.runtime.AbstractJob; import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor; import org.jkiss.dbeaver.model.runtime.VoidProgressMonitor; import org.jkiss.dbeaver.model.runtime.load.AbstractLoadService; import org.jkiss.dbeaver.model.runtime.load.ILoadService; import org.jkiss.dbeaver.model.runtime.load.ILoadVisualizer; import java.lang.reflect.InvocationTargetException; public class LoadingJob<RESULT> extends AbstractJob { private static final Log log = Log.getLog(LoadingJob.class); public static final Object LOADING_FAMILY = new Object(); public static <RESULT> LoadingJob<RESULT> createService( ILoadService<RESULT> loadingService, ILoadVisualizer<RESULT> visualizer) { return new LoadingJob<>(loadingService, visualizer); } private ILoadService<RESULT> loadingService; private ILoadVisualizer<RESULT> visualizer; public LoadingJob(ILoadService<RESULT> loadingService, ILoadVisualizer<RESULT> visualizer) { super(loadingService.getServiceName()); this.loadingService = loadingService; this.visualizer = visualizer; setUser(false); } public ILoadService<RESULT> getLoadingService() { return loadingService; } public ILoadVisualizer<RESULT> getVisualizer() { return visualizer; } @Override protected IStatus run(DBRProgressMonitor monitor) { return run(monitor, true); } private IStatus run(DBRProgressMonitor monitor, boolean lazy) { monitor = visualizer.overwriteMonitor(monitor); if (this.loadingService instanceof AbstractLoadService) { ((AbstractLoadService) this.loadingService).initService(monitor, this); } LoadingUIJob<RESULT> updateUIJob = new LoadingUIJob<>(this, monitor); updateUIJob.schedule(); Throwable error = null; RESULT result = null; try { result = this.loadingService.evaluate(monitor); } catch (InvocationTargetException e) { error = e.getTargetException(); } catch (InterruptedException e) { return new Status(Status.CANCEL, DBeaverCore.PLUGIN_ID, "Loading interrupted"); } finally { DBeaverUI.asyncExec(new LoadFinisher(result, error)); } return Status.OK_STATUS; } @Override public boolean belongsTo(Object family) { return family == loadingService.getFamily(); } public void syncRun() { run(new VoidProgressMonitor(), false); } private class LoadFinisher implements Runnable { private final RESULT innerResult; private final Throwable innerError; public LoadFinisher(RESULT innerResult, Throwable innerError) { this.innerResult = innerResult; this.innerError = innerError; } @Override public void run() { visualizer.completeLoading(innerResult); if (innerError != null) { log.debug(innerError); UIUtils.showErrorDialog( null, getName(), null, innerError); } } } static class LoadingUIJob<RESULT> extends AbstractUIJob { private static final long DELAY = 200; private ILoadService<RESULT> loadService; private ILoadVisualizer<RESULT> visualizer; private DBRProgressMonitor mainMonitor; LoadingUIJob(LoadingJob<RESULT> loadingJob, DBRProgressMonitor mainMonitor) { super(loadingJob.getName()); this.loadService = loadingJob.getLoadingService(); this.visualizer = loadingJob.getVisualizer(); this.mainMonitor = mainMonitor; setSystem(true); } @Override public IStatus runInUIThread(DBRProgressMonitor monitor) { /* if (mainMonitor.isCanceled()) { // Try to cancel current load service try { loadService.cancel(); } catch (InvocationTargetException e) { log.warn("Error while canceling service", e.getTargetException()); } return Status.CANCEL_STATUS; } else { */ if (!visualizer.isCompleted()) { visualizer.visualizeLoading(); schedule(DELAY); } //} return Status.OK_STATUS; } @Override public boolean belongsTo(Object family) { return family == LOADING_FAMILY; } @Override protected void canceling() { super.canceling(); } } }