gt:                             File contribFolder = DriverDescriptor.getDriversContribFolder();
context: /*
   * DBeaver - Universal Database Manager
   * Copyright (C) 2010-2016 Serge Rieder (serge@jkiss.org)
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License (version 2)
   * as published by the Free Software Foundation.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License along
   * with this program; if not, write to the Free Software Foundation, Inc.,
   * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
   */
  package org.jkiss.dbeaver.tools.project;
  
  import org.jkiss.dbeaver.Log;
  import org.eclipse.core.resources.*;
  import org.eclipse.core.runtime.CoreException;
  import org.eclipse.core.runtime.QualifiedName;
  import org.eclipse.jface.viewers.IStructuredSelection;
  import org.eclipse.jface.wizard.Wizard;
  import org.eclipse.swt.SWT;
  import org.eclipse.ui.IImportWizard;
  import org.eclipse.ui.IWorkbench;
  import org.jkiss.dbeaver.DBException;
  import org.jkiss.dbeaver.core.CoreMessages;
  import org.jkiss.dbeaver.core.DBeaverCore;
  import org.jkiss.dbeaver.core.DBeaverUI;
  import org.jkiss.dbeaver.model.connection.DBPDriverLibrary;
  import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
  import org.jkiss.dbeaver.model.runtime.DBRRunnableWithProgress;
  import org.jkiss.dbeaver.registry.*;
  import org.jkiss.dbeaver.registry.driver.DriverDescriptor;
  import org.jkiss.dbeaver.utils.RuntimeUtils;
  import org.jkiss.dbeaver.ui.UIUtils;
  import org.jkiss.dbeaver.utils.ContentUtils;
  import org.jkiss.dbeaver.utils.GeneralUtils;
  import org.jkiss.utils.CommonUtils;
  import org.jkiss.utils.IOUtils;
  import org.jkiss.utils.xml.XMLException;
  import org.jkiss.utils.xml.XMLUtils;
  import org.w3c.dom.Document;
  import org.w3c.dom.Element;
  
  import java.io.*;
  import java.lang.reflect.InvocationTargetException;
  import java.util.*;
  import java.util.zip.ZipEntry;
  import java.util.zip.ZipFile;
  
  public class ProjectImportWizard extends Wizard implements IImportWizard {
  
      private static final Log log = Log.getLog(ProjectImportWizard.class);
  
      private ProjectImportData data = new ProjectImportData();
  
      public ProjectImportWizard() {
  	}
  
  	@Override
      public void init(IWorkbench workbench, IStructuredSelection selection) {
          setWindowTitle(CoreMessages.dialog_project_import_wizard_title);
          setNeedsProgressMonitor(true);
      }
  
      @Override
      public void addPages() {
          super.addPages();
          addPage(new ProjectImportWizardPageFile(data));
          //addPage(new ProjectImportWizardPageFinal(data));
      }
  
  	@Override
  	public boolean performFinish() {
          try {
              DBeaverUI.run(getContainer(), true, true, new DBRRunnableWithProgress() {
                  @Override
                  public void run(DBRProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
                      try {
                          importProjects(monitor);
                      } catch (Exception e) {
                          throw new InvocationTargetException(e);
                      }
                  }
              });
          }
          catch (InterruptedException ex) {
              return false;
          }
          catch (InvocationTargetException ex) {
              UIUtils.showErrorDialog(
                  getShell(),
                  "Import error",
                  "Cannot import projects",
                  ex.getTargetException());
              return false;
          }
          UIUtils.showMessageBox(getShell(), CoreMessages.dialog_project_import_wizard_message_success_import_title, CoreMessages.dialog_project_import_wizard_message_success_import_message, SWT.ICON_INFORMATION);
          return true;
  	}
  
      private void importProjects(DBRProgressMonitor monitor) throws IOException, DBException
      {
          try (ZipFile zipFile = new ZipFile(data.getImportFile(), ZipFile.OPEN_READ)) {
              ZipEntry metaEntry = zipFile.getEntry(ExportConstants.META_FILENAME);
              if (metaEntry == null) {
                  throw new DBException("Cannot find meta file");
              }
              final Map<String, String> libMap = new HashMap<>();
              final Map<String, String> driverMap = new HashMap<>();
              InputStream metaStream = zipFile.getInputStream(metaEntry);
              if (metaStream == null) {
                  throw new DBException("Cannot open meta file '" + metaEntry.getName() + "'"); //$NON-NLS-2$
              }
              try {
                  final Document metaDocument = XMLUtils.parseDocument(metaStream);
                  {
                      // Read libraries map
                      final Element libsElement = XMLUtils.getChildElement(metaDocument.getDocumentElement(), ExportConstants.TAG_LIBRARIES);
                      if (libsElement != null) {
                          final Collection<Element> libList = XMLUtils.getChildElementList(libsElement, RegistryConstants.TAG_FILE);
                          monitor.beginTask(CoreMessages.dialog_project_import_wizard_monitor_load_libraries, libList.size());
                          for (Element libElement : libList) {
                              libMap.put(
                                  libElement.getAttribute(ExportConstants.ATTR_PATH),
                                  libElement.getAttribute(ExportConstants.ATTR_FILE));
                              monitor.worked(1);
                          }
                          monitor.done();
                      }
                  }
  
                  {
                      // Collect drivers to import
                      final Element driversElement = XMLUtils.getChildElement(metaDocument.getDocumentElement(), RegistryConstants.TAG_DRIVERS);
                      if (driversElement != null) {
                          final Collection<Element> driverList = XMLUtils.getChildElementList(driversElement, RegistryConstants.TAG_DRIVER);
                          monitor.beginTask(CoreMessages.dialog_project_import_wizard_monitor_import_drivers, driverList.size());
                          for (Element driverElement : driverList) {
                              if (monitor.isCanceled()) {
                                  break;
                              }
  
                              importDriver(monitor, driverElement, zipFile, libMap, driverMap);
                              monitor.worked(1);
                          }
                          // Save drivers
                          DataSourceProviderRegistry.getInstance().saveDrivers();
                          monitor.done();
                      }
                  }
  
                  {
                      // Import projects
                      final Element projectsElement = XMLUtils.getChildElement(metaDocument.getDocumentElement(), ExportConstants.TAG_PROJECTS);
                      if (projectsElement != null) {
                          final Collection<Element> projectList = XMLUtils.getChildElementList(projectsElement, ExportConstants.TAG_PROJECT);
                          monitor.beginTask(CoreMessages.dialog_project_import_wizard_monitor_import_projects, projectList.size());
                          for (Element projectElement : projectList) {
                              if (monitor.isCanceled()) {
                                  break;
                              }
  
                              importProject(monitor, projectElement, zipFile, driverMap);
                              monitor.worked(1);
                          }
                          monitor.done();
                      }
                  }
  
              } catch (XMLException e) {
                  throw new DBException("Cannot parse meta file", e);
              } catch (CoreException e) {
                  throw new DBException("Cannot persist project", e);
              } finally {
                  metaStream.close();
              }
          }
      }
  
      private DriverDescriptor importDriver(
          DBRProgressMonitor monitor,
          Element driverElement,
          ZipFile zipFile,
          Map<String, String> libMap,
          Map<String, String> driverMap) throws IOException, DBException
      {
          String providerId = driverElement.getAttribute(RegistryConstants.ATTR_PROVIDER);
          String driverId = driverElement.getAttribute(RegistryConstants.ATTR_ID);
          boolean isCustom = CommonUtils.getBoolean(driverElement.getAttribute(RegistryConstants.ATTR_CUSTOM));
          String driverCategory = driverElement.getAttribute(RegistryConstants.ATTR_CATEGORY);
          String driverName = driverElement.getAttribute(RegistryConstants.ATTR_NAME);
          String driverClass = driverElement.getAttribute(RegistryConstants.ATTR_CLASS);
          String driverURL = driverElement.getAttribute(RegistryConstants.ATTR_URL);
          String driverDefaultPort = driverElement.getAttribute(RegistryConstants.ATTR_PORT);
          String driverDescription = driverElement.getAttribute(RegistryConstants.ATTR_DESCRIPTION);
  
          DataSourceProviderDescriptor dataSourceProvider = DataSourceProviderRegistry.getInstance().getDataSourceProvider(providerId);
          if (dataSourceProvider == null) {
              throw new DBException("Cannot find data source provider '" + providerId + "' for driver '" + driverName + "'");
          }
          monitor.subTask(CoreMessages.dialog_project_import_wizard_monitor_load_driver + driverName);
  
          DriverDescriptor driver = null;
          if (!isCustom) {
              // Get driver by ID
              driver = dataSourceProvider.getDriver(driverId);
              if (driver == null) {
                  log.warn("Driver '" + driverId + "' not found in data source provider '" + dataSourceProvider.getName() + "'"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
              }
          }
          if (driver == null) {
              // Try to find existing driver by class name
              List<DriverDescriptor> matchedDrivers = new ArrayList<>();
              for (DriverDescriptor tmpDriver : dataSourceProvider.getEnabledDrivers()) {
                  if (tmpDriver.getDriverClassName().equals(driverClass)) {
                      matchedDrivers.add(tmpDriver);
                  }
              }
              if (matchedDrivers.size() == 1) {
                  driver = matchedDrivers.get(0);
              } else if (!matchedDrivers.isEmpty()) {
                  // Multiple drivers with the same class - tru to find driver with the same sample URL or with the same name
                  for (DriverDescriptor tmpDriver : matchedDrivers) {
                      if (CommonUtils.equalObjects(tmpDriver.getSampleURL(), driverURL) || CommonUtils.equalObjects(tmpDriver.getName(), driverName)) {
                          driver = tmpDriver;
                          break;
                      }
                  }
                  if (driver == null) {
                      // Not found - lets use first one
                      log.warn("Ambiguous driver '" + driverName + "' - multiple drivers with class '" + driverClass + "' found. First one will be used"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
                      driver = matchedDrivers.get(0);
                  }
              }
          }
          if (driver == null) {
              // Create new driver
              driver = dataSourceProvider.createDriver();
              driver.setName(driverName);
              driver.setCategory(driverCategory);
              driver.setDescription(driverDescription);
              driver.setDriverClassName(driverClass);
              if (!CommonUtils.isEmpty(driverDefaultPort)) {
                  driver.setDriverDefaultPort(driverDefaultPort);
              }
              driver.setSampleURL(driverURL);
              driver.setModified(true);
              dataSourceProvider.addDriver(driver);
          }
  
          // Parameters and properties
          for (Element libElement : XMLUtils.getChildElementList(driverElement, RegistryConstants.TAG_PARAMETER)) {
              driver.setDriverParameter(
                  libElement.getAttribute(RegistryConstants.ATTR_NAME),
                  libElement.getAttribute(RegistryConstants.ATTR_VALUE),
                  false);
          }
          for (Element libElement : XMLUtils.getChildElementList(driverElement, RegistryConstants.TAG_PROPERTY)) {
              driver.setConnectionProperty(
                  libElement.getAttribute(RegistryConstants.ATTR_NAME),
                  libElement.getAttribute(RegistryConstants.ATTR_VALUE));
          }
  
          // Add libraries (only for managable drivers with empty library list)
          if (CommonUtils.isEmpty(driver.getDriverLibraries())) {
              List<String> libraryList = new ArrayList<>();
              for (Element libElement : XMLUtils.getChildElementList(driverElement, RegistryConstants.TAG_FILE)) {
                  libraryList.add(libElement.getAttribute(RegistryConstants.ATTR_PATH));
              }
  
              for (String libPath : libraryList) {
                  File libFile = new File(libPath);
                  if (libFile.exists()) {
                      // Just use path as-is (may be it is local re-import or local environments equal to export environment)
                      driver.addDriverLibrary(libPath, DBPDriverLibrary.FileType.jar);
                  } else {
                      // Get driver library from archive
                      String archiveLibEntry = libMap.get(libPath);
                      if (archiveLibEntry != null) {
                          ZipEntry libEntry = zipFile.getEntry(archiveLibEntry);
                          if (libEntry != null) {
                              // Extract driver to "drivers" folder
                              String libName = libFile.getName();
  