1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 package gov.nist.secauto.metaschema.maven.plugin;
28
29 import gov.nist.secauto.metaschema.core.model.IModule;
30 import gov.nist.secauto.metaschema.core.model.MetaschemaException;
31 import gov.nist.secauto.metaschema.core.model.xml.ModuleLoader;
32 import gov.nist.secauto.metaschema.core.util.ObjectUtils;
33 import gov.nist.secauto.metaschema.databind.codegen.JavaGenerator;
34 import gov.nist.secauto.metaschema.databind.codegen.config.DefaultBindingConfiguration;
35
36 import org.apache.maven.plugin.MojoExecutionException;
37 import org.apache.maven.plugins.annotations.LifecyclePhase;
38 import org.apache.maven.plugins.annotations.Mojo;
39 import org.apache.maven.plugins.annotations.Parameter;
40
41 import java.io.File;
42 import java.io.IOException;
43 import java.io.OutputStream;
44 import java.nio.file.Files;
45 import java.nio.file.StandardOpenOption;
46 import java.util.Arrays;
47 import java.util.Collections;
48 import java.util.HashSet;
49 import java.util.List;
50 import java.util.Set;
51 import java.util.stream.Collectors;
52
53 import edu.umd.cs.findbugs.annotations.NonNull;
54
55
56
57
58 @Mojo(name = "generate-sources", defaultPhase = LifecyclePhase.GENERATE_SOURCES)
59 public class GenerateSourcesMojo
60 extends AbstractMetaschemaMojo {
61 private static final String STALE_FILE_NAME = "generateSourcesStaleFile";
62
63
64
65
66 @Parameter
67 protected File[] configs;
68
69
70
71
72
73
74
75
76
77
78
79 @Override
80 protected String getStaleFileName() {
81 return STALE_FILE_NAME;
82 }
83
84
85
86
87
88
89 protected List<File> getConfigs() {
90 List<File> retval;
91 if (configs == null) {
92 retval = Collections.emptyList();
93 } else {
94 retval = Arrays.asList(configs);
95 }
96 return retval;
97 }
98
99
100
101
102
103
104
105
106
107 protected void generate(@NonNull Set<IModule> modules) throws MojoExecutionException {
108 DefaultBindingConfiguration bindingConfiguration = new DefaultBindingConfiguration();
109 for (File config : getConfigs()) {
110 try {
111 getLog().info("Loading binding configuration: " + config.getPath());
112 bindingConfiguration.load(config);
113 } catch (IOException ex) {
114 throw new MojoExecutionException(
115 String.format("Unable to load binding configuration from '%s'.", config.getPath()), ex);
116 }
117 }
118
119 try {
120 getLog().info("Generating Java classes in: " + getOutputDirectory().getPath());
121 JavaGenerator.generate(modules, ObjectUtils.notNull(getOutputDirectory().toPath()),
122 bindingConfiguration);
123 } catch (IOException ex) {
124 throw new MojoExecutionException("Creation of Java classes failed.", ex);
125 }
126 }
127
128 @Override
129 public void execute() throws MojoExecutionException {
130 File staleFile = getStaleFile();
131 try {
132 staleFile = staleFile.getCanonicalFile();
133 } catch (IOException ex) {
134 getLog().warn("Unable to resolve canonical path to stale file. Treating it as not existing.", ex);
135 }
136
137 boolean generate;
138 if (shouldExecutionBeSkipped()) {
139 getLog().debug(String.format("Source file generation is configured to be skipped. Skipping."));
140 generate = false;
141 } else if (!staleFile.exists()) {
142 getLog().info(String.format("Stale file '%s' doesn't exist! Generating source files.", staleFile.getPath()));
143 generate = true;
144 } else {
145 generate = isGenerationRequired();
146 }
147
148 if (generate) {
149
150 File outputDir = getOutputDirectory();
151 getLog().debug(String.format("Using outputDirectory: %s", outputDir.getPath()));
152
153 if (!outputDir.exists()) {
154 if (!outputDir.mkdirs()) {
155 throw new MojoExecutionException("Unable to create output directory: " + outputDir);
156 }
157 }
158
159
160 final ModuleLoader loader = new ModuleLoader();
161 loader.allowEntityResolution();
162 final Set<IModule> modules = new HashSet<>();
163 for (File source : getSources().collect(Collectors.toList())) {
164 getLog().info("Using metaschema source: " + source.getPath());
165 IModule module;
166 try {
167 module = loader.load(source);
168 } catch (MetaschemaException | IOException ex) {
169 throw new MojoExecutionException("Loading of metaschema failed", ex);
170 }
171 modules.add(module);
172 }
173
174 generate(modules);
175
176
177 if (!staleFileDirectory.exists()) {
178 if (!staleFileDirectory.mkdirs()) {
179 throw new MojoExecutionException("Unable to create output directory: " + staleFileDirectory);
180 }
181 }
182 try (OutputStream os
183 = Files.newOutputStream(staleFile.toPath(), StandardOpenOption.CREATE, StandardOpenOption.WRITE,
184 StandardOpenOption.TRUNCATE_EXISTING)) {
185 os.close();
186 getLog().info("Created stale file: " + staleFile);
187 } catch (IOException ex) {
188 throw new MojoExecutionException("Failed to write stale file: " + staleFile.getPath(), ex);
189 }
190
191
192 getBuildContext().refresh(getOutputDirectory());
193 }
194
195
196 try {
197 getMavenProject().addCompileSourceRoot(getOutputDirectory().getCanonicalFile().getPath());
198 } catch (IOException ex) {
199 throw new MojoExecutionException("Unable to add output directory to maven sources.", ex);
200 }
201 }
202 }