Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Efficiently refresh resources changed in generation mojos #331

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,97 @@ protected void createStaleFile(@NonNull File staleFile) throws MojoExecutionExce
}
}

@SuppressWarnings("PMD.AvoidCatchingGenericException")
@Override
public void execute() throws MojoExecutionException {
File staleFile = getStaleFile();
try {
staleFile = ObjectUtils.notNull(staleFile.getCanonicalFile());
} catch (IOException ex) {
if (getLog().isWarnEnabled()) {
getLog().warn("Unable to resolve canonical path to stale file. Treating it as not existing.", ex);
}
}

boolean generate;
if (shouldExecutionBeSkipped()) {
if (getLog().isDebugEnabled()) {
getLog().debug(String.format("Generation is configured to be skipped. Skipping."));
}
generate = false;
} else if (staleFile.exists()) {
generate = isGenerationRequired();
} else {
if (getLog().isInfoEnabled()) {
getLog().info(String.format("Stale file '%s' doesn't exist! Generation is required.", staleFile.getPath()));
}
generate = true;
}

if (generate) {

List<File> generatedFiles;
try {
generatedFiles = performGeneration();
} finally {
// ensure the stale file is created to ensure that regeneration is only
// performed when a
// change is made
createStaleFile(staleFile);
}

if (getLog().isInfoEnabled()) {
getLog().info(String.format("Generated %d files.", generatedFiles.size()));
}

// for m2e
for (File file : generatedFiles) {
getBuildContext().refresh(file);
}
}
}

@SuppressWarnings({ "PMD.AvoidCatchingGenericException", "PMD.ExceptionAsFlowControl" })
@NonNull
private List<File> performGeneration() throws MojoExecutionException {
File outputDir = getOutputDirectory();
if (getLog().isDebugEnabled()) {
getLog().debug(String.format("Using outputDirectory: %s", outputDir.getPath()));
}

if (!outputDir.exists() && !outputDir.mkdirs()) {
throw new MojoExecutionException("Unable to create output directory: " + outputDir);
}

IBindingContext bindingContext;
try {
bindingContext = newBindingContext();
} catch (MetaschemaException | IOException ex) {
throw new MojoExecutionException("Failed to create the binding context", ex);
}

// generate Java sources based on provided metaschema sources
Set<IModule> modules;
try {
modules = getModulesToGenerateFor(bindingContext);
} catch (Exception ex) {
throw new MojoExecutionException("Loading of metaschema modules failed", ex);
}

return generate(modules);
}

/**
* Perform the generation operation.
*
* @return the files generated during the operation
*
* @throws MojoExecutionException
* if an error occurred while performing the generation operation
*/
@NonNull
protected abstract List<File> generate(@NonNull Set<IModule> modules) throws MojoExecutionException;

protected final class LoggingValidationHandler
extends AbstractValidationResultProcessor {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@
import gov.nist.secauto.metaschema.core.configuration.IConfiguration;
import gov.nist.secauto.metaschema.core.configuration.IMutableConfiguration;
import gov.nist.secauto.metaschema.core.model.IModule;
import gov.nist.secauto.metaschema.core.model.MetaschemaException;
import gov.nist.secauto.metaschema.core.util.CollectionUtil;
import gov.nist.secauto.metaschema.core.util.ObjectUtils;
import gov.nist.secauto.metaschema.databind.IBindingContext;
import gov.nist.secauto.metaschema.schemagen.ISchemaGenerator;
import gov.nist.secauto.metaschema.schemagen.SchemaGenerationFeature;
import gov.nist.secauto.metaschema.schemagen.json.JsonSchemaGenerator;
Expand All @@ -30,6 +29,7 @@
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.EnumSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Set;
Expand Down Expand Up @@ -131,7 +131,9 @@ protected String getStaleFileName() {
* @throws MojoExecutionException
* if an error occurred during generation
*/
protected void generate(@NonNull Set<IModule> modules) throws MojoExecutionException {
@Override
@NonNull
protected List<File> generate(@NonNull Set<IModule> modules) throws MojoExecutionException {
IMutableConfiguration<SchemaGenerationFeature<?>> schemaGenerationConfig
= new DefaultConfiguration<>();

Expand Down Expand Up @@ -167,31 +169,36 @@ protected void generate(@NonNull Set<IModule> modules) throws MojoExecutionExcep
}

Path outputDirectory = ObjectUtils.notNull(getOutputDirectory().toPath());
List<File> generatedSchemas = new LinkedList<>();
for (IModule module : modules) {
if (getLog().isInfoEnabled()) {
getLog().info(String.format("Processing metaschema: %s", module.getLocation()));
}
if (module.getExportedRootAssemblyDefinitions().isEmpty()) {
continue;
}
generateSchemas(module, schemaGenerationConfig, outputDirectory, schemaFormats);
generatedSchemas.addAll(generateSchemas(module, schemaGenerationConfig, outputDirectory, schemaFormats));
}
return CollectionUtil.unmodifiableList(generatedSchemas);
}

@SuppressWarnings("PMD.AvoidCatchingGenericException")
private static void generateSchemas(
@NonNull
private List<File> generateSchemas(
@NonNull IModule module,
@NonNull IConfiguration<SchemaGenerationFeature<?>> schemaGenerationConfig,
@NonNull Path outputDirectory,
@NonNull Set<SchemaFormat> schemaFormats) throws MojoExecutionException {

String shortName = module.getShortName();

List<File> generatedSchemas = new LinkedList<>();
if (schemaFormats.contains(SchemaFormat.XSD)) {
try { // XML Schema
String filename = String.format("%s_schema.xsd", shortName);
Path xmlSchema = ObjectUtils.notNull(outputDirectory.resolve(filename));
generateSchema(module, schemaGenerationConfig, xmlSchema, XML_SCHEMA_GENERATOR);
generatedSchemas.add(xmlSchema.toFile());
} catch (Exception ex) {
throw new MojoExecutionException("Unable to generate XML schema.", ex);
}
Expand All @@ -200,12 +207,14 @@ private static void generateSchemas(
if (schemaFormats.contains(SchemaFormat.JSON_SCHEMA)) {
try { // JSON Schema
String filename = String.format("%s_schema.json", shortName);
Path xmlSchema = ObjectUtils.notNull(outputDirectory.resolve(filename));
generateSchema(module, schemaGenerationConfig, xmlSchema, JSON_SCHEMA_GENERATOR);
Path jsonSchema = ObjectUtils.notNull(outputDirectory.resolve(filename));
generateSchema(module, schemaGenerationConfig, jsonSchema, JSON_SCHEMA_GENERATOR);
generatedSchemas.add(jsonSchema.toFile());
} catch (Exception ex) {
throw new MojoExecutionException("Unable to generate JSON schema.", ex);
}
}
return CollectionUtil.unmodifiableList(generatedSchemas);
}

private static void generateSchema(
Expand All @@ -223,75 +232,4 @@ private static void generateSchema(
generator.generateFromModule(module, writer, schemaGenerationConfig);
}
}

@Override
public void execute() throws MojoExecutionException {
File staleFile = getStaleFile();
try {
staleFile = ObjectUtils.notNull(staleFile.getCanonicalFile());
} catch (IOException ex) {
if (getLog().isWarnEnabled()) {
getLog().warn("Unable to resolve canonical path to stale file. Treating it as not existing.", ex);
}
}

boolean generate;
if (shouldExecutionBeSkipped()) {
if (getLog().isDebugEnabled()) {
getLog().debug(String.format("Schema generation is configured to be skipped. Skipping."));
}
generate = false;
} else if (staleFile.exists()) {
generate = isGenerationRequired();
} else {
if (getLog().isInfoEnabled()) {
getLog().info(String.format("Stale file '%s' doesn't exist! Generating source files.", staleFile.getPath()));
}
generate = true;
}

if (generate) {
performGeneration();
createStaleFile(staleFile);

// for m2e
getBuildContext().refresh(getOutputDirectory());
}
// // add generated sources to Maven
// try {
// getMavenProject()..addCompileSourceRoot(getOutputDirectory().getCanonicalFile().getPath());
// } catch (IOException ex) {
// throw new MojoExecutionException("Unable to add output directory to maven
// sources.", ex);
// }
}

@SuppressWarnings("PMD.AvoidCatchingGenericException")
private void performGeneration() throws MojoExecutionException {
File outputDir = getOutputDirectory();
if (getLog().isDebugEnabled()) {
getLog().debug(String.format("Using outputDirectory: %s", outputDir.getPath()));
}

if (!outputDir.exists() && !outputDir.mkdirs()) {
throw new MojoExecutionException("Unable to create output directory: " + outputDir);
}

IBindingContext bindingContext;
try {
bindingContext = newBindingContext();
} catch (MetaschemaException | IOException ex) {
throw new MojoExecutionException("Failed to create the binding context", ex);
}

// generate schemas based on provided metaschema sources
Set<IModule> modules;
try {
modules = getModulesToGenerateFor(bindingContext);
} catch (Exception ex) {
throw new MojoExecutionException("Loading of metaschema modules failed", ex);
}

generate(modules);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@
package gov.nist.secauto.metaschema.maven.plugin;

import gov.nist.secauto.metaschema.core.model.IModule;
import gov.nist.secauto.metaschema.core.model.MetaschemaException;
import gov.nist.secauto.metaschema.core.util.ObjectUtils;
import gov.nist.secauto.metaschema.databind.IBindingContext;
import gov.nist.secauto.metaschema.databind.codegen.IProduction;
import gov.nist.secauto.metaschema.databind.codegen.JavaGenerator;
import gov.nist.secauto.metaschema.databind.codegen.config.DefaultBindingConfiguration;

Expand All @@ -23,6 +22,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import edu.umd.cs.findbugs.annotations.NonNull;

Expand Down Expand Up @@ -78,7 +78,9 @@ protected List<File> getConfigs() {
* @throws MojoExecutionException
* if an error occurred while generating sources
*/
protected void generate(@NonNull Set<IModule> modules) throws MojoExecutionException {
@Override
@NonNull
protected List<File> generate(@NonNull Set<IModule> modules) throws MojoExecutionException {
DefaultBindingConfiguration bindingConfiguration = new DefaultBindingConfiguration();
for (File config : getConfigs()) {
try {
Expand All @@ -92,87 +94,28 @@ protected void generate(@NonNull Set<IModule> modules) throws MojoExecutionExcep
}
}

IProduction production;
try {
if (getLog().isInfoEnabled()) {
getLog().info("Generating Java classes in: " + getOutputDirectory().getPath());
}
JavaGenerator.generate(modules, ObjectUtils.notNull(getOutputDirectory().toPath()),
production = JavaGenerator.generate(
modules,
ObjectUtils.notNull(getOutputDirectory().toPath()),
bindingConfiguration);
} catch (IOException ex) {
throw new MojoExecutionException("Creation of Java classes failed.", ex);
}
}

@SuppressWarnings("PMD.AvoidCatchingGenericException")
@Override
public void execute() throws MojoExecutionException {
File staleFile = getStaleFile();
try {
staleFile = ObjectUtils.notNull(staleFile.getCanonicalFile());
} catch (IOException ex) {
if (getLog().isWarnEnabled()) {
getLog().warn("Unable to resolve canonical path to stale file. Treating it as not existing.", ex);
}
}

boolean generate;
if (shouldExecutionBeSkipped()) {
if (getLog().isDebugEnabled()) {
getLog().debug(String.format("Source file generation is configured to be skipped. Skipping."));
}
generate = false;
} else if (staleFile.exists()) {
generate = isGenerationRequired();
} else {
if (getLog().isInfoEnabled()) {
getLog().info(String.format("Stale file '%s' doesn't exist! Generating source files.", staleFile.getPath()));
}
generate = true;
}

if (generate) {
performGeneration();
createStaleFile(staleFile);

// for m2e
getBuildContext().refresh(getOutputDirectory());
}

// add generated sources to Maven
try {
getMavenProject().addCompileSourceRoot(getOutputDirectory().getCanonicalFile().getPath());
} catch (IOException ex) {
throw new MojoExecutionException("Unable to add output directory to maven sources.", ex);
}
}

@SuppressWarnings({ "PMD.AvoidCatchingGenericException", "PMD.ExceptionAsFlowControl" })
private void performGeneration() throws MojoExecutionException {
File outputDir = getOutputDirectory();
if (getLog().isDebugEnabled()) {
getLog().debug(String.format("Using outputDirectory: %s", outputDir.getPath()));
}

if (!outputDir.exists() && !outputDir.mkdirs()) {
throw new MojoExecutionException("Unable to create output directory: " + outputDir);
}

IBindingContext bindingContext;
try {
bindingContext = newBindingContext();
} catch (MetaschemaException | IOException ex) {
throw new MojoExecutionException("Failed to create the binding context", ex);
}

// generate Java sources based on provided metaschema sources
Set<IModule> modules;
try {
modules = getModulesToGenerateFor(bindingContext);
} catch (Exception ex) {
throw new MojoExecutionException("Loading of metaschema modules failed", ex);
}

generate(modules);
return ObjectUtils.notNull(production.getGeneratedClasses()
.map(gen -> gen.getClassFile().toFile())
.collect(Collectors.toUnmodifiableList()));
}

}
Loading