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

io.vlingo.maven.codegen.NativeActorProxyGenerator Maven / Gradle / Ivy

// Copyright © 2012-2020 VLINGO LABS. All rights reserved.
//
// This Source Code Form is subject to the terms of the
// Mozilla Public License, v. 2.0. If a copy of the MPL
// was not distributed with this file, You can obtain
// one at https://mozilla.org/MPL/2.0/.

package io.vlingo.maven.codegen;

import static java.util.stream.Collectors.toSet;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.project.MavenProject;

import io.vlingo.actors.ProxyGenerator;

@Mojo(name="nativeActorProxyGen", defaultPhase = LifecyclePhase.GENERATE_SOURCES, requiresDependencyCollection = ResolutionScope.COMPILE_PLUS_RUNTIME, requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME)
public class NativeActorProxyGenerator extends AbstractMojo {
  private static final Path REFLECTION_JSON = new File("target/classes/reflection.json").toPath();

  @Parameter(defaultValue = "src/main/java")
  private String sourceRoot;
  @Parameter()
  private String[] additionalProtocols;
  @Parameter(defaultValue = "${project}", readonly = true)
  private MavenProject mavenProject;

  private final io.vlingo.actors.Logger logger;

  public NativeActorProxyGenerator() {
    this.logger = io.vlingo.actors.Logger.basicLogger();
    logger.info("vlingo/maven: Native actor proxy generator loaded.");
  }

  @Override
  public void execute() throws MojoExecutionException {
    final ProtocolScanner scanner = new ProtocolScanner(new File(sourceRoot));
    final Set protocolsAndProxies = new HashSet<>(scanner.scan());
    final ProxyGenerator proxyGenerator = newGenerator();
    final NativeImageReflectionConfigurationGenerator reflectionConfigurationGenerator = new NativeImageReflectionConfigurationGenerator(protocolsAndProxies);
    final Set actorProtocols = protocolsAndProxies.stream().filter(className -> !className.endsWith("__Proxy")).collect(toSet());

    try {
      actorProtocols.forEach(proxyGenerator::generateFor);

      if (additionalProtocols != null) {
        protocolsAndProxies.addAll(Arrays.asList(additionalProtocols));
      }

      protocolsAndProxies.addAll(additionalProtocolsFromLibraries());
      Files.write(REFLECTION_JSON, reflectionConfigurationGenerator.generate().getBytes());
    } catch (Exception e) {
      final String message = "Proxy generator failed because: " + e.getMessage();
      logger.error(message, e);
      e.printStackTrace();
      throw new MojoExecutionException(message, e);
    }
  }

  private ProxyGenerator newGenerator() throws MojoExecutionException {
    try {
      return ProxyGenerator.forMain(getClass().getClassLoader(), true, logger);
    } catch (Exception e) {
      final String message = "Proxy generator failed because: " + e.getMessage();
      logger.error(message, e);
      e.printStackTrace();
      throw new MojoExecutionException(message, e);
    }
  }

  private Set additionalProtocolsFromLibraries() {
    return mavenProject.getArtifacts().stream()
            .peek(e -> {
              logger.info(e.toString());
              logger.info(e.getType());
              logger.info(e.getFile().toString());
            })
            .filter(Artifact::isResolved)
            .map(Artifact::getFile)
            .map(this::contentFromVlingoReflectionList)
            .filter(Objects::nonNull)
            .flatMap(fileContent -> Arrays.stream(fileContent.split("\n")))
            .map(String::trim)
            .collect(toSet());
  }

  private String contentFromVlingoReflectionList(File file) {
    try (ZipInputStream zis = new ZipInputStream(new FileInputStream(file))) {
      ZipEntry zipEntry = zis.getNextEntry();
      byte[] buffer = new byte[1024];
      while (zipEntry != null) {
        if (zipEntry.getName().equals("vlingo-reflection")) {
          ByteArrayOutputStream bos = new ByteArrayOutputStream();
          int len;
          while ((len = zis.read(buffer)) > 0) {
            bos.write(buffer, 0, len);
          }
          bos.close();
          return new String(bos.toByteArray());
        } else {
          zipEntry = zis.getNextEntry();
        }
      }
    } catch (Exception e) {
      logger.error("Could not load reflection list from " + file.toString(), e);
      return null;
    }

    return null;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy