/* * 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.driver; import org.eclipse.core.runtime.IConfigurationElement; import org.jkiss.code.NotNull; import org.jkiss.code.Nullable; import org.jkiss.dbeaver.Log; import org.jkiss.dbeaver.core.DBeaverCore; import org.jkiss.dbeaver.model.access.DBAAuthInfo; import org.jkiss.dbeaver.model.connection.DBPDriverLibrary; import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor; import org.jkiss.dbeaver.model.runtime.OSDescriptor; import org.jkiss.dbeaver.registry.RegistryConstants; import org.jkiss.dbeaver.runtime.WebUtils; import org.jkiss.utils.CommonUtils; import java.io.*; import java.net.URLConnection; import java.text.NumberFormat; import java.util.Collection; import java.util.Collections; /** * DriverLibraryAbstract */ public abstract class DriverLibraryAbstract implements DBPDriverLibrary { private static final Log log = Log.getLog(DriverLibraryAbstract.class); protected final DriverDescriptor driver; protected final FileType type; protected final OSDescriptor system; protected String path; protected boolean custom; protected boolean disabled; public static DriverLibraryAbstract createFromPath(DriverDescriptor driver, FileType type, String path, String preferredVersion) { if (path.startsWith(DriverLibraryRepository.PATH_PREFIX)) { return new DriverLibraryRepository(driver, type, path); } else if (path.startsWith(DriverLibraryMavenArtifact.PATH_PREFIX)) { return new DriverLibraryMavenArtifact(driver, type, path, preferredVersion); } else { if (DriverLibraryRemote.supportsURL(path)) { return new DriverLibraryRemote(driver, type, path); } else { return new DriverLibraryLocal(driver, type, path); } } } public static DriverLibraryAbstract createFromConfig(DriverDescriptor driver, IConfigurationElement config) { String path = config.getAttribute(RegistryConstants.ATTR_PATH); if (CommonUtils.isEmpty(path)) { log.error("Bad file path"); return null; } if (path.startsWith(DriverLibraryRepository.PATH_PREFIX)) { return new DriverLibraryRepository(driver, config); } else if (path.startsWith(DriverLibraryMavenArtifact.PATH_PREFIX)) { return new DriverLibraryMavenArtifact(driver, config); } else { if (DriverLibraryRemote.supportsURL(path)) { return new DriverLibraryRemote(driver, config); } else { return new DriverLibraryLocal(driver, config); } } } protected DriverLibraryAbstract(DriverDescriptor driver, FileType type, String path) { this.driver = driver; this.type = type; this.system = null; this.path = path; this.custom = true; } protected DriverLibraryAbstract(DriverDescriptor driver, IConfigurationElement config) { this.driver = driver; this.type = FileType.valueOf(config.getAttribute(RegistryConstants.ATTR_TYPE)); String osName = config.getAttribute(RegistryConstants.ATTR_OS); this.system = osName == null ? null : new OSDescriptor( osName, config.getAttribute(RegistryConstants.ATTR_ARCH)); this.path = config.getAttribute(RegistryConstants.ATTR_PATH); this.custom = false; } public DriverDescriptor getDriver() { return driver; } @Override public String getVersion() { return null; } @NotNull @Override public Collection<String> getAvailableVersions(DBRProgressMonitor monitor) throws IOException { return Collections.emptyList(); } @Override public String getPreferredVersion() { return null; } @Override public void setPreferredVersion(String version) { // do nothing } @NotNull @Override public FileType getType() { return type; } @NotNull @Override public String getPath() { return path; } @Override public String getDescription() { return null; } @Override public boolean isCustom() { return custom; } public void setCustom(boolean custom) { this.custom = custom; } @Override public boolean isDisabled() { return disabled; } public void setDisabled(boolean disabled) { this.disabled = disabled; } @Override public boolean matchesCurrentPlatform() { return system == null || system.matches(DBeaverCore.getInstance().getLocalSystem()); } public void downloadLibraryFile(@NotNull DBRProgressMonitor monitor, boolean forceUpdate, String taskName) throws IOException, InterruptedException { final File localFile = getLocalFile(); if (localFile == null) { throw new IOException("No target file for '" + getPath() + "'"); } if (!forceUpdate && localFile.exists()) { return; } final File localDir = localFile.getParentFile(); if (!localDir.exists()) { if (!localDir.mkdirs()) { log.warn("Can't create directory for local driver file '" + localDir.getAbsolutePath() + "'"); } } String externalURL = getExternalURL(monitor); if (externalURL == null) { throw new IOException("Unresolved file reference: " + getPath()); } final URLConnection connection = WebUtils.openConnection(externalURL, getAuthInfo(monitor)); int contentLength = connection.getContentLength(); if (contentLength < 0) { contentLength = 0; } int bufferLength = contentLength / 10; if (bufferLength > 1000000) { bufferLength = 1000000; } if (bufferLength < 50000) { bufferLength = 50000; } monitor.beginTask(taskName + " - " + externalURL, contentLength); boolean success = false; try (final OutputStream outputStream = new FileOutputStream(localFile)) { try (final InputStream inputStream = connection.getInputStream()) { final NumberFormat numberFormat = NumberFormat.getNumberInstance(); byte[] buffer = new byte[bufferLength]; int totalRead = 0; for (;;) { if (monitor.isCanceled()) { throw new InterruptedException(); } //monitor.subTask(numberFormat.format(totalRead) + "/" + numberFormat.format(contentLength)); final int count = inputStream.read(buffer); if (count <= 0) { success = true; break; } outputStream.write(buffer, 0, count); monitor.worked(count); totalRead += count; } } } finally { if (!success) { if (!localFile.delete()) { log.warn("Can't delete local driver file '" + localFile.getAbsolutePath() + "'"); } } monitor.done(); } } @Nullable protected DBAAuthInfo getAuthInfo(DBRProgressMonitor monitor) { return null; } @Override public String toString() { return getDisplayName(); } }