1 package org.apache.maven.plugins.ejb;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.io.IOException;
24 import java.util.Arrays;
25 import java.util.Collections;
26 import java.util.List;
27
28 import org.apache.commons.io.input.XmlStreamReader;
29 import org.apache.maven.archiver.MavenArchiveConfiguration;
30 import org.apache.maven.archiver.MavenArchiver;
31 import org.apache.maven.artifact.DependencyResolutionRequiredException;
32 import org.apache.maven.execution.MavenSession;
33 import org.apache.maven.plugin.AbstractMojo;
34 import org.apache.maven.plugin.MojoExecutionException;
35 import org.apache.maven.plugins.annotations.Component;
36 import org.apache.maven.plugins.annotations.LifecyclePhase;
37 import org.apache.maven.plugins.annotations.Mojo;
38 import org.apache.maven.plugins.annotations.Parameter;
39 import org.apache.maven.plugins.annotations.ResolutionScope;
40 import org.apache.maven.project.MavenProject;
41 import org.apache.maven.project.MavenProjectHelper;
42 import org.apache.maven.shared.filtering.MavenFileFilter;
43 import org.apache.maven.shared.filtering.MavenFilteringException;
44 import org.apache.maven.shared.filtering.MavenResourcesExecution;
45 import org.apache.maven.shared.utils.io.FileUtils.FilterWrapper;
46 import org.codehaus.plexus.archiver.Archiver;
47 import org.codehaus.plexus.archiver.ArchiverException;
48 import org.codehaus.plexus.archiver.jar.JarArchiver;
49 import org.codehaus.plexus.archiver.jar.ManifestException;
50 import org.codehaus.plexus.util.FileUtils;
51
52
53
54
55
56
57
58 @Mojo( name = "ejb", requiresDependencyResolution = ResolutionScope.RUNTIME, threadSafe = true,
59 defaultPhase = LifecyclePhase.PACKAGE )
60 public class EjbMojo
61 extends AbstractMojo
62 {
63 private static final List<String> DEFAULT_INCLUDES_LIST =
64 Collections.unmodifiableList( Arrays.asList( "**/**" ) );
65
66
67 private static final List<String> DEFAULT_CLIENT_EXCLUDES_LIST =
68 Collections.unmodifiableList(
69 Arrays.asList(
70 "**/*Bean.class",
71 "**/*CMP.class",
72 "**/*Session.class",
73 "**/package.html"
74 )
75 );
76
77
78
79
80
81 public static final String DEFAULT_CLIENT_CLASSIFIER = "client";
82
83
84
85
86 public static final String DEFAULT_EJBJAR = "META-INF/ejb-jar.xml";
87
88
89
90
91 @Parameter( defaultValue = "${project.build.directory}", required = true, readonly = true )
92 private File outputDirectory;
93
94
95
96
97 @Parameter( defaultValue = "${project.build.outputDirectory}", required = true )
98 private File sourceDirectory;
99
100
101
102
103 @Parameter( defaultValue = "${project.build.finalName}", readonly = true )
104 private String jarName;
105
106
107
108
109 @Parameter
110 private String classifier;
111
112
113
114
115
116
117 @Parameter( defaultValue = DEFAULT_CLIENT_CLASSIFIER )
118 private String clientClassifier;
119
120
121
122
123 @Parameter( defaultValue = DEFAULT_EJBJAR )
124 private String ejbJar;
125
126
127
128
129 @Parameter( defaultValue = "false" )
130 private boolean generateClient;
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147 @Parameter
148 private List<String> clientExcludes;
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164 @Parameter
165 private List<String> clientIncludes;
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181 @Parameter
182 private List<String> excludes;
183
184
185
186
187 @Parameter( defaultValue = "${project}", readonly = true, required = true )
188 private MavenProject project;
189
190
191
192
193 @Component( role = Archiver.class, hint = "jar" )
194 private JarArchiver jarArchiver;
195
196
197
198
199
200
201
202
203
204
205
206
207
208 @Parameter( defaultValue = "3.1" )
209 private String ejbVersion;
210
211
212
213
214 @Component( role = Archiver.class, hint = "jar" )
215 private JarArchiver clientJarArchiver;
216
217
218
219
220 @Component
221 private MavenProjectHelper projectHelper;
222
223
224
225
226
227 @Parameter
228 private MavenArchiveConfiguration archive = new MavenArchiveConfiguration();
229
230
231
232
233
234
235 @Parameter( defaultValue = "false" )
236 private boolean escapeBackslashesInFilePath;
237
238
239
240
241
242
243 @Parameter
244 protected String escapeString;
245
246
247
248
249
250
251 @Parameter( defaultValue = "false" )
252 private boolean filterDeploymentDescriptor;
253
254
255
256
257
258
259 @Parameter
260 private List<String> filters;
261
262
263
264
265 @Component( role = MavenFileFilter.class, hint = "default" )
266 private MavenFileFilter mavenFileFilter;
267
268
269
270
271 @Parameter( defaultValue = "${session}", readonly = true, required = true )
272 private MavenSession session;
273
274
275
276
277
278
279
280
281 @Parameter( defaultValue = "${project.build.outputTimestamp}" )
282 private String outputTimestamp;
283
284 private static final String EJB_TYPE = "ejb";
285
286 private static final String EJB_CLIENT_TYPE = "ejb-client";
287
288
289
290
291 public void execute()
292 throws MojoExecutionException
293 {
294
295 if ( !sourceDirectory.exists() )
296 {
297 getLog().warn( "The created EJB jar will be empty cause the " + sourceDirectory.getPath()
298 + " did not exist." );
299 sourceDirectory.mkdirs();
300 }
301
302 File jarFile = generateEjb();
303
304 if ( hasClassifier() )
305 {
306 if ( !isClassifierValid() )
307 {
308 String message = "The given classifier '" + getClassifier() + "' is not valid.";
309 getLog().error( message );
310 throw new MojoExecutionException( message );
311 }
312
313
314
315 projectHelper.attachArtifact( project, EJB_TYPE, getClassifier(), jarFile );
316 }
317 else
318 {
319 if ( projectHasAlreadySetAnArtifact() )
320 {
321 throw new MojoExecutionException( "You have to use a classifier "
322 + "to attach supplemental artifacts to the project instead of replacing them." );
323 }
324
325 project.getArtifact().setFile( jarFile );
326 }
327
328 if ( generateClient )
329 {
330 File clientJarFile = generateEjbClient();
331 if ( hasClientClassifier() )
332 {
333 if ( !isClientClassifierValid() )
334 {
335 String message = "The given client classifier '" + getClientClassifier() + "' is not valid.";
336 getLog().error( message );
337 throw new MojoExecutionException( message );
338 }
339
340 projectHelper.attachArtifact( project, EJB_CLIENT_TYPE, getClientClassifier(), clientJarFile );
341 }
342 else
343 {
344
345
346 projectHelper.attachArtifact( project, "ejb-client", getClientClassifier(), clientJarFile );
347 }
348
349 }
350 }
351
352 private boolean projectHasAlreadySetAnArtifact()
353 {
354 if ( getProject().getArtifact().getFile() != null )
355 {
356 return getProject().getArtifact().getFile().isFile();
357 }
358 else
359 {
360 return false;
361 }
362 }
363
364 private File generateEjb()
365 throws MojoExecutionException
366 {
367 File jarFile = EjbHelper.getJarFile( outputDirectory, jarName, getClassifier() );
368
369 getLog().info( "Building EJB " + jarName + " with EJB version " + ejbVersion );
370
371 MavenArchiver archiver = new MavenArchiver();
372
373 archiver.setArchiver( jarArchiver );
374
375 archiver.setCreatedBy( "Maven EJB Plugin", "org.apache.maven.plugins", "maven-ejb-plugin" );
376
377 archiver.setOutputFile( jarFile );
378
379
380 archiver.configureReproducible( outputTimestamp );
381
382 File deploymentDescriptor = new File( sourceDirectory, ejbJar );
383
384 checkEJBVersionCompliance( deploymentDescriptor );
385
386 try
387 {
388 List<String> defaultExcludes = Arrays.asList( ejbJar, "**/package.html" );
389 List<String> defaultIncludes = DEFAULT_INCLUDES_LIST;
390
391 IncludesExcludes ie =
392 new IncludesExcludes( Collections.<String>emptyList(), excludes, defaultIncludes, defaultExcludes );
393
394 archiver.getArchiver().addDirectory( sourceDirectory, ie.resultingIncludes(), ie.resultingExcludes() );
395
396
397 if ( deploymentDescriptor.exists() )
398 {
399
400 if ( filterDeploymentDescriptor )
401 {
402 filterDeploymentDescriptor( deploymentDescriptor );
403 }
404 archiver.getArchiver().addFile( deploymentDescriptor, ejbJar );
405 }
406
407
408 archiver.createArchive( session, project, archive );
409 }
410 catch ( ArchiverException | ManifestException | IOException | DependencyResolutionRequiredException e )
411 {
412 throw new MojoExecutionException( "There was a problem creating the EJB archive: " + e.getMessage(), e );
413 }
414 catch ( MavenFilteringException e )
415 {
416 throw new MojoExecutionException( "There was a problem filtering the deployment descriptor: "
417 + e.getMessage(), e );
418 }
419
420 return jarFile;
421
422 }
423
424 private File generateEjbClient()
425 throws MojoExecutionException
426 {
427 File clientJarFile = EjbHelper.getJarFile( outputDirectory, jarName, getClientClassifier() );
428
429 getLog().info( "Building EJB client " + clientJarFile.getPath() );
430
431 MavenArchiver clientArchiver = new MavenArchiver();
432
433 clientArchiver.setArchiver( clientJarArchiver );
434
435 clientArchiver.setCreatedBy( "Maven EJB Plugin", "org.apache.maven.plugins", "maven-ejb-plugin" );
436
437 clientArchiver.setOutputFile( clientJarFile );
438
439
440 clientArchiver.configureReproducible( outputTimestamp );
441
442 try
443 {
444 List<String> defaultExcludes = DEFAULT_CLIENT_EXCLUDES_LIST;
445 List<String> defaultIncludes = DEFAULT_INCLUDES_LIST;
446
447 IncludesExcludes ie =
448 new IncludesExcludes( clientIncludes, clientExcludes, defaultIncludes, defaultExcludes );
449
450 clientArchiver.getArchiver().addDirectory( sourceDirectory, ie.resultingIncludes(),
451 ie.resultingExcludes() );
452
453 clientArchiver.createArchive( session, project, archive );
454
455 }
456 catch ( ArchiverException | ManifestException | IOException | DependencyResolutionRequiredException e )
457 {
458 throw new MojoExecutionException( "There was a problem creating the EJB client archive: " + e.getMessage(),
459 e );
460 }
461
462 return clientJarFile;
463 }
464
465 static void validateEjbVersion( String ejbVersion )
466 throws MojoExecutionException
467 {
468 if ( !ejbVersion.matches( "\\A[2-4]\\.[0-9]\\z" ) )
469 {
470 throw new MojoExecutionException( "ejbVersion is not valid: " + ejbVersion
471 + ". Must be 2.x, 3.x or 4.x (where x is a digit)" );
472 }
473 }
474
475 private void checkEJBVersionCompliance( File deploymentDescriptor )
476 throws MojoExecutionException
477 {
478 validateEjbVersion( ejbVersion );
479
480 if ( ejbVersion.matches( "\\A2\\.[0-9]\\z" ) && !deploymentDescriptor.exists() )
481 {
482 throw new MojoExecutionException( "Error assembling EJB: " + ejbJar + " is required for ejbVersion 2.x" );
483 }
484 }
485
486 private void filterDeploymentDescriptor( File deploymentDescriptor )
487 throws MavenFilteringException, IOException
488 {
489 getLog().debug( "Filtering deployment descriptor." );
490 MavenResourcesExecution mavenResourcesExecution = new MavenResourcesExecution();
491 mavenResourcesExecution.setEscapeString( escapeString );
492 List<FilterWrapper> filterWrappers =
493 mavenFileFilter.getDefaultFilterWrappers( project, filters, escapeBackslashesInFilePath, this.session,
494 mavenResourcesExecution );
495
496
497 File unfilteredDeploymentDescriptor = new File( sourceDirectory, ejbJar + ".unfiltered" );
498 FileUtils.copyFile( deploymentDescriptor, unfilteredDeploymentDescriptor );
499 mavenFileFilter.copyFile( unfilteredDeploymentDescriptor, deploymentDescriptor, true, filterWrappers,
500 getEncoding( unfilteredDeploymentDescriptor ) );
501
502 FileUtils.forceDelete( unfilteredDeploymentDescriptor );
503 }
504
505
506
507
508 private boolean hasClassifier()
509 {
510 return EjbHelper.hasClassifier( getClassifier() );
511 }
512
513
514
515
516
517 private boolean hasClientClassifier()
518 {
519 return EjbHelper.hasClassifier( getClientClassifier() );
520 }
521
522 private boolean isClassifierValid()
523 {
524 return EjbHelper.isClassifierValid( getClassifier() );
525 }
526
527 private boolean isClientClassifierValid()
528 {
529 return EjbHelper.isClassifierValid( getClientClassifier() );
530 }
531
532
533
534
535
536
537
538
539 private String getEncoding( File xmlFile )
540 throws IOException
541 {
542 try ( XmlStreamReader xmlReader = new XmlStreamReader( xmlFile ) )
543 {
544 final String encoding = xmlReader.getEncoding();
545 return encoding;
546 }
547 }
548
549 public String getClassifier()
550 {
551 return classifier;
552 }
553
554 public String getClientClassifier()
555 {
556 return clientClassifier;
557 }
558
559 public MavenProject getProject()
560 {
561 return project;
562 }
563
564 }