/* * 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.registry; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.InvalidRegistryObjectException; import org.eclipse.jface.text.templates.TemplateContextType; import org.jkiss.code.NotNull; import org.jkiss.dbeaver.Log; import org.jkiss.dbeaver.core.CoreMessages; import org.jkiss.dbeaver.core.DBeaverCore; import org.jkiss.dbeaver.model.DBPDataSourceProvider; import org.jkiss.dbeaver.model.DBPImage; import org.jkiss.dbeaver.model.preferences.DBPPropertyDescriptor; import org.jkiss.dbeaver.model.impl.AbstractDescriptor; import org.jkiss.dbeaver.model.impl.PropertyDescriptor; import org.jkiss.dbeaver.model.navigator.meta.*; import org.jkiss.dbeaver.registry.driver.DriverDescriptor; import org.jkiss.dbeaver.ui.UIIcon; import org.jkiss.utils.ArrayUtils; import org.jkiss.utils.CommonUtils; import org.jkiss.utils.SecurityUtils; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * DataSourceProviderDescriptor */ public class DataSourceProviderDescriptor extends AbstractDescriptor { private static final Log log = Log.getLog(DataSourceProviderDescriptor.class); public static final String EXTENSION_ID = "org.jkiss.dbeaver.dataSourceProvider"; //$NON-NLS-1$ private DataSourceProviderRegistry registry; private DataSourceProviderDescriptor parentProvider; private final String id; private final ObjectType implType; private final String name; private final String description; private DBPImage icon; private DBPDataSourceProvider instance; private DBXTreeNode treeDescriptor; private final Map<String, DBXTreeNode> treeNodeMap = new HashMap<>(); private boolean driversManagable; private final List<DBPPropertyDescriptor> driverProperties = new ArrayList<>(); private final List<DriverDescriptor> drivers = new ArrayList<>(); private final List<DataSourceViewDescriptor> views = new ArrayList<>(); private final String parentId; public DataSourceProviderDescriptor(DataSourceProviderRegistry registry, IConfigurationElement config) { super(config); this.registry = registry; parentId = config.getAttribute(RegistryConstants.ATTR_PARENT); this.id = config.getAttribute(RegistryConstants.ATTR_ID); this.implType = new ObjectType(config.getAttribute(RegistryConstants.ATTR_CLASS)); this.name = config.getAttribute(RegistryConstants.ATTR_LABEL); this.description = config.getAttribute(RegistryConstants.ATTR_DESCRIPTION); this.icon = iconToImage(config.getAttribute(RegistryConstants.ATTR_ICON)); if (this.icon == null) { this.icon = UIIcon.GEN_DATABASE_TYPE; } // Load tree structure IConfigurationElement[] trees = config.getChildren(RegistryConstants.TAG_TREE); if (!ArrayUtils.isEmpty(trees)) { this.treeDescriptor = this.loadTreeInfo(trees[0]); } // Load driver properties { for (IConfigurationElement propsElement : config.getChildren(RegistryConstants.TAG_DRIVER_PROPERTIES)) { for (IConfigurationElement prop : propsElement.getChildren(PropertyDescriptor.TAG_PROPERTY_GROUP)) { driverProperties.addAll(PropertyDescriptor.extractProperties(prop)); } } } // Load supplied drivers { for (IConfigurationElement driversElement : config.getChildren(RegistryConstants.TAG_DRIVERS)) { this.driversManagable = driversElement.getAttribute(RegistryConstants.ATTR_MANAGABLE) == null || CommonUtils.getBoolean(driversElement.getAttribute(RegistryConstants.ATTR_MANAGABLE)); for (IConfigurationElement driverElement : driversElement.getChildren(RegistryConstants.TAG_DRIVER)) { try { this.drivers.add(loadDriver(driverElement)); } catch (Exception e) { log.error("Error loading driver", e); } } } } // Load views { for (IConfigurationElement viewsElement : config.getChildren(RegistryConstants.TAG_VIEWS)) { for (IConfigurationElement viewElement : viewsElement.getChildren(RegistryConstants.TAG_VIEW)) { this.views.add( new DataSourceViewDescriptor(this, viewElement)); } } } } public void dispose() { drivers.clear(); instance = null; } public DataSourceProviderRegistry getRegistry() { return registry; } public String getId() { return id; } public String getName() { return name; } public String getDescription() { return description; } public DBPImage getIcon() { return icon; } @NotNull public DBPDataSourceProvider getInstance(DriverDescriptor driver) { if (instance == null) { initProviderBundle(driver); try { // locate class this.instance = implType.createInstance(DBPDataSourceProvider.class); // Initialize it this.instance.init(DBeaverCore.getInstance()); } catch (Throwable ex) { this.instance = null; throw new IllegalStateException("Can't initialize data source provider '" + implType.getImplName() + "'", ex); } } return instance; } private void initProviderBundle(DriverDescriptor driver) { } public DataSourceProviderDescriptor getParentProvider() { if (parentProvider == null && !CommonUtils.isEmpty(parentId)) { this.parentProvider = registry.getDataSourceProvider(parentId); if (this.parentProvider == null) { log.warn("Provider '" + parentId + "' not found"); } } return parentProvider; } public DBXTreeNode getTreeDescriptor() { if (treeDescriptor != null) { return treeDescriptor; } DataSourceProviderDescriptor parentProvider = getParentProvider(); if (parentProvider != null) { return parentProvider.getTreeDescriptor(); } return null; } public boolean isDriversManagable() { return driversManagable; } public List<DBPPropertyDescriptor> getDriverProperties() { return driverProperties; } public DBPPropertyDescriptor getDriverProperty(String name) { for (DBPPropertyDescriptor prop : driverProperties) { if (prop.getId().equals(name)) { return prop; } } return null; } public List<DriverDescriptor> getDrivers() { return drivers; } public List<DriverDescriptor> getEnabledDrivers() { List<DriverDescriptor> eDrivers = new ArrayList<>(); for (DriverDescriptor driver : drivers) { if (!driver.isDisabled() && driver.getReplacedBy() == null && driver.isSupportedByLocalSystem()) { eDrivers.add(driver); } } return eDrivers; } public DriverDescriptor getDriver(String id) { for (DriverDescriptor driver : drivers) { if (driver.getId().equals(id)) { while (driver.getReplacedBy() != null) { driver = driver.getReplacedBy(); } return driver; } } return null; } public DriverDescriptor createDriver() { return createDriver(SecurityUtils.generateGUID(false)); } public DriverDescriptor createDriver(String id) { return new DriverDescriptor(this, id); } public void addDriver(DriverDescriptor driver) { this.drivers.add(driver); } public boolean removeDriver(DriverDescriptor driver) { if (!driver.isCustom()) { driver.setDisabled(true); driver.setModified(true); return true; } else { return this.drivers.remove(driver); } } public DataSourceViewDescriptor getView(String targetID) { for (DataSourceViewDescriptor view : views) { if (view.getTargetID().equals(targetID)) { return view; } } return null; } private DBXTreeNode loadTreeInfo(IConfigurationElement config) { DBXTreeItem treeRoot = new DBXTreeItem( this, null, config.getAttribute(RegistryConstants.ATTR_ID), CoreMessages.model_navigator_Connection, CoreMessages.model_navigator_Connection, config.getAttribute(RegistryConstants.ATTR_PATH), null, false, true, false, false, false, config.getAttribute(RegistryConstants.ATTR_VISIBLE_IF), null); loadTreeChildren(config, treeRoot); loadTreeIcon(treeRoot, config); return treeRoot; } private void loadTreeChildren(IConfigurationElement config, DBXTreeNode parent) { IConfigurationElement[] children = config.getChildren(); if (!ArrayUtils.isEmpty(children)) { for (IConfigurationElement child : children) { loadTreeNode(parent, child); } } } private void loadTreeNode(DBXTreeNode parent, IConfigurationElement config) { DBXTreeNode child = null; final String refId = config.getAttribute(RegistryConstants.ATTR_REF); if (!CommonUtils.isEmpty(refId)) { child = treeNodeMap.get(refId); if (child != null) { parent.addChild(child); } else { log.warn("Bad node reference: " + refId); } } else { String nodeType = config.getName(); if (nodeType.equals(RegistryConstants.TAG_FOLDER)) { DBXTreeFolder folder = new DBXTreeFolder( this, parent, config.getAttribute(RegistryConstants.ATTR_ID), config.getAttribute(RegistryConstants.ATTR_TYPE), config.getAttribute(RegistryConstants.ATTR_LABEL), CommonUtils.getBoolean(config.getAttribute(RegistryConstants.ATTR_NAVIGABLE), true), CommonUtils.getBoolean(config.getAttribute(RegistryConstants.ATTR_VIRTUAL)), config.getAttribute(RegistryConstants.ATTR_VISIBLE_IF)); folder.setDescription(config.getAttribute(RegistryConstants.ATTR_DESCRIPTION)); child = folder; } else if (nodeType.equals(RegistryConstants.TAG_ITEMS)) { String recursive = config.getAttribute(RegistryConstants.ATTR_RECURSIVE); child = new DBXTreeItem( this, parent, config.getAttribute(RegistryConstants.ATTR_ID), config.getAttribute(RegistryConstants.ATTR_LABEL), config.getAttribute(RegistryConstants.ATTR_ITEM_LABEL), config.getAttribute(RegistryConstants.ATTR_PATH), config.getAttribute(RegistryConstants.ATTR_PROPERTY), CommonUtils.getBoolean(config.getAttribute(RegistryConstants.ATTR_OPTIONAL)), CommonUtils.getBoolean(config.getAttribute(RegistryConstants.ATTR_NAVIGABLE), true), CommonUtils.getBoolean(config.getAttribute(RegistryConstants.ATTR_INLINE)), CommonUtils.getBoolean(config.getAttribute(RegistryConstants.ATTR_VIRTUAL)), CommonUtils.getBoolean(config.getAttribute(RegistryConstants.ATTR_STANDALONE)), config.getAttribute(RegistryConstants.ATTR_VISIBLE_IF), recursive); } else if (nodeType.equals(RegistryConstants.TAG_OBJECT)) { child = new DBXTreeObject( this, parent, config.getAttribute(RegistryConstants.ATTR_ID), config.getAttribute(RegistryConstants.ATTR_VISIBLE_IF), config.getAttribute(RegistryConstants.ATTR_LABEL), config.getAttribute(RegistryConstants.ATTR_DESCRIPTION), config.getAttribute(RegistryConstants.ATTR_EDITOR)); } else { // Unknown node type //log.warn("Unknown node type: " + nodeType); } if (child != null) { if (!CommonUtils.isEmpty(child.getId())) { treeNodeMap.put(child.getId(), child); } loadTreeHandlers(child, config); loadTreeIcon(child, config); loadTreeChildren(config, child); } } } private void loadTreeHandlers(DBXTreeNode node, IConfigurationElement config) { IConfigurationElement[] handlerElements = config.getChildren("handler"); if (!ArrayUtils.isEmpty(handlerElements)) { for (IConfigurationElement iconElement : handlerElements) { try { DBXTreeNodeHandler.Action action = DBXTreeNodeHandler.Action.valueOf(iconElement.getAttribute("action")); String performName = iconElement.getAttribute("perform"); String command = iconElement.getAttribute("command"); DBXTreeNodeHandler.Perform perform; if (!CommonUtils.isEmpty(performName)) { perform = DBXTreeNodeHandler.Perform.valueOf(performName); } else if (!CommonUtils.isEmpty(command)) { perform = DBXTreeNodeHandler.Perform.command; } else { perform = DBXTreeNodeHandler.Perform.none; } node.addActionHandler(action, perform, command); } catch (Exception e) { log.error("Error adding node handler", e); } } } } private void loadTreeIcon(DBXTreeNode node, IConfigurationElement config) { String defaultIcon = config.getAttribute(RegistryConstants.ATTR_ICON); IConfigurationElement[] iconElements = config.getChildren(RegistryConstants.ATTR_ICON); if (!ArrayUtils.isEmpty(iconElements)) { for (IConfigurationElement iconElement : iconElements) { String icon = iconElement.getAttribute(RegistryConstants.ATTR_ICON); String expr = iconElement.getAttribute(RegistryConstants.ATTR_IF); boolean isDefault = CommonUtils.getBoolean(iconElement.getAttribute(RegistryConstants.ATTR_DEFAULT)); if (isDefault && CommonUtils.isEmpty(expr)) { defaultIcon = icon; } else { DBPImage iconImage = iconToImage(icon); if (iconImage != null) { node.addIcon(new DBXTreeIcon(expr, iconImage)); } } } } if (defaultIcon != null) { DBPImage defaultImage = iconToImage(defaultIcon); if (defaultImage != null) { node.setDefaultIcon(defaultImage); } } } private DriverDescriptor loadDriver(IConfigurationElement config) { return new DriverDescriptor(this, config); } public void loadTemplateVariableResolvers(TemplateContextType contextType) { //Collection<TemplateVariableResolver> } @Override public String toString() { return id; } }