1
2
3
4
5
6
7
8 package it.imolinfo.jbi4ejb.webservice.generator;
9
10 import it.imolinfo.jbi4ejb.Logger;
11 import it.imolinfo.jbi4ejb.LoggerFactory;
12 import it.imolinfo.jbi4ejb.exception.ClassGenerationException;
13 import it.imolinfo.jbi4ejb.exception.EJBDeployException;
14 import it.imolinfo.jbi4ejb.jbi.Messages;
15 import it.imolinfo.jbi4ejb.webservice.generator.bcm.RemoteEnancherAdapter;
16 import it.imolinfo.jbi4ejb.webservice.generator.bcm.SerializableDecorationAdapter;
17 import it.imolinfo.jbi4ejb.webservice.generator.bcm.SerializableInspectorAdapter;
18
19 import java.io.File;
20 import java.io.FileFilter;
21 import java.io.FileInputStream;
22 import java.io.FileNotFoundException;
23 import java.io.FileOutputStream;
24 import java.io.IOException;
25 import java.io.PrintWriter;
26 import java.io.StringWriter;
27 import java.net.MalformedURLException;
28 import java.net.URL;
29 import java.net.URLClassLoader;
30 import java.util.ArrayList;
31 import java.util.Arrays;
32 import java.util.HashSet;
33 import java.util.List;
34 import java.util.Set;
35
36 import org.objectweb.asm.ClassReader;
37 import org.objectweb.asm.ClassVisitor;
38 import org.objectweb.asm.ClassWriter;
39 import org.objectweb.asm.util.CheckClassAdapter;
40 import org.objectweb.asm.util.TraceClassVisitor;
41
42
43
44
45
46
47 public final class Util {
48
49
50 private static final Logger LOG = LoggerFactory.getLogger(Util.class);
51 private static final Messages MESSAGES = Messages.getMessages(Util.class);
52
53
54 private static final String PROTOCOL;
55
56
57 static {
58 if (System.getProperty("os.name").indexOf("Win") >= 0) {
59 PROTOCOL = "file:///";
60 } else {
61 PROTOCOL = "file://";
62 }
63 }
64
65
66
67
68 private Util() {}
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90 public static void compileJavaClasses(String workdirsrc,
91 String workdirclasses, List<String> javaSources,
92 List<String> jarFiles, List<String> extraClassPath)
93 throws ClassGenerationException {
94
95 LOG.debug(">>>>> compileJavaClasses - begin");
96
97 LOG.debug("compileJavaClasses" + ".\n workdirsrc=" + workdirsrc +
98 ";\n workdirclasses=" + workdirclasses + ";\n javaSources=" +
99 javaSources + ";\n jarFiles=" + jarFiles +
100 ";\n extraClassPath=" + extraClassPath);
101
102 List<String> params = new ArrayList<String>(Arrays.asList(new String[] {
103 "-d", workdirclasses, "-sourcepath", workdirsrc }));
104
105 LOG.debug("creating classpath - begin");
106
107 String classpath = "";
108
109
110
111 if (jarFiles != null) {
112
113 for (String jarFileName : jarFiles) {
114 classpath += jarFileName + File.pathSeparator;
115
116 LOG.debug("ClassPath + (jar) " + jarFileName);
117 }
118
119 }
120
121
122
123 if (extraClassPath != null) {
124 for (String extra : extraClassPath) {
125
126 File f = new File(extra);
127 if (!f.isDirectory()) {
128
129 String extraParent = f.getParent();
130 LOG.debug("-----> EXTRA=[" + extraParent + "]");
131 classpath += extraParent + File.pathSeparator;
132 } else {
133 classpath += extra + File.pathSeparator;
134 }
135
136 LOG.debug("ClassPath + (extra) " + extra);
137 }
138 } else {
139 LOG.debug("No extra classpath.");
140 }
141
142
143
144 if (!"".equals(classpath)) {
145 LOG.debug("Final ClassPath=" + classpath);
146
147 params.add("-cp");
148 params.add(classpath);
149 } else {
150 LOG.debug("Final ClassPath=<<EMPTY>>");
151 }
152
153 LOG.debug("creating classpath - end.");
154
155
156
157
158 params.addAll(javaSources);
159
160 System.out
161 .println("command line: " + Arrays.toString(params.toArray()));
162
163 File classesdir = new File(workdirclasses);
164 if (!classesdir.exists()) {
165 boolean result = classesdir.mkdirs();
166
167 if (!result) {
168 String msg=MESSAGES.getString("EJB001006_Failure_in_creating_classes_dir");
169 LOG.error(msg);
170 throw new ClassGenerationException(msg);
171 } else {
172 LOG.debug("Classes Dir Created:" + classesdir);
173 }
174 } else {
175 LOG.debug("Classes Dir Already Exists:" + classesdir);
176 }
177
178 StringWriter stringWriter = new StringWriter();
179 PrintWriter printstream = new PrintWriter(stringWriter);
180
181 LOG.debug("Compiling - begin");
182
183 int result = com.sun.tools.javac.Main.compile(params
184 .toArray(new String[] {}), printstream);
185
186 LOG.debug("Compiling - end. result=" + result);
187
188
189
190 LOG.debug("compilation output: \n" + stringWriter.toString());
191
192 if (!(result == 0)) {
193 String msg=MESSAGES.getString("EJB001007_Classes_compilation_failed");
194 LOG.error(msg);
195 throw new ClassGenerationException(msg);
196 } else {
197 LOG.debug("Compilation OK.");
198 }
199
200 LOG.debug("<<<<< compileJavaClasses - end");
201 }
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216 public static List<String> findJavaSources(String basedir,
217 List<String> exclude) throws EJBDeployException {
218
219 List<String> javaSourcesNames = new ArrayList<String>();
220 List<File> sourceFiles = findFilesFromSourceDirectory(basedir, ".java");
221
222 for (File source : sourceFiles) {
223
224 String src = null;
225 try {
226
227 src = source.getCanonicalPath();
228
229 } catch (IOException e) {
230 String msg=MESSAGES.getString("EJB001008_findJavaSources", new Object[]{e.getMessage()});
231 LOG.error(msg,e);
232 throw new EJBDeployException(msg,e);
233 }
234
235
236
237
238
239
240
241
242 if (src.endsWith("src")) {
243
244 LOG.debug("The file " + src + " won't be compiled.");
245
246 } else if (containsIgnoreSlashes(exclude, src)) {
247
248 LOG.debug("The file " + src + " won't be compiled.");
249
250 } else {
251 LOG.debug("The file " + src + " will be compiled.");
252 javaSourcesNames.add(src);
253 }
254 }
255
256 LOG.debug("<<<<< findJavaSources(String, List<String>) - end");
257 return javaSourcesNames;
258 }
259
260
261
262
263
264
265
266
267
268
269 public static boolean containsIgnoreSlashes(List<String> list, String myString) {
270 if (myString == null) {
271 return false;
272 }
273 if (list == null) {
274 return false;
275 }
276
277 String xrr = myString.replace('\\', ' ').replace('/', ' ');
278
279 for (String c : list) {
280 String crr = c.replace('\\', ' ').replace('/', ' ');
281
282 if (xrr.equalsIgnoreCase(crr)) {
283 return true;
284 }
285 }
286
287
288 return false;
289 }
290
291
292
293
294
295
296
297
298
299
300
301 public static List<File> findFilesFromSourceDirectory(String basedirString,
302 final String extensionFilter) {
303
304 File basedir = new File(basedirString);
305
306 FileFilter filter = new FileFilter() {
307 public boolean accept(File file) {
308
309 boolean filterAccept = file.getName().endsWith(extensionFilter);
310
311 return filterAccept;
312 }
313 };
314
315 List<File> directories = findDirectories(basedir);
316
317 List<File> filterdFiles = new ArrayList<File>();
318 for (File dir : directories) {
319 File[] innerFilteredFiles = dir.listFiles(filter);
320 filterdFiles.addAll(Arrays.asList(innerFilteredFiles));
321 }
322
323 return filterdFiles;
324 }
325
326
327
328
329
330
331
332
333
334
335
336
337
338 public static List<File> findFilesFromSourceDirectoryFromExactFileName(String basedirString,
339 final String exactName) {
340
341 File basedir = new File(basedirString);
342
343 FileFilter filter = new FileFilter() {
344 public boolean accept(File file) {
345
346 boolean filterAccept = file.getName().equals(exactName);
347
348 return filterAccept;
349 }
350 };
351
352 List<File> directories = findDirectories(basedir);
353 directories.add(basedir);
354 List<File> filterdFiles = new ArrayList<File>();
355 for (File dir : directories) {
356 File[] innerFilteredFiles = dir.listFiles(filter);
357 filterdFiles.addAll(Arrays.asList(innerFilteredFiles));
358 }
359
360 return filterdFiles;
361 }
362
363
364
365
366
367
368
369
370
371 private static List<File> findDirectories(File basedir) {
372 List<File> directories = new ArrayList<File>();
373
374 if (basedir == null || "".equals(basedir.getAbsolutePath())) {
375 return directories;
376 }
377
378 FileFilter directoryFilter = new FileFilter() {
379 public boolean accept(File file) {
380 return file.isDirectory();
381 }
382 };
383
384 File[] files = basedir.listFiles(directoryFilter);
385
386 if (files == null) {
387 return directories;
388 }
389
390 for (int i = 0; i < files.length; i++) {
391 List<File> innerDirectories = findDirectories(files[i]);
392 directories.addAll(innerDirectories);
393 directories.add(files[i]);
394 }
395
396 return directories;
397 }
398
399
400
401
402
403
404
405
406
407
408
409
410
411 public static String tweakInterfaceClasses(String portTypeClassName,
412 String classesDirName) throws ClassGenerationException {
413
414 LOG.debug(">>>>>>>>>> tweakInterfaceClasses - begin");
415
416 LOG.debug("remotizing class: " + portTypeClassName + " in dir: " +
417 classesDirName);
418
419 ClassWriter cw = new ClassWriter(true);
420 ClassVisitor cc = new CheckClassAdapter(cw);
421 StringWriter sw = new StringWriter();
422 ClassVisitor tv = new TraceClassVisitor(cc, new PrintWriter(sw));
423
424 RemoteEnancherAdapter cv = new RemoteEnancherAdapter(tv,
425 getAsFullyQualifiedNameInternalForm(portTypeClassName));
426
427 LOG.debug("new ClassReader - Begin");
428 ClassReader cr;
429 try {
430 cr = new ClassReader(new FileInputStream(getAsFileName(
431 classesDirName, portTypeClassName, ".class")));
432 } catch (IOException e) {
433 String msg=MESSAGES.getString("EJB001009_tweakInterfaceClasses", new Object[]{e.getMessage()});
434 LOG.error(msg,e);
435 throw new ClassGenerationException(msg,e);
436 }
437
438 cr.accept(cv, true);
439
440 LOG.debug("output of tracer during creation of class: " +
441 portTypeClassName + "\n" + sw.toString());
442
443 byte[] newBytecode = cw.toByteArray();
444
445
446 String relativeFileName = cv.getCompleteName().replace('/',
447 File.separatorChar);
448
449 LOG.debug("relativeFileName=" + relativeFileName +
450 "; cv.getCompleteName()=" + cv.getCompleteName());
451
452 Util.saveAsJavaClass(classesDirName + File.separator +
453 relativeFileName + ".class", newBytecode);
454
455 String remoteClassName = cv.getCompleteName().replace('/', '.');
456
457 LOG.debug("<<<<<<<<<< tweakInterfaceClasses - end:" + remoteClassName);
458 return remoteClassName;
459 }
460
461
462
463
464
465
466
467
468
469
470
471
472
473 private static String getAsFileName(String basedir, String javaName,
474 String ext) {
475
476 char sep = File.separator.charAt(0);
477 String basedirTmp = basedir.replace('\\', sep).replace('/', sep);
478
479 return basedirTmp + sep + javaName.replace('.', sep) + ext;
480 }
481
482
483
484
485
486
487
488
489
490 private static String getAsFullyQualifiedNameInternalForm(String javaName) {
491
492 return javaName.replace('.', '/');
493 }
494
495
496
497
498
499
500
501
502
503
504
505
506 public static void saveAsJavaClass(String absoluteFileName,
507 byte[] newBytecode) throws ClassGenerationException {
508
509 LOG.debug(">>>>> saveAs - begin:" + absoluteFileName);
510
511 try {
512 FileOutputStream fos = new FileOutputStream(absoluteFileName);
513
514 fos.write(newBytecode);
515 fos.close();
516 } catch (FileNotFoundException e) {
517 String msg=MESSAGES.getString("EJB001010_saveAsJavaClass", new Object[]{e.getMessage()});
518 LOG.error(msg,e);
519 throw new ClassGenerationException(msg,e);
520 } catch (IOException e) {
521 String msg=MESSAGES.getString("EJB001010_saveAsJavaClass", new Object[]{e.getMessage()});
522 LOG.error(msg,e);
523 throw new ClassGenerationException(msg,e);
524 }
525
526 LOG.debug("<<<<< saveAs - end");
527 }
528
529
530
531
532
533
534
535
536
537
538
539
540
541 public static URLClassLoader getURLClassLoader(String absolutePath, ClassLoader parent)
542 throws MalformedURLException {
543 URL u = new URL(PROTOCOL + absolutePath + "/");
544 URLClassLoader urlClassLoader = new URLClassLoader(new URL[] { u },
545 parent);
546 LOG
547 .debug("url classloader: " +
548 Arrays.asList(urlClassLoader.getURLs()));
549 return urlClassLoader;
550 }
551
552
553
554
555
556
557
558
559
560
561
562 public static URLClassLoader getURLClassLoader(String absolutePath)
563 throws MalformedURLException {
564 return getURLClassLoader(absolutePath, Util.class.getClassLoader());
565 }
566
567
568
569
570
571
572
573
574
575
576
577
578
579 public static void tweakSerializableDecoration(String absPath,
580 Long newSerialVersionUid) throws ClassGenerationException {
581
582 ClassWriter cw = new ClassWriter(true);
583 ClassVisitor cc = new CheckClassAdapter(cw);
584 StringWriter sw = new StringWriter();
585 ClassVisitor tv = new TraceClassVisitor(cc, new PrintWriter(sw));
586
587 SerializableDecorationAdapter cv = new SerializableDecorationAdapter(
588 tv, newSerialVersionUid);
589
590 ClassReader cr = Util.getAsmCLassReader(absPath);
591
592 cr.accept(cv, true);
593 LOG.debug("ClassReader.accept ... done");
594
595 LOG.debug("output of tracer during creation of class: " + absPath +
596 "\n" + sw.toString());
597
598 byte[] newBytecode = cw.toByteArray();
599
600 Util.saveAsJavaClass(absPath, newBytecode);
601 }
602
603
604
605
606
607
608
609
610
611
612
613
614
615 public static ClassVisitor tweakSerializableInspection(String absPath)
616 throws ClassGenerationException {
617
618 ClassWriter cw = new ClassWriter(true);
619 ClassVisitor cc = new CheckClassAdapter(cw);
620 StringWriter sw = new StringWriter();
621 ClassVisitor tv = new TraceClassVisitor(cc, new PrintWriter(sw));
622
623 SerializableInspectorAdapter cv = new SerializableInspectorAdapter(tv);
624
625 ClassReader cr = Util.getAsmCLassReader(absPath);
626
627 cr.accept(cv, true);
628 LOG.debug("ClassReader.accept ... done");
629
630 return cv;
631 }
632
633
634
635
636
637
638
639
640
641
642
643
644 public static ClassReader getAsmCLassReader(String className)
645 throws ClassGenerationException {
646
647 LOG.debug(">>>>> getAsmCLassReader - begin");
648 ClassReader cr = null;
649 try {
650
651 cr = new ClassReader(new FileInputStream(className));
652
653 } catch (IOException e) {
654 String msg=MESSAGES.getString("EJB001011_Could_not_instantiate_class_reader_for_class", new Object[]{className});
655 LOG.error(msg,e);
656 throw new ClassGenerationException(msg,e);
657 }
658
659 LOG.debug("<<<<< getAsmCLassReader - end. ClassReader=" + cr);
660 return cr;
661 }
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676 @SuppressWarnings("unchecked")
677 public static Set<Class> findClassUsed(String dir, List<File> classList)
678 throws ClassGenerationException {
679 LOG.debug(">>>>> findClassUsedInTheOperations - begin");
680
681 LOG.debug("operationsClass=" + classList);
682
683 if (classList == null || classList.size() == 0) {
684 LOG.info("EJB001012_Operations_class_not_found");
685 return new HashSet<Class>();
686 }
687
688 Set<Class> result = new HashSet<Class>();
689
690 for (int i = 0; i < classList.size(); i++) {
691 Class clazz = classLoad(dir, classList.get(i));
692 LOG.debug("classLoad:" + clazz);
693
694
695
696 List<Class> types = UtilClassCollector.extractTypes(clazz);
697
698 for (Class currType : types) {
699 result = UtilClassCollector.visitClassCollector(result,
700 currType);
701 }
702 }
703
704 LOG.debug("<<<<< findClassUsedInTheOperations - end:" + result);
705 return result;
706 }
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722 @SuppressWarnings("unchecked")
723 private static Class classLoad(String dir, File classAsFile)
724 throws ClassGenerationException {
725 URLClassLoader urlClassLoader = null;
726
727 try {
728 File fcd = new File(dir);
729
730 if (LOG.isDebugEnabled()) {
731 LOG
732 .debug("ClassesDir.getAbsolutePath=" +
733 fcd.getAbsolutePath());
734 }
735
736 URL u = new URL(PROTOCOL + fcd.getAbsolutePath() + "/");
737 urlClassLoader = new URLClassLoader(new URL[] { u }, Util.class
738 .getClassLoader());
739
740 LOG.debug("url classloader: " +
741 Arrays.asList(urlClassLoader.getURLs()));
742
743 String className = getClassName(classAsFile, dir);
744 LOG.debug("class name: " + className);
745 return urlClassLoader.loadClass(className);
746
747 } catch (MalformedURLException e) {
748
749
750 String msg=MESSAGES.getString("EJB001013_classLoad", new Object[]{e.getMessage()});
751 LOG.error(msg,e);
752 throw new ClassGenerationException(msg,e);
753 } catch (ClassNotFoundException e) {
754
755
756
757 String msg=MESSAGES.getString("EJB001013_classLoad", new Object[]{e.getMessage()});
758 LOG.error(msg,e);
759 throw new ClassGenerationException(msg,e);
760 }
761 }
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776 private static String getClassName(File file, String basedir)
777 throws ClassGenerationException {
778 LOG.debug(">>>>> getClassName - begin");
779
780 String absoluteFileName = file.getAbsolutePath();
781 String absoulteBaseDir = new File(basedir).getAbsolutePath();
782
783 LOG.debug("absoluteFileName: " + absoluteFileName +
784 "; absoulteBaseDir: " + absoulteBaseDir);
785
786 if (!absoluteFileName.startsWith(absoulteBaseDir)) {
787
788
789
790 String msg=MESSAGES.getString("EJB001014_getClassName", new Object[]{absoluteFileName}, new Object[]{absoulteBaseDir});
791 LOG.error(msg);
792 throw new ClassGenerationException(msg);
793 }
794
795
796 String relativeFileName = absoluteFileName.substring(absoulteBaseDir
797 .length() + 1);
798 LOG.debug("relativeFileName.class=" + relativeFileName);
799
800
801 if (relativeFileName.endsWith(".class")) {
802 relativeFileName = relativeFileName.substring(0, relativeFileName
803 .length() - ".class".length());
804 LOG.debug("relativeFileName=" + relativeFileName);
805 }
806
807 String className = relativeFileName.replace(File.separator, ".");
808 LOG.debug("className=" + className);
809
810 LOG.debug("<<<<< getClassName - end");
811 return className;
812 }
813
814
815
816
817
818
819
820
821
822
823
824 public static List<String> prepareClassPath(String libDirName)
825 throws ClassGenerationException {
826
827 LOG.debug(">>>>> prepareClassPath - begin");
828 List<File> jarFiles
829 = Util.findFilesFromSourceDirectory(libDirName, ".jar");
830
831 List<String> jarFilesName = new ArrayList<String>();
832
833 for (File jarFile:jarFiles) {
834 try {
835 LOG.debug("Adding jar " + jarFile.getCanonicalPath() + " ... ");
836
837 jarFilesName.add(jarFile.getCanonicalPath());
838
839 LOG.debug("... jar " + jarFile.getCanonicalPath() + " added.");
840 } catch (IOException e) {
841
842
843 String msg=MESSAGES.getString("EJB001015_prepareClassPath", new Object[]{e.getMessage()});
844 LOG.error(msg,e);
845 throw new ClassGenerationException(msg,e);
846 }
847 }
848
849 LOG.debug("<<<<< prepareClassPath - end");
850 return jarFilesName;
851 }
852 }