/* * 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.core; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Platform; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.PlatformUI; import org.jkiss.code.NotNull; import org.jkiss.dbeaver.DBException; import org.jkiss.dbeaver.Log; import org.jkiss.dbeaver.model.DBPExternalFileManager; import org.jkiss.dbeaver.model.app.*; import org.jkiss.dbeaver.model.data.DBDRegistry; import org.jkiss.dbeaver.model.edit.DBERegistry; import org.jkiss.dbeaver.model.impl.app.DefaultCertificateStorage; import org.jkiss.dbeaver.model.navigator.DBNModel; import org.jkiss.dbeaver.model.preferences.DBPPreferenceStore; import org.jkiss.dbeaver.model.qm.QMController; import org.jkiss.dbeaver.model.qm.QMUtils; import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor; import org.jkiss.dbeaver.model.runtime.OSDescriptor; import org.jkiss.dbeaver.registry.DataSourceProviderRegistry; import org.jkiss.dbeaver.registry.PluginServiceRegistry; import org.jkiss.dbeaver.registry.ProjectRegistry; import org.jkiss.dbeaver.registry.datatype.DataTypeProviderRegistry; import org.jkiss.dbeaver.registry.editor.EntityEditorsRegistry; import org.jkiss.dbeaver.runtime.IPluginService; import org.jkiss.dbeaver.runtime.jobs.KeepAliveJob; import org.jkiss.dbeaver.runtime.net.GlobalProxyAuthenticator; import org.jkiss.dbeaver.runtime.net.GlobalProxySelector; import org.jkiss.dbeaver.runtime.qm.QMControllerImpl; import org.jkiss.dbeaver.runtime.qm.QMLogFileWriter; import org.jkiss.dbeaver.utils.ContentUtils; import org.jkiss.dbeaver.utils.GeneralUtils; import org.jkiss.utils.CommonUtils; import org.jkiss.utils.StandardConstants; import org.osgi.framework.Bundle; import java.io.File; import java.io.IOException; import java.net.Authenticator; import java.net.ProxySelector; import java.nio.file.Files; import java.util.ArrayList; import java.util.List; /** * DBeaverCore */ public class DBeaverCore implements DBPPlatform { // The plug-in ID public static final String PLUGIN_ID = "org.jkiss.dbeaver.core"; //$NON-NLS-1$ private static final Log log = Log.getLog(DBeaverCore.class); public static final String TEMP_PROJECT_NAME = ".dbeaver-temp"; //$NON-NLS-1$ private static final DBPApplication DEFAULT_APPLICATION = new EclipseApplication(); static DBeaverCore instance; @NotNull private static DBPApplication application = DEFAULT_APPLICATION; private static volatile boolean isClosing = false; private File tempFolder; private IWorkspace workspace; private OSDescriptor localSystem; private DBNModel navigatorModel; private QMControllerImpl queryManager; private QMLogFileWriter qmLogWriter; private ProjectRegistry projectRegistry; private DBACertificateStorage certificateStorage; private final List<IPluginService> activatedServices = new ArrayList<>(); private static boolean disposed = false; public static DBeaverCore getInstance() { if (instance == null) { synchronized (DBeaverCore.class) { if (disposed) { throw new IllegalStateException("DBeaver core already disposed"); } if (instance == null) { // Initialize DBeaver Core DBeaverCore.createInstance(); } } } return instance; } private static DBeaverCore createInstance() { log.debug("Initializing " + GeneralUtils.getProductTitle()); if (Platform.getProduct() != null) { Bundle definingBundle = Platform.getProduct().getDefiningBundle(); if (definingBundle != null) { log.debug("Host plugin: " + definingBundle.getSymbolicName() + " " + definingBundle.getVersion()); } else { log.debug("!!! No product bundle found"); } } try { instance = new DBeaverCore(); instance.initialize(); return instance; } catch (Throwable e) { log.error("Error initializing DBeaverCore", e); throw new IllegalStateException("Error initializing DBeaverCore", e); } } public static String getCorePluginID() { return DBeaverActivator.getInstance().getBundle().getSymbolicName(); } public static boolean isStandalone() { return application.isStandalone(); } public static void setApplication(@NotNull DBPApplication app) { application = app; } public static boolean isClosing() { if (isClosing) { return true; } IWorkbench workbench = PlatformUI.getWorkbench(); return workbench == null || workbench.isClosing(); } public static void setClosing(boolean closing) { isClosing = closing; } public static DBPPreferenceStore getGlobalPreferenceStore() { return DBeaverActivator.getInstance().getPreferences(); } DBeaverCore() { } private void initialize() { long startTime = System.currentTimeMillis(); log.debug("Initialize Core..."); // Register properties adapter this.workspace = ResourcesPlugin.getWorkspace(); this.localSystem = new OSDescriptor(Platform.getOS(), Platform.getOSArch()); QMUtils.initApplication(this); this.queryManager = new QMControllerImpl(); this.qmLogWriter = new QMLogFileWriter(); this.queryManager.registerMetaListener(qmLogWriter); // Init default network settings Authenticator.setDefault(new GlobalProxyAuthenticator()); ProxySelector.setDefault(new GlobalProxySelector(ProxySelector.getDefault())); this.certificateStorage = new DefaultCertificateStorage( new File(DBeaverActivator.getInstance().getStateLocation().toFile(), "security")); // Init project registry this.projectRegistry = new ProjectRegistry(workspace); // Projects registry initializeProjects(); // Navigator model this.navigatorModel = new DBNModel(this); this.navigatorModel.initialize(); // Activate plugin services for (IPluginService pluginService : PluginServiceRegistry.getInstance().getServices()) { try { pluginService.activateService(); activatedServices.add(pluginService); } catch (Throwable e) { log.error("Error activating plugin service", e); } } // Keep-alive job new KeepAliveJob().scheduleMonitor(); log.debug("Core initialized (" + (System.currentTimeMillis() - startTime) + "ms)"); } private void initializeProjects() { final IProgressMonitor monitor = new NullProgressMonitor(); try { projectRegistry.loadProjects(monitor); } catch (DBException e) { log.error("Error loading projects", e); } } public synchronized void dispose() { long startTime = System.currentTimeMillis(); log.debug("Shutdown Core..."); DBeaverCore.setClosing(true); // Deactivate plugin services for (IPluginService pluginService : activatedServices) { try { pluginService.deactivateService(); } catch (Exception e) { log.error("Error deactivating plugin service", e); } } activatedServices.clear(); // Dispose navigator model first // It is a part of UI if (this.navigatorModel != null) { this.navigatorModel.dispose(); //this.navigatorModel = null; } // Dispose project registry // It will close all open connections if (this.projectRegistry != null) { this.projectRegistry.dispose(); this.projectRegistry = null; } if (this.qmLogWriter != null) { this.queryManager.unregisterMetaListener(qmLogWriter); this.qmLogWriter.dispose(); this.qmLogWriter = null; } if (this.queryManager != null) { this.queryManager.dispose(); //queryManager = null; } DataSourceProviderRegistry.getInstance().dispose(); if (isStandalone() && workspace != null) { try { IProgressMonitor monitor = new NullProgressMonitor(); workspace.save(true, monitor); } catch (CoreException ex) { log.error("Can't save workspace", ex); //$NON-NLS-1$ } } // Remove temp folder if (tempFolder != null) { if (!ContentUtils.deleteFileRecursive(tempFolder)) { log.warn("Can't delete temp folder '" + tempFolder.getAbsolutePath() + "'"); } tempFolder = null; } DBeaverCore.application = DEFAULT_APPLICATION; DBeaverCore.instance = null; DBeaverCore.disposed = true; System.gc(); log.debug("Shutdown completed in " + (System.currentTimeMillis() - startTime) + "ms"); } @NotNull @Override public IWorkspace getWorkspace() { return workspace; } @NotNull @Override public DBPProjectManager getProjectManager() { return getProjectRegistry(); } public OSDescriptor getLocalSystem() { return localSystem; } @NotNull @Override public DBPApplication getApplication() { return application; } @NotNull @Override public DBNModel getNavigatorModel() { return navigatorModel; } @NotNull public QMController getQueryManager() { return queryManager; } @NotNull @Override public DBDRegistry getValueHandlerRegistry() { return DataTypeProviderRegistry.getInstance(); } @NotNull @Override public DBERegistry getEditorsRegistry() { return EntityEditorsRegistry.getInstance(); } @NotNull @Override public DBPPreferenceStore getPreferenceStore() { return getGlobalPreferenceStore(); } @NotNull @Override public DBACertificateStorage getCertificateStorage() { return certificateStorage; } @NotNull @Override public DBASecureStorage getSecureStorage() { return application.getSecureStorage(); } public ProjectRegistry getProjectRegistry() { return projectRegistry; } public DBPExternalFileManager getExternalFileManager() { return projectRegistry; } @NotNull public File getTempFolder(DBRProgressMonitor monitor, String name) { if (tempFolder == null) { // Make temp folder monitor.subTask("Create temp folder"); try { final java.nio.file.Path tempDirectory = Files.createTempDirectory(TEMP_PROJECT_NAME); tempFolder = tempDirectory.toFile(); } catch (IOException e) { final String sysTempFolder = System.getProperty(StandardConstants.ENV_TMP_DIR); if (!CommonUtils.isEmpty(sysTempFolder)) { tempFolder = new File(sysTempFolder, TEMP_PROJECT_NAME); if (!tempFolder.mkdirs()){ final String sysUserFolder = System.getProperty(StandardConstants.ENV_USER_HOME); if (!CommonUtils.isEmpty(sysUserFolder)) { tempFolder = new File(sysUserFolder, TEMP_PROJECT_NAME); if (!tempFolder.mkdirs()){ tempFolder = new File(TEMP_PROJECT_NAME); if (!tempFolder.mkdirs()){ log.error("Can't create temp directory!"); } } } } } } } return tempFolder; } @Override public boolean isShuttingDown() { return isClosing(); } @NotNull public List<IProject> getLiveProjects() { List<IProject> result = new ArrayList<>(); for (IProject project : workspace.getRoot().getProjects()) { if (project.exists() && !project.isHidden()) { result.add(project); } } return result; } }