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

net.morimekta.providence.maven.plugin.BaseGenerateSourcesMojo Maven / Gradle / Ivy

/*
 * Copyright 2016 Providence Authors
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you 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 net.morimekta.providence.maven.plugin;

import net.morimekta.providence.generator.Generator;
import net.morimekta.providence.generator.GeneratorException;
import net.morimekta.providence.generator.GeneratorFactory;
import net.morimekta.providence.generator.GeneratorOptions;
import net.morimekta.providence.generator.format.java.JavaGenerator;
import net.morimekta.providence.generator.format.java.JavaGeneratorFactory;
import net.morimekta.providence.generator.format.java.JavaOptions;
import net.morimekta.providence.generator.util.FileManager;
import net.morimekta.providence.maven.util.ProvidenceInput;
import net.morimekta.providence.reflect.ProgramLoader;
import net.morimekta.providence.reflect.ProgramRegistry;
import net.morimekta.providence.reflect.parser.ThriftException;
import net.morimekta.util.FileUtil;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.components.io.fileselectors.IncludeExcludeFileSelector;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import java.util.Set;

/**
 * mvn net.morimekta.providence:providence-maven-plugin:1.3.1:help -Ddetail=true -Dgoal=compile
 */
public abstract class BaseGenerateSourcesMojo extends AbstractMojo {
    // -----------    PARSER OPTIONS    ----------- //

    /**
     * If the thrift program parser should fail if enum value is missing for
     * any enum value definition parsed.
     */
    @Parameter(defaultValue = "false",
               property = "providence.gen.require_enum_value",
               alias = "requireEnumValue")
    protected boolean require_enum_value;

    /**
     * If the thrift program parser should fail if field ID is missing for any
     * field definitions parsed.
     */
    @Parameter(defaultValue = "false",
               property = "providence.gen.require_field_id",
               alias = "requireFieldId")
    protected boolean require_field_id;

    /**
     * Allow reserved words that would cause name problems in some thrift generated
     * code. This allows reserved words as names, not thrift keywords. This applies
     * to all type names (enums, messages, services, typedefs), all fields (message
     * fields, method params, method throws), method names, const names and enum
     * values.
     */
    @Parameter(defaultValue = "true",
               alias = "allow_reserved_names",
               property = "providence.gen.allow_language_reserved_names")
    protected boolean allow_language_reserved_names = true;

    // -----------    GENERATE OPTIONS    ----------- //
    /**
     * If set to true will add jackson 2 annotations to messages and enums.
     * Required additional dependency on jackson 2 extra libraries:
     * 
    *
  • com.fasterxml.jackson.extra:jackson-annotations:2.x *
  • com.fasterxml.jackson.extra:jackson-extra:2.x *
  • com.fasterxml.jackson.extra:jackson-databind:2.x *
*/ @Parameter(defaultValue = "false", property = "providence.gen.jackson") protected boolean jackson; /** * Generate model methods to read and write same as the binary protocol. * Can be turned off to reduce the amount of generated code. Serialization * will work regardless, but keeping this enabled speeds up the binary * serialization significantly. */ @Parameter(defaultValue = "true", property = "providence.gen.rw_binary") protected boolean rw_binary = true; /** * Make all message types serializable. Defaults to true. If false, only * exceptions will be serializable (as the java.lang.Throwable * class implements serializable). */ @Parameter(defaultValue = "false", property = "providence.gen.serializable") protected boolean serializable = false; /** * If set to true will add hazelcast annotations to messages and enums. */ @Parameter(defaultValue = "false", property = "providence.gen.hazelcast_portable") protected boolean hazelcast_portable; /** * If true add version to generated annotations. */ @Parameter(defaultValue = "true", property = "providence.gen.generated_annotation_version") protected boolean generated_annotation_version; /** * If true add date to generated annotations. */ @Parameter(defaultValue = "true", property = "providence.gen.generated_annotation_date") protected boolean generated_annotation_date; @Parameter(defaultValue = "false", property = "providence.gen.generate_providence_core_types") protected boolean generate_providence_core_types; /** * Print extra debug info to the maven log. */ @Parameter(defaultValue = "false", property = "providence.print_debug") protected boolean print_debug; /** * If true will add the generated sources to be compiled. */ @Parameter(defaultValue = "true") protected boolean compileOutput; /** * Skip thrift files if they are missing the java namespace. */ @Parameter(defaultValue = "false", property = "providence.skip_if_missing_namespace") protected boolean skipIfMissingNamespace; // --- After here are internals, components and maven-set params. /** * Location of the output artifact. */ @Parameter(defaultValue = "${project.build.directory}", readonly = true, required = true) protected File buildDir = null; @Parameter(defaultValue = "${project}", readonly = true, required = true) protected MavenProject project = null; boolean executeInternal(File outputDir, IncludeExcludeFileSelector inputSelector, String defaultInputIncludes, boolean testCompile) throws MojoExecutionException, MojoFailureException { Set inputFiles = ProvidenceInput.getInputFiles( project.getBasedir().toPath(), inputSelector, defaultInputIncludes, print_debug, getLog()); if (inputFiles.isEmpty()) { return false; } if (!outputDir.exists()) { if (!outputDir.mkdirs()) { throw new MojoExecutionException("Unable to create target directory " + outputDir); } } Path workingDir = buildDir.toPath().resolve(testCompile ? "providence-test" : "providence"); try { if (Files.exists(workingDir)) { Files.list(workingDir).forEach(file -> { try { FileUtil.deleteRecursively(file); } catch (IOException e) { throw new UncheckedIOException(e.getMessage(), e); } }); } else { Files.createDirectories(workingDir); } } catch (IOException | UncheckedIOException e) { throw new MojoExecutionException(e.getMessage(), e); } FileManager fileManager = new FileManager(outputDir.toPath()); ProgramLoader loader = new ProgramLoader(require_field_id, require_enum_value, allow_language_reserved_names); if (print_debug) { inputFiles.forEach(f -> getLog().info("Compiling: " + f)); } JavaOptions javaOptions = new JavaOptions(); javaOptions.jackson = jackson; javaOptions.rw_binary = rw_binary; javaOptions.serializable = serializable; javaOptions.hazelcast_portable = hazelcast_portable; javaOptions.generated_annotation_version = generated_annotation_version; javaOptions.generated_annotation_date = generated_annotation_date; javaOptions.generate_providence_core_types = generate_providence_core_types; GeneratorOptions generatorOptions = new GeneratorOptions(); generatorOptions.generator_program_name = "providence-maven-plugin"; generatorOptions.program_version = getVersionString(); GeneratorFactory factory = new JavaGeneratorFactory(); Generator generator = new JavaGenerator(fileManager, generatorOptions, javaOptions); Path base = project.getBasedir().toPath().toAbsolutePath(); if (project.getParent() != null && project.getParent().getBasedir() != null) { // Only replace with parent if parent is a parent directory of this. Path parentBase = project.getParent().getBasedir().toPath().toAbsolutePath(); if (base.toString().startsWith(parentBase.toString())) { base = parentBase; } } List registries = new ArrayList<>(); for (Path in : inputFiles) { try { ProgramRegistry registry = loader.load(in); if (skipIfMissingNamespace && registry.getProgram().getNamespaceForLanguage(factory.generatorName()) == null) { getLog().warn("Skipping (no " + factory.generatorName() + " namespace) " + base.relativize(in)); } else { registries.add(registry); } } catch (ThriftException e) { // ParseException is a SerializerException. And serialize exceptions can come from // failing to make sense of constant definitions. getLog().error(" ============ >> PROVIDENCE << ============"); getLog().error(""); Arrays.stream(e.displayString().split("\r?\n", Short.MAX_VALUE)) .forEach(l -> getLog().error(l)); getLog().error(""); getLog().error(" ============ << PROVIDENCE >> ============"); throw new MojoFailureException("Failed to parse thrift file: " + in.getFileName(), e); } catch (IOException e) { throw new MojoExecutionException("Failed to read thrift file: " + in.getFileName(), e); } } for (ProgramRegistry registry : registries) { try { generator.generate(registry); } catch (GeneratorException e) { throw new MojoFailureException("Failed to generate program: " + registry.getProgram().getProgramName(), e); } catch (IOException e) { throw new MojoExecutionException("Failed to write program file: " + registry.getProgram().getProgramName(), e); } } try { generator.generateGlobal(loader.getGlobalRegistry(), inputFiles); } catch (GeneratorException e) { throw new MojoFailureException("Failed to generate global", e); } catch (IOException e) { throw new MojoExecutionException("Failed to write global file", e); } return compileOutput; } private static String getVersionString() { Properties properties = new Properties(); try (InputStream in = BaseGenerateSourcesMojo.class.getResourceAsStream( "/net/morimekta/providence/maven/providence_version.properties")) { properties.load(in); } catch (IOException e) { throw new UncheckedIOException(e.getMessage(), e); } return properties.getProperty("providence.version"); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy