001/* 002 * SPDX-FileCopyrightText: none 003 * SPDX-License-Identifier: CC0-1.0 004 */ 005 006package dev.metaschema.maven.plugin; 007 008import org.apache.maven.plugin.MojoExecutionException; 009import org.apache.maven.plugins.annotations.LifecyclePhase; 010import org.apache.maven.plugins.annotations.Mojo; 011import org.apache.maven.plugins.annotations.Parameter; 012 013import java.io.File; 014import java.io.IOException; 015import java.util.Arrays; 016import java.util.Collections; 017import java.util.List; 018import java.util.Set; 019import java.util.stream.Collectors; 020 021import dev.metaschema.core.model.IModule; 022import dev.metaschema.core.util.ObjectUtils; 023import dev.metaschema.databind.codegen.IProduction; 024import dev.metaschema.databind.codegen.JavaGenerator; 025import dev.metaschema.databind.codegen.config.DefaultBindingConfiguration; 026import dev.metaschema.databind.io.BindingException; 027import edu.umd.cs.findbugs.annotations.NonNull; 028 029/** 030 * Goal which generates Java source files for a given set of Metaschema modules. 031 */ 032@Mojo(name = "generate-sources", defaultPhase = LifecyclePhase.GENERATE_SOURCES) 033public class GenerateSourcesMojo 034 extends AbstractMetaschemaMojo { 035 private static final String STALE_FILE_NAME = "generateSourcesStaleFile"; 036 037 /** 038 * A set of binding configurations. 039 */ 040 @Parameter 041 protected File[] configs; 042 043 /** 044 * <p> 045 * Gets the last part of the stale filename. 046 * </p> 047 * <p> 048 * The full stale filename will be generated by pre-pending 049 * {@code "." + getExecution().getExecutionId()} to this staleFileName. 050 * 051 * @return the stale filename postfix 052 */ 053 @Override 054 protected String getStaleFileName() { 055 return STALE_FILE_NAME; 056 } 057 058 /** 059 * Retrieve a list of binding configurations. 060 * 061 * @return the collection of binding configurations 062 */ 063 protected List<File> getConfigs() { 064 List<File> retval; 065 if (configs == null) { 066 retval = Collections.emptyList(); 067 } else { 068 retval = Arrays.asList(configs); 069 } 070 return retval; 071 } 072 073 /** 074 * Generate the Java source files for the provided Metaschemas. 075 * 076 * @param modules 077 * the collection of Metaschema modules to generate sources for 078 * @return the list of generated Java source files 079 * @throws MojoExecutionException 080 * if an error occurred while generating sources 081 */ 082 @Override 083 @NonNull 084 protected List<File> generate(@NonNull Set<IModule> modules) throws MojoExecutionException { 085 DefaultBindingConfiguration bindingConfiguration = new DefaultBindingConfiguration(); 086 for (File config : getConfigs()) { 087 try { 088 if (getLog().isInfoEnabled()) { 089 getLog().info("Loading binding configuration: " + config.getPath()); 090 } 091 bindingConfiguration.load(config); 092 } catch (IOException | BindingException ex) { 093 throw new MojoExecutionException( 094 String.format("Unable to load binding configuration from '%s'.", config.getPath()), ex); 095 } 096 } 097 098 IProduction production; 099 try { 100 if (getLog().isInfoEnabled()) { 101 getLog().info("Generating Java classes in: " + getOutputDirectory().getPath()); 102 } 103 production = JavaGenerator.generate( 104 modules, 105 ObjectUtils.notNull(getOutputDirectory().toPath()), 106 bindingConfiguration); 107 } catch (IOException ex) { 108 throw new MojoExecutionException("Creation of Java classes failed.", ex); 109 } 110 111 // add generated sources to Maven 112 try { 113 getMavenProject().addCompileSourceRoot(getOutputDirectory().getCanonicalFile().getPath()); 114 } catch (IOException ex) { 115 throw new MojoExecutionException("Unable to add output directory to maven sources.", ex); 116 } 117 118 return ObjectUtils.notNull(production.getGeneratedClasses() 119 .map(gen -> gen.getClassFile().toFile()) 120 .collect(Collectors.toUnmodifiableList())); 121 } 122}