1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package com.mindtree.techworks.insight.releng.mvn.jsmooth;
22
23 import java.io.File;
24 import java.io.IOException;
25 import java.net.URISyntaxException;
26 import java.net.URL;
27 import java.security.CodeSource;
28 import java.util.ArrayList;
29 import java.util.Collections;
30 import java.util.Iterator;
31 import java.util.List;
32 import java.util.Set;
33 import java.util.zip.ZipFile;
34
35 import net.charabia.jsmoothgen.application.ExeCompiler;
36 import net.charabia.jsmoothgen.application.JSmoothModelBean;
37 import net.charabia.jsmoothgen.application.JSmoothModelPersistency;
38 import net.charabia.jsmoothgen.skeleton.SkeletonBean;
39 import net.charabia.jsmoothgen.skeleton.SkeletonList;
40
41 import org.apache.maven.artifact.Artifact;
42 import org.apache.maven.plugin.AbstractMojo;
43 import org.apache.maven.plugin.MojoExecutionException;
44 import org.apache.maven.plugin.MojoFailureException;
45 import org.apache.maven.project.MavenProject;
46 import org.apache.maven.project.MavenProjectHelper;
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70 public class JSmoothCompileMojo extends AbstractMojo {
71
72
73
74
75
76
77 private boolean skipJSmooth;
78
79
80
81
82
83
84
85 private String jsmoothFile;
86
87
88
89
90
91
92 private String iconLocation;
93
94
95
96
97
98
99
100 private boolean setExeName;
101
102
103
104
105
106
107
108 private boolean setJarName;
109
110
111
112
113
114
115
116 private String dependencyBaseDir;
117
118
119
120
121
122
123 private boolean includeDependencies;
124
125
126
127
128
129
130
131 private String dependencyScope;
132
133
134
135
136
137
138
139
140 private MavenProject project;
141
142
143
144
145
146
147 private MavenProjectHelper projectHelper;
148
149
150
151
152
153
154 public void execute() throws MojoExecutionException, MojoFailureException {
155 if (skipJSmooth) {
156 getLog()
157 .info(
158 "Skipping JSmooth Compile, as skipJSmooth flag is set to false");
159 }
160
161
162 File jSmthFile = resolveFile(jsmoothFile);
163 getLog().info("Using jsmooth file... " + jSmthFile.getAbsolutePath());
164
165
166 JSmoothModelBean jsmoothModel = null;
167 try {
168 jsmoothModel = JSmoothModelPersistency.load(jSmthFile);
169 } catch (IOException e) {
170 getLog().error("IOException while reading jsmooth file", e);
171 throw new MojoFailureException(this,
172 "IOException reading jsmooth file", e.getMessage());
173 }
174
175
176 manipulateModelFile(jsmoothModel);
177
178
179 File jsmoothTmpDir = createTemporaryDirectory();
180
181
182 writeJsmoothFile(jsmoothTmpDir, jsmoothModel);
183
184
185 File skeletonDir = writeSkeletons(jsmoothTmpDir);
186
187
188 File compiledFile = compileJSmooth(skeletonDir, jsmoothModel);
189
190 projectHelper.attachArtifact(project, "exe", compiledFile);
191 }
192
193 private File compileJSmooth(File skeletonRoot, JSmoothModelBean model) throws MojoExecutionException {
194 try {
195 SkeletonList skelList = new SkeletonList(skeletonRoot);
196
197 File out = new File(project.getBuild().getDirectory(), model
198 .getExecutableName());
199 SkeletonBean skel = skelList.getSkeleton(model.getSkeletonName());
200 File skelroot = skelList.getDirectory(skel);
201
202 final ExeCompiler compiler = new ExeCompiler();
203 compiler.addListener(new ExeCompiler.StepListener() {
204
205 public void complete() {
206 getLog().info("JSmooth generation complete");
207 }
208
209 public void failed() {
210 getLog().error("JSmooth generation failed");
211 }
212
213 public void setNewState(int percentComplete, String state) {
214
215 getLog().debug(
216 "jsmooth: " + state + " ( " + percentComplete
217 + "%)");
218 }
219 });
220
221 if (compiler.compile(skelroot, skel, new File(project.getBuild()
222 .getDirectory()), model, out)) {
223 getLog().info(
224 "Java application wrapped in "
225 + model.getExecutableName());
226 } else {
227 getLog().error("jsmoothgen failed: " + compiler.getErrors());
228 throw new MojoExecutionException(this, "jsmoothgen failed: ", compiler.getErrors().toString());
229 }
230
231 return out;
232 } catch (MojoExecutionException exc) {
233 throw exc;
234 } catch (Exception exc) {
235 throw new MojoExecutionException(this, "Error building the jsmooth wrapper", exc.getMessage());
236 }
237
238 }
239
240
241
242
243
244
245
246
247
248
249
250
251
252 private File writeSkeletons(File jsmoothTmpDir)
253 throws MojoFailureException, MojoExecutionException {
254
255 CodeSource cs = getClass().getProtectionDomain().getCodeSource();
256 if (null == cs) {
257
258 throw new MojoFailureException(
259 "Unable to determine the source of this jar and hence cannot extract skeletons");
260 }
261 URL baseUrl = cs.getLocation();
262 getLog().debug("Determined code source location: " + baseUrl.toExternalForm());
263 File destinationDir = new File(jsmoothTmpDir + File.separator
264 + "skeletons");
265 try {
266
267
268 File basePath = null;
269 try {
270 basePath = new File(baseUrl.toURI());
271 } catch (URISyntaxException e) {
272 getLog().debug("Failed the URI method.. faling back to path");
273 basePath = new File(baseUrl.getPath());
274 }
275 getLog().debug(
276 "Attempting extraction from" + basePath.getAbsolutePath());
277
278
279 if (basePath.getAbsolutePath().endsWith(".jar")
280 || basePath.getAbsolutePath().endsWith(".zip")) {
281 ZipFile sourceFile = new ZipFile(basePath);
282 FileUtils.extractZipDirectories(sourceFile, destinationDir,
283 "skeletons", true, getLog());
284 } else {
285 File skeletonDir = new File(basePath.getAbsolutePath()
286 + File.separator + "skeletons");
287 if (skeletonDir.exists()) {
288 FileUtils.copyDirectory(skeletonDir, destinationDir);
289 } else {
290 throw new MojoFailureException(
291 "Unable to determine the source of this jar and hence cannot extract skeletons");
292 }
293 }
294 } catch (IOException e) {
295
296 throw new MojoExecutionException(this,
297 "Error copying skeleton files", e.getMessage());
298 }
299 return destinationDir;
300 }
301
302
303
304
305
306
307
308
309
310 private void writeJsmoothFile(File jsmoothTmpDir,
311 JSmoothModelBean jsmoothModel) {
312 File tmpFileNm = new File(jsmoothFile);
313 String tempJSmoothFileName = jsmoothTmpDir.getAbsolutePath()
314 + File.separator + tmpFileNm.getName();
315 try {
316 JSmoothModelPersistency.save(new File(tempJSmoothFileName),
317 jsmoothModel);
318 } catch (IOException e) {
319 getLog().warn("IOException writing jsmooth file", e);
320
321 }
322 }
323
324
325
326
327
328
329
330
331 private File createTemporaryDirectory() throws MojoExecutionException {
332 String jsmoothTmpDirPath = project.getBuild().getDirectory()
333 + File.separator + "jsmooth-temp";
334 File jsmoothTmpDir = new File(jsmoothTmpDirPath);
335 if (!jsmoothTmpDir.exists()) {
336 if (!jsmoothTmpDir.mkdir()) {
337 throw new MojoExecutionException(
338 "Cannot create temporary directory");
339 }
340 }
341
342 return jsmoothTmpDir;
343 }
344
345
346
347
348
349
350
351
352
353 private void manipulateModelFile(JSmoothModelBean jsmoothModel)
354 throws MojoExecutionException {
355
356
357 if (null != iconLocation && iconLocation.trim().length() > 0) {
358 File iconFileLoc = resolveFile(iconLocation);
359 getLog().info(
360 "Setting Icon location to : "
361 + iconFileLoc.getAbsolutePath());
362 jsmoothModel.setIconLocation(iconFileLoc.getAbsolutePath());
363 }
364
365 String finalBuildName = project.getBuild().getFinalName();
366
367 if (setExeName) {
368 getLog().info(
369 "Setting final output name to :" + finalBuildName + ".exe");
370 jsmoothModel.setExecutableName(finalBuildName + ".exe");
371 }
372
373 if (setJarName) {
374
375 getLog().info("Setting jar name to :" + finalBuildName + ".jar");
376 jsmoothModel.setJarLocation(finalBuildName + ".jar");
377 }
378
379 if (includeDependencies) {
380 getLog().debug(
381 "Including dependencies with base scope: "
382 + dependencyScope);
383 List impliedScopes = getImpliedScopes(dependencyScope);
384 Set dependencyArtifacts = project.getArtifacts();
385 ArrayList dependentArtifacts = new ArrayList(dependencyArtifacts
386 .size());
387
388 String baseDir = "";
389 if (null != dependencyBaseDir) {
390 baseDir = dependencyBaseDir.trim();
391 if (!baseDir.endsWith("/") || !baseDir.endsWith(File.separator)) {
392 baseDir = baseDir + File.separator;
393 }
394 }
395
396 for (Iterator dependencyItr = dependencyArtifacts.iterator(); dependencyItr
397 .hasNext();) {
398 Artifact dependencyArtifact = (Artifact) dependencyItr.next();
399 if (impliedScopes.contains(dependencyArtifact.getScope())) {
400 getLog().debug(
401 "Including dependency: "
402 + dependencyArtifact.getId());
403 String dependencyPath = baseDir
404 + dependencyArtifact.getFile().getName();
405 getLog().debug("Inluding dependency as: " + dependencyPath);
406 dependentArtifacts.add(dependencyPath);
407 }
408 }
409
410 if (!dependentArtifacts.isEmpty()) {
411 String[] existingClasspath = jsmoothModel.getClassPath();
412 if (null != existingClasspath && existingClasspath.length > 0) {
413 Collections.addAll(dependentArtifacts, existingClasspath);
414 }
415
416 jsmoothModel.setClassPath((String[]) dependentArtifacts
417 .toArray(new String[dependentArtifacts.size()]));
418 }
419 }
420 }
421
422
423
424
425
426
427
428
429
430
431
432
433
434 private List getImpliedScopes(String scope) {
435 List resolvedScopeList = new ArrayList();
436
437 if (Artifact.SCOPE_COMPILE.equals(scope)) {
438 resolvedScopeList.add(Artifact.SCOPE_COMPILE);
439 } else if (Artifact.SCOPE_RUNTIME.equals(scope)) {
440 resolvedScopeList.add(Artifact.SCOPE_COMPILE);
441 resolvedScopeList.add(Artifact.SCOPE_RUNTIME);
442 } else if (Artifact.SCOPE_TEST.equals(scope)) {
443 resolvedScopeList.add(Artifact.SCOPE_COMPILE);
444 resolvedScopeList.add(Artifact.SCOPE_RUNTIME);
445 resolvedScopeList.add(Artifact.SCOPE_TEST);
446 }
447
448 return resolvedScopeList;
449 }
450
451
452
453
454
455
456
457
458
459
460 private File resolveFile(String path) throws MojoExecutionException {
461
462 getLog().debug("Resolving path: " + path);
463
464
465 if (null == path || path.trim().length() == 0) {
466 throw new MojoExecutionException("The path location is required.");
467 }
468
469
470 File fileLoc = new File(path);
471 if (fileLoc.exists() && fileLoc.canRead() && fileLoc.isFile()) {
472 return fileLoc;
473 }
474
475
476 File baseDir = project.getBasedir();
477 getLog().debug(
478 "Using base directory path : " + baseDir.getAbsolutePath());
479 String finalFilePath = baseDir.getAbsolutePath() + File.separatorChar
480 + path;
481 getLog().debug("Computed file path : " + finalFilePath);
482 fileLoc = new File(finalFilePath);
483 if (fileLoc.exists() && fileLoc.canRead() && fileLoc.isFile()) {
484 return fileLoc;
485 }
486
487
488 throw new MojoExecutionException("The file specified [" + path
489 + "] either does not exist, or cannot be resolved "
490 + "or cannot be read.");
491 }
492
493
494
495
496 public boolean isSkipJSmooth() {
497 return skipJSmooth;
498 }
499
500
501
502
503
504 public void setSkipJSmooth(boolean skipJSmooth) {
505 this.skipJSmooth = skipJSmooth;
506 }
507
508
509
510
511 public String getJsmoothFile() {
512 return jsmoothFile;
513 }
514
515
516
517
518
519 public void setJsmoothFile(String jsmoothFile) {
520 this.jsmoothFile = jsmoothFile;
521 }
522
523
524
525
526 public MavenProject getProject() {
527 return project;
528 }
529
530
531
532
533 public String getIconLocation() {
534 return iconLocation;
535 }
536
537
538
539
540
541 public void setIconLocation(String iconLocation) {
542 this.iconLocation = iconLocation;
543 }
544
545
546
547
548 public boolean isSetExeName() {
549 return setExeName;
550 }
551
552
553
554
555
556 public void setSetExeName(boolean setExeName) {
557 this.setExeName = setExeName;
558 }
559
560
561
562
563 public boolean isSetJarName() {
564 return setJarName;
565 }
566
567
568
569
570
571 public void setSetJarName(boolean setJarName) {
572 this.setJarName = setJarName;
573 }
574
575
576
577
578 public boolean isIncludeDependencies() {
579 return includeDependencies;
580 }
581
582
583
584
585
586 public void setIncludeDependencies(boolean includeDependencies) {
587 this.includeDependencies = includeDependencies;
588 }
589
590
591
592
593 public String getDependencyBaseDir() {
594 return dependencyBaseDir;
595 }
596
597
598
599
600
601 public void setDependencyBaseDir(String dependencyBaseDir) {
602 this.dependencyBaseDir = dependencyBaseDir;
603 }
604
605
606
607
608 public String getDependencyScope() {
609 return dependencyScope;
610 }
611
612
613
614
615
616 public void setDependencyScope(String dependencyScope) {
617 this.dependencyScope = dependencyScope;
618 }
619
620 }