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 private void checkEJBVersionCompliance( File deploymentDescriptor )
466 throws MojoExecutionException
467 {
468 if ( !ejbVersion.matches( "\\A[2-3]\\.[0-9]\\z" ) )
469 {
470 throw new MojoExecutionException( "ejbVersion is not valid: " + ejbVersion
471 + ". Must be 2.x or 3.x (where x is a digit)" );
472 }
473
474 if ( ejbVersion.matches( "\\A2\\.[0-9]\\z" ) && !deploymentDescriptor.exists() )
475 {
476 throw new MojoExecutionException( "Error assembling EJB: " + ejbJar + " is required for ejbVersion 2.x" );
477 }
478 }
479
480 private void filterDeploymentDescriptor( File deploymentDescriptor )
481 throws MavenFilteringException, IOException
482 {
483 getLog().debug( "Filtering deployment descriptor." );
484 MavenResourcesExecution mavenResourcesExecution = new MavenResourcesExecution();
485 mavenResourcesExecution.setEscapeString( escapeString );
486 List<FilterWrapper> filterWrappers =
487 mavenFileFilter.getDefaultFilterWrappers( project, filters, escapeBackslashesInFilePath, this.session,
488 mavenResourcesExecution );
489
490
491 File unfilteredDeploymentDescriptor = new File( sourceDirectory, ejbJar + ".unfiltered" );
492 FileUtils.copyFile( deploymentDescriptor, unfilteredDeploymentDescriptor );
493 mavenFileFilter.copyFile( unfilteredDeploymentDescriptor, deploymentDescriptor, true, filterWrappers,
494 getEncoding( unfilteredDeploymentDescriptor ) );
495
496 FileUtils.forceDelete( unfilteredDeploymentDescriptor );
497 }
498
499
500
501
502 private boolean hasClassifier()
503 {
504 return EjbHelper.hasClassifier( getClassifier() );
505 }
506
507
508
509
510
511 private boolean hasClientClassifier()
512 {
513 return EjbHelper.hasClassifier( getClientClassifier() );
514 }
515
516 private boolean isClassifierValid()
517 {
518 return EjbHelper.isClassifierValid( getClassifier() );
519 }
520
521 private boolean isClientClassifierValid()
522 {
523 return EjbHelper.isClassifierValid( getClientClassifier() );
524 }
525
526
527
528
529
530
531
532
533 private String getEncoding( File xmlFile )
534 throws IOException
535 {
536 try ( XmlStreamReader xmlReader = new XmlStreamReader( xmlFile ) )
537 {
538 final String encoding = xmlReader.getEncoding();
539 return encoding;
540 }
541 }
542
543 public String getClassifier()
544 {
545 return classifier;
546 }
547
548 public String getClientClassifier()
549 {
550 return clientClassifier;
551 }
552
553 public MavenProject getProject()
554 {
555 return project;
556 }
557
558 }