View Javadoc

1    /****************************************************************************
2    * Copyright (c) 2005, 2006, 2007, 2008, 2009 Imola Informatica.
3    * All rights reserved. This program and the accompanying materials
4    * are made available under the terms of the LGPL License v2.1
5    * which accompanies this distribution, and is available at
6    * http://www.gnu.org/licenses/lgpl.html
7    ****************************************************************************/
8   package it.imolinfo.jbi4corba.webservice.generator;
9   
10  import it.imolinfo.jbi4corba.Logger;
11  import it.imolinfo.jbi4corba.LoggerFactory;
12  import it.imolinfo.jbi4corba.exception.ClassGenerationException;
13  import it.imolinfo.jbi4corba.exception.Jbi4CorbaException;
14  import it.imolinfo.jbi4corba.utils.HelperFileUtil;
15  import it.imolinfo.jbi4corba.webservice.generator.bcm.CorbaEnumAdapter;
16  import it.imolinfo.jbi4corba.webservice.generator.bcm.CorbaOnewayAdapter;
17  import it.imolinfo.jbi4corba.webservice.generator.bcm.SerializableDecorationAdapter;
18  import it.imolinfo.jbi4corba.webservice.generator.bcm.SerializableInspectorAdapter;
19  
20  import java.io.ByteArrayOutputStream;
21  import java.io.File;
22  import java.io.FileFilter;
23  import java.io.FileInputStream;
24  import java.io.FileNotFoundException;
25  import java.io.FileOutputStream;
26  import java.io.FileWriter;
27  import java.io.IOException;
28  import java.io.InputStream;
29  import java.io.ObjectStreamClass;
30  import java.io.OutputStream;
31  import java.io.PrintStream;
32  import java.io.PrintWriter;
33  import java.io.StringWriter;
34  import java.lang.reflect.InvocationTargetException;
35  import java.lang.reflect.Method;
36  import java.lang.reflect.Modifier;
37  import java.net.MalformedURLException;
38  import java.net.URL;
39  import java.net.URLClassLoader;
40  import java.util.ArrayList;
41  import java.util.Arrays;
42  import java.util.Collection;
43  import java.util.HashMap;
44  import java.util.HashSet;
45  import java.util.List;
46  import java.util.Map;
47  import java.util.Set;
48  
49  import org.apache.cxf.helpers.FileUtils;
50  import org.objectweb.asm.ClassReader;
51  import org.objectweb.asm.ClassVisitor;
52  import org.objectweb.asm.ClassWriter;
53  import org.objectweb.asm.util.CheckClassAdapter;
54  import org.objectweb.asm.util.TraceClassVisitor;
55  
56  /**
57   * A collection of utility methods.
58   */
59  public class Util {
60  
61  	private static final String CLASS_FILE_EXTENSION = ".class";
62  
63  	/**
64  	 * The platform dependent protocol used to load file and classes.
65  	 */
66  	public static final String PROTOCOL;
67  
68  	/**
69  	 * Buffer size to copy from an InputStream to the output.
70  	 */
71  	private static final int DEFAULT_BUFFER_SIZE = 4096;
72  
73  	/**
74  	 * Logger.
75  	 */
76  	private static final Logger LOG = LoggerFactory.getLogger(Util.class);
77  
78  	/**
79  	 * Default constructor.
80  	 */
81  	public Util() {
82  
83  	}
84  
85  	static {
86  		if (System.getProperty("os.name").indexOf("Win") >= 0) {
87  			PROTOCOL = "file:///";
88  		} else {
89  			PROTOCOL = "file://";
90  		}
91  	}
92  
93  	/**
94  	 * @param classesDir
95  	 *            The classes dir
96  	 * @param className
97  	 *            The class name
98  	 * @param extraClasspath
99  	 *            The extra class path
100 	 * 
101 	 * @throws ClassGenerationException
102 	 *             The class generation exception
103 	 */
104 	public static void compileRemoteClassesNoValueMethodsON(String classesDir,
105 			String className, List<String> extraClasspath)
106 			throws ClassGenerationException {
107 
108 		LOG.debug(">>>>> compileRemoteClassesNoValueMethodsON - begin");
109 
110 		String cp = classesDir;
111 
112 		if (extraClasspath != null) {
113 			for (String i : extraClasspath) {
114 				cp += File.pathSeparator + i;
115 			}
116 		}
117 
118 		List<String> params = new ArrayList<String>(Arrays.asList(new String[] {
119 				"-classpath", classesDir, "-d", classesDir, "-idl", "-always",
120 				"-factory", // FIXME test
121 				"-iiop", "-nolocalstubs", "-noValueMethods", // only when -idl
122 				"-poa", "-verbose", className }));
123 
124 		compileRemoteClasses(classesDir, className, params);
125 
126 		LOG.debug("<<<<< compileRemoteClassesNoValueMethodsON - end");
127 	}
128 
129 	/**
130 	 * @param classesDir
131 	 *            The classes dir
132 	 * @param className
133 	 *            The class name
134 	 * @param extraClasspath
135 	 *            The extra class path
136 	 * @throws ClassGenerationException
137 	 *             The class generation exception
138 	 */
139 	public static void compileRemoteClassesNoValueMethodsOFF(String classesDir,
140 			String className, List<String> extraClasspath)
141 			throws ClassGenerationException {
142 
143 		LOG.debug(">>>>> compileRemoteClassesNoValueMethodsOFF - begin");
144 
145 		String cp = classesDir;
146 
147 		if (extraClasspath != null) {
148 			for (String i : extraClasspath) {
149 				cp += File.pathSeparator + i;
150 			}
151 		}
152 
153 		List<String> params = new ArrayList<String>(Arrays.asList(new String[] {
154 				"-classpath", cp, "-d", classesDir, "-idl", "-always", "-iiop",
155 				"-nolocalstubs", "-verbose", className }));
156 
157 		compileRemoteClasses(classesDir, className, params);
158 
159 		LOG.debug("<<<<< compileRemoteClassesNoValueMethodsOFF - end");
160 	}
161 
162 	// XXX javadoc
163 	/**
164 	 * @param classesDir
165 	 *            The classes dir
166 	 * @param className
167 	 *            The class name
168 	 * @param params
169 	 *            The params
170 	 * @throws ClassGenerationException
171 	 *             The class generation exception
172 	 */
173 	private static void compileRemoteClasses(String classesDir,
174 			String className, List<String> params)
175 			throws ClassGenerationException {
176 
177 		LOG.debug(">>>>> compileRemoteClasses - begin");
178 
179 		LOG.debug("compileRemoteClasses - classesDir=" + classesDir
180 				+ "; className=" + className);
181 
182 		/*
183 		 * -idl Causes rmic to generate OMG IDL for the classes specified and
184 		 * any classes referenced. IDL provides a purely declarative,
185 		 * programming language-independent way of specifying an object's API.
186 		 * The IDL is used as a specification for methods and data that can be
187 		 * written in and invoked from any language that provides CORBA
188 		 * bindings.
189 		 * 
190 		 * When the -idl option is used, other options also include:
191 		 * 
192 		 * -always or -alwaysgenerate: Forces re-generation
193 		 * 
194 		 * -factory: Uses factory keyword in generated IDL.
195 		 * 
196 		 * -idlModule fromJavaPackage[.class] toIDLModule Specifies IDLEntity
197 		 * package mapping. For example: -idlModule foo.bar my::real::idlmod.
198 		 * 
199 		 * -idlFile fromJavaPackage[.class] toIDLFile Specifies IDLEntity file
200 		 * mapping. For example: -idlFile test.pkg.X TEST16.idl.
201 		 * 
202 		 * -iiop Causes rmic to generate IIOP stub and tie classes, rather than
203 		 * JRMP stub and skeleton classes. A stub class is a local proxy for a
204 		 * remote object and is used by clients to send calls to a server. Each
205 		 * remote interface requires a stub class, which implements that remote
206 		 * interface. A client's reference to a remote object is actually a
207 		 * reference to a stub. Tie classes are used on the server side to
208 		 * process incoming calls, and dispatch the calls to the proper
209 		 * implementation class. Each implementation class requires a tie class.
210 		 * 
211 		 * Invoking rmic with the -iiop generates stubs and ties that conform to
212 		 * this naming convention: _<implementationName>_stub.class
213 		 * _<interfaceName>_tie.class
214 		 * 
215 		 * When the -iiop option is used, other options also include:
216 		 * 
217 		 * -always or -alwaysgenerate Forces re-generation even when existing
218 		 * stubs/ties/IDL are newer than the input class. -nolocalstubs Do not
219 		 * create stubs optimized for same-process clients and servers.
220 		 * -noValueMethods Must be used with the -idl option. Prevents addition
221 		 * of valuetype methods and initializers to emitted IDL. These methods
222 		 * and initializers are optional for valuetypes, and are generated
223 		 * unless the -noValueMethods option is specified when using the -idl
224 		 * option. -poa Changes the inheritance from
225 		 * org.omg.CORBA_2_3.portable.ObjectImpl to
226 		 * org.omg.PortableServer.Servant. The PortableServer module for the
227 		 * Portable Object Adapter (POA) defines the native Servant type. In the
228 		 * Java programming language, the Servant type is mapped to the Java
229 		 * org.omg.PortableServer.Servant class. It serves as the base class for
230 		 * all POA servant implementations and provides a number of methods that
231 		 * may be invoked by the application programmer, as well as methods
232 		 * which are invoked by the POA itself and may be overridden by the user
233 		 * to control aspects of servant behavior.
234 		 */
235 
236 		ByteArrayOutputStream BAOS = new ByteArrayOutputStream();
237 		PrintStream printstream = new PrintStream(BAOS);
238 
239 		sun.rmi.rmic.Main main = new sun.rmi.rmic.Main(printstream, "rmic");
240 
241 		boolean result = main.compile(params.toArray(new String[] {}));
242 
243 		// com.sun.tools.javac.Main.main(params.toArray(new String[] {}));
244 		LOG.debug("compilation output: \n" + BAOS.toString());
245 		if (!result) {
246 			Object[] args = new Object[] { params, result, BAOS.toString() };
247 
248 			LOG.error("CRB000528_Error_compiling_classes", args);
249 			throw new ClassGenerationException(
250 					"CRB000528_Error_compiling_classes", args, null);
251 		} else {
252 			LOG.debug("compilation ok");
253 		}
254 
255 		LOG.debug("<<<<< compileRemoteClasses - end");
256 	}
257 
258 	/**
259 	 * Finding the *.java files in the directory 'basedir'.
260 	 * 
261 	 * @param basedir
262 	 *            The directory where the method looks up the files.
263 	 * 
264 	 * @return The list of java source file (canonical path)
265 	 * 
266 	 * @throws Jbi4CorbaException
267 	 *             The Jbi4Corba exception
268 	 */
269 	public static List<String> findJavaSources(String basedir)
270 			throws Jbi4CorbaException {
271 
272 		LOG.debug(">>>>> findJavaSources(String) - begin");
273 
274 		List<String> javaSourcesNames = findJavaSources(basedir, null);
275 
276 		LOG.debug("<<<<< findJavaSources(String) - end");
277 		return javaSourcesNames;
278 	}
279 
280 	/**
281 	 * This method looking for 'x' inside the list. The type of the slash and
282 	 * the case will be ignored.
283 	 * 
284 	 * @param list
285 	 *            The list to inspect.
286 	 * @param x
287 	 *            The object to find.
288 	 * 
289 	 * @return true, if x is contained in the list.
290 	 */
291 	private static boolean containsIgnoreSlashes(List<String> list, String x) {
292 		if (x == null) {
293 			return false;
294 		}
295 		// else
296 		if (list == null) {
297 			return false;
298 		}
299 		// else
300 
301 		String xrr = x.replace('\\', ' ').replace('/', ' ');
302 
303 		for (String c : list) {
304 			String crr = c.replace('\\', ' ').replace('/', ' ');
305 
306 			if (xrr.equalsIgnoreCase(crr)) {
307 				return true;
308 			}
309 		}
310 
311 		// else
312 		return false;
313 	}
314 
315 	/**
316 	 * 
317 	 * @param basedir
318 	 *            The basedir
319 	 * @param exclude
320 	 *            The exclude
321 	 * @return The return
322 	 * @throws Jbi4CorbaException
323 	 *             The Jbi4Corba exception
324 	 */
325 	public static List<String> findJavaSources(String basedir,
326 			List<String> exclude) throws Jbi4CorbaException {
327 
328 		LOG.debug(">>>>> findJavaSources(String, List<String>) - begin");
329 
330 		List<String> javaSourcesNames = new ArrayList<String>();
331 		List<File> sourceFiles = findFilesFromSourceDirectory(basedir, ".java");
332 
333 		for (File source : sourceFiles) {
334 
335 			String src = null;
336 			try {
337 
338 				src = source.getCanonicalPath();
339 
340 			} catch (IOException e) {
341 				Object[] args = new Object[] { basedir };
342 
343 				LOG.error("CRB000529_Unexpected_error", args, e);
344 				throw new Jbi4CorbaException("CRB000529_Unexpected_error",
345 						args, e);
346 			}
347 
348 			/*
349 			 * Some files is not compiled.
350 			 * 
351 			 * This feature is useful when we add to the classpath some class
352 			 * compiled before this task and bytecode manipulated.
353 			 */
354 			if (src.endsWith("src")) {
355 
356 				LOG.debug("The file " + src + " won't be compile.");
357 
358 			} else if (containsIgnoreSlashes(exclude, src)) {
359 
360 				LOG.debug("The file " + src + " won't be compile.");
361 
362 			} else {
363 				LOG.debug("The file " + src + " will be compiled.");
364 				javaSourcesNames.add(src);
365 			}
366 		}
367 
368 		LOG.debug("<<<<< findJavaSources(String, List<String>) - end");
369 		return javaSourcesNames;
370 	}
371 
372 	/**
373 	 * This method find all the java source file with the suffix
374 	 * 'DefaultFacoty.java'.
375 	 * 
376 	 * @param basedir
377 	 *            The directory inspected.
378 	 * 
379 	 * @return The list of files found.
380 	 * 
381 	 * @throws IOException
382 	 *             The IO exception
383 	 */
384 	public static List<String> findAllDefaultFactory(String basedir)
385 			throws IOException {
386 
387 		final String suffix = "DefaultFactory.java";
388 
389 		LOG.debug(">>>>> findAllDefaultFactory - begin");
390 
391 		List<String> javaSourcesNames = new ArrayList<String>();
392 		List<File> sourceFiles = findFilesFromSourceDirectory(basedir, suffix);
393 
394 		for (File source : sourceFiles) {
395 			javaSourcesNames.add(source.getAbsolutePath());
396 
397 			LOG.debug("findAllDefaultFactory + " + source.getCanonicalPath());
398 		}
399 
400 		LOG.debug("<<<<< findAllDefaultFactory - end");
401 		return javaSourcesNames;
402 	}
403 
404 	/**
405 	 * Finding the *.idl files in the directory 'basedir'.
406 	 * 
407 	 * @param basedir
408 	 *            The directory where the method looks up the files.
409 	 * 
410 	 * @return The list of IDL file (canonical path)
411 	 * 
412 	 * @throws Jbi4CorbaException
413 	 *             The Jbi4Corba exception
414 	 */
415 	public static List<String> findIdlFiles(String basedir)
416 			throws Jbi4CorbaException {
417 
418 		LOG.debug(">>>>> findIdlFiles - begin");
419 
420 		List<String> javaSourcesNames = new ArrayList<String>();
421 		List<File> sourceFiles = findFilesFromSourceDirectory(basedir, ".idl");
422 
423 		for (File source : sourceFiles) {
424 
425 			String src = null;
426 			try {
427 				src = source.getCanonicalPath();
428 			} catch (IOException e) {
429 				Object[] args = new Object[] { basedir };
430 
431 				LOG.error("CRB000530_Unexpected_error", args, e);
432 				throw new Jbi4CorbaException("CRB000530_Unexpected_error",
433 						args, e);
434 			}
435 
436 			javaSourcesNames.add(src);
437 			LOG.debug("findIdlFiles + " + src);
438 		}
439 
440 		LOG.debug("<<<<< findIdlFiles - end");
441 		return javaSourcesNames;
442 	}
443 
444 	/**
445 	 * This method find all the files in a directory according to the filter.
446 	 * MARCO 23/09/2007: now searches also in the root
447 	 * <code>baseDirString</code> (not only in the subdirectories). <br/>
448 	 * 
449 	 * @param basedirString
450 	 *            The directory where the method works.
451 	 * @param extensionFilter
452 	 *            The filter (the suffix of the files).
453 	 * @return The return
454 	 */
455 	public static List<File> findFilesFromSourceDirectory(String basedirString,
456 			final String extensionFilter) {
457 
458 		LOG.debug(">>>>> findFilesFromSourceDirectory - begin");
459 
460 		File basedir = new File(basedirString);
461 
462 		FileFilter filter = new FileFilter() {
463 			public boolean accept(File file) {
464 
465 				boolean filterAcceptExtension = file.getName().endsWith(
466 						extensionFilter);
467 				// Excludes the package-info.class classes
468 				boolean filterAccept = filterAcceptExtension
469 						&& (!file.getName().equals("package-info.class"));
470 
471 				// LOG.debug("findFilesFromSourceDirectory"
472 				// + "; extensionFilter=" + extensionFilter
473 				// + "; filterAccept=" + filterAccept
474 				// + "; file=" + file.getName());
475 
476 				return filterAccept;
477 			}
478 		};
479 
480 		LOG.debug("findFilesFromSourceDirectory" + "; basedir=" + basedir
481 				+ "; FileFilter=" + filter + "; extensionFilter="
482 				+ extensionFilter);
483 
484 		List<File> directories = findDirectories(basedir);
485 		/*
486 		 * MARCO: Added (23/09/2008) to test also the base directory.
487 		 */
488 		if (basedir != null) {
489 			directories.add(basedir);
490 		}
491 		LOG.debug("directories: " + directories);
492 
493 		List<File> filterdFiles = new ArrayList<File>();
494 		for (File dir : directories) {
495 			File[] innerFilteredFiles = dir.listFiles(filter);
496 
497 			if (innerFilteredFiles != null)
498 			{
499 				LOG.debug("inner filtered files: "
500 						+ Arrays.asList(innerFilteredFiles));
501 	
502 				filterdFiles.addAll(Arrays.asList(innerFilteredFiles));
503 			}
504 		}
505 
506 		LOG.debug("<<<<< findFilesFromSourceDirectory - end");
507 		return filterdFiles;
508 	}
509 
510 	// XXX javadoc
511 
512 	/**
513 	 * @param basedir
514 	 *            The basedir
515 	 * @return The return
516 	 */
517 	private static List<File> findDirectories(File basedir) {
518 		List<File> directories = new ArrayList<File>();
519 
520 		if (basedir == null || "".equals(basedir)) {
521 			return directories;
522 		}
523 
524 		FileFilter directoryFilter = new FileFilter() {
525 			public boolean accept(File file) {
526 				return file.isDirectory();
527 			}
528 		};
529 
530 		File[] files = basedir.listFiles(directoryFilter);
531 
532 		if (files == null) {
533 			return directories;
534 		}
535 
536 		for (int i = 0; i < files.length; i++) {
537 			List<File> innerDirectories = findDirectories(files[i]);
538 			directories.addAll(innerDirectories);
539 			directories.add(files[i]);
540 		}
541 
542 		return directories;
543 	}
544 
545 	/**
546 	 * XXX javadoc.
547 	 * 
548 	 * @param workdirsrc
549 	 *            The work dir src
550 	 * @param workdirclasses
551 	 *            The workdir classes
552 	 * @param javaSources
553 	 *            The java sources
554 	 * @param jarFiles
555 	 *            The jar files
556 	 * @param extraClassPath
557 	 *            The extra class path
558 	 * @throws ClassGenerationException
559 	 *             The class generation exception
560 	 */
561 	public static void compileJavaClasses(String workdirsrc,
562 			String workdirclasses, List<String> javaSources,
563 			List<String> jarFiles, List<String> extraClassPath)
564 			throws ClassGenerationException {
565 
566 		LOG.debug(">>>>> compileJavaClasses - begin");
567 
568 		LOG.debug("compileJavaClasses" + ".\n workdirsrc=" + workdirsrc
569 				+ ";\n workdirclasses=" + workdirclasses + ";\n javaSources="
570 				+ javaSources + ";\n jarFiles=" + jarFiles
571 				+ ";\n extraClassPath=" + extraClassPath);
572 
573 		List<String> params = new ArrayList<String>(Arrays.asList(new String[] {
574 				"-d", workdirclasses, "-sourcepath", workdirsrc }));
575 
576 		LOG.debug("creating classpath - begin");
577 
578 		String classpath = "";
579 
580 		// jars ...
581 
582 		if (jarFiles != null) {
583 
584 			for (String jarFileName : jarFiles) {
585 				classpath += jarFileName + File.pathSeparator; // ":" or ";"
586 
587 				LOG.debug("ClassPath + (jar) " + jarFileName);
588 			}
589 
590 		}
591 
592 		// ... and extra
593 
594 		if (extraClassPath != null) {
595 			for (String extra : extraClassPath) {
596 
597 				File f = new File(extra);
598 				if (!f.isDirectory()) {
599 					extra = f.getParent();
600 					LOG.debug("-----> EXTRA=[" + extra + "]");
601 				}
602 
603 				classpath += extra + File.pathSeparator; // ":" or ";"
604 
605 				LOG.debug("ClassPath + (extra) " + extra);
606 			}
607 		} else {
608 			LOG.debug("No extra classpath.");
609 		}
610 
611 		// at the end I must set up the classpath
612 
613 		if (!"".equals(classpath)) {
614 			LOG.debug("Final ClassPath=" + classpath);
615 
616 			params.add("-cp");
617 			params.add(classpath);
618 		} else {
619 			LOG.debug("Final ClassPath=<<EMPTY>>");
620 		}
621 
622 		LOG.debug("creating classpath - end.");
623 
624 		// log.debug("javaSources: " + Arrays.toString(javaSources.toArray()));
625 		// log.debug("params: " + Arrays.toString(params.toArray()));
626 
627 		params.addAll(javaSources);
628 
629 		LOG.debug("command line: " + Arrays.toString(params.toArray()));
630 
631 		File classesdir = new File(workdirclasses);
632                 //if the class dir exists we have do delete all file and gnerate new classes
633                 if(classesdir.exists()){
634                     LOG.debug("Classes Dir Already Exists:" + classesdir);
635                     FileUtils.delete(classesdir);
636                 }
637 		if (!classesdir.exists()) {
638 			boolean result = classesdir.mkdirs();
639 
640 			if (!result) {
641 				Object[] args = new Object[] { classesdir };
642 
643 				LOG.error("CRB000531_Unable_to_create_compilation_directory",
644 						args);
645 				throw new ClassGenerationException(
646 						"CRB000531_Unable_to_create_compilation_directory",
647 						args, null);
648 			} else {
649 				LOG.debug("Classes Dir Created:" + classesdir);
650 			}
651 		} else {
652 			LOG.debug("Classes Dir Already Exists:" + classesdir);                        
653 		}
654 
655 		StringWriter stringWriter = new StringWriter();
656 		PrintWriter printstream = new PrintWriter(stringWriter);
657 
658 		// Main main = new Main(printstream, "javac");
659 		// Class mainclass = com.sun.tools.javac.Main.class;
660 
661 		/*
662 		 * ClassLoader mainclassClassLoader=mainclass.getClassLoader();
663 		 * log.debug
664 		 * ("mainclass: "+mainclass+" classloader: "+mainclass.getClassLoader
665 		 * ()); Class
666 		 * xmlAccessTypeClass=javax.xml.bind.annotation.XmlAccessType.class;
667 		 * log.debug("XmlAccessClass: "+xmlAccessTypeClass+" classloader: "+
668 		 * xmlAccessTypeClass.getClassLoader()); try {
669 		 * mainclassClassLoader.loadClass
670 		 * ("javax.xml.bind.annotation.XmlAccessType"); } catch
671 		 * (ClassNotFoundException e) {
672 		 * log.error("could not instantiate class: " +
673 		 * "javax.xml.bind.annotation.XmlAccessType", e); throw new
674 		 * ClassGenerationException("could not instantiate class: " +
675 		 * "javax.xml.bind.annotation.XmlAccessType", e); }
676 		 */
677 
678 		LOG.debug("Compiling - begin");
679 
680 		int result = com.sun.tools.javac.Main.compile(params
681 				.toArray(new String[] {}), printstream);
682 
683 		LOG.debug("Compiling - end. result=" + result);
684 
685 		// com.sun.tools.javac.Main.main(params.toArray(new String[] {}));
686 
687 		LOG.debug("compilation output: \n" + stringWriter.toString());
688 
689 		if (!(result == 0)) {
690 			Object[] args = new Object[] { params, result,
691 					stringWriter.toString() };
692 
693 			LOG.error("CRB000528_Error_compiling_classes", args);
694 			throw new ClassGenerationException(
695 					"CRB000528_Error_compiling_classes", args, null);
696 		} else {
697 			LOG.debug("Compilation OK.");
698 		}
699 
700 		LOG.debug("<<<<< compileJavaClasses - end");
701 	}
702 
703 	/**
704 	 * This method extracts all the MethodSignature in the 'Operations' source
705 	 * files.
706 	 * 
707 	 * @param sourceDir
708 	 *            The directory where we find the files.
709 	 * 
710 	 * @return The map of method signature associated to the qualified java name
711 	 *         of the class (the key of the map).
712 	 * 
713 	 * @throws ClassGenerationException
714 	 *             The class generation exception
715 	 */
716 	public static Map<String, List<MethodSignature>> extractMethodSignatureOfTheCorbaOperations(
717 			String sourceDir) throws ClassGenerationException {
718 
719 		// find
720 		List<File> corbaOperationsSourceFileList = Util
721 				.findFilesFromSourceDirectory(sourceDir, "Operations.java");
722 
723 		Map<String, List<MethodSignature>> map = new HashMap<String, List<MethodSignature>>();
724 
725 		// check
726 		if (corbaOperationsSourceFileList == null
727 				|| corbaOperationsSourceFileList.size() == 0) {
728 
729 			LOG.debug("No files found with the suffix 'Operations.java'");
730 			return map;
731 		}
732 
733 		// else
734 
735 		UtilJavaSourceParsing parser = new UtilJavaSourceParsing();
736 
737 		for (File operationFile : corbaOperationsSourceFileList) {
738 
739 			String absPath = operationFile.getAbsolutePath();
740 			LOG.debug("parsing ... " + absPath);
741 
742 			String fullQualifiedName = extractJavaQualifiedName(sourceDir,
743 					absPath, ".java");
744 
745 			List<MethodSignature> methodSignatureList = parser
746 					.extractMethodSignature(absPath, fullQualifiedName);
747 
748 			map.put(fullQualifiedName, methodSignatureList);
749             LOG.debug("signatures name: "+fullQualifiedName+" signs: "+Arrays.toString(methodSignatureList.toArray()));
750 		}
751 
752 		return map;
753 	}
754 
755 	/**
756 	 * This method extracs all the class used as method's parameter or method's
757 	 * result.
758 	 * 
759 	 * @param dir
760 	 *            Where looking for the classes.
761 	 * @return The set of class found.
762 	 * @throws ClassGenerationException
763 	 *             The class generation exception
764 	 */
765 	public static Set<Class> findClassUsedInTheOperations(String dir)
766 			throws ClassGenerationException {
767 		LOG.debug(">>>>> findClassUsedInTheOperations - begin");
768 
769 		List<File> operationsClass = Util.findFilesFromSourceDirectory(dir,
770 				"Operations.class");
771 
772 		Set<Class> result = findClassUsed(dir, operationsClass);
773 
774 		LOG.debug("<<<<< findClassUsedInTheOperations - end:" + result);
775 		return result;
776 	}
777 	/**
778 	 * This method extracts all the types used in idl
779 	 * file.
780 	 * 
781 	 * @param dir
782 	 *            Where looking for the classes.
783 	 * @return The set of class found.
784 	 * @throws ClassGenerationException
785 	 *             The class generation exception
786 	 */
787 	public static Set<Class> findAllTypesUsedInIDL(String dir)
788 			throws ClassGenerationException {
789 		LOG.debug(">>>>> findClassUsedInTheOperations - begin");
790 
791 		List<File> operationsClass = Util.findFilesFromSourceDirectory(dir,
792 				"Helper.class");
793 		
794 		Set<Class> result = findAllTypes(dir, operationsClass);
795 
796 		LOG.debug("<<<<< findClassUsedInTheOperations - end:" + result);
797 		return result;
798 	}
799 
800 	
801 	/**
802 	 * findAllTypes - finds all types defined in IDL
803 	 * 
804 	 * @param dir
805 	 * @param typeClasses
806 	 * @return
807 	 * @throws ClassGenerationException
808 	 */
809 	public static HashMap<String,String> getTypesMap(String dir) throws ClassGenerationException {
810 		
811 		List<File> typeClasses = Util.findFilesFromSourceDirectory(dir,
812 		"Helper.class");
813 
814 		if (typeClasses == null || typeClasses.size() == 0) {
815 			LOG.info("CRB000532_type_classes_not_found");
816 			return new HashMap<String,String>();
817 		}
818 
819 		HashMap<String,String> result = new HashMap<String,String>();
820 		String id="";
821 		for (int i = 0; i < typeClasses.size(); i++) {
822 			
823 			Class helperclazz = loadHelperClass(dir, typeClasses.get(i));
824 			
825 			try {
826 				id = helperclazz.getMethod("id",null ).invoke(null,null).toString();
827 			} catch (Exception e) {
828                                 throw new ClassGenerationException("CRB000533_Could_not_invoke_id_in_the_helper_class",e);
829 			}
830 			LOG.debug("loadTypeClass:" + helperclazz);
831 			if (helperclazz != null && !helperclazz.getCanonicalName().startsWith("org.omg."))
832 				result.put(id,helperclazz.getCanonicalName());
833 		}
834 		return result;
835 	}
836 
837 	/**
838 	 * findAllTypes - finds all types defined in IDL
839 	 * 
840 	 * @param dir
841 	 * @param typeClasses
842 	 * @return
843 	 * @throws ClassGenerationException
844 	 */
845 	private static Set<Class> findAllTypes(String dir,
846 			List<File> typeClasses) throws ClassGenerationException {
847 		LOG.debug(">>>>> findAllTypes - begin");
848 
849 		LOG.debug("Type Classes =" + typeClasses);
850 
851 		if (typeClasses == null || typeClasses.size() == 0) {
852 			LOG.info("CRB000532_type_classes_not_found");
853 			return new HashSet<Class>();
854 		}
855 
856 		Set<Class> result = new HashSet<Class>();
857 
858 		for (int i = 0; i < typeClasses.size(); i++) {
859 			Class clazz = loadTypeClass(dir, typeClasses.get(i));
860 			LOG.debug("loadTypeClass:" + clazz);
861 			if (clazz != null && !clazz.getCanonicalName().startsWith("org.omg."))
862 				result.add(clazz);
863 		}
864 		return result;
865 	}
866 	
867 	/**
868 	 * loadTypeClass - loads type
869 	 * 
870 	 * @param dir
871 	 * @param classAsFile
872 	 * @return
873 	 * @throws ClassGenerationException
874 	 */
875 	private static Class loadTypeClass(String dir, File classAsFile) throws ClassGenerationException {
876 		URLClassLoader urlClassLoader = null;
877 		String className = null;
878 
879 		try {
880 			File fcd = new File(dir);
881 
882 			if (LOG.isDebugEnabled()) {
883 				LOG
884 						.debug("ClassesDir.getAbsolutePath="
885 								+ fcd.getAbsolutePath());
886 			}
887 
888 			URL u = new URL(PROTOCOL + fcd.getAbsolutePath() + "/");
889 			urlClassLoader = new URLClassLoader(new URL[] { u }, Util.class
890 					.getClassLoader());
891 
892 			LOG.debug("url classloader: "
893 					+ Arrays.asList(urlClassLoader.getURLs()));
894 
895 			className = getClassName(classAsFile, dir, CLASS_FILE_EXTENSION);
896 			// remove Helper
897 			className = className.substring(0, className.length() - 6);
898 			LOG.debug("class name: " + className);
899 			return urlClassLoader.loadClass(className);
900 
901 		} catch (MalformedURLException e) {
902 			Object[] args = new Object[] { PROTOCOL
903 					+ new File(dir).getAbsolutePath() + "/" };
904 
905 			LOG.error("CRB000533_Could_not_instantiate_url_class_loader", args,
906 					e);
907 			throw new ClassGenerationException(
908 					"CRB000533_Could_not_instantiate_url_class_loader", args, e);
909 		} catch (ClassNotFoundException e) {
910 			Object[] args = new Object[] { PROTOCOL
911 					+ new File(dir).getAbsolutePath() + "/" };
912 
913 			LOG.debug("Class " + className + "is not a type", args,
914 					e);
915 			return null;
916 		}
917 		
918 	}
919 	
920 	/**
921 	 * loadTypeClass - loads type
922 	 * 
923 	 * @param dir
924 	 * @param classAsFile
925 	 * @return
926 	 * @throws ClassGenerationException
927 	 */
928 	private static Class loadHelperClass(String dir, File classAsFile) throws ClassGenerationException {
929 		URLClassLoader urlClassLoader = null;
930 		String className = null;
931 
932 		try {
933 			File fcd = new File(dir);
934 
935 			if (LOG.isDebugEnabled()) {
936 				LOG
937 						.debug("ClassesDir.getAbsolutePath="
938 								+ fcd.getAbsolutePath());
939 			}
940 
941 			URL u = new URL(PROTOCOL + fcd.getAbsolutePath() + "/");
942 			urlClassLoader = new URLClassLoader(new URL[] { u }, Util.class
943 					.getClassLoader());
944 
945 			LOG.debug("url classloader: "
946 					+ Arrays.asList(urlClassLoader.getURLs()));
947 
948 			className = getClassName(classAsFile, dir, CLASS_FILE_EXTENSION);
949 			
950 			LOG.debug("class name: " + className);
951 			return urlClassLoader.loadClass(className);
952 
953 		} catch (MalformedURLException e) {
954 			Object[] args = new Object[] { PROTOCOL
955 					+ new File(dir).getAbsolutePath() + "/" };
956 
957 			LOG.error("CRB000533_Could_not_instantiate_url_class_loader", args,
958 					e);
959 			throw new ClassGenerationException(
960 					"CRB000533_Could_not_instantiate_url_class_loader", args, e);
961 		} catch (ClassNotFoundException e) {
962 			Object[] args = new Object[] { PROTOCOL
963 					+ new File(dir).getAbsolutePath() + "/" };
964 
965 			LOG.debug("Class " + className + "is not a type", args,
966 					e);
967 			return null;
968 		}
969 		
970 	}
971 
972 	/**
973 	 * This method extracs all the class used as method's parameter or method's
974 	 * result.
975 	 * 
976 	 * @param dir
977 	 *            The dir
978 	 * @param classList
979 	 *            The class list
980 	 * @return the return
981 	 * @throws ClassGenerationException
982 	 *             The class generation exception
983 	 */
984 	public static Set<Class> findClassUsed(String dir, List<File> classList)
985 			throws ClassGenerationException {
986 		LOG.debug(">>>>> findClassUsedInTheOperations - begin");
987 
988 		LOG.debug("operationsClass=" + classList);
989 
990 		if (classList == null || classList.size() == 0) {
991 			LOG.info("CRB000532_Operations_class_not_found");
992 			return new HashSet<Class>();
993 		}
994 
995 		Set<Class> result = new HashSet<Class>();
996 
997 		for (int i = 0; i < classList.size(); i++) {
998 			Class clazz = classLoad(dir, classList.get(i));
999 			LOG.debug("classLoad:" + clazz);
1000 
1001 			// I don't want to include the operations class,
1002 			// so I extract the data types used inside
1003 			List<Class> types = UtilClassCollector.extractTypes(clazz);
1004 
1005 			for (Class currType : types) {
1006 				result = UtilClassCollector.visitClassCollector(result,
1007 						currType);
1008 			}
1009 		}
1010 
1011 		// check Holder
1012 		List<Class> holder = findHolderUsed(dir);
1013 		for (Class currType : holder) {
1014 			result = UtilClassCollector.visitClassCollector(result, currType);
1015 		}
1016 
1017 		LOG.debug("<<<<< findClassUsedInTheOperations - end:" + result);
1018 		return result;
1019 	}
1020 
1021 	/**
1022 	 * 
1023 	 * @param dir
1024 	 *            The dir
1025 	 * @param classAsFile
1026 	 *            The class AsFile
1027 	 * @return The return
1028 	 * @throws ClassGenerationException
1029 	 *             The class generation exception
1030 	 */
1031 	public static Class classLoad(String dir, File classAsFile)
1032 			throws ClassGenerationException {
1033 		URLClassLoader urlClassLoader = null;
1034 
1035 		try {
1036 			File fcd = new File(dir);
1037 
1038 			if (LOG.isDebugEnabled()) {
1039 				LOG
1040 						.debug("ClassesDir.getAbsolutePath="
1041 								+ fcd.getAbsolutePath());
1042 			}
1043 
1044 			URL u = new URL(PROTOCOL + fcd.getAbsolutePath() + "/");
1045 			urlClassLoader = new URLClassLoader(new URL[] { u }, Util.class
1046 					.getClassLoader());
1047 
1048 			LOG.debug("url classloader: "
1049 					+ Arrays.asList(urlClassLoader.getURLs()));
1050 
1051 			String className = getClassName(classAsFile, dir, CLASS_FILE_EXTENSION);
1052 			LOG.debug("class name: " + className);
1053 			return urlClassLoader.loadClass(className);
1054 
1055 		} catch (MalformedURLException e) {
1056 			Object[] args = new Object[] { PROTOCOL
1057 					+ new File(dir).getAbsolutePath() + "/" };
1058 
1059 			LOG.error("CRB000533_Could_not_instantiate_url_class_loader", args,
1060 					e);
1061 			throw new ClassGenerationException(
1062 					"CRB000533_Could_not_instantiate_url_class_loader", args, e);
1063 		} catch (ClassNotFoundException e) {
1064 			Object[] args = new Object[] { PROTOCOL
1065 					+ new File(dir).getAbsolutePath() + "/" };
1066 
1067 			LOG.error("CRB000533_Could_not_instantiate_url_class_loader", args,
1068 					e);
1069 			throw new ClassGenerationException(
1070 					"CRB000533_Could_not_instantiate_url_class_loader", args, e);
1071 		}
1072 	}
1073 
1074 	/**
1075 	 * Load ths class using the class name in the target directory.
1076 	 * 
1077 	 * @param dir
1078 	 *            The dir
1079 	 * @param classAsFile
1080 	 *            The class AsFile
1081 	 * @param addParent
1082 	 *            if true, link the classLoader with the Util ClassLoader.
1083 	 * @return The return
1084 	 * @throws ClassGenerationException
1085 	 *             The class generation exception
1086 	 */
1087 	public static Class classLoad(String dir, String className)
1088 			throws ClassGenerationException {
1089 		return classLoad(dir, className, true);
1090 	}
1091 
1092 	/**
1093 	 * Load ths class using the class name in the target directory.
1094 	 * 
1095 	 * @param dir
1096 	 *            The dir
1097 	 * @param classAsFile
1098 	 *            The class AsFile
1099 	 * @param addParent
1100 	 *            if true, link the classLoader with the Util ClassLoader.
1101 	 * @return The return
1102 	 * @throws ClassGenerationException
1103 	 *             The class generation exception
1104 	 */
1105 	public static Class classLoad(String dir, String className,
1106 			boolean addParent) throws ClassGenerationException {
1107 		URLClassLoader urlClassLoader = null;
1108 		// ChildFirstClassLoader urlClassLoader = null;
1109 
1110 		try {
1111 			File fcd = new File(dir);
1112 
1113 			if (LOG.isDebugEnabled()) {
1114 				LOG
1115 						.debug("ClassesDir.getAbsolutePath="
1116 								+ fcd.getAbsolutePath());
1117 			}
1118 
1119 			URL u = new URL(PROTOCOL + fcd.getAbsolutePath() + "/");
1120 			if (addParent) {
1121 				urlClassLoader = new URLClassLoader(new URL[] { u }, Util.class
1122 						.getClassLoader());
1123 			} else {
1124 				urlClassLoader = new URLClassLoader(new URL[] { u });
1125 			}
1126 
1127 			LOG.debug("url classloader: "
1128 					+ Arrays.asList(urlClassLoader.getURLs()));
1129 
1130 			LOG.debug("class name: " + className);
1131 			return urlClassLoader.loadClass(className);
1132 
1133 		} catch (MalformedURLException e) {
1134 			Object[] args = new Object[] { PROTOCOL
1135 					+ new File(dir).getAbsolutePath() + "/" };
1136 
1137 			LOG.error("CRB000533_Could_not_instantiate_url_class_loader", args,
1138 					e);
1139 			throw new ClassGenerationException(
1140 					"CRB000533_Could_not_instantiate_url_class_loader", args, e);
1141 		} catch (ClassNotFoundException e) {
1142 			Object[] args = new Object[] { PROTOCOL
1143 					+ new File(dir).getAbsolutePath() + "/" };
1144 
1145 			LOG.error("CRB000533_Could_not_instantiate_url_class_loader", args,
1146 					e);
1147 			throw new ClassGenerationException(
1148 					"CRB000533_Could_not_instantiate_url_class_loader", args, e);
1149 		}
1150 	}
1151 
1152 	/**
1153 	 * This method find all the '.class' files in classesDir.
1154 	 * 
1155 	 * @param classesDir
1156 	 *            The directory to inspect.
1157 	 * @param classLoader
1158 	 *            The class loader used to istantiate the classes.
1159 	 * 
1160 	 * @return The list of files found.
1161 	 * 
1162 	 * @throws ClassGenerationException
1163 	 *             The class generation exception
1164 	 */
1165 	public static List<Class> findGeneratedClasses(String classesDir,
1166 			ClassLoader classLoader) throws ClassGenerationException {
1167 
1168 		LOG.debug(">>>>> findGeneratedClasses - begin");
1169 
1170 		LOG.debug("INPUT. classesDir=" + classesDir + "; classLoader"
1171 				+ classLoader);
1172 
1173 		List<Class> classes = new ArrayList<Class>();
1174 		List<File> classFiles = Util.findFilesFromSourceDirectory(classesDir,
1175 				CLASS_FILE_EXTENSION);
1176 		LOG.debug("class files: " + classFiles);
1177 		for (File classFile : classFiles) {
1178 			String className = getClassName(classFile, classesDir, CLASS_FILE_EXTENSION);
1179 			LOG.debug("class name: " + className);
1180 			try {
1181 				Class clazz = classLoader.loadClass(className);
1182 				LOG.debug("clazz=" + clazz + " ... ");
1183 
1184 				classes.add(clazz);
1185 				LOG.debug("... clazz=" + clazz + " added.");
1186 			} catch (ClassNotFoundException e) {
1187 				Object[] args = new Object[] { className };
1188 
1189 				LOG.error("CRB000534_Could_not_instantiate_class", args, e);
1190 				throw new ClassGenerationException(
1191 						"CRB000534_Could_not_instantiate_class", args, e);
1192 			} catch (ClassFormatError e) {
1193 				Object[] args = new Object[] { className };
1194 
1195 				LOG.error("CRB000534_Could_not_instantiate_class", args, e);
1196 				throw new ClassGenerationException(
1197 						"CRB000534_Could_not_instantiate_class", args, e);
1198 			}
1199 		}
1200 
1201 		LOG.debug("<<<<< findGeneratedClasses - end");
1202 		return classes;
1203 	}
1204 	
1205 	/**
1206 	 * Gets the class name from the file absolute path, representing both 
1207 	 * "java" and "class" file names
1208 	 * @param absoluteFilePath
1209 	 *            The file absolute path
1210 	 * @param basedir
1211 	 *            The base dir path
1212 	 * @param extension ".class" or ".java"           
1213 	 * @return The return
1214 	 * @throws ClassGenerationException
1215 	 *             The class generation exception
1216 	 */
1217 	public static String getClassName(String absoluteFilePath, String basedir, String extension)
1218 			throws ClassGenerationException {
1219 		LOG.debug(">>>>> getClassName - begin");
1220 		
1221 		String absoulteBaseDir = new File(basedir).getAbsolutePath();
1222 
1223 		LOG.debug("absoluteFileName: " + absoluteFilePath
1224 				+ "; absoulteBaseDir: " + absoulteBaseDir);
1225 
1226 		if (!absoluteFilePath.startsWith(absoulteBaseDir)) {
1227 			Object[] args = new Object[] { absoluteFilePath,
1228 					absoulteBaseDir };
1229 
1230 			LOG.error("CRB000535_Classfile_is_not_under_dir", args);
1231 			throw new ClassGenerationException(
1232 					"CRB000535_Classfile_is_not_under_dir", args, null);
1233 		}
1234 
1235 		// +1 excludes the trailing slash
1236 		String relativeFileName = absoluteFilePath.substring(absoulteBaseDir
1237 				.length() + 1);
1238 		LOG.debug("relativeFileName.class=" + relativeFileName);
1239 
1240 		// eliminates .class
1241 		if (relativeFileName.endsWith(extension)) {
1242 			relativeFileName = relativeFileName.substring(0, relativeFileName
1243 					.length() - extension.length());
1244 			LOG.debug("relativeFileName=" + relativeFileName);
1245 		}
1246 
1247 		String className = relativeFileName.replace(File.separator, ".");
1248 		LOG.debug("className=" + className);
1249 
1250 		LOG.debug("<<<<< getClassName - end");
1251 		return className;
1252 	}	
1253 
1254 	/**
1255 	 * Gets the class name from the file absolute path, representing both 
1256 	 * "java" and "class" file names
1257 	 * @param file
1258 	 *            The file 
1259 	 * @param basedir
1260 	 *            The base dir path
1261 	 * @param extension ".class" or ".java"           
1262 	 * @return The return
1263 	 * @throws ClassGenerationException
1264 	 *             The class generation exception
1265 	 */
1266 	public static String getClassName(File file, String basedir, String extension)
1267 			throws ClassGenerationException {
1268 			LOG.debug(">>>>> getClassName - begin");
1269 			String absoluteFileName = file.getAbsolutePath();
1270 			return getClassName(absoluteFileName, basedir, extension);
1271 	}
1272 
1273 
1274 	/**
1275 	 * @param classesDirName
1276 	 *            The classes dir name
1277 	 * @param className
1278 	 *            The class name
1279 	 * @return The return
1280 	 * @throws ClassGenerationException
1281 	 *             The class generation exception
1282 	 */
1283 	public static ClassReader getAsmCLassReader(String classesDirName,
1284 			String className) throws ClassGenerationException {
1285 
1286 		LOG.debug(">>>>> getAsmCLassReader - begin");
1287 
1288 		ClassReader cr = getAsmCLassReader(classesDirName + File.separator
1289 				+ className);
1290 
1291 		LOG.debug("<<<<< getAsmCLassReader - end. ClassReader=" + cr);
1292 		return cr;
1293 	}
1294 
1295 	/**
1296 	 * This method returns the class reader used for the bytecode manipulation.
1297 	 * 
1298 	 * @param className
1299 	 *            The absolute path of the class (eg: /var/Foo.class).
1300 	 * 
1301 	 * @return The class reader associated to the input class.
1302 	 * 
1303 	 * @throws ClassGenerationException
1304 	 *             The class generation exception.
1305 	 */
1306 	public static ClassReader getAsmCLassReader(String className)
1307 			throws ClassGenerationException {
1308 
1309 		LOG.debug(">>>>> getAsmCLassReader - begin");
1310 		ClassReader cr = null;
1311 		try {
1312 
1313 			cr = new ClassReader(new FileInputStream(className));
1314 
1315 		} catch (IOException e) {
1316 			Object[] args = new Object[] { className };
1317 
1318 			LOG.error("CRB000536_Could_not_instantiate_class_reader_for_class",
1319 					args, e);
1320 			throw new ClassGenerationException(
1321 					"CRB000536_Could_not_instantiate_class_reader_for_class",
1322 					args, e);
1323 		}
1324 
1325 		LOG.debug("<<<<< getAsmCLassReader - end. ClassReader=" + cr);
1326 		return cr;
1327 	}
1328 
1329 
1330 	/**
1331 	 * @param classesDirName
1332 	 *            The classes dir name
1333 	 * @param relativeFileName
1334 	 *            The relative file name
1335 	 * @param newBytecode
1336 	 *            The new Bytecode
1337 	 * @throws ClassGenerationException
1338 	 *             The class generation exception
1339 	 */
1340 	public static void saveAsJavaClass(String classesDirName,
1341 			String relativeFileName, byte[] newBytecode)
1342 			throws ClassGenerationException {
1343 
1344 		LOG.debug(">>>>> saveAs - begin");
1345 
1346 		saveAsJavaClass(classesDirName + File.separator + relativeFileName,
1347 				newBytecode);
1348 
1349 		LOG.debug("<<<<< saveAs - end");
1350 	}
1351 
1352 	// XXX javadoc
1353 	/**
1354 	 * @param absoluteFileName
1355 	 *            The absolute file name
1356 	 * @param newBytecode
1357 	 *            The new Byte code
1358 	 * @throws ClassGenerationException
1359 	 *             The class generation exception
1360 	 */
1361 	public static void saveAsJavaClass(String absoluteFileName,
1362 			byte[] newBytecode) throws ClassGenerationException {
1363 
1364 		LOG.debug(">>>>> saveAs - begin:" + absoluteFileName);
1365 
1366 		try {
1367 			FileOutputStream fos = new FileOutputStream(absoluteFileName);
1368 
1369 			fos.write(newBytecode);
1370 			fos.close();
1371 		} catch (FileNotFoundException e) {
1372 			Object[] args = new Object[] { absoluteFileName };
1373 
1374 			LOG.error("CRB000537_Could_not_instantiate_file_writer_for_class",
1375 					args, e);
1376 			throw new ClassGenerationException(
1377 					"CRB000537_Could_not_instantiate_file_writer_for_class",
1378 					args, e);
1379 		} catch (IOException e) {
1380 			Object[] args = new Object[] { absoluteFileName };
1381 
1382 			LOG.error("CRB000538_Could_not_save_class", args, e);
1383 			throw new ClassGenerationException(
1384 					"CRB000538_Could_not_save_class", args, e);
1385 		}
1386 
1387 		LOG.debug("<<<<< saveAs - end");
1388 	}
1389 
1390 	/**
1391 	 * This method save a java file.
1392 	 * 
1393 	 * @param code
1394 	 *            The code of the file.
1395 	 * @param dir
1396 	 *            The directory where the file will be save.
1397 	 * @param name
1398 	 *            The name of the file.
1399 	 * 
1400 	 * @return The new File.
1401 	 * 
1402 	 * @throws ClassGenerationException
1403 	 *             The class generation exception.
1404 	 */
1405 	public static File saveAsJavaSource(String code, String dir, String name)
1406 			throws ClassGenerationException {
1407 		LOG.debug(">>>>> saveAsJavaSource - begin");
1408 
1409 		File newFile = new File(dir + File.separator + name + ".java");
1410 		FileWriter fw = null;
1411 		try {
1412 			fw = new FileWriter(newFile);
1413 			fw.write(code.toCharArray());
1414 			fw.close();
1415 		} catch (IOException e) {
1416 			Object[] args = new Object[] { name };
1417 
1418 			LOG.error("CRB000539_Saving_file_problem", args, e);
1419 			throw new ClassGenerationException("CRB000539_Saving_file_problem",
1420 					args, e);
1421 		}
1422 
1423 		LOG.debug("<<<<< saveAsJavaSource - end");
1424 		return newFile;
1425 	}
1426 
1427 	/**
1428 	 * This method saves a file.
1429 	 * 
1430 	 * @param content
1431 	 *            The content of the file stored in a string
1432 	 * @param dir
1433 	 *            The directory where the file will be save.
1434 	 * @param name
1435 	 *            The name of the file.
1436 	 * 
1437 	 * @return The new File.
1438 	 * 
1439 	 * @throws ClassGenerationException
1440 	 *             The class generation exception.
1441 	 */
1442 	public static File saveFile(String code, String dir, String name)
1443 			throws ClassGenerationException {
1444 		LOG.debug(">>>>> saveFile - begin");
1445 
1446 		File newFile = new File(dir + File.separator + name);
1447 		FileWriter fw = null;
1448 		try {
1449 			fw = new FileWriter(newFile);
1450 			fw.write(code.toCharArray());
1451 			fw.close();
1452 		} catch (IOException e) {
1453 			Object[] args = new Object[] { name };
1454 
1455 			LOG.error("CRB000539_Saving_file_problem", args, e);
1456 			throw new ClassGenerationException("CRB000539_Saving_file_problem",
1457 					args, e);
1458 		}
1459 
1460 		LOG.debug("<<<<< saveFile - end");
1461 		return newFile;
1462 	}
1463 	/**
1464 	 * The files with the 'DefaultFactory.java' suffix instantiate a value type
1465 	 * but the implementation of this data types must be provided by the
1466 	 * developers. To automate the process the method creates a new (empty) java
1467 	 * source file that extends the class of the value type.
1468 	 * 
1469 	 * @param workdirsrc
1470 	 *            The directory where the method look for the 'DefaultFactory'
1471 	 *            java files. The generated files will be placed here.
1472 	 * 
1473 	 * @param addToStringEquals
1474 	 *            If true the method toString and equals will be added.
1475 	 * 
1476 	 * @return The list of a full java name of the value types.
1477 	 * 
1478 	 * @throws ClassGenerationException
1479 	 *             The class generation exception
1480 	 */
1481 	public static List<String> valueTypesImpl(String workdirsrc,
1482 			boolean addToStringEquals) throws ClassGenerationException {
1483 
1484 		LOG.debug(">>>>> valueTypesImpl - begin");
1485 
1486 		List<String> vtList = new ArrayList<String>();
1487 
1488 		if (workdirsrc == null) {
1489 			LOG.warn("CRB000540_ValueTypesImpl_cannot_work_workdirsrc_is_null");
1490 			LOG.debug("<<<<< valueTypesImpl - end");
1491 			return vtList;
1492 		}
1493 
1494 		try {
1495 			final int suffixLen = "DefaultFactory.java".length();
1496 			List<String> valueTypes = Util.findAllDefaultFactory(workdirsrc);
1497 
1498 			// XXX this code is not very clean
1499 			for (int i = 0; i < valueTypes.size(); i++) {
1500 				String item = valueTypes.get(i);
1501 				String itemBase = item.substring(0, item.length() - suffixLen);
1502 
1503 				String x = replaceSeparatorWithDot(itemBase);
1504 
1505 				String pkg = extractPackage(workdirsrc, x.substring(0, x
1506 						.lastIndexOf(".")));
1507 
1508 				String clsSuper = x.substring(x.lastIndexOf(".") + 1);
1509 				String cls = clsSuper + "Impl";
1510 
1511 				String pt = workdirsrc + File.separator
1512 						+ replaceDotWithSeparator(pkg);
1513 
1514 				LOG.debug("valueTypesImpl;\n PACKAGE = " + pkg
1515 						+ ";\n CLASS   = " + cls + ";\n PATH    = " + pt);
1516 
1517 				String jsf = generateJavaSourceFile(pkg, cls, clsSuper,
1518 						addToStringEquals);
1519 
1520 				saveAsJavaSource(jsf, pt, cls);
1521 
1522 				// update the value type list
1523 				vtList.add(pkg + "." + clsSuper);
1524 			}
1525 
1526 		} catch (IOException ioe) {
1527 			LOG.error("CRB000541_Error_during_generation_the_implementation_"
1528 					+ "class_of_the_valuetype", ioe);
1529 			throw new ClassGenerationException(
1530 					"CRB000541_Error_during_generati"
1531 							+ "on_the_implementation_class_of_the_valuetype",
1532 					ioe);
1533 		}
1534 
1535 		LOG.debug("<<<<< valueTypesImpl - end. #valueTypes:" + vtList.size());
1536 		return vtList;
1537 	}
1538 
1539 	/**
1540 	 * This method generates a java class with no methods and no attributes.
1541 	 * 
1542 	 * @param pkg
1543 	 *            The 'package' of the class.
1544 	 * @param className
1545 	 *            The name of the class.
1546 	 * @param parent
1547 	 *            The super class.
1548 	 * 
1549 	 * @param addToStringEquals
1550 	 *            If true the code will contain the methods toString and equals.
1551 	 * 
1552 	 * @return The code generated
1553 	 * 
1554 	 * @throws ClassGenerationException
1555 	 */
1556 	private static String generateJavaSourceFile(String pkg, String className,
1557 			String parent, boolean addToStringEquals) {
1558 
1559 		LOG.debug(">>>>> generateJavaSourceFile - begin");
1560 
1561 		String code = null;
1562 		if (addToStringEquals) {
1563 			String importString = "import org.apache.commons.lang.builder.EqualsBuilder;\n"
1564 					+ "import org.apache.commons.lang.builder.ReflectionToStringBuilder;\n";
1565 
1566 			String toStringMethod = "public String toString() {\n"
1567 					+ "return ReflectionToStringBuilder.toString(this);\n"
1568 					+ "}\n";
1569 
1570 			String equalsMethod = "public boolean equals(Object obj) {\n"
1571 					+ "return EqualsBuilder.reflectionEquals(this, obj);\n"
1572 					+ "}\n";
1573 
1574 			code = "//it.imolinfo.jbi4corba - auto generated code\n"
1575 					+ "package " + pkg + ";\n" + importString + "public class "
1576 					+ className + " extends " + parent + " {\n "
1577 					+ toStringMethod + equalsMethod + "}\n";
1578 		} else {
1579 			code = "//it.imolinfo.jbi4corba - auto generated code\n"
1580 					+ "package " + pkg + ";\n" + "public class " + className
1581 					+ " extends " + parent + " {\n " + "}\n";
1582 		}
1583 
1584 		LOG.debug("<<<<< generateJavaSourceFile - end. code:" + code);
1585 		return code;
1586 	}
1587 
1588 	/**
1589 	 * This method replaces the file sperator with a dot.
1590 	 * 
1591 	 * @param s
1592 	 *            The working string.
1593 	 * 
1594 	 * @return The new string.
1595 	 */
1596 	public static String replaceSeparatorWithDot(String s) {
1597 		LOG.debug("replaceSeparatorWithDot. the input is " + s);
1598 		if (s == null) {
1599 			LOG.debug("replaceSeparatorWithDot. "
1600 					+ "the input is null. returning empty String");
1601 			return "";
1602 		}
1603 		// else
1604 		if ("".equals(s)) {
1605 			LOG.debug("replaceSeparatorWithDot. "
1606 					+ "the input is an empty String. returning empty String");
1607 			return "";
1608 		}
1609 		// else
1610 		// PACIUF String re = "\\".equals(File.separator) ? "\\\\" :
1611 		// File.separator;
1612 		// PACIUF String res = s.replaceAll(re, ".").replaceAll("/", ".");
1613 		String res = s.replace('\\', '.').replace('/', '.');
1614 
1615 		LOG.debug("replaceSeparatorWithDot. " + "the input is " + s
1616 				+ " returning " + res);
1617 		return res;
1618 	}
1619 
1620 	/**
1621 	 * This method replaces the dot with a file sperator.
1622 	 * 
1623 	 * @param s
1624 	 *            The working path.
1625 	 * 
1626 	 * @return The new string.
1627 	 */
1628 	public static String replaceDotWithSeparator(String s) {
1629 		LOG.debug("replaceDotWithSeparator. the input is " + s);
1630 		if (s == null) {
1631 			LOG.debug("replaceDotWithSeparator. "
1632 					+ "the input is null. returning empty String");
1633 			return "";
1634 		}
1635 		// else
1636 		if ("".equals(s)) {
1637 			LOG.debug("replaceDotWithSeparator. "
1638 					+ "the input is an empty String. returning empty String");
1639 			return "";
1640 		}
1641 		// else
1642 		String rep = "\\".equals(File.separator) ? "\\\\" : File.separator;
1643 		String res = s.replaceAll("\\.", rep);
1644 		LOG.debug("replaceDotWithSeparator. " + "the input is " + s
1645 				+ " returning " + res);
1646 		return res;
1647 	}
1648 
1649 	/**
1650 	 * This method is used to extract the package of the class in input.
1651 	 * 
1652 	 * @param basedir
1653 	 *            The source directory
1654 	 * @param filename
1655 	 *            The absolute path of the directory that contains a java class.
1656 	 */
1657 	private static String extractPackage(String basedir, String filename) {
1658 		LOG.debug(">>>>> extractPackage - begin");
1659 
1660 		// to normalize the basedir and the filename
1661 		// we replace all the separator with a dot
1662 		String bd = replaceSeparatorWithDot(basedir);
1663 		String fn = replaceSeparatorWithDot(filename);
1664 		LOG.debug("\nbasedir  =" + bd + ";\nfilename =" + fn);
1665 
1666 		/*
1667 		 * Example: If the basedir is '/src' and the filename is '/src/foo' Then
1668 		 * the normalized names are: '.src' and '.src.foo'
1669 		 * 
1670 		 * ...
1671 		 * 
1672 		 * To extract the package name 'foo' we apply the following algorithm: -
1673 		 * find the basedirIndex basedirIndex = 0 - remove the part of the
1674 		 * filename before the basedir (if any) fn = .src.foo.Bar - remove from
1675 		 * the filename the basedir fn = foo
1676 		 */
1677 		LOG.debug("fn.indexOf(bd)=" + fn.indexOf(bd));
1678 		LOG.debug("fn.substring(fn.indexOf(bd))="
1679 				+ fn.substring(fn.indexOf(bd)));
1680 		LOG.debug("bd.length() + 1=" + (bd.length() + 1));
1681 		LOG.debug("fn.substring(fn.indexOf(bd)).substring(bd.length() + 1)="
1682 				+ fn.substring(fn.indexOf(bd)).substring(bd.length() + 1));
1683 		String pack = fn.substring(fn.indexOf(bd)).substring(bd.length() + 1);
1684 		LOG.debug("PACK=" + pack);
1685 
1686 		LOG.debug("<<<<< extractPackage - end");
1687 		return pack;
1688 	}
1689 
1690 	/**
1691 	 * 
1692 	 * @param basedir
1693 	 *            The base dir
1694 	 * @param filename
1695 	 *            The file name
1696 	 * @param extension
1697 	 *            The extension
1698 	 * @return The return
1699 	 */
1700 	// XXX javadoc
1701 	private static String extractJavaQualifiedName(String basedir,
1702 			String filename, String extension) {
1703 
1704 		LOG.debug(">>>>> extractJavaQualifiedName - begin");
1705 
1706 		int extLen = (extension == null) ? 0 : extension.length();
1707 
1708 		String bd = replaceSeparatorWithDot(basedir);
1709 		String fn = replaceSeparatorWithDot(filename);
1710 		LOG.debug("\nbasedir  =" + bd + ";\nfilename =" + fn);
1711 
1712 		// (filename - .java) - basedir
1713 		int bdIndex = fn.indexOf(bd) + bd.length() + 1;
1714 		String full = fn.substring(bdIndex, fn.length() - extLen);
1715 
1716 		LOG.debug("<<<<< extractJavaQualifiedName - end. return=" + full);
1717 		return full;
1718 	}
1719 
1720 	/**
1721 	 * XXX javadoc.
1722 	 * 
1723 	 * @param vtList
1724 	 *            The vt list
1725 	 * @param classesDirName
1726 	 *            The classes dir name
1727 	 * @param cl
1728 	 *            The class loader
1729 	 * @return The return
1730 	 * @throws ClassGenerationException
1731 	 *             The class generation exception
1732 	 * 
1733 	 */
1734 	public static Map<String, Object> valueTypeMapHandler(List<String> vtList,
1735 			String classesDirName, ClassLoader cl)
1736 			throws ClassGenerationException {
1737 
1738 		LOG.debug(">>>>> valueTypeMapHandler - begin");
1739 
1740 		Map<String, Object> map = new HashMap<String, Object>();
1741 
1742 		// for each valuetype ...
1743 		for (String vt : vtList) {
1744 
1745 			// ... get the ID of the valuetype from the helper class ...
1746 			String valueTypeId = getValueTypeIdFromHelperClass(vt + "Helper",
1747 					cl);
1748 
1749 			// ... and the factory instance.
1750 			Object valueTypeDefaultFactoryInstance = getValueTypeDefaultFactoryInstance(
1751 					vt + "DefaultFactory", cl);
1752 
1753 			if (valueTypeId == null) {
1754 				LOG.warn("CRB000523_ID_null_for_valuetype", vt);
1755 			} else {
1756 				map.put(valueTypeId, valueTypeDefaultFactoryInstance);
1757 			}
1758 		}
1759 
1760 		LOG.debug("<<<<< valueTypeMapHandler - end");
1761 		return map;
1762 	}
1763 
1764 	/**
1765 	 * XXX javadoc.
1766 	 * 
1767 	 * @param vtList
1768 	 *            The vt list
1769 	 * @param classesDirName
1770 	 *            The classes dir name
1771 	 * @param cl
1772 	 *            The class loader
1773 	 * @return The return
1774 	 * @throws ClassGenerationException
1775 	 *             The class generation exception
1776 	 * 
1777 	 */
1778 	public static Map<String, Object> valueTypeMapHandlerWithJbi4corbaFactory(
1779 			List<String> vtList, String classesDirName, ClassLoader cl)
1780 			throws ClassGenerationException {
1781 
1782 		LOG.debug(">>>>> valueTypeMapHandler - begin");
1783 
1784 		Map<String, Object> map = new HashMap<String, Object>();
1785 
1786 		// for each valuetype ...
1787 		for (String vt : vtList) {
1788 
1789 			// ... get the ID of the valuetype from the helper class ...
1790 			String valueTypeId = getValueTypeIdFromHelperClass(vt + "Helper",
1791 					cl);
1792 
1793 			// ... and the factory instance.
1794 			Object valueTypeDefaultFactoryInstance = getValueTypeDefaultFactoryInstance(
1795 					vt + "DefaultFactoryJbi4corba", cl);
1796 
1797 			if (valueTypeId == null) {
1798 				LOG.warn("CRB000523_ID_null_for_valuetype", vt);
1799 			} else {
1800 				map.put(valueTypeId, valueTypeDefaultFactoryInstance);
1801 			}
1802 		}
1803 
1804 		LOG.debug("<<<<< valueTypeMapHandler - end");
1805 		return map;
1806 	}
1807 
1808 	/**
1809 	 * 
1810 	 * @param factory
1811 	 *            The factory
1812 	 * @param cl
1813 	 *            The class loader
1814 	 * @return The return
1815 	 * @throws ClassGenerationException
1816 	 *             The class generation exception
1817 	 */
1818 	private static Object getValueTypeDefaultFactoryInstance(String factory,
1819 			ClassLoader cl) throws ClassGenerationException {
1820 
1821 		LOG
1822 				.debug(">>>>> getValueTypeDefaultFactoryInstance - begin:"
1823 						+ factory);
1824 
1825 		Class c = null;
1826 		try {
1827 
1828 			c = cl.loadClass(factory);
1829 
1830 		} catch (ClassNotFoundException e) {
1831 			Object[] args = new Object[] { c };
1832 
1833 			LOG.error("CRB000524_Error_creating_an_instance_of", args, e);
1834 			throw new ClassGenerationException(
1835 					"CRB000524_Error_creating_an_instance_of", args, e);
1836 		}
1837 		LOG.debug("FactoryClass:" + c);
1838 
1839 		Object o = null;
1840 		try {
1841 
1842 			o = c.newInstance();
1843 
1844 		} catch (InstantiationException e) {
1845 			Object[] args = new Object[] { c };
1846 
1847 			LOG.error("CRB000524_Error_creating_an_instance_of", args, e);
1848 			throw new ClassGenerationException(
1849 					"CRB000524_Error_creating_an_instance_of", args, e);
1850 		} catch (IllegalAccessException e) {
1851 			Object[] args = new Object[] { c };
1852 
1853 			LOG.error("CRB000524_Error_creating_an_instance_of", args, e);
1854 			throw new ClassGenerationException(
1855 					"CRB000524_Error_creating_an_instance_of", args, e);
1856 		}
1857 
1858 		LOG.debug("<<<<< getValueTypeDefaultFactoryInstance - end:" + o);
1859 		return o;
1860 	}
1861 
1862 	/**
1863 	 * 
1864 	 * @param helper
1865 	 *            The helper
1866 	 * @param cl
1867 	 *            The class loader
1868 	 * @return The return
1869 	 * @throws ClassGenerationException
1870 	 *             The class generation exception
1871 	 */
1872 	public static String getValueTypeIdFromHelperClass(String helper,
1873 			ClassLoader cl) throws ClassGenerationException {
1874 
1875 		LOG.debug(">>>>> getValueTypeIdFromHelperClass - begin:" + helper);
1876 
1877 		Class c = null;
1878 		try {
1879 			c = cl.loadClass(helper);
1880 		} catch (ClassNotFoundException e) {
1881 			Object[] args = new Object[] { c };
1882 
1883 			LOG.error("CRB000525_Error_getting_the_value_type_id_from_class",
1884 					args, e);
1885 			throw new ClassGenerationException(
1886 					"CRB000525_Error_getting_the_value_type_id_from_class",
1887 					args, e);
1888 		}
1889 		LOG.debug("HelperClass:" + c);
1890 
1891 		Object o = null;
1892 		try {
1893 
1894 			o = c.getMethod("id", (Class[]) null).invoke(null, (Object[]) null);
1895 
1896 		} catch (IllegalArgumentException e) {
1897 			Object[] args = new Object[] { c };
1898 
1899 			LOG.error("CRB000525_Error_getting_the_value_type_id_from_class",
1900 					args, e);
1901 			throw new ClassGenerationException(
1902 					"CRB000525_Error_getting_the_value_type_id_from_class",
1903 					args, e);
1904 		} catch (SecurityException e) {
1905 			Object[] args = new Object[] { c };
1906 
1907 			LOG.error("CRB000525_Error_getting_the_value_type_id_from_class",
1908 					args, e);
1909 			throw new ClassGenerationException(
1910 					"CRB000525_Error_getting_the_value_type_id_from_class",
1911 					args, e);
1912 		} catch (IllegalAccessException e) {
1913 			Object[] args = new Object[] { c };
1914 
1915 			LOG.error("CRB000525_Error_getting_the_value_type_id_from_class",
1916 					args, e);
1917 			throw new ClassGenerationException(
1918 					"CRB000525_Error_getting_the_value_type_id_from_class",
1919 					args, e);
1920 		} catch (InvocationTargetException e) {
1921 			Object[] args = new Object[] { c };
1922 
1923 			LOG.error("CRB000525_Error_getting_the_value_type_id_from_class",
1924 					args, e);
1925 			throw new ClassGenerationException(
1926 					"CRB000525_Error_getting_the_value_type_id_from_class",
1927 					args, e);
1928 		} catch (NoSuchMethodException e) {
1929 			Object[] args = new Object[] { c };
1930 
1931 			LOG.error("CRB000525_Error_getting_the_value_type_id_from_class",
1932 					args, e);
1933 			throw new ClassGenerationException(
1934 					"CRB000525_Error_getting_the_value_type_id_from_class",
1935 					args, e);
1936 		}
1937 
1938 		LOG.debug("<<<<< getValueTypeIdFromHelperClass - end:" + o);
1939 		return (String) o;
1940 	}
1941 
1942 	/**
1943 	 * The list of names of the jars used in the classpath.
1944 	 * 
1945 	 * @param libDirName
1946 	 *            The directory where the jars are located.
1947 	 * 
1948 	 * @return The list of names of the jars used in the classpath.
1949 	 * 
1950 	 * @throws ClassGenerationException
1951 	 *             The class generation exception
1952 	 */
1953 	public static List<String> prepareClassPath(String libDirName)
1954 			throws ClassGenerationException {
1955 
1956 		LOG.debug(">>>>> prepareClassPath - begin for directory: libDirName");
1957 		List<File> jarFiles = Util.findFilesFromSourceDirectory(libDirName,
1958 				".jar");
1959 
1960 		List<String> jarFilesName = new ArrayList<String>();
1961 
1962 		for (File jarFile : jarFiles) {
1963 			try {
1964 				LOG.debug("Adding jar " + jarFile.getCanonicalPath() + " ... ");
1965 
1966 				jarFilesName.add(jarFile.getCanonicalPath());
1967 
1968 				LOG.debug("... jar " + jarFile.getCanonicalPath() + " added.");
1969 			} catch (IOException e) {
1970 				Object[] args = new Object[] { jarFile, e.getMessage() };
1971 
1972 				LOG.error("CRB000507_Error_getting_canonicalPath_from_file",
1973 						args, e);
1974 				throw new ClassGenerationException(
1975 						"CRB000507_Error_getting_canonicalPath_from_file",
1976 						args, e);
1977 			}
1978 		}
1979 
1980 		LOG.debug("<<<<< prepareClassPath - end");
1981 		return jarFilesName;
1982 	}
1983 
1984 	/**
1985 	 * This method generates the new valuetypes factories. For each valuetype we
1986 	 * generate a class that extends the default value factory. The created
1987 	 * classes have the suffix 'Jbi4corba' (e.g.:
1988 	 * MyValueTypeDefaultFactoryJbi4corba.java).
1989 	 * 
1990 	 * @param vtList
1991 	 *            The list of valuetypes.
1992 	 * @param basedir
1993 	 *            The directory where the sources are located.
1994 	 * 
1995 	 * @return The list of new factory (as full java name).
1996 	 * 
1997 	 * @throws ClassGenerationException
1998 	 *             If the one new factory cannot saved.
1999 	 */
2000 	public static List<String> generateValueTypeFactoryJbi4corba(
2001 			List<String> vtList, String basedir)
2002 			throws ClassGenerationException {
2003 		LOG.debug(">>>>> generateValueTypeFactoryJbi4corba - begin");
2004 
2005 		List<String> newFactoryList = new ArrayList<String>();
2006 
2007 		if (vtList == null || vtList.size() == 0) {
2008 			LOG.debug("No factory to create.");
2009 			return newFactoryList;
2010 		}
2011 		// else
2012 		for (String vt : vtList) {
2013 			int lastDot = vt.lastIndexOf(".");
2014 			String factoryPackage = vt.substring(0, lastDot);
2015 			String factoryName = vt.substring(lastDot + 1) + "DefaultFactory";
2016 			String newFactoryName = factoryName + "Jbi4corba";
2017 
2018 			String newFactorySource = "// JBI4CORBA - Code Generation\n"
2019 					+ "package " + factoryPackage + ";\n" + "public class "
2020 					+ newFactoryName + " extends " + factoryName + " {\n\n"
2021 					// no extra code for this class
2022 					+ "}\n";
2023 
2024 			newFactoryList.add(factoryPackage + "." + newFactoryName);
2025 
2026 			String targetDir = basedir + File.separator
2027 					+ factoryPackage.replace('.', File.separatorChar);
2028 			saveAsJavaSource(newFactorySource, targetDir, newFactoryName);
2029 
2030 			if (LOG.isDebugEnabled()) {
2031 				LOG.debug("Generated a new factory:" + factoryPackage + "."
2032 						+ newFactoryName);
2033 			}
2034 		}
2035 
2036 		LOG.debug("<<<<< generateValueTypeFactoryJbi4corba - end."
2037 				+ "Number of new factory generated:" + newFactoryList.size());
2038 
2039 		return newFactoryList;
2040 	}
2041 
2042 	/**
2043 	 * This method modify the bytecode of a class: add Serializable interface
2044 	 * and set the serial version UID.
2045 	 * 
2046 	 * @param absPath
2047 	 *            The absolute path of the class to modify.
2048 	 * @param newSerialVersionUid
2049 	 *            The new serialVersionUID.
2050 	 * 
2051 	 * @throws ClassGenerationException
2052 	 *             The class generation exception
2053 	 */
2054 	public static void tweakSerializableDecoration(String absPath,
2055 			Long newSerialVersionUid) throws ClassGenerationException {
2056 
2057 		ClassWriter cw = new ClassWriter(true); // visitMaxs
2058 		ClassVisitor cc = new CheckClassAdapter(cw);
2059 		StringWriter sw = new StringWriter();
2060 		ClassVisitor tv = new TraceClassVisitor(cc, new PrintWriter(sw));
2061 
2062 		SerializableDecorationAdapter cv = new SerializableDecorationAdapter(
2063 				tv, newSerialVersionUid);
2064 
2065 		ClassReader cr = Util.getAsmCLassReader(absPath);
2066 
2067 		cr.accept(cv, true);
2068 		LOG.debug("ClassReader.accept ... done");
2069 
2070 		LOG.debug("output of tracer during creation of class: " + absPath
2071 				+ "\n" + sw.toString());
2072 
2073 		byte[] newBytecode = cw.toByteArray();
2074 
2075 		Util.saveAsJavaClass(absPath, newBytecode);
2076 	}
2077 
2078 	/**
2079 	 * This method inspect a class to verify if it is Serilizable and to extract
2080 	 * the serial version UID (if exists).
2081 	 * 
2082 	 * @param absPath
2083 	 *            The absolute path of the class to inspect.
2084 	 * 
2085 	 * @return The meta info of the class visited.
2086 	 * 
2087 	 * @throws ClassGenerationException
2088 	 *             The class generation exception
2089 	 */
2090 	public static ClassMetaInfo tweakSerializableInspection(String absPath)
2091 			throws ClassGenerationException {
2092 
2093 		ClassWriter cw = new ClassWriter(true); // visitMaxs
2094 		ClassVisitor cc = new CheckClassAdapter(cw);
2095 		StringWriter sw = new StringWriter();
2096 		ClassVisitor tv = new TraceClassVisitor(cc, new PrintWriter(sw));
2097 
2098 		SerializableInspectorAdapter cv = new SerializableInspectorAdapter(tv);
2099 
2100 		ClassReader cr = Util.getAsmCLassReader(absPath);
2101 
2102 		cr.accept(cv, true);
2103 		LOG.debug("ClassReader.accept ... done");
2104 
2105 		return cv.getClassMetaInfo();
2106 	}
2107 
2108 	/**
2109 	 * This method is used to discover the 'oneway' operations inside a corba
2110 	 * stub.
2111 	 * 
2112 	 * @param bin
2113 	 *            The classes directory.
2114 	 * 
2115 	 * @return The map key is the full java name of the class inspected and the
2116 	 *         value is the list of oneway operations associated to the class.
2117 	 * 
2118 	 * @throws ClassGenerationException
2119 	 *             The class generation exception
2120 	 */
2121 	public static Map<String, List<String>> findOnewayOperations(String bin)
2122 			throws ClassGenerationException {
2123 
2124 		// find all the corba stubs ...
2125 		List<File> binList = findFilesFromSourceDirectory(bin, "Stub.class");
2126 
2127 		Map<String, List<String>> global = new HashMap<String, List<String>>();
2128 
2129 		// ... for each file
2130 		for (File stubFile : binList) {
2131 			String absPath = stubFile.getAbsolutePath();
2132 
2133 			// ... inspect the bytecode
2134 			Map<String, List<String>> map = tweakOnewayInspection(absPath);
2135 
2136 			if (map.size() == 0) {
2137 				LOG.debug("No 'oneway' operations for " + absPath);
2138 			} else {
2139 				global.putAll(map);
2140 			}
2141 		}
2142 
2143 		return global;
2144 	}
2145 
2146 	/**
2147 	 * This method is used to inspect the bytecode of a class to discover the
2148 	 * corba 'oneway' requests.
2149 	 * 
2150 	 * @param absPath
2151 	 *            The absolute path of the corba stub.
2152 	 * 
2153 	 * @return The map key is the full java name of the class inspected and the
2154 	 *         value is the list of oneway operations associated to the class.
2155 	 * 
2156 	 * @throws ClassGenerationException
2157 	 *             The class generation exception
2158 	 */
2159 	public static Map<String, List<String>> tweakOnewayInspection(String absPath)
2160 			throws ClassGenerationException {
2161 
2162 		ClassWriter cw = new ClassWriter(true); // visitMaxs
2163 		ClassVisitor cc = new CheckClassAdapter(cw);
2164 		StringWriter sw = new StringWriter();
2165 		ClassVisitor cv = new TraceClassVisitor(cc, new PrintWriter(sw));
2166 
2167 		CorbaOnewayAdapter ca = new CorbaOnewayAdapter(cv, sw);
2168 
2169 		ClassReader cr = getAsmCLassReader(absPath);
2170 
2171 		cr.accept(ca, true);
2172 		LOG.debug("ClassReader.accept ... done");
2173 
2174 		LOG.debug("Class=" + ca.getAssociatedInterface()
2175 				+ "; Oneway operations:" + ca.getOnewayOperationList().size());
2176 
2177 		Map<String, List<String>> map = new HashMap<String, List<String>>();
2178 
2179 		if (ca.getOnewayOperationList().size() != 0) {
2180 			map.put(ca.getAssociatedInterface(), ca.getOnewayOperationList());
2181 		}
2182 
2183 		return map;
2184 	}
2185 
2186 	/**
2187 	 * This method finds the corba enumerations and replace them with a standard
2188 	 * enum classes. These classes implement the IDLEntity interface and provide
2189 	 * two methods used from the helper classes.
2190 	 * 
2191 	 * @param src
2192 	 *            The source directory.
2193 	 * @param bin
2194 	 *            The classes directory.
2195 	 * 
2196 	 * @return The map that contains all the corba enum. The key of the map is
2197 	 *         the full java name of the corba enum and the value is the list of
2198 	 *         the associated label.
2199 	 * 
2200 	 * @throws ClassGenerationException
2201 	 *             The class generation exception
2202 	 */
2203 	public static Map<String, List<String>> replaceCorbaEnumaration(String src,
2204 			String bin) throws ClassGenerationException {
2205 
2206 		// finding the corba enumeration with the associated labels.
2207 		Map<String, List<String>> corbaEnumMap = findCorbaEnum(bin);
2208 
2209 		// for each corba enum ...
2210 		for (String corbaEnum : corbaEnumMap.keySet()) {
2211 			LOG.debug("corbaEnum=" + corbaEnum);
2212 
2213 			// ... extracting the associated labels
2214 			List<String> labelList = corbaEnumMap.get(corbaEnum);
2215 
2216 			// extract the package and the simple class name
2217 			int lastDot = corbaEnum.lastIndexOf('.');
2218 			String aPack = corbaEnum.substring(0, lastDot);
2219 			String aClas = corbaEnum.substring(lastDot + 1);
2220 
2221 			// ... generating a 'special' enum class
2222 			String newEnumSource = generateSpecialEnumClass(aPack, aClas,
2223 					labelList);
2224 
2225 			// ... saving the new file (code, dir, name)
2226 			String dir = src + File.separator
2227 					+ aPack.replace('.', File.separatorChar);
2228 			saveAsJavaSource(newEnumSource, dir, aClas);
2229 
2230 			// ... removing the old compiled class
2231 			String flatBin = bin.replace('/', File.separatorChar).replace('\\',
2232 					File.separatorChar);
2233 
2234 			String zombie = flatBin + File.separator
2235 					+ corbaEnum.replace('.', File.separatorChar) + CLASS_FILE_EXTENSION;
2236 
2237 			File zombieFile = new File(zombie);
2238 
2239 			if (zombieFile.exists()) {
2240 				LOG.debug("The file " + zombie + " exists.");
2241 			} else {
2242 				LOG.debug("The file " + zombie + " does NOT exists.");
2243 			}
2244 
2245 			boolean deleteResult = zombieFile.delete();
2246 			if (deleteResult) {
2247 				LOG.debug("Removing file " + zombie + " ... ok");
2248 			} else {
2249 				LOG.debug("Removing file " + zombie + " ... failure");
2250 			}
2251 
2252 		}
2253 
2254 		return corbaEnumMap;
2255 	}
2256 
2257 	/**
2258 	 * This method generates the source code of a standard enum class with some
2259 	 * special features. It implements IDLEntity and provides the methods
2260 	 * 'value' and 'from_int'.
2261 	 * 
2262 	 * @param aPackage
2263 	 *            The package of the class.
2264 	 * @param aClassName
2265 	 *            The simple class name.
2266 	 * @param labelList
2267 	 *            The list of label for the enumaration.
2268 	 * 
2269 	 * @return The source code generated.
2270 	 */
2271 	public static String generateSpecialEnumClass(String aPackage,
2272 			String aClassName, List<String> labelList) {
2273 
2274 		StringBuffer labelSource = new StringBuffer("    ");
2275 		if (labelList == null || labelList.size() == 0) {
2276 			String enumClass = aPackage + "." + aClassName;
2277 			Object[] args = new Object[] { enumClass };
2278 			LOG.warn("CRB000549_EmptyEnum", args);
2279 			labelSource.append(";");
2280 		} else {
2281 			for (int i = 0; i < labelList.size(); i++) {
2282 
2283 				if (i == (labelList.size() - 1)) {
2284 					labelSource.append(labelList.get(i) + ";");
2285 				} else {
2286 					labelSource.append(labelList.get(i) + ",");
2287 				}
2288 			}
2289 		}
2290 
2291 		StringBuffer staticMembers = new StringBuffer();
2292 		int idx = 0;
2293 		for (String member : labelList) {
2294 			staticMembers.append("public static final int ");
2295 			staticMembers.append("_" + member + " ");
2296 			staticMembers.append("= ");
2297 			staticMembers.append(idx++);
2298 			staticMembers.append(";");
2299 			staticMembers.append("\n");
2300 		}
2301 		StringBuffer source = new StringBuffer();
2302 		source.append("package " + aPackage + ";");
2303 		source.append("\n\n");
2304 		source.append("public enum " + aClassName);
2305 		source.append(" implements org.omg.CORBA.portable.IDLEntity { ");
2306 		source.append("\n\n");
2307 		source.append(labelSource);
2308 		source.append("\n\n");
2309 		source.append("public int value() {return ordinal();} ");
2310 		source.append("\n\n");
2311 		source.append("public static " + aClassName);
2312 		source.append(" from_int (int value) { return " + aClassName
2313 				+ ".values()[value]; } ");
2314 		source.append("\n\n");
2315 		source.append(staticMembers.toString());
2316 		source.append("}");
2317 
2318 		return source.toString();
2319 	}
2320 
2321 	/**
2322 	 * This method find the corba enum.
2323 	 * 
2324 	 * @param bin
2325 	 *            The classes directory.
2326 	 * 
2327 	 * @return The corba enums. The key of the map is the path of the class and
2328 	 *         the value is the ordered list of the possible enum labels.
2329 	 * 
2330 	 * @throws ClassGenerationException
2331 	 *             The class generation exception
2332 	 */
2333 	protected static Map<String, List<String>> findCorbaEnum(String bin)
2334 			throws ClassGenerationException {
2335 
2336 		Map<String, List<String>> corbaEnumMap = new HashMap<String, List<String>>();
2337 
2338 		// finding all the compiled classes ...
2339 		List<File> binList = findFilesFromSourceDirectory(bin, CLASS_FILE_EXTENSION);
2340 
2341 		// ... inspecting all of them to find a corba enum class
2342 		for (File currentFile : binList) {
2343 
2344 			String absPath = currentFile.getAbsolutePath();
2345 
2346 			ClassWriter cw = new ClassWriter(true); // visitMaxs
2347 			ClassVisitor cc = new CheckClassAdapter(cw);
2348 			StringWriter sw = new StringWriter();
2349 			ClassVisitor cv = new TraceClassVisitor(cc, new PrintWriter(sw));
2350 
2351 			CorbaEnumAdapter ca = new CorbaEnumAdapter(cv);
2352 
2353 			ClassReader cr = getAsmCLassReader(absPath);
2354 
2355 			cr.accept(ca, true);
2356 			LOG.debug("ClassReader.accept ... done");
2357 
2358 			String className = ca.getInternalClassName().replace('/', '.');
2359 
2360 			if (ca.isCorbaEnum()) {
2361 				LOG.debug("The class " + className + " is a corba enum.");
2362 
2363 				corbaEnumMap.put(className, ca.getEnumLabelList());
2364 			} else {
2365 				LOG.debug("The class " + className + " is NOT a corba enum.");
2366 			}
2367 
2368 		}
2369 
2370 		return corbaEnumMap;
2371 	}
2372 
2373 	/**
2374 	 * This method load the class 'remoteClassName' using the ClassLoader in
2375 	 * input and generates an implementation class.
2376 	 * 
2377 	 * The method expects an interface as imput class.
2378 	 * 
2379 	 * @param urlClassLoader
2380 	 *            The ClassLoader used to load the class.
2381 	 * @param remoteClassName
2382 	 *            The full name of the Interface to implement.
2383 	 * @param addRemoteSupport
2384 	 *            Check if adding Remote interface to the implementation class is needed	
2385 	 * 
2386 	 * @return The source code generated.
2387 	 * 
2388 	 * @throws ClassGenerationException
2389 	 *             When the class name is empty or the class does not exist.
2390 	 */
2391 	public static String generateImplementationClass(
2392 			ClassLoader urlClassLoader, String remoteClassName, boolean addRemoteSupport)
2393 			throws ClassGenerationException {
2394 
2395 		String sRemoteInterface=null;
2396 		if (addRemoteSupport)
2397 		{
2398 			sRemoteInterface = ", java.rmi.Remote";
2399 		}
2400 		else
2401 		{
2402 			sRemoteInterface = "";
2403 		}
2404 		LOG.debug("generateRemoteClassImplementation" + "; ClassLoader="
2405 				 + "; remoteClassName=" + remoteClassName);
2406 
2407 		// check
2408 		if (remoteClassName == null || "".equals(remoteClassName)) {
2409 			Object[] arg = new Object[] { "remoteClassName" };
2410 			LOG.error("CRB000551_NotEmptyJavaClassName", arg);
2411 			throw new ClassGenerationException(
2412 					"CRB000551_NotEmptyJavaClassName", arg);
2413 		}
2414 
2415 		// collect the method's signature of the abstract methods.
2416 		Class remoteClass = null;
2417 		try {
2418 			remoteClass = urlClassLoader.loadClass(remoteClassName);
2419 		} catch (ClassNotFoundException e) {
2420 			Object[] arg = new Object[] { "remoteClassName" };
2421 			LOG.error("CRB000552_ClassNotFound", arg, e);
2422 			throw new ClassGenerationException("CRB000552_ClassNotFound", arg,
2423 					e);
2424 		}
2425 
2426 		if (remoteClass == null) {
2427 			Object[] arg = new Object[] { "remoteClassName" };
2428 			LOG.error("CRB000552_ClassNotFound", arg);
2429 			throw new ClassGenerationException("CRB000552_ClassNotFound", arg);
2430 		}
2431 
2432 		// I want to save the class in the same package of the interface.
2433 		String pack = remoteClass.getPackage().getName();
2434 
2435 		// The default name of the implementation class.
2436 		String name = remoteClass.getSimpleName() + "Impl";
2437 
2438 		LOG.debug("The name of the Implementation Class:" + pack + "." + name);
2439 
2440 		List<MethodSignature> msList = new ArrayList<MethodSignature>();
2441 		Method[] arrayOfMethod = remoteClass.getMethods();
2442 
2443 		// FOR EACH method ...
2444 		for (Method method : arrayOfMethod) {
2445 
2446 			// ... that is an abstract method ...
2447 			int mod = method.getModifiers();
2448 
2449 			// check ( ... but is possible ? )
2450 			if (!Modifier.isAbstract(mod)) {
2451 				Object[] arg = new Object[] { method.getName() };
2452 				LOG.warn("CRB000553_UnexpectedNonAbstractMethod", arg);
2453 				continue;
2454 			}
2455 
2456 			// ... I create an object that represent the associated signature
2457 			MethodSignature ms = new MethodSignature();
2458 
2459 			// method name
2460 			ms.setMethodName(method.getName());
2461 
2462 			// parameter types
2463 			List<Param> typeList = new ArrayList<Param>();
2464 			Class[] arrayOfType = method.getParameterTypes();
2465 			for (Class type : arrayOfType) {
2466 				String canonical = type.getCanonicalName();
2467 				Param param = new Param();
2468 				param.setTypeName(canonical);
2469 				typeList.add(param);
2470 				LOG.debug("Parameter=" + canonical);
2471 			}
2472 			ms.setParameters(typeList);
2473 			arrayOfType = null;
2474 
2475 			// return type
2476 			Class returnClass = method.getReturnType();
2477 			ms.setReturnType(returnClass.getCanonicalName());
2478 
2479 			// exception types
2480 			List<String> exceptions = new ArrayList<String>();
2481 			arrayOfType = method.getExceptionTypes();
2482 			for (Class type : arrayOfType) {
2483 				String canonical = type.getCanonicalName();
2484 				exceptions.add(canonical);
2485 
2486 				LOG.debug("Exception=" + canonical);
2487 			}
2488 			ms.setExceptionsType(exceptions);
2489 
2490 			// add to the list
2491 			msList.add(ms);
2492 		}
2493 
2494 		String cihFullname = "it.imolinfo.jbi4corba.webservice.runtime."
2495 				+ "ConsumerInvocationHandler";
2496 
2497 		// When I have collected all the method's signature I use it to generate
2498 		// the source code of the class.
2499 		String implSource = "package " + pack + ";" + "\n\n" + "public class "
2500 				+ name + " implements " + remoteClassName
2501 				+ sRemoteInterface+"{" 
2502 				+ "\n\n" + " protected " + cihFullname
2503 				+ " consumerInvocationHandler;" + "\n\n" + "\n  public " + name
2504 				+ "() {" + "\n    // NOP" + "\n  }" + "\n\n" + "\n  public "
2505 				+ name + "(" + cihFullname + " cih) {"
2506 				+ "\n    consumerInvocationHandler = cih;" + "\n  }" + "\n\n"
2507 				+ methodImplementation(msList,addRemoteSupport) + "\n\n" + "}\n";
2508 
2509 		if (LOG.isDebugEnabled()) {
2510 			LOG.debug("\n--------\n" + implSource + "\n--------\n");
2511 		}
2512 		return implSource;
2513 	}
2514 
2515 	/**
2516 	 * This method is used to generate the source code of the methods in the
2517 	 * list.
2518 	 * 
2519 	 * @param msList
2520 	 *            A list of method's signature.
2521 	 * 
2522 	 * @return The default source code of all the methods.
2523 	 */
2524 	protected static String methodImplementation(List<MethodSignature> msList, boolean addRemoteSupport) {
2525 
2526 		// If I have no methods I return an empty string.
2527 		if (msList == null || msList.isEmpty()) {
2528 			return "";
2529 		}
2530 
2531 		// else
2532 
2533 		String src = "";
2534 
2535 		// FOR EACH method's signature ...
2536 		for (MethodSignature ms : msList) {
2537 
2538 			// ... I generate the list of the parameters using the full
2539 			// qualified name
2540 			// for the data type to avoid the explicit import.
2541 			String paramSource = "";
2542 			for (int i = 0; i < ms.getParameters().size(); i++) {
2543 				if (i == 0) {
2544 					paramSource = ms.getParameters().get(i).getTypeName()
2545 							+ " param" + i;
2546 				} else {
2547 					paramSource += ", "
2548 							+ ms.getParameters().get(i).getTypeName()
2549 							+ " param" + i;
2550 				}
2551 			}
2552 
2553 			// ... I generate the body of the method using the return type.
2554 			// If the return type is a primitive data type I return zero,
2555 			// otherwise I return null.
2556 			// If I have no return type I simply add the return statement.
2557 
2558 			// ... I generate the 'throws' statement of the method.
2559 			String exceptionSource = "";
2560 			for (int i = 0; i < ms.getExceptionsType().size(); i++) {
2561 				if (i == 0) {
2562 					exceptionSource = "throws " + ms.getExceptionsType().get(i);
2563 				} else {
2564 					exceptionSource += ", " + ms.getExceptionsType().get(i);
2565 				}
2566 			}
2567 
2568 			// ... and, at the end, I generate the source code of the method.
2569 			String methodSource = "public " + ms.getReturnType() + " "
2570 					+ ms.getMethodName() + "(" + paramSource + ") "
2571 					+ exceptionSource + " { "
2572 					+ generateTheBodyOfTheMethodForImplTie(ms, addRemoteSupport) + " }";
2573 
2574 			// ... all the methods is appended to the source.
2575 			src += methodSource + "\n\n";
2576 		}
2577 
2578 		return src;
2579 	}
2580 
2581 	/**
2582 	 * This method is used to generate the body of the methods of the the class
2583 	 * that must be implement the skeleton (tie) previously created.
2584 	 * 
2585 	 * The body call the method 'public Object invoke(Object proxy, Method
2586 	 * method, Object[] args) throws Throwable;' of a ConsumerInvocationHandler
2587 	 * object where - proxy is this class - method is the method to be invoked -
2588 	 * args are the parameters of the method invoked.
2589 	 * 
2590 	 * This 'call' may raise a 'Throwable' exception that must be caught. By
2591 	 * design the only 2 kind of exception raised are: -
2592 	 * Jbi4CorbaRuntimeException; - Jbi4CorbaException.
2593 	 * 
2594 	 * In the first case: - the method caught the exception - extracts the
2595 	 * exception's message - throws a RemoteException with the same message.
2596 	 * 
2597 	 * In the second case: - the method caught the exception (in thi case we
2598 	 * have a soap fault) - extracts the fault - throws the fault itself
2599 	 * 
2600 	 * @param methodSignature
2601 	 *            The method's signature.
2602 	 */
2603 	protected static String generateTheBodyOfTheMethodForImplTie(
2604 			MethodSignature methodSignature, boolean addRemoteSupport) {
2605 
2606 		String sThrowsStatement;
2607 		String sThrowsStatementWithMesssage;
2608 		if (addRemoteSupport)
2609 		{
2610 			sThrowsStatement = "\n   throw new java.rmi.RemoteException(e.getMessage());";
2611 			sThrowsStatementWithMesssage = "\n     throw new java.rmi.RemoteException(message);";
2612 		}
2613 		else
2614 		{
2615 			sThrowsStatement = "\n   throw new RuntimeException(e.getMessage());";
2616 			sThrowsStatementWithMesssage="\n   throw new RuntimeException(message);";
2617 		}
2618 		
2619 		String arrayOfParamValue = "new Object [] {";
2620 		String arrayOfParamType = "new Class [] {";
2621 		int paramSize = methodSignature.getParameters().size();
2622 		for (int iParam = 0; iParam < paramSize; iParam++) {
2623 			if (iParam == 0) {
2624 				arrayOfParamValue += ("param" + iParam);
2625 				arrayOfParamType += methodSignature.getParameters().get(iParam)
2626 						.getTypeName()
2627 						+ CLASS_FILE_EXTENSION;
2628 			} else {
2629 				arrayOfParamValue += (", param" + iParam);
2630 				arrayOfParamType += (", "
2631 						+ methodSignature.getParameters().get(iParam)
2632 								.getTypeName() + CLASS_FILE_EXTENSION);
2633 			}
2634 		}
2635 		arrayOfParamValue += "}";
2636 		arrayOfParamType += "}";
2637 		LOG.debug("arrayOfParamValue=[" + arrayOfParamValue + "]");
2638 		LOG.debug("arrayOfParamType=[" + arrayOfParamType + "]");
2639 
2640 		String getMethodAsString = "\n java.lang.reflect.Method method = null;"
2641 				+ "\n try {" + "\n   method = this.getClass().getMethod(\""
2642 				+ methodSignature.getMethodName() + "\", " + arrayOfParamType
2643 				+ ");" + "\n } catch (SecurityException e) {"
2644 				+ sThrowsStatement
2645 				//+ "\n   throw new java.rmi.RemoteException(e.getMessage());"
2646 				+ "\n } catch (NoSuchMethodException e) {"
2647 				//+ "\n   throw new java.rmi.RemoteException(e.getMessage());"
2648 				+ sThrowsStatement
2649 				+ "\n }" + "\n\n";
2650 
2651 		/*
2652 		 * public Object invoke(Object proxy, Method method, Object[] args)
2653 		 * throws Throwable;
2654 		 */
2655 
2656 		String allEx = "";
2657 		for (String exceptionType : methodSignature.getExceptionsType()) {
2658 			String ex = "\nif (t instanceof " + exceptionType + ") {"
2659 					+ "  throw (" + exceptionType + ") t;" + "}";
2660 			if ("".equals(allEx)) {
2661 				allEx += ex;
2662 			} else {
2663 				allEx += "\n else " + ex;
2664 			}
2665 		}
2666 
2667 		// cast the return type
2668 		String returnCast = null;
2669 		if ("double".equals(methodSignature.getReturnType())) {
2670 			returnCast = "return (Double) cih;";
2671 		} else if ("byte".equals(methodSignature.getReturnType())) {
2672 			returnCast = "return (Byte) cih;";
2673 		} else if ("short".equals(methodSignature.getReturnType())) {
2674 			returnCast = "return (Short) cih;";
2675 		} else if ("int".equals(methodSignature.getReturnType())) {
2676 			returnCast = "return (Integer) cih;";
2677 		} else if ("long".equals(methodSignature.getReturnType())) {
2678 			returnCast = "return (Long) cih;";
2679 		} else if ("float".equals(methodSignature.getReturnType())) {
2680 			returnCast = "return (Float) cih;";
2681 		} else if ("boolean".equals(methodSignature.getReturnType())) {
2682 			returnCast = "return (Boolean) cih;";
2683 		} else if ("char".equals(methodSignature.getReturnType())) {
2684 			returnCast = "return (Character) cih;";
2685 		} else if ("char".equals(methodSignature.getReturnType())) {
2686 			returnCast = "return (Character) cih;";
2687 		} else if ("void".equals(methodSignature.getReturnType())) {
2688 			returnCast = "return;"; // FIXME verify
2689 		} else {
2690 			returnCast = "return (" + methodSignature.getReturnType()
2691 					+ ") cih;";
2692 		}
2693 
2694 		String runtime = "it.imolinfo.jbi4corba.exception.Jbi4CorbaRuntimeException";
2695 
2696 		String invokeAsString = "\n Object cih = null;" + "\n try {"
2697 				+ "\n   cih = consumerInvocationHandler.invoke(this, method, "
2698 				+ arrayOfParamValue + ");" + "\n } catch (Throwable tx) {"
2699 				+ "\n   if (tx instanceof " + runtime + ") {"
2700 				+ "\n     String message = tx.getMessage();"
2701 				+ sThrowsStatementWithMesssage
2702 				//+ "\n     throw new java.rmi.RemoteException(message);"
2703 				+ "\n   } else {" + "\n     Throwable t = tx.getCause();"
2704 				+ allEx + "\n   }" + "\n }" + "\n\n" + returnCast;
2705 
2706 		return getMethodAsString + invokeAsString;
2707 	}
2708 
2709 	public static Map<Long, String> extractSerialVersionUid(String classesDir,
2710 			List<String> pathList) throws ClassGenerationException {
2711 
2712 		Map<Long, String> uidMap = new HashMap<Long, String>();
2713 
2714 		if (pathList == null) {
2715 			// TODO
2716 		}
2717 		// else
2718 		for (String path : pathList) {
2719 			File file = new File(path);
2720 			Class clazz = classLoad(classesDir, file);
2721 			Long uid = extractSerialVersionUid(clazz);
2722 
2723 			if (uid == null) {
2724 				// TODO
2725 			} else {
2726 				uidMap.put(uid, path);
2727 			}
2728 		}
2729 
2730 		return uidMap;
2731 	}
2732 
2733 	public static Long extractSerialVersionUid(Class classToSerialize) {
2734 		Long uid = null;
2735 
2736 		if (classToSerialize == null) {
2737 			return uid;
2738 		}
2739 
2740 		try {
2741 			classToSerialize.getDeclaredField("serialVersionUID");
2742 			LOG.debug("Class: " + classToSerialize.getName()
2743 					+ " with serialVersionUID");
2744 			return uid;
2745 		} catch (NoSuchFieldException e) {
2746 			LOG.debug("Class: " + classToSerialize.getName()
2747 					+ " without serialVersionUID");
2748 		}
2749 
2750 		LOG.debug("Looking for class: " + classToSerialize.getName());
2751 
2752 		ObjectStreamClass objectStreamClass = ObjectStreamClass
2753 				.lookup(classToSerialize);
2754 
2755 		if (objectStreamClass == null) {
2756 			LOG.info("CRB000560_objectStreamClass_null",
2757 					new Object[] { classToSerialize.getName() });
2758 
2759 		} else {
2760 
2761 			uid = objectStreamClass.getSerialVersionUID();
2762 			LOG.debug(classToSerialize.getName() + " uid: " + uid);
2763 		}
2764 
2765 		return uid;
2766 	}
2767 
2768 	// ==================================
2769 	// Methods for debuggin
2770 	// ==================================
2771 
2772 	/**
2773 	 * @param message
2774 	 *            The message
2775 	 * @param collection
2776 	 *            The collection
2777 	 */
2778 	public static void debug(String message, Collection collection) {
2779 		if (!LOG.isDebugEnabled()) {
2780 			return;
2781 		}
2782 		// else
2783 		String msg = (message == null) ? "" : message;
2784 
2785 		if (collection == null) {
2786 			LOG.debug(msg + "; Collection is null.");
2787 			return;
2788 		}
2789 		// else
2790 		if (collection.size() == 0) {
2791 			LOG.debug(msg + "; Collection is empty.");
2792 			return;
2793 		}
2794 		// else
2795 		int counter = 0;
2796 		for (Object o : collection) {
2797 			LOG.debug(msg + "; Collection[" + (counter++) + "]=" + o);
2798 		}
2799 	}
2800 
2801 	/**
2802 	 * @param message
2803 	 *            The message
2804 	 * @param map
2805 	 *            A map
2806 	 */
2807 	public static void debug(String message, Map map) {
2808 		if (!LOG.isDebugEnabled()) {
2809 			return;
2810 		}
2811 		// else
2812 		String msg = (message == null) ? "" : message;
2813 
2814 		if (map == null) {
2815 			LOG.debug(msg + "; Map is null.");
2816 			return;
2817 		}
2818 		// else
2819 		if (map.size() == 0) {
2820 			LOG.debug(msg + "; Map is empty.");
2821 			return;
2822 		}
2823 		// else
2824 		for (Object k : map.keySet()) {
2825 			LOG.debug(msg + "; Collection[" + k + "]=" + map.get(k));
2826 		}
2827 	}
2828 
2829 	/**
2830 	 * Creates an unique directory form the seed (seed.tmp) in the rootDir.
2831 	 * 
2832 	 * @param rootDir
2833 	 * @param seed
2834 	 * @return
2835 	 * @throws IOException
2836 	 */
2837 	public static synchronized File createUniqueDirectory(File rootDir,
2838 			String seed) throws IOException {
2839 
2840 		int index = seed.lastIndexOf('.');
2841 
2842 		if (index > 0) {
2843 			seed = seed.substring(0, index);
2844 		}
2845 		File result = null;
2846 		int count = 0;
2847 		while (result == null) {
2848 			String name = seed + "." + count + ".tmp";
2849 			File file = new File(rootDir, name);
2850 			if (!file.exists()) {
2851 				file.mkdirs();
2852 				result = file;
2853 			}
2854 			count++;
2855 		}
2856 		return result;
2857 	}
2858 
2859 	/**
2860 	 * Builds the directory.
2861 	 * 
2862 	 * @param file
2863 	 * @return
2864 	 */
2865 	public static boolean buildDirectory(File file) {
2866 		return file.exists() || file.mkdirs();
2867 	}
2868 
2869 	/**
2870 	 * Copy an input stream to an output.
2871 	 * 
2872 	 * @param in
2873 	 * @param out
2874 	 * @throws IOException
2875 	 */
2876 	public static void copyInputStream(InputStream in, OutputStream out)
2877 			throws IOException {
2878 
2879 		byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
2880 
2881 		int len = in.read(buffer);
2882 		while (len >= 0) {
2883 			out.write(buffer, 0, len);
2884 			len = in.read(buffer);
2885 		}
2886 		in.close();
2887 		out.close();
2888 	}
2889 
2890 	private static List<Class> findHolderUsed(String dir)
2891 			throws ClassGenerationException {
2892 
2893 		LOG.debug("findHolderUsed - Begin");
2894 
2895 		List<Class> result = new ArrayList<Class>();
2896 		List<File> filesHolder = findFilesFromSourceDirectory(dir,
2897 				"Holder.class");
2898 		LOG.debug("filesHolder: " + filesHolder);
2899 		for (int i = 0; i < filesHolder.size(); i++) {
2900 			String nameClassHolder = filesHolder.get(i).getName();
2901 			LOG.debug("classHolder Name: " + nameClassHolder);
2902 			nameClassHolder = nameClassHolder.substring(0, nameClassHolder
2903 					.length() - 12);
2904 
2905 			List<File> listHolder = findFilesFromSourceDirectory(dir,
2906 					nameClassHolder + CLASS_FILE_EXTENSION);
2907 			if (listHolder != null && listHolder.size() > 0) {
2908 				for (File holder : listHolder) {
2909 					Class clazzHolder = classLoad(dir, holder);
2910 					if (!clazzHolder.isInterface()) {
2911 						LOG.debug("Found class used in the Holder: "
2912 								+ clazzHolder.getName());
2913 						result.add(clazzHolder);
2914 					}
2915 				}
2916 			}
2917 		}
2918 		LOG.debug("findHolderUsed - End");
2919 		return result;
2920 	}
2921 
2922 	/**
2923 	 * Try to load the class the class name in the target directory; if no class
2924 	 * is found, NO EXCEPTION IS THROWN.
2925 	 * 
2926 	 * @param dir
2927 	 *            The dir
2928 	 * @param classAsFile
2929 	 *            The class AsFile
2930 	 * @return The return
2931 	 * @throws ClassGenerationException
2932 	 *             The class generation exception
2933 	 */
2934 	public static Class classLoadQuiet(String dir, String className)
2935 			throws ClassGenerationException {
2936 
2937 		URLClassLoader urlClassLoader = null;
2938 
2939 		try {
2940 			File fcd = new File(dir);
2941 
2942 			if (LOG.isDebugEnabled()) {
2943 				LOG
2944 						.debug("ClassesDir.getAbsolutePath="
2945 								+ fcd.getAbsolutePath());
2946 			}
2947 
2948 			URL u = new URL(PROTOCOL + fcd.getAbsolutePath() + "/");
2949 			urlClassLoader = new URLClassLoader(new URL[] { u }, Util.class
2950 					.getClassLoader());
2951 
2952 			LOG.debug("url classloader: "
2953 					+ Arrays.asList(urlClassLoader.getURLs()));
2954 
2955 			return urlClassLoader.loadClass(className);
2956 
2957 		} catch (MalformedURLException e) {
2958 			return null;
2959 
2960 		} catch (ClassNotFoundException e) {
2961 			return null;
2962 		}
2963 	}
2964 
2965 	/**
2966 	   * isThrowableSubClass 
2967 	   * 
2968 	   * @param cls
2969 	   * @return
2970 	   */
2971 	  public static boolean isThrowableSubClass(Class cls)
2972 	  {
2973 		  if (cls == null || cls.getName() == null)
2974 			  return false;
2975 		  
2976 		  if (cls.getName().equals("java.lang.Throwable"))
2977 		  {
2978 			  return true;
2979 		  }
2980 		  else if (cls.getName().equals("java.lang.Object"))
2981 		  {
2982 			  return false;
2983 		  }
2984 		  else return isThrowableSubClass(cls.getSuperclass());
2985 	  }
2986 	
2987 }