All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.codemodder.plugins.maven.operator.AbstractQueryCommand Maven / Gradle / Ivy

package io.codemodder.plugins.maven.operator;

import io.github.pixee.security.BoundedLineReader;
import java.io.BufferedReader;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Common Base Class - Meant to be used by Simple Queries using either Invoker and/or Embedder, thus
 * relying on dependency:tree mojo outputting into a text file - which might be cached.
 */
abstract class AbstractQueryCommand extends AbstractCommand {

  protected static final Logger LOGGER = LoggerFactory.getLogger(AbstractQueryCommand.class);

  /**
   * Generates a temporary file path used to store the output of the
   *
   * 
dependency:tree
* * mojo * * @param pomFilePath POM Original File Path */ private Path getOutputPath(Path pomFilePath) { Path basePath = pomFilePath.getParent(); String outputBasename = String.format("output-%08X.txt", pomFilePath.hashCode()); return basePath.resolve(outputBasename); } /** * Given a POM URI, returns a File Object * * @param d POMDocument */ private Path getPomFilePath(POMDocument d) throws URISyntaxException { return Paths.get(d.getPomPath().toURI()); } /** * Abstract Method to extract dependencies * * @param outputPath Output Path to where to store the content * @param pomFilePath Input Pom Path * @param c Project Model */ protected abstract void extractDependencyTree(Path outputPath, Path pomFilePath, ProjectModel c); /** * Internal Holder Variable * *

Todo: OF COURSE IT BREAKS THE PROTOCOL */ protected Collection result = null; /** * Retrieves the collection of dependencies resulting from the query command execution. * * @return A collection of Dependency objects representing project dependencies. */ public Collection getResult() { return result; } /** * We declare the main logic here - details are made in the child classes for now Executes the * query command, extracting and processing project dependencies. * * @param pm The ProjectModel representing the project on which to execute the command. * @return true if the execution was successful, false otherwise. * @throws URISyntaxException If there is an issue with URIs in the execution. * @throws IOException If an IO error occurs during execution. */ @Override public boolean execute(ProjectModel pm) throws URISyntaxException, IOException { Path pomFilePath = getPomFilePath(pm.getPomFile()); Path outputPath = getOutputPath(pomFilePath); if (Files.exists(outputPath)) { Files.delete(outputPath); } try { extractDependencyTree(outputPath, pomFilePath, pm); } catch (InvalidContextException e) { return false; } result = extractDependencies(outputPath).values(); return true; } /** * Given a File containing the output of the dependency:tree mojo, read its contents and parse, * creating an array of dependencies * *

About the file contents: We receive something such as this, then filter it out: * *

   *     br.com.ingenieux:pom-operator:jar:0.0.1-SNAPSHOT
   *     +- xerces:xercesImpl:jar:2.12.1:compile
   *     |  \- xml-apis:xml-apis:jar:1.4.01:compile
   *     \- org.jetbrains.kotlin:kotlin-test:jar:1.5.31:test
   * 
* * @param outputPath file to read */ private Map extractDependencies(Path outputPath) throws IOException { Map dependencyMap = new HashMap<>(); try (BufferedReader reader = Files.newBufferedReader(outputPath)) { String line; boolean skipFirstLine = true; while ((line = BoundedLineReader.readLine(reader, 5_000_000)) != null) { if (skipFirstLine) { skipFirstLine = false; continue; } String trimmedLine = trimSpecialChars(line); String[] elements = trimmedLine.split(":"); if (elements.length >= 5) { String groupId = elements[0]; String artifactId = elements[1]; String packaging = elements[2]; String version = elements[3]; String scope = elements[4]; Dependency dependency = new Dependency(groupId, artifactId, version, null, packaging, scope); dependencyMap.put(line, dependency); } } } return dependencyMap; } private String trimSpecialChars(String input) { char[] specialChars = "+-|\\ ".toCharArray(); int start = 0; int end = input.length(); while (start < end && isSpecialChar(input.charAt(start))) { start++; } while (end > start && isSpecialChar(input.charAt(end - 1))) { end--; } if (start > 0 || end < input.length()) { return input.substring(start, end); } return input; } private boolean isSpecialChar(char c) { char[] specialChars = "+-|\\ ".toCharArray(); for (char specialChar : specialChars) { if (c == specialChar) { return true; } } return false; } @Override public boolean postProcess(ProjectModel c) { return false; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy