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

tech.jhipster.lite.project.infrastructure.secondary.FileSystemProjectDownloader Maven / Gradle / Ivy

There is a newer version: 1.22.0
Show newest version
package tech.jhipster.lite.project.infrastructure.secondary;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import tech.jhipster.lite.project.domain.ProjectPath;
import tech.jhipster.lite.project.domain.download.Project;
import tech.jhipster.lite.project.domain.download.ProjectName;
import tech.jhipster.lite.shared.error.domain.Assert;
import tech.jhipster.lite.shared.generation.domain.ExcludeFromGeneratedCodeCoverage;

class FileSystemProjectDownloader {

  private static final Pattern PROJECT_NAME_PATTERN = Pattern.compile("\"description\": *\"([^\"]+)\"");

  public Optional download(ProjectPath path) {
    Assert.notNull("path", path);

    Path source = Paths.get(path.get());

    if (notAProject(source)) {
      return Optional.empty();
    }

    return zip(source)
      .map(content -> {
        ProjectName projectName = readProjectName(source);

        return Optional.of(new Project(projectName, content));
      })
      .orElse(Optional.empty());
  }

  private boolean notAProject(Path source) {
    return Files.notExists(source) || !Files.isDirectory(source);
  }

  @ExcludeFromGeneratedCodeCoverage(reason = "Hard to test exception handling")
  private ProjectName readProjectName(Path source) {
    Path packageJsonPath = source.resolve("package.json");

    if (Files.notExists(packageJsonPath)) {
      return ProjectName.DEFAULT;
    }

    try {
      Matcher matcher = PROJECT_NAME_PATTERN.matcher(Files.readString(packageJsonPath));

      if (!matcher.find()) {
        return ProjectName.DEFAULT;
      }

      return new ProjectName(matcher.group(1));
    } catch (IOException e) {
      throw new ProjectZippingException(e);
    }
  }

  @ExcludeFromGeneratedCodeCoverage(reason = "Hard to test exception handling")
  private static Optional zip(Path source) {
    ByteArrayOutputStream result = new ByteArrayOutputStream();

    try (Stream sourceFiles = Files.walk(source); ZipOutputStream zip = new ZipOutputStream(result)) {
      List files = sourceFiles.filter(regularFiles()).filter(notNodeModules()).toList();

      if (files.isEmpty()) {
        return Optional.empty();
      }

      files.forEach(appendFileEntry(source, zip));
    } catch (IOException e) {
      throw new ProjectZippingException(e);
    }

    return Optional.of(result.toByteArray());
  }

  private static Predicate regularFiles() {
    return Files::isRegularFile;
  }

  private static Predicate notNodeModules() {
    return path -> !path.toString().contains("/node_modules/");
  }

  private static Consumer appendFileEntry(Path source, ZipOutputStream zip) {
    return path -> {
      ZipEntry zipEntry = new ZipEntry(source.relativize(path).toString());

      appendToZipEntry(zip, path, zipEntry);
    };
  }

  @ExcludeFromGeneratedCodeCoverage(reason = "Hard to test exception handling")
  private static void appendToZipEntry(ZipOutputStream zip, Path path, ZipEntry zipEntry) {
    try {
      zip.putNextEntry(zipEntry);
      Files.copy(path, zip);
      zip.closeEntry();
    } catch (IOException e) {
      throw new ProjectZippingException(e);
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy