28
28
import java .nio .charset .StandardCharsets ;
29
29
import java .nio .file .Files ;
30
30
import java .nio .file .Path ;
31
+ import java .nio .file .Paths ;
31
32
import java .util .Collections ;
32
33
import java .util .Comparator ;
33
34
import java .util .List ;
49
50
import org .apache .maven .project .MavenProjectHelper ;
50
51
import org .apache .maven .project .ProjectBuilder ;
51
52
import org .apache .maven .shared .artifact .filter .collection .ArtifactsFilter ;
53
+ import org .apache .velocity .Template ;
52
54
import org .apache .velocity .VelocityContext ;
53
55
import org .apache .velocity .app .VelocityEngine ;
54
56
import org .apache .velocity .tools .generic .CollectionTool ;
59
61
/**
60
62
* This goal renders dependencies based on a velocity template.
61
63
*
62
- * @since 3.8.2
64
+ * @since 3.9.0
63
65
*/
64
66
@ Mojo (
65
67
name = "render-dependencies" ,
66
68
requiresDependencyResolution = ResolutionScope .TEST ,
67
69
defaultPhase = LifecyclePhase .GENERATE_SOURCES ,
68
70
threadSafe = true )
69
71
public class RenderDependenciesMojo extends AbstractDependencyFilterMojo {
72
+ /**
73
+ * Encoding to write the rendered template.
74
+ * @since 3.9.0
75
+ */
70
76
@ Parameter (property = "outputEncoding" , defaultValue = "${project.reporting.outputEncoding}" )
71
77
private String outputEncoding ;
72
78
73
79
/**
74
80
* The file to write the rendered template string. If undefined, it just prints the classpath as [INFO].
81
+ * @since 3.9.0
75
82
*/
76
83
@ Parameter (property = "mdep.outputFile" )
77
84
private File outputFile ;
78
85
79
86
/**
80
87
* If not null or empty it will attach the artifact with this classifier.
88
+ * @since 3.9.0
81
89
*/
82
90
@ Parameter (property = "mdep.classifier" , defaultValue = "template" )
83
91
private String classifier ;
84
92
85
93
/**
86
94
* Extension to use for the attached file if classifier is not null/empty.
95
+ * @since 3.9.0
87
96
*/
88
97
@ Parameter (property = "mdep.extension" , defaultValue = "txt" )
89
98
private String extension ;
90
99
91
100
/**
92
101
* velocity template to use to render the output file.
102
+ * @since 3.9.0
93
103
*/
94
104
@ Parameter (property = "mdep.template" , defaultValue = "<set the template>" )
95
105
private String template ;
@@ -148,8 +158,16 @@ protected void doExecute() throws MojoExecutionException {
148
158
* @return the template rendered.
149
159
*/
150
160
private String render (final List <Artifact > artifacts ) {
161
+ final Path templatePath = getTemplatePath ();
162
+ final boolean fromFile = templatePath != null && Files .exists (templatePath );
163
+
151
164
final Properties props = new Properties ();
152
165
props .setProperty ("runtime.strict_mode.enable" , "true" );
166
+ if (fromFile ) {
167
+ props .setProperty (
168
+ "resource.loader.file.path" ,
169
+ templatePath .toAbsolutePath ().getParent ().toString ());
170
+ }
153
171
154
172
final VelocityEngine ve = new VelocityEngine (props );
155
173
ve .init ();
@@ -160,19 +178,29 @@ private String render(final List<Artifact> artifacts) {
160
178
161
179
// Merge template + context
162
180
final StringWriter writer = new StringWriter ();
163
- try {
164
- ve . evaluate ( context , writer , "tpl-" + Math . abs ( hashCode ()), template );
165
- } finally {
166
- try {
167
- writer . close ( );
168
- } catch ( final IOException e ) {
169
- // no-op, not possible
181
+ try ( final StringWriter ignored = writer ) {
182
+ if ( fromFile ) {
183
+ final Template template =
184
+ ve . getTemplate ( templatePath . getFileName (). toString ());
185
+ template . merge ( context , writer );
186
+ } else {
187
+ ve . evaluate ( context , writer , "tpl-" + Math . abs ( hashCode ()), template );
170
188
}
189
+ } catch (final IOException e ) {
190
+ // no-op, not possible
171
191
}
172
192
173
193
return writer .toString ();
174
194
}
175
195
196
+ private Path getTemplatePath () {
197
+ try {
198
+ return Paths .get (template );
199
+ } catch (final RuntimeException re ) {
200
+ return null ;
201
+ }
202
+ }
203
+
176
204
/**
177
205
* Trivial null protection impl for comparing callback.
178
206
* @param getter nominal getter.
@@ -227,6 +255,10 @@ protected ArtifactsFilter getMarkedArtifactFilter() {
227
255
return null ;
228
256
}
229
257
258
+ public void setExtension (final String extension ) {
259
+ this .extension = extension ;
260
+ }
261
+
230
262
public void setOutputEncoding (final String outputEncoding ) {
231
263
this .outputEncoding = outputEncoding ;
232
264
}
0 commit comments