diff --git a/common/plugins/org.jboss.tools.common/.classpath b/common/plugins/org.jboss.tools.common/.classpath index c654d14e7..4a00becd8 100644 --- a/common/plugins/org.jboss.tools.common/.classpath +++ b/common/plugins/org.jboss.tools.common/.classpath @@ -7,6 +7,5 @@ - diff --git a/common/plugins/org.jboss.tools.common/META-INF/MANIFEST.MF b/common/plugins/org.jboss.tools.common/META-INF/MANIFEST.MF index ca98a8f0a..ec9b56bf6 100644 --- a/common/plugins/org.jboss.tools.common/META-INF/MANIFEST.MF +++ b/common/plugins/org.jboss.tools.common/META-INF/MANIFEST.MF @@ -1,7 +1,6 @@ Manifest-Version: 1.0 Bundle-Name: %Bundle-Name.0 -Bundle-ClassPath: ., - lib/jackson-dataformat-yaml-2.13.2.jar +Bundle-ClassPath: . Bundle-Activator: org.jboss.tools.common.CommonPlugin Bundle-Vendor: %providerName Bundle-SymbolicName: org.jboss.tools.common;singleton:=true diff --git a/common/plugins/org.jboss.tools.common/pom.xml b/common/plugins/org.jboss.tools.common/pom.xml index 36fcd4ee7..d0c6ede7f 100644 --- a/common/plugins/org.jboss.tools.common/pom.xml +++ b/common/plugins/org.jboss.tools.common/pom.xml @@ -10,43 +10,4 @@ org.jboss.tools.common eclipse-plugin - - - - org.apache.maven.plugins - maven-dependency-plugin - - - get-deps-lib - - copy - - generate-resources - - - - - - com.fasterxml.jackson.dataformat - jackson-dataformat-yaml - 2.13.2 - - - false - ${basedir}/lib/ - - - - - maven-clean-plugin - - - - ${basedir}/lib - - - - - - diff --git a/common/plugins/org.jboss.tools.common/src/org/jboss/tools/common/util/DownloadHelper.java b/common/plugins/org.jboss.tools.common/src/org/jboss/tools/common/util/DownloadHelper.java deleted file mode 100644 index f31d83b91..000000000 --- a/common/plugins/org.jboss.tools.common/src/org/jboss/tools/common/util/DownloadHelper.java +++ /dev/null @@ -1,404 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2020-2022 Red Hat, Inc. - * Distributed under license by Red Hat, Inc. All rights reserved. - * This program is made available under the terms of the - * Eclipse Public License v2.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v20.html - * - * Contributors: - * Red Hat, Inc. - initial API and implementation - ******************************************************************************/ -package org.jboss.tools.common.util; - -import java.io.BufferedInputStream; -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.StringReader; -import java.io.StringWriter; -import java.lang.reflect.InvocationTargetException; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.CompletableFuture; -import java.util.function.Function; -import java.util.function.Predicate; -import java.util.function.UnaryOperator; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.apache.commons.compress.archivers.ArchiveEntry; -import org.apache.commons.compress.archivers.ArchiveInputStream; -import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; -import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream; -import org.apache.commons.compress.compressors.CompressorException; -import org.apache.commons.compress.compressors.CompressorStreamFactory; -import org.apache.commons.exec.CommandLine; -import org.apache.commons.exec.DefaultExecutor; -import org.apache.commons.exec.PumpStreamHandler; -import org.apache.commons.io.FilenameUtils; -import org.apache.commons.io.IOUtils; -import org.apache.commons.io.output.WriterOutputStream; -import org.apache.commons.lang3.StringUtils; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClients; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.Platform; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.dialogs.ProgressMonitorDialog; -import org.eclipse.jface.operation.IRunnableWithProgress; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.PlatformUI; -import org.jboss.tools.common.CommonPlugin; - -public class DownloadHelper { - - public static final String HOME_FOLDER = System.getProperty("user.home"); //$NON-NLS-1$ - - private final class ToolDownloadRunnable implements IRunnableWithProgress { - private final String toolName; - private final Path path; - private final ToolsConfig.Platform platform; - private final Path dlFilePath; - - ToolDownloadRunnable(String toolName, Path path, ToolsConfig.Platform platform, Path dlFilePath) { - this.toolName = toolName; - this.path = path; - this.platform = platform; - this.dlFilePath = dlFilePath; - } - - @Override - public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { - monitor.beginTask("Connecting to remote url...", IProgressMonitor.UNKNOWN); - try (CloseableHttpClient client = HttpClients.createDefault()) { - HttpGet request = new HttpGet(platform.getUrl().toString()); - try (CloseableHttpResponse response = client.execute(request)) { - monitor.beginTask("Downloading " + toolName + "...", (int) response.getEntity().getContentLength()); - try (InputStream content = response.getEntity().getContent()) { - downloadFile(content, dlFilePath, monitor); - if (monitor.isCanceled()) { - throw new InterruptedException("Interrupted"); - } - } - uncompress(dlFilePath, path); - monitor.done(); - } catch (UnsupportedOperationException e) { - throw new InvocationTargetException(e); - } catch (IOException e) { - throw new InvocationTargetException(e); - } - } catch (IOException e) { - throw new InvocationTargetException(e); - } - - } - } - - private static final UnaryOperator UNCOMPRESSOR = new UnaryOperator() { - @Override - public InputStream apply(InputStream input) { - - try { - return new CompressorStreamFactory().createCompressorInputStream(input); - } catch (CompressorException e) { - throw new RuntimeException(e); - } - } - }; - - private static final UnaryOperator UNTAR = new UnaryOperator() { - @Override - public InputStream apply(InputStream input) { - return new TarArchiveInputStream(input); - } - }; - - private static final UnaryOperator UNZIP = new UnaryOperator() { - @Override - public InputStream apply(InputStream input) { - return new ZipArchiveInputStream(input); - } - }; - - private static final Map> MAPPERS = new HashMap>(); - - static { - MAPPERS.put("gz", UNCOMPRESSOR); //$NON-NLS-1$ - MAPPERS.put("zip", UNZIP); //$NON-NLS-1$ - MAPPERS.put("tar", UNTAR); //$NON-NLS-1$ - } - - private DownloadHelper() { - } - - private static DownloadHelper instance; - - public static DownloadHelper getInstance() { - if (instance == null) { - instance = new DownloadHelper(); - } - return instance; - } - - /** - * Download tool if required. First look at PATH then use the configuration file - * provided by the url to download the tool. The format of the file is the - * following: - * - *
-	 * {
-	 *   "tools": {
-	 *     "tool": {
-	 *       "version": "1.0.0",
-	 *       "versionCmd": "version", //the argument(s) to add to cmdFileName to get the version
-	 *       "versionExtractRegExp": "", //the regular expression to extract the version string from the version command
-	 *       "versionMatchRegExpr": "", //the regular expression use to match the extracted version to decide if download if required
-	 *       "baseDir": "" //the basedir to install to, a sub folder named after version will be created, can use $HOME
-	 *       "platforms": {
-	 *         "win": {
-	 *           "url": "https://tool.com/tool/v1.0.0/odo-windows-amd64.exe.tar.gz",
-	 *           "cmdFileName": "tool.exe",
-	 *           "dlFileName": "tool-windows-amd64.exe.gz"
-	 *         },
-	 *         "osx": {
-	 *           "url": "https://tool.com/tool/v1.0.0/odo-darwin-amd64.tar.gz",
-	 *           "cmdFileName": "tool",
-	 *           "dlFileName": "tool-darwin-amd64.gz"
-	 *         },
-	 *         "lnx": {
-	 *           "url": "https://tool.com/tool/v1.0.0/odo-linux-amd64.tar.gz",
-	 *           "cmdFileName": "odo",
-	 *           "dlFileName": "odo-linux-amd64.gz"
-	 *         }
-	 *       }
-	 *     }
-	 *   }
-	 * }
-	 * 
- * - * @param toolName - * @param url - * @return - * @throws IOException - */ - public String downloadIfRequired(final String toolName, URL url) throws IOException { - ToolsConfig config = ToolsConfig.loadToolsConfig(url); - ToolsConfig.Tool tool = config.getTools().get(toolName); - if (tool == null) { - throw new IOException("Tool " + toolName + " not found in config file " + url); - } - final ToolsConfig.Platform platform = getPlatformBasedOnOs(tool); - if (platform == null) { - throw new IOException("Platform for Tool " + toolName + " not found in config file " + url); - } - String command = platform.getCmdFileName(); - String version = getVersionFromPath(tool, platform); - if (!areCompatible(version, tool.getVersionMatchRegExpr())) { - final Path path = Paths.get(tool.getBaseDir().replace("$HOME", HOME_FOLDER), "cache", tool.getVersion(), - command); - if (!Files.exists(path)) { - return askAndDownloadToolinUI(toolName, tool, platform, version, path); - } - return path.toString(); - } - return command; - } - - private ToolsConfig.Platform getPlatformBasedOnOs(ToolsConfig.Tool tool) { - String osArch = Platform.getOSArch(); - String osId = Platform.getOS(); - if (tool.getPlatforms().containsKey(osId + "-" + osArch)) { - return tool.getPlatforms().get(osId + "-" + osArch); - } - return tool.getPlatforms().get(osId); - - } - - public CompletableFuture downloadIfRequiredAsync(String toolName, URL url) { - CompletableFuture result = new CompletableFuture<>(); - Display.getDefault().asyncExec(() -> { - try { - result.complete(downloadIfRequired(toolName, url)); - } catch (IOException e) { - result.completeExceptionally(e); - } - }); - return result; - } - - private String askAndDownloadToolinUI(final String toolName, ToolsConfig.Tool tool, - final ToolsConfig.Platform platform, String version, final Path path) throws IOException { - Display display = Display.getCurrent(); - if (display != null) { - return askAndDownloadTool(toolName, tool, platform, version, path); - } - String[] result = new String[1]; - IOException[] error = new IOException[1]; - Display.getDefault().syncExec(() -> { - try { - result[0] = askAndDownloadTool(toolName, tool, platform, version, path); - } catch (IOException e) { - error[0] = e; - } - - }); - if (error[0] != null) { - throw error[0]; - } - return result[0]; - } - - private String askAndDownloadTool(final String toolName, ToolsConfig.Tool tool, final ToolsConfig.Platform platform, - String version, final Path path) throws IOException { - final Path dlFilePath = path.resolveSibling(platform.getDlFileName()); - final String cmd = path.toString(); - if (isDownloadAllowed(toolName, version, tool.getVersion())) { - IRunnableWithProgress op = new ToolDownloadRunnable(toolName, path, platform, dlFilePath); - try { - new ProgressMonitorDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell()).run(true, - true, op); - } catch (InvocationTargetException e) { - throw new IOException(e.getLocalizedMessage(), e); - } catch (InterruptedException e) { - throw new IOException(toolName + " download interrupted.", e); - } - return cmd; - - } - // return default from config file - return platform.getCmdFileName(); - } - - public boolean isDownloadAllowed(String tool, String currentVersion, String requiredVersion) { - String message = StringUtils.isEmpty(currentVersion) - ? tool + " not found, do you want to download " + tool + " " + requiredVersion + " ?" - : tool + " " + currentVersion + " found, required version is " + requiredVersion - + ", do you want to download " + tool + " ?"; - String title = tool + " tool required"; - return MessageDialog.open(MessageDialog.QUESTION_WITH_CANCEL, - PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), title, message, SWT.NONE); - } - - private boolean areCompatible(String version, String versionMatchRegExpr) { - boolean compatible = true; - if (StringUtils.isNotBlank(versionMatchRegExpr)) { - Pattern pattern = Pattern.compile(versionMatchRegExpr); - compatible = pattern.matcher(version).matches(); - } else if (StringUtils.isBlank(version)) { - compatible = false; - } - return compatible; - } - - private String getVersionFromPath(ToolsConfig.Tool tool, ToolsConfig.Platform platform) { - - final Pattern pattern = Pattern.compile(tool.getVersionExtractRegExp()); - String[] arguments = tool.getVersionCmd().split(" "); - String version = ""; - try { - String output = executeInCommandline(platform.getCmdFileName(), new File(HOME_FOLDER), arguments); - try (BufferedReader reader = new BufferedReader(new StringReader(output))) { - version = reader.lines().map(new Function() { - @Override - public Matcher apply(String line) { - return pattern.matcher(line); - } - }).filter(new Predicate() { - @Override - public boolean test(Matcher matcher) { - return matcher.matches(); - } - }).map(new Function() { - @Override - public String apply(Matcher matcher) { - return matcher.group(1); - } - }).findFirst().orElse(""); - } - } catch (IOException e) { - // do not throw or verify error, as the tool can be not present in the first - // try. - } - return version; - - } - - void downloadFile(InputStream input, Path dlFileName, IProgressMonitor monitor) throws IOException { - byte[] buffer = new byte[4096]; - Files.createDirectories(dlFileName.getParent()); - try (OutputStream output = Files.newOutputStream(dlFileName)) { - int lg; - while (((lg = input.read(buffer)) > 0) && !monitor.isCanceled()) { - output.write(buffer, 0, lg); - monitor.worked(lg); - } - } - } - - private InputStream mapStream(String filename, InputStream input) { - String extension; - while (((extension = FilenameUtils.getExtension(filename)) != null) && MAPPERS.containsKey(extension)) { - filename = FilenameUtils.removeExtension(filename); - input = MAPPERS.get(extension).apply(input); - } - return input; - } - - void uncompress(Path dlFilePath, Path cmd) throws IOException { - try (InputStream input = new BufferedInputStream(Files.newInputStream(dlFilePath)); - InputStream subStream = mapStream(dlFilePath.toString(), input)) { - if (subStream instanceof ArchiveInputStream) { - ArchiveEntry entry; - - while ((entry = ((ArchiveInputStream) subStream).getNextEntry()) != null) { - save(subStream, cmd.resolveSibling(entry.getName()), entry.getSize()); - } - } else { - save(subStream, cmd, -1L); - } - } - } - - private void save(InputStream source, Path destination, long length) throws IOException { - try (OutputStream stream = Files.newOutputStream(destination)) { - if (length == -1L) { - IOUtils.copy(source, stream); - } else { - IOUtils.copyLarge(source, stream, 0L, length); - } - if (!destination.toFile().setExecutable(true)) { - CommonPlugin.getDefault().logError("Cannot set executable bit for: " + destination.toFile().getPath()); - } - } - } - - private String executeInCommandline(String executable, File workingDirectory, String... arguments) - throws IOException { - DefaultExecutor executor = new DefaultExecutor(); - try (StringWriter writer = new StringWriter(); - WriterOutputStream outStream = new WriterOutputStream(writer, StandardCharsets.UTF_8)) { - PumpStreamHandler handler = new PumpStreamHandler(outStream); - executor.setStreamHandler(handler); - executor.setWorkingDirectory(workingDirectory); - CommandLine command = new CommandLine(executable).addArguments(arguments); - String result = ""; - try { - executor.execute(command); - result = writer.toString(); - } catch (IOException e) { - throw new IOException(e.getLocalizedMessage() + " " + result, e); - } - return result; - } - } -} diff --git a/common/plugins/org.jboss.tools.common/src/org/jboss/tools/common/util/ToolsConfig.java b/common/plugins/org.jboss.tools.common/src/org/jboss/tools/common/util/ToolsConfig.java deleted file mode 100644 index 6ea8e3dc1..000000000 --- a/common/plugins/org.jboss.tools.common/src/org/jboss/tools/common/util/ToolsConfig.java +++ /dev/null @@ -1,127 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2020 Red Hat, Inc. - * Distributed under license by Red Hat, Inc. All rights reserved. - * This program is made available under the terms of the - * Eclipse Public License v2.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v20.html - * - * Contributors: - * Red Hat, Inc. - initial API and implementation - ******************************************************************************/ -package org.jboss.tools.common.util; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; - -import java.io.IOException; -import java.net.URL; -import java.util.HashMap; -import java.util.Map; - -@JsonIgnoreProperties(ignoreUnknown = true) -public class ToolsConfig { - private static final ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); - - public static class Tool { - private Map platforms = new HashMap(); - - private String version; - private String versionCmd; - private String versionExtractRegExp; - private String versionMatchRegExpr; - private String baseDir; - - public Map getPlatforms() { - return platforms; - } - - public void setPlatforms(Map platforms) { - this.platforms = platforms; - } - - public String getVersion() { - return version; - } - - public void setVersion(String version) { - this.version = version; - } - - public String getVersionCmd() { - return versionCmd; - } - - public void setVersionCmd(String versionCmd) { - this.versionCmd = versionCmd; - } - - public String getVersionExtractRegExp() { - return versionExtractRegExp; - } - - public void setVersionExtractRegExp(String versionExtractRegExp) { - this.versionExtractRegExp = versionExtractRegExp; - } - - public String getVersionMatchRegExpr() { - return versionMatchRegExpr; - } - - public void setVersionMatchRegExpr(String versionMatchRegExpr) { - this.versionMatchRegExpr = versionMatchRegExpr; - } - - public String getBaseDir() { - return baseDir; - } - - public void setBaseDir(String baseDir) { - this.baseDir = baseDir; - } - } - - public static class Platform { - private URL url; - private String cmdFileName; - private String dlFileName; - - public URL getUrl() { - return url; - } - - public void setUrl(URL url) { - this.url = url; - } - - public String getCmdFileName() { - return cmdFileName; - } - - public void setCmdFileName(String cmdFileName) { - this.cmdFileName = cmdFileName; - } - - public String getDlFileName() { - return dlFileName; - } - - public void setDlFileName(String dlFileName) { - this.dlFileName = dlFileName; - } - } - - private Map tools = new HashMap(); - - public Map getTools() { - return tools; - } - - public void setTools(Map tools) { - this.tools = tools; - } - - public static ToolsConfig loadToolsConfig(URL url) throws IOException { - return mapper.readValue(url, ToolsConfig.class); - } -}