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.jbi.JbiServiceDescriptor;
15  import it.imolinfo.jbi4corba.jbi.Messages;
16  import it.imolinfo.jbi4corba.utils.HelperIDLJUtil;
17  import it.imolinfo.jbi4corba.webservice.generator.bcm.ConstructorAdapter;
18  import it.imolinfo.jbi4corba.webservice.generator.bcm.IdlToWsdlAdapter;
19  import it.imolinfo.jbi4corba.webservice.generator.bcm.InterfaceTypeClassAdapter;
20  import it.imolinfo.jbi4corba.webservice.generator.bcm.WebServiceAnnotationAdapter;
21  import it.imolinfo.jbi4corba.webservice.generator.typedef.TypeDef;
22  import it.imolinfo.jbi4corba.webservice.generator.typedef.TypeDefUtil;
23  
24  import java.io.BufferedWriter;
25  import java.io.File;
26  import java.io.FileWriter;
27  import java.io.IOException;
28  import java.io.PrintWriter;
29  import java.io.StringWriter;
30  import java.net.MalformedURLException;
31  import java.net.URISyntaxException;
32  import java.net.URL;
33  import java.net.URLClassLoader;
34  import java.util.ArrayList;
35  import java.util.Arrays;
36  import java.util.Collection;
37  import java.util.HashMap;
38  import java.util.HashSet;
39  import java.util.Hashtable;
40  import java.util.Iterator;
41  import java.util.List;
42  import java.util.Map;
43  import java.util.Set;
44  import java.util.Map.Entry;
45  
46  import org.apache.cxf.helpers.ServiceUtils;
47  import org.objectweb.asm.ClassReader;
48  import org.objectweb.asm.ClassVisitor;
49  import org.objectweb.asm.ClassWriter;
50  import org.objectweb.asm.util.CheckClassAdapter;
51  import org.objectweb.asm.util.TraceClassVisitor;
52  
53  
54  
55  /**
56   * This class provides the 'IDL to WSDL' code generation.
57   */
58  @SuppressWarnings("unchecked")
59  public class ProviderServiceClassesGenerator {
60  
61    /**
62     * Logger.
63     */
64    private static final Logger LOG
65      = LoggerFactory.getLogger(ProviderServiceClassesGenerator.class);
66    
67    private static final Messages MESSAGES = 
68    	Messages.getMessages(ProviderServiceClassesGenerator.class);
69  
70    /**
71     * The properties used to control the behavior during the code generation.
72     */
73    protected static CodeGenerationProperties codeGenerationProperties
74      = new CodeGenerationProperties();
75  
76    //URL CLassLoader
77    private URLClassLoader urlClassLoader;
78    //URL Original
79    private ChildFirstClassLoader originalClassLoader;
80    
81    /**
82     *The Hashtable used for contain the generated classes  
83     * Ther is a ClientCorbaClassesHolder 
84     * String is the IDL File
85     * HashTable is the HashTable that indexing classes by JbiDesc 
86     */
87    
88    private static Hashtable<String, Hashtable<JbiServiceDescriptor,ClientCorbaClassesHolder>> 
89            idlClassTable =new Hashtable<String, Hashtable<JbiServiceDescriptor,ClientCorbaClassesHolder>>();
90    
91     /**
92      * A handle to the unique Singleton instance.
93      */
94     static private ProviderServiceClassesGenerator instance = null; 
95    
96    
97    /**
98     * Empty Constructor.
99     */
100   public ProviderServiceClassesGenerator() {   
101   }
102 
103   /**
104    * Empty Constructor.
105    *
106    * @param prop
107    *    This object contains all the configuration to perform the activities.
108    *
109    */
110   public ProviderServiceClassesGenerator(CodeGenerationProperties prop) {
111     codeGenerationProperties = prop;
112   }
113 
114  
115   /**
116    * This class is used to generate a service from a IDL file.
117    *
118    * Algorithm:
119    * <br/>
120    * - idl to java
121    * <br/>
122    * - provide value type implementation inspecting 'DefaultFactory' files.
123    * <br/>
124    * - compile java files.
125    * <br/>
126    * - bytecode manipulation:
127    *   all the classes used in the 'xxxOperations.class' is visited.
128    *   Where there is a non private attribute a getter/setter pair method
129    *   will be added and all the array will be initialized to avoid
130    *   NullPointerException.
131    * <br/>
132    * - return a list of holder classes.
133    *
134    * @param serviceDescriptor        Used to estract 'idlFileNameDirectory'
135    *                                 and 'idlFileName'.
136    *
137    * @param workdir    The java source files and compiled files are placed
138    *                     in 'workdir/src' and 'workdir/classes'
139    *
140    * @param libDirName The directory where the method looks for the jars.
141    *
142    * @return    The list of 'holder' classes containing the reference to
143    *          corba object, helper and operations classes.
144    *
145    * @throws ClassGenerationException  The Class Generation Exception
146    */
147   public List<ClientCorbaClassesHolder> generateProviderServiceClasses(
148           JbiServiceDescriptor serviceDescriptor,
149           String workdir,
150           String libDirName, String portTypeName) throws ClassGenerationException {
151           
152           List<JbiServiceDescriptor> serviceDescriptorList=new ArrayList<JbiServiceDescriptor>();
153           List<String> portTypeNameList= new ArrayList<String>();
154           
155           serviceDescriptorList.add(serviceDescriptor);
156           portTypeNameList.add(portTypeName);
157           
158          return generateProviderServiceClasses(serviceDescriptorList, workdir, libDirName, portTypeNameList);
159            
160   }
161   
162   
163    public List<ClientCorbaClassesHolder> generateProviderServiceClasses(
164          JbiServiceDescriptor serviceDescriptor,
165           String workdir,
166           List<String> jars, String portTypeName) throws ClassGenerationException {
167    
168    
169           ArrayList<JbiServiceDescriptor> serviceDescriptorList=new ArrayList<JbiServiceDescriptor>();
170           ArrayList<String> portTypeNameList= new ArrayList<String>();
171           
172           serviceDescriptorList.add(serviceDescriptor);
173           portTypeNameList.add(portTypeName);
174           
175           return generateProviderServiceClasses(serviceDescriptorList, workdir, jars, portTypeNameList);
176    
177    }
178   
179   
180   /**
181    * This class is used to generate a service from a IDL file.
182    *
183    * Algorithm:
184    * <br/>
185    * - idl to java
186    * <br/>
187    * - provide value type implementation inspecting 'DefaultFactory' files.
188    * <br/>
189    * - compile java files.
190    * <br/>
191    * - bytecode manipulation:
192    *   all the classes used in the 'xxxOperations.class' is visited.
193    *   Where there is a non private attribute a getter/setter pair method
194    *   will be added and all the array will be initialized to avoid
195    *   NullPointerException.
196    * <br/>
197    * - return a list of holder classes.
198    *
199    * @param serviceDescriptor        Used to estract 'idlFileNameDirectory'
200    *                                 and 'idlFileName'.
201    *
202    * @param workdir    The java source files and compiled files are placed
203    *                     in 'workdir/src' and 'workdir/classes'
204    *
205    * @param libDirName The directory where the method looks for the jars.
206    *
207    * @return    The list of 'holder' classes containing the reference to
208    *          corba object, helper and operations classes.
209    *
210    * @throws ClassGenerationException  The Class Generation Exception
211    */
212   public List<ClientCorbaClassesHolder> generateProviderServiceClasses(
213           List<JbiServiceDescriptor> serviceDescriptorList,
214           String workdir,
215           String libDirName, List<String> portTypeName) throws ClassGenerationException   {
216       
217     
218      portTypeName=new ArrayList<String>();
219      for(int i=0;i<serviceDescriptorList.size();i++){
220         portTypeName.add(serviceDescriptorList.get(i).getPortTypeName().getLocalPart());
221      }
222       
223     LOG.debug(">>>>> generateProviderServiceClasses - begin");
224 
225     // ===================================
226     //       find jar list used to compile
227     // ===================================
228     List<String> jars = null;
229     LOG.debug("codeGenerationProperties.isValueTypeImplementationWithToStringAndEquals():" + codeGenerationProperties.isValueTypeImplementationWithToStringAndEquals());
230     
231     if (codeGenerationProperties.isValueTypeImplementationWithToStringAndEquals()) {
232       jars = Util.prepareClassPath(libDirName);
233     }
234     
235     // MARCO 22/09/2008: if  the jars is null, the jaxb jar location must be found!
236     // With no jaxb jar in the classpath, the sources cannot be compiled.
237     // With the jaxb jar file path, all the jar in the same directory are added.
238     if (jars == null) {
239                 
240         Class xmlAccessTypeClass=javax.xml.bind.annotation.XmlSeeAlso.class;
241         if ((xmlAccessTypeClass != null) 
242                 && (xmlAccessTypeClass.getProtectionDomain() != null)
243                 && (xmlAccessTypeClass.getProtectionDomain().getCodeSource() != null)) { 
244             URL jaxbJarLocation = xmlAccessTypeClass.getProtectionDomain().getCodeSource().getLocation();
245             LOG.info("JAXB Location: " + jaxbJarLocation);
246             try {
247             LOG.info("JAXB Location to URI: " + jaxbJarLocation.toURI());
248             } catch(URISyntaxException e) {}
249             
250             LOG.info("JAXB Location getPath: " + jaxbJarLocation.getPath());
251             if ((jaxbJarLocation != null) && (jaxbJarLocation.getFile() != null)) {
252                 File jaxbLocationFile;
253                 // That's weird...but it seems the only way to safely
254                 // convert an URL to a File in a portable way 
255                 // (i mean a way that works only in Windows SO with path with spaces).
256                 // See CRB-171 Jira issue.
257                 try {
258                 	jaxbLocationFile = new File(jaxbJarLocation.toURI());
259                 } catch(URISyntaxException e) {
260                 	jaxbLocationFile = new File(jaxbJarLocation.getPath());
261                 } catch(IllegalArgumentException e) {     
262                     // Can be thrown a java.lang.IllegalArgumentException by the File constructor.
263                     jaxbLocationFile = new File(jaxbJarLocation.getPath());
264                 }
265 
266                 //String jaxbLocationDirectory = jaxbLocationFile.getParent();
267                 //LOG.debug("jaxbLocationDirectory:" + jaxbLocationDirectory);
268                 jars = new ArrayList<String>();
269                 try {
270 					jars.add(jaxbLocationFile.getCanonicalPath());
271 				} catch (IOException e) {
272 					Object[] args = new Object[] { jaxbLocationFile, e.getMessage() };
273 					LOG.error("CRB000507_Error_getting_canonicalPath_from_file",
274 							args, e);
275 					throw new ClassGenerationException(
276 							"CRB000507_Error_getting_canonicalPath_from_file",
277 							args, e);
278 				}                
279             }
280         }
281     }
282  
283     List<ClientCorbaClassesHolder> list = generateProviderServiceClasses(
284             serviceDescriptorList,
285             workdir,
286             jars, 
287             portTypeName);
288 
289     LOG.debug(">>>>> generateProviderServiceClasses - end");
290     return list;
291   }
292   
293   
294   /**
295      * This class is used to generate a service from a IDL file.
296      * 
297      * Algorithm: <br/> - idl to java <br/> - provide value type implementation
298      * inspecting 'DefaultFactory' files. <br/> - compile java files. <br/> -
299      * bytecode manipulation: all the classes used in the 'xxxOperations.class'
300      * is visited. Where there is a non private attribute a getter/setter pair
301      * method will be added and all the array will be initialized to avoid
302      * NullPointerException. <br/> - return a list of holder classes.
303      * 
304      * @param serviceDescriptor Used to estract 'idlFileNameDirectory' and
305      *                'idlFileName'.
306      * @param workdir The java source files and compiled files are placed in
307      *                'workdir/src' and 'workdir/classes'
308      * @param jars The list of jars used to generate the classes.
309      * @param portTypeName the porttype name (for the wsdl annotations). Can be null (in this case, the class name is used).
310      * 
311      * @return The list of 'holder' classes containing the reference to corba
312      *         object, helper and operations classes.
313      * 
314      * @throws ClassGenerationException The class generation exception
315      * 
316      * The portTypeName is necessary for the generation of the classes
317      */
318   public List<ClientCorbaClassesHolder> generateProviderServiceClasses(
319           List<JbiServiceDescriptor> serviceDescriptorList,
320           String workdir,
321           List<String> jars, List<String> portTypeName) throws ClassGenerationException {
322           
323     LOG.debug(">>>>> generateProviderServiceClasses - begin");
324     
325     boolean isRoleConsumer = (
326     		serviceDescriptorList.size() > 0 && 
327     		serviceDescriptorList.get(0).getRole() != null && 
328     		serviceDescriptorList.get(0).getRole().equalsIgnoreCase(JbiServiceDescriptor.CONSUMER));
329 
330    
331     String workdirsrc = workdir + "/src";
332     String workdirclasses = workdir + "/classes";
333     String workdirOrigclasses = workdir + "/origclasses"; 
334     String serviceNameSpace = null;
335     
336     //The IdlFilenameDrectory and the IdlFileName is the Same for Each Interface
337    
338     String idlFilename = serviceDescriptorList.get(0).getIdlFileNameDirectory()
339                        + File.separator
340                        + serviceDescriptorList.get(0).getIdlFileName();
341                        
342     
343     // =================================
344     //                IDL to Java (idlj)
345     // =================================
346     
347     if (isRoleConsumer) {
348     	HelperIDLJUtil.idljPoaTie(workdirsrc,
349     	        serviceDescriptorList.get(0).getIdlFileNameDirectory(),
350     	        idlFilename);
351     }
352     else
353     {
354         HelperIDLJUtil.idlj(workdirsrc,
355                 serviceDescriptorList.get(0).getIdlFileNameDirectory(),
356                 idlFilename);
357     }
358 
359 
360     // =================================
361     //       Collecting Method Signature
362     // =================================
363     Map<String, List<MethodSignature>> mapOperationsMethod
364       = Util.extractMethodSignatureOfTheCorbaOperations(workdirsrc);
365     
366     // =================================
367     //      VALUETYPE IDL IMPLEMENTATION
368     // =================================
369     List<String> vtList = Util.valueTypesImpl(workdirsrc,
370       codeGenerationProperties.isValueTypeImplementationWithToStringAndEquals());
371     LOG.debug("end creating java sources implementation for value types.");   
372     
373     // =================================
374     //                       COMPILE 1/2
375     // =================================
376     List<String> javaSources = null;
377     try {
378       javaSources = Util.findJavaSources(workdir);
379       LOG.debug("find java sources ... done");
380     } catch (Jbi4CorbaException e) {
381       Object[] args = new Object[] { workdir };
382 
383       LOG.error("CRB000522_Error_finding_java_classes", args, e);
384       throw new ClassGenerationException(
385               "CRB000522_Error_finding_java_classes", args, e);
386     }
387 
388     Util.compileJavaClasses(workdirsrc,
389                             workdirclasses,
390                             javaSources,
391                             jars,
392                             null);
393 
394     LOG.debug("compileJavaClasses 1 of 2 ... done");
395 
396     // =================================
397     //                        CORBA ENUM
398     // =================================
399     Map<String, List<String>> corbaEnumMap
400       = Util.replaceCorbaEnumaration(workdirsrc, workdirclasses);
401 
402     // =================================
403     //                       COMPILE 2/2
404     // =================================
405     javaSources = null;
406     try {
407       javaSources = Util.findJavaSources(workdir);
408       LOG.debug("find java sources ... done");
409     } catch (Jbi4CorbaException e) {
410       Object[] args = new Object[] { workdir };
411 
412       LOG.error("CRB000522_Error_finding_java_classes", args, e);
413       throw new ClassGenerationException(
414               "CRB000522_Error_finding_java_classes", args, e);
415     }
416     
417     // =================================
418     // FOR EACH PACKAGE, ADDS THE PACKAGE-INFO.JAVA
419     // =================================        
420     List<String> packages = new ArrayList<String>();    
421     List<String> filesCreated = new ArrayList<String>();
422     LOG.debug("javaSources: "+javaSources);
423     for (String source : javaSources) {
424         // System Operation Linux
425         String tempworkdirsrc = workdirsrc;
426         if (System.getProperty("os.name").indexOf("Win") >= 0) {
427             // System Operation Windows
428             LOG.debug("System Operation [ Windows ]");
429             //tempworkdirsrc = tempworkdirsrc.replace("/", File.separator);
430             try {
431                 File myTempDir = new File(workdirsrc);
432                 tempworkdirsrc = myTempDir.getCanonicalPath();
433                 
434             } catch (IOException ioe) {
435                 String msg = "Error in getting temp dir:" + ioe.getMessage();
436                 throw new ClassGenerationException(msg, ioe);
437             }
438         }
439         // LOG.debug(">>>> tempworkdirsrc : "+tempworkdirsrc);
440         int posPath = source.indexOf(tempworkdirsrc);
441         
442         String classSourceName = source.substring(posPath + tempworkdirsrc.length() + 1 , source.length());  
443         
444         String className = classSourceName.replace(File.separator, ".");
445         String classNameMinusJava = className;
446         if ((className.endsWith(".java"))) {
447             classNameMinusJava = className.substring(0,className.length() - 5);            
448         }
449         String namespace = ServiceUtils.makeNamespaceFromClassName(classNameMinusJava, "http");        
450         int lastSlashIndex = classSourceName.lastIndexOf(File.separator);
451         String packageNameWithSlash = lastSlashIndex!= -1?classSourceName.substring(0,lastSlashIndex):classSourceName;
452         if (packageNameWithSlash.startsWith(File.separator)){
453             packageNameWithSlash=packageNameWithSlash.substring(1);
454         }
455         LOG.debug("packageNameWithSlash: "+packageNameWithSlash);
456         String packageName =  packageNameWithSlash.replace(File.separator, ".");         
457         if(classSourceName.equals(className)){
458         	packageName="";
459         }
460          
461         if (!packages.contains(packageName) && !packageName.equals("")) {
462             String returnPath = createsPackageInfo(namespace, packageName, workdirsrc);
463             filesCreated.add(returnPath);
464             packages.add(packageName);
465         }
466     }
467     javaSources.addAll(filesCreated);
468     //Compile the class
469     //We have to store a Copy of class in another folder for reuse it on runtime invokation
470     //For Invoke Servant with correct parameter
471     Util.compileJavaClasses(workdirsrc,
472                             workdirclasses,
473                             javaSources,
474                             jars,
475                             null);
476     //Compile and produce the Original Class for the correct invocation of corba 
477     //Servant
478      Util.compileJavaClasses(workdirsrc,
479                             workdirOrigclasses,
480                             javaSources,
481                             jars,
482                             null);
483      LOG.debug("compileJavaClasses 2 of 2 ... done");     
484      
485      // =================================
486      // TYPEDEF identifications and classes creation. Collect all the
487      // typedefs (identified by the Helper without interface class)
488      // and then creates the class
489      // =================================     
490      // Creates the type def classes and gets the TypeDef data
491      Map<String,TypeDef> typeDefs = null;
492      try {
493       	// Geth the typeDefs informations
494      	typeDefs = TypeDefUtil.getTypeDefs(workdirclasses);
495      	
496      	if (LOG.isDebugEnabled()) {     
497      		LOG.debug("TypeDefs found: " + typeDefs.size());
498      		Iterator itTypeDefs = typeDefs.keySet().iterator();
499      		while (itTypeDefs.hasNext()) {
500      			LOG.debug("Found TypeDef:" + typeDefs.get(itTypeDefs.next()));
501      		}
502      	}
503      } catch (Jbi4CorbaException e) {
504          Object[] args = new Object[] { workdir };
505          LOG.error("CRB000522_Error_creating_typedef_classes", args, e);
506          throw new ClassGenerationException(
507                  "CRB000522_Error_creating_typedef_classes", args, e);
508      }        
509      
510      // =================================
511      //           TYPEDEF CLASSES CREATION
512      // =================================
513   	Iterator itTypeDefs = typeDefs.keySet().iterator();
514   	while (itTypeDefs.hasNext()) {
515   		String typeDefKey = (String) itTypeDefs.next();
516   		if (LOG.isDebugEnabled()) {
517   			LOG.debug("Creating class for TypeDef:" + typeDefKey);
518   		} 		
519   		typeDefs.get(typeDefKey).createTypeDefClass(workdirclasses);  		
520   		typeDefs.get(typeDefKey).createTypeDefClass(workdirOrigclasses);
521   	}     
522 
523     // =================================
524     //                 ONEWAY OPERATIONS
525     // =================================
526     Map<String, List<String>> onewayMap
527       = Util.findOnewayOperations(workdirclasses);
528 
529     updateOnewayMethodSignature(onewayMap, mapOperationsMethod);
530 
531     // =================================
532     //                       ANNOTATIONS
533     // =================================    
534     Set<String> exceptions = new HashSet<String>();
535     
536     
537     //Each class holder is generated by an EndpointName an an NameSpace
538     //The NameSpaces can be Different
539     //This is The part when the List of interface's from a WSDL  a  is translated to single WSDL
540     //*********************************************************************************************************
541     // Union types
542     Map<String, UnionType> allUnionTypes = new HashMap<String,UnionType>();
543     
544     // Interface Types 
545     Map<String, InterfaceType> allInterfaceTypes = new HashMap<String,InterfaceType>();
546        
547     // Here ALL the types, used for ANY 
548     Set<Class> allTypes = Util.findAllTypesUsedInIDL(workdirclasses);
549                 
550     //Obtain all the id used in the idl Helper an the associated class
551     Map<String,String> idToClassMap =Util.getTypesMap(workdirclasses);
552 
553     // Find all UnionTypes
554     UnionTypeUtils unionUt = new UnionTypeUtils();
555     unionUt.processTypes(allTypes, workdirclasses, allUnionTypes,TypeUtils.UNION);
556     addUnionWrappers(allUnionTypes, workdirclasses);
557     
558     //Find all InterfaceType
559     InterfaceTypeUtils iu = new InterfaceTypeUtils();
560     iu.processTypes(allTypes, workdirclasses, allInterfaceTypes,TypeUtils.INTERFACE);
561 
562     //Add the Object type as interface type
563     //Added to manage the Object type...
564     allInterfaceTypes.put(org.omg.CORBA.Object.class.getName(), new InterfaceType(org.omg.CORBA.Object.class.getName()));
565  
566     for (String corbaOperation : mapOperationsMethod.keySet()) {
567     	
568         JbiServiceDescriptor serviceDescriptor =null;
569         String portypeName=null;
570     	
571         
572         // Map the correct Interface with the correct namespace's
573         // The deploy regard's only a subset of interfaces , for the interface not binded 
574         // tha namespace is generated by the idl as default namespace
575         
576         //Multiple interfaces
577         if(serviceDescriptorList.size()>1){
578         	//Take the portType name from the name of the interface
579         	int start=corbaOperation.lastIndexOf(".")+1;
580             int end=corbaOperation.lastIndexOf("Operations");
581 
582             String namespace="http://"+corbaOperation.substring(0, end);
583             portypeName=corbaOperation.substring(start, end);
584 
585             for (JbiServiceDescriptor jbiserviceDescriptor : serviceDescriptorList){
586         		
587                 //Added NamespaceCheck
588                 if(jbiserviceDescriptor.getPortTypeName().getNamespaceURI().equals("")){
589                    //Added to support old WSDL created after the namespace naming convenction
590                    if(!jbiserviceDescriptor.getServiceNameSpace().startsWith("http")||jbiserviceDescriptor.getServiceNameSpace().startsWith("http://default")){
591 
592                         if( jbiserviceDescriptor.getPortTypeName().getLocalPart().equals(portypeName)){
593                             serviceDescriptor=jbiserviceDescriptor;
594                             break;
595                         }
596 
597                   }else{
598 
599                        if( jbiserviceDescriptor.getServiceNameSpace().equals(namespace)&& jbiserviceDescriptor.getPortTypeName().getLocalPart().equals(portypeName)){
600 
601                             serviceDescriptor=jbiserviceDescriptor;
602                             break;
603                         }
604 
605                   }
606 
607                 }else{
608                     if(jbiserviceDescriptor.getPortTypeName().getNamespaceURI().equals(namespace) && jbiserviceDescriptor.getPortTypeName().getLocalPart().equals(portypeName)){
609                         serviceDescriptor=jbiserviceDescriptor;
610                         break;
611                     }
612                 }
613 
614           }
615         
616         }else{
617         //Single interface
618              serviceDescriptor=serviceDescriptorList.get(0);
619              portypeName=portTypeName.get(0);
620              
621         }
622         //This is possible when the the assembly contains only a subset of the entire interfaces declared in the IDL
623         //Default namespace associations for the service descriptor ????
624         if (serviceDescriptor==null){
625         	serviceDescriptor=serviceDescriptorList.get(0);
626             portypeName=portTypeName.get(0);
627         	
628         }
629                
630         serviceNameSpace = serviceDescriptor.getServiceNameSpace();  
631         
632         
633        LOG.debug("JbiServiceDescriptor=" + serviceDescriptor
634             + "; workdir="            + workdir
635             + "; workdirsrc="         + workdirsrc
636             + "; workdirclasses="     + workdirclasses
637             + "; workdirorigclasses=" + workdirOrigclasses
638             + "; idlFilename="        + idlFilename
639             + "; serviceNameSpace="   + serviceNameSpace);
640       
641       //Add the Orignal Class Loader for the correct Service Invokation
642    
643       setOrginalClassLoader(workdirOrigclasses); 
644       LOG.debug("Added OriginalClassLoader "+getOriginalClassLoader()); 
645       // CALCULATE THE HOLDER VALUE TYPE FOR THE OPERATION. The classes dir is necessary to 
646       // get the correct holder value class with introspection.
647       List <MethodSignature> corbaOperationSignatures =  mapOperationsMethod.get(corbaOperation);
648       
649       //**********************************************************************
650       // INOUT
651       HolderUtils.populateCorbaHolderValueType(workdirclasses, corbaOperationSignatures, allUnionTypes.keySet(), allInterfaceTypes.keySet());
652       //**********************************************************************
653  
654       
655       //***************************************************************************
656       //UnionTypes
657       tweakUnionTypes(workdirclasses, allUnionTypes.values()); // replace modifier private with public for verifyXXX
658       //*************************************************************************
659       
660        //********************************************************************** 
661       
662       //replace interface return type and parameter type with W3CEndpointReference
663       if(allInterfaceTypes.size()>0) {
664     	  tweakInterfacesTypes(workdirclasses,corbaOperation, allInterfaceTypes);
665       }
666       //*************************************************************************
667    
668       LOG.debug("Adding to portype: " + portypeName +" the namespace:" + serviceNameSpace);
669       
670       // Adds the Classes annotation
671       
672       Set<String> exceptionFromOperation = tweakCorbaOperation(corbaOperation,
673                           workdirclasses,
674                           mapOperationsMethod.get(corbaOperation), serviceNameSpace,portypeName, allUnionTypes,allInterfaceTypes, allTypes);
675       exceptions.addAll(exceptionFromOperation);
676       
677     }          
678     //*********************************************************************************************************
679     
680     // =================================
681     //            BYTE CODE MANIPULATION
682     // =================================
683     Set<Class> cs = Util.findClassUsedInTheOperations(workdirclasses);
684     //Util.debug("findClassUsedInTheOperations - result", cs);
685     Map<String,Map<String, String>> allFieldsUniontypeMapping  = new HashMap<String, Map<String, String>>();
686     //This map contain all- associations fieldname:Type for return correct type during RunTime
687     Map<String,Map<String, String>> allFiledsInterfacetypeMapping  = new HashMap<String, Map<String, String>>();    
688     
689     if (cs == null || cs.size() == 0) {
690         LOG.debug("No class to tweak.");
691     } else {
692         Iterator<Class> i = cs.iterator();
693         while (i.hasNext()) {
694           String fullname = i.next().getName();
695           
696           boolean skip = false;
697           // Skips the IdlToWsdl bytecode manipulation if:
698           // - It's a enum
699           // IT's a typeDef (already generated)
700           if ((corbaEnumMap.containsKey(fullname)) || (typeDefs.containsKey(fullname))) {
701         	  skip = true;
702           }
703                     
704           if (skip) {
705             LOG.debug("(SKIPPED) tweaking for " + fullname);
706           } else {
707             LOG.debug("tweaking for " + fullname);
708 
709             String f = replaceDotWithSlash(fullname) + ".class";
710             
711             boolean isException = false;                       
712             
713             // Test if this clas is one of the exceptions
714             if ((f.endsWith(".class"))) {
715                 String classNameMinusClass = f.substring(0,f.length() - 6);                
716                 if (exceptions.contains(classNameMinusClass)) {
717                     isException = true;
718                 }                                
719             }
720             Map<String,String> fieldsUniontypeMapping  = new HashMap<String, String>();  
721             Map<String,String> fieldsInterfacetypeMapping  = new HashMap<String, String>();  
722             if(allInterfaceTypes.get(fullname)==null){
723                 //Bytecode Manipulation 
724             	tweakIdlToWsdlClasses(f, workdirclasses, allUnionTypes, fieldsUniontypeMapping,allInterfaceTypes,fieldsInterfacetypeMapping, isException,false);
725                 tweakIdlToWsdlClasses(f, workdirOrigclasses, allUnionTypes, fieldsUniontypeMapping, allInterfaceTypes, fieldsInterfacetypeMapping, isException, true);
726             	//change Parameters Type in the constructor Class 
727             	if(allInterfaceTypes.size()>0){
728             		tweakConstructor(f,workdirclasses,allInterfaceTypes, isException);
729                 }
730             }
731             allFieldsUniontypeMapping.put(f, fieldsUniontypeMapping);
732             allFiledsInterfacetypeMapping.put(f,fieldsInterfacetypeMapping);
733           }
734         }
735 
736     }
737           
738     // replace union parameters/return type in the method signatures
739     List<File> operationsClass
740     = Util.findFilesFromSourceDirectory(workdirclasses, "Operations.class");
741     for (int i = 0; i < operationsClass.size(); i++) {
742         Class clazz = Util.classLoad(workdirclasses, operationsClass.get(i));
743         
744         tweakOperationsWithUnionTypes(workdirclasses, clazz, allUnionTypes);
745         tweakOperationsWithAnyTypes(workdirclasses, clazz);
746     }
747     
748     // =================================
749     //                      FIND SERVICE
750     // =================================
751     List<ClientCorbaClassesHolder> generatedServices
752         = findGeneratedServices(workdirclasses);
753 
754     LOG.debug("generatedServices=" + generatedServices);
755 
756 	//The Value types id must be collected in the Orginal classloader
757     Map<String, Object> map = Util.valueTypeMapHandler(
758 		 vtList, workdirclasses, getOriginalClassLoader());	
759   
760     // update the list with the map and with the method signature info
761     for (ClientCorbaClassesHolder holder : generatedServices) {
762       holder.setValueTypeIdAndInstance(map);
763       //The Holder 
764       
765       List <MethodSignature> corbaOperationSignatures = mapOperationsMethod.get(holder.getOperationsClass().getName());
766       holder.setMethodSignatures(corbaOperationSignatures);
767       
768       //add union types for operation
769       holder.addUnionTypes(allUnionTypes);
770       //store correspondance between substituted uniontypes with Object and uniontypes
771       holder.setSubstitutedUnionFields(allFieldsUniontypeMapping);
772       
773        //add Interface types for operation
774       holder.addInterfaceTypes(allInterfaceTypes);
775       //store correspondance between substituted uniontypes with Object and uniontypes
776       holder.setSubstitutedInterfaceFields(allFiledsInterfacetypeMapping);
777       
778       holder.setAllIDLTypes(allTypes);
779       
780       holder.setIdToClassMap(idToClassMap);
781       
782       holder.setCorbaEnumMap(corbaEnumMap);
783       
784       holder.setTypeDefs(typeDefs);
785       
786       
787       // For each method, loads this actual <code>Method</code> object that can be changed (if holder are included)
788       for (MethodSignature methodSignature: corbaOperationSignatures) {
789           //**********************************************************************
790           // INOUT
791           HolderUtils.populateChangedMethod(methodSignature, workdirclasses, allUnionTypes.keySet(), allInterfaceTypes.keySet());
792           
793           //**********************************************************************                    
794           
795       }
796     }
797 
798     LOG.debug("<<<<<<<<<< generateProviderServiceClasses - end");
799     return generatedServices;
800   }
801   
802   
803   
804   /**
805    * addUnionWrappers 
806    * Create wrapper classes for union types
807    * 
808    * @param operationUnionTypes
809    * @param workdirclasses
810    * @throws ClassGenerationException
811    */
812   private void addUnionWrappers(Map<String, UnionType> operationUnionTypes,
813 		String workdirclasses) throws ClassGenerationException {
814 
815 	
816 	for (Entry<String, UnionType> entry : operationUnionTypes.entrySet())
817 	{
818 		UnionType union = entry.getValue();
819 		
820 		UnionTypeUtils.createUnionClassWrapper(union, operationUnionTypes, workdirclasses);
821 	}
822 	
823 }
824 
825 /**
826    * tweakConstructor
827    * 
828    * This method uses ASM to change the the return type in class with method that return an interface: 
829    * and take as parameters an Interface 
830    * 
831    * @author Luca Acquaviva
832    */
833    private String tweakConstructor(
834             String className,
835             String classesDirName, 
836             Map<String, InterfaceType> allInterfaceTypes, boolean isException) throws ClassGenerationException {
837 
838            	
839 
840         ClassWriter  cw = new ClassWriter(true); // visitMaxs
841         ClassVisitor cc = new CheckClassAdapter(cw);
842         StringWriter sw = new StringWriter();
843         ClassVisitor tv = new TraceClassVisitor(cc, new PrintWriter(sw));
844 
845         
846         ConstructorAdapter cv = new ConstructorAdapter(tv, cw, className,allInterfaceTypes, isException);
847 
848         ClassReader cr = Util.getAsmCLassReader(classesDirName, className);
849 
850         
851         cr.accept(cv, true);
852 
853         byte [] newBytecode = cw.toByteArray();
854 
855         // write class in the right place
856 
857         String relativeFileName = className.replace('/', File.separatorChar);
858 
859         Util.saveAsJavaClass(classesDirName, relativeFileName, newBytecode);
860         
861         return className.replace('/', '.');
862     }
863    /**
864    * tweakInterfacesTypes
865    * 
866    * This method uses ASM to change the the return type in class with method that return an interface: 
867    * and take as parameters an Interface 
868    * @param workdirclasses directory that contain the source class	
869    * @param Operation the class to tweak
870    * @param The map that contains all the type identified as Interface
871    * 
872    * @author Luca Acquaviva
873    */
874   private void tweakInterfacesTypes(String workdirclasses,String Operation, Map<String, InterfaceType> opIntTypes) throws ClassGenerationException {
875 
876 	        
877 	        ClassWriter  cw = new ClassWriter(true); // visitMaxs
878 		    ClassVisitor cc = new CheckClassAdapter(cw);
879 		  
880 		    InterfaceTypeClassAdapter clsa = new InterfaceTypeClassAdapter(cc, opIntTypes);
881 		    
882 		    String absPath = workdirclasses + File.separator
883 		      + Operation.replace('.', File.separatorChar) + ".class";
884 
885 		    ClassReader cr = Util.getAsmCLassReader(absPath);
886 
887 		    cr.accept(clsa, true);  
888 
889 		    byte [] newBytecode = cw.toByteArray();
890 		    
891 		    Util.saveAsJavaClass(absPath, newBytecode);
892 		
893 }
894     
895   /**
896      * This class is used to generate a service from a IDL file.
897      * 
898      * Algorithm: <br/> - idl to java <br/> - provide value type implementation
899      * inspecting 'DefaultFactory' files. <br/> - compile java files. <br/> -
900      * bytecode manipulation: all the classes used in the 'xxxOperations.class'
901      * is visited. Where there is a non private attribute a getter/setter pair
902      * method will be added and all the array will be initialized to avoid
903      * NullPointerException. <br/> - return a list of holder classes.
904      * 
905      * @param serviceDescriptor Used to estract 'idlFileNameDirectory' and
906      *                'idlFileName'.
907      * @param workdir The java source files and compiled files are placed in
908      *                'workdir/src' and 'workdir/classes'
909      * @param jars The list of jars used to generate the classes.
910      * @param portTypeName the porttype name (for the wsdl annotations). Can be null (in this case, the class name is used).
911      * 
912      * @return The list of 'holder' classes containing the reference to corba
913      *         object, helper and operations classes.
914      * 
915      * @throws ClassGenerationException The class generation exception
916      */
917     
918  
919 
920 /**
921    * tweakUnionTypes
922    * 
923    * This method uses ASM to change the union types classes: replace modifier 'private' to 'public'
924    * of method verifyXXX where XXX represents the fields of the union types 
925    * 
926    */
927   private void tweakUnionTypes(String workdirclasses, Collection<UnionType> operationUnionTypes) throws ClassGenerationException {
928 
929 	  for ( UnionType union : operationUnionTypes)
930 		{
931 			
932 			ClassWriter  cw = new ClassWriter(true); // visitMaxs
933 		    ClassVisitor cc = new CheckClassAdapter(cw);
934 		    
935 		    UnionTypeClassAdapter clsa = new UnionTypeClassAdapter(cc, union.getTypeFieldNameList());
936 		    
937 		    String absPath = workdirclasses + File.separator
938 		      + union.getTypeName().replace('.', File.separatorChar) + ".class";
939 
940 		    ClassReader cr = Util.getAsmCLassReader(absPath);
941 
942 		    cr.accept(clsa, true);  
943 
944 		    byte [] newBytecode = cw.toByteArray();
945 
946 		    Util.saveAsJavaClass(absPath, newBytecode);
947 		}
948 }
949   
950   /**
951    * tweakOperationsWithUnionTypes
952    * 
953    * This method uses ASM to create uniontype wrappers for operations parameters/return type 
954    * 
955    */
956   private void tweakOperationsWithUnionTypes(String workdirclasses, Class operationClass, Map<String, UnionType> allUnionTypes) throws ClassGenerationException {
957 
958 			ClassWriter  cw = new ClassWriter(true); // visitMaxs
959 		    ClassVisitor cc = new CheckClassAdapter(cw);
960 		    
961 		    OperationWithUnionTypesAdapter clsa = new OperationWithUnionTypesAdapter(cc, allUnionTypes, workdirclasses);
962 		    
963 		    String absPath = workdirclasses + File.separator
964 		      + operationClass.getName().replace('.', File.separatorChar) + ".class";
965 
966 		    ClassReader cr = Util.getAsmCLassReader(absPath);
967 
968 		    cr.accept(clsa, true);  
969 
970 		    byte [] newBytecode = cw.toByteArray();
971 
972 		    Util.saveAsJavaClass(absPath, newBytecode);
973 	
974 }
975 
976   /**
977    * tweakOperationsWithAnyTypes
978    * 
979    * @param clazz
980  * @throws ClassGenerationException 
981    */  
982 private void tweakOperationsWithAnyTypes(String workdirclasses, Class operationClass) throws ClassGenerationException {
983 
984 	    ClassWriter  cw = new ClassWriter(true); // visitMaxs
985 	    ClassVisitor cc = new CheckClassAdapter(cw);
986 	    
987 	    OperationWithAnyTypesAdapter clsa = new OperationWithAnyTypesAdapter(cc);
988 	    
989 	    String absPath = workdirclasses + File.separator
990 	      + operationClass.getName().replace('.', File.separatorChar) + ".class";
991 
992 	    ClassReader cr = Util.getAsmCLassReader(absPath);
993 
994 	    cr.accept(clsa, true);  
995 
996 	    byte [] newBytecode = cw.toByteArray();
997 
998 	    Util.saveAsJavaClass(absPath, newBytecode);
999 		
1000 	}
1001   
1002 /**
1003    * Creates the pacakge-info.java file for the correct jaxb mapping.
1004    * @param namespace
1005    * @param packagePath
1006    * @param dirClasses
1007    */
1008   public String createsPackageInfo(String namespace, String packagePath, String dirClasses) throws ClassGenerationException {
1009            
1010       String returnPath = null;
1011       String packageInfoJavaFileName=null;
1012       if(!packagePath.equals("")){
1013     	  packageInfoJavaFileName = dirClasses + File.separator + packagePath.replace(".", File.separator) + File.separator + "package-info.java";      
1014       }else{
1015     	  packageInfoJavaFileName = dirClasses  + File.separator + "package-info.java";
1016       }
1017       LOG.debug("Creating the package-info.java file into the directory: " + packageInfoJavaFileName);      
1018       File packageInfoJavaFile = new File(packageInfoJavaFileName);
1019       StringBuffer str = new StringBuffer();
1020       str.append("@javax.xml.bind.annotation.XmlSchema(namespace=\"")
1021       .append(namespace)
1022       .append("\"")
1023       .append(",attributeFormDefault=javax.xml.bind.annotation.XmlNsForm.QUALIFIED")
1024       .append("," +
1025       		"elementFormDefault=javax.xml.bind.annotation.XmlNsForm.QUALIFIED)")      		
1026       .append("\n")
1027       .append("package ")
1028       .append(packagePath)
1029       .append(";");
1030       try {
1031     	  
1032         packageInfoJavaFile.createNewFile();
1033         FileWriter fout = new FileWriter(packageInfoJavaFile);
1034         fout.write(str.toString());
1035         fout.flush();
1036         fout.close();
1037         returnPath = packageInfoJavaFile.getCanonicalPath();
1038     } catch (IOException e) {
1039     	String msg=MESSAGES.getString("CRB000561_Error_creating_package_info_file", 
1040     			new Object[] {e.getMessage()});
1041         LOG.error(msg,e);
1042         throw new ClassGenerationException(msg,e);
1043 
1044     }
1045     return returnPath;      
1046   }
1047  
1048 
1049   /**
1050    * This method is used to update the 'oneway' property
1051    * of the method signature.
1052    *
1053    * @param onewayMap
1054    *            A map where the key is a full java class name
1055    *            and the value is a list of oneway methods.
1056    *
1057    * @param mapOperationsMethod
1058    *            A map where the key is a full java class name
1059    *            and the value is a list method signatures. 
1060    */
1061   protected void updateOnewayMethodSignature(
1062     Map<String, List<String>> onewayMap,
1063     Map<String, List<MethodSignature>> mapOperationsMethod) {
1064 
1065     Set<String> onewayClasses = onewayMap.keySet();
1066 
1067     // for each class that contains one or more oneway methods ...
1068     for (String onewayClass : onewayClasses) {
1069       // ... extracting the list of method's signature associated
1070       List<MethodSignature> methodSignatureList
1071          = mapOperationsMethod.get(onewayClass);
1072       LOG.debug("onewayClass=" + onewayClass
1073         + " => methodSignatureList=" + methodSignatureList);
1074 
1075       // ... extracting the list of the oneway methods
1076       List<String> onewayMethodList = onewayMap.get(onewayClass);
1077 
1078       // for each oneway method find the associated method signature to update
1079       // the oneway property.
1080       for (String onewayMethod : onewayMethodList) {
1081         boolean ok = setOnewayPropertyOnTheMethodSignature(onewayMethod,
1082                                                            methodSignatureList);
1083         if (! ok) {
1084           Object [] args = new Object[] {onewayMethod};
1085           LOG.warn("CRB000547_OnewayMethodNotFound", args);
1086         }
1087       }
1088 
1089     }
1090   }
1091 
1092   /**
1093    * This method searches the right signature
1094    * and set to true the 'oneway' property.
1095    *
1096    * @param   onewayMethod
1097    *              The name of the oneway method.
1098    * @param   methodSignatureList
1099    *              The list of the method's signature to inspect
1100    *
1101    * @return  false when the oneway method is not found in the list.
1102    */
1103   protected boolean setOnewayPropertyOnTheMethodSignature(
1104     String onewayMethod, List<MethodSignature> methodSignatureList) {
1105 
1106     if (onewayMethod == null || methodSignatureList == null) {
1107       LOG.warn("CRB000548_NullParameter");
1108       return false;
1109     }
1110 
1111     boolean found = false;
1112 
1113     for (MethodSignature methodSignature : methodSignatureList) {
1114 
1115       /* The IDL doesn't support the overloading of a method.
1116        */
1117       if (methodSignature.getMethodName().equals(onewayMethod)) {
1118         found = true;
1119         methodSignature.setOneway(true);
1120       }
1121     }
1122 
1123     LOG.debug("oneway method found:" + found);
1124     return found;
1125   }
1126   
1127   
1128   /**
1129      * Adds the jsr-181 annotations for the parameter and the class.
1130      * 
1131      * @param qualifiedJavaName The qualified java name
1132      * @param dir The dir
1133      * @param methodSignatureList The method signature list
1134      * 
1135      * @return the Set of thrown exceptions
1136      * 
1137      * @throws ClassGenerationException The class generation exception
1138      */
1139   private Set<String> tweakCorbaOperation(String qualifiedJavaName, String dir,
1140     List<MethodSignature> methodSignatureList, String nameSpace, String portTypeName, Map<String, UnionType> unionTypes, Map<String, InterfaceType> interfaceTypes, Set<Class> allTypes) throws ClassGenerationException {
1141 
1142     ClassWriter  cw = new ClassWriter(true); // visitMaxs
1143     ClassVisitor cc = new CheckClassAdapter(cw);
1144     StringWriter sw = new StringWriter();
1145     ClassVisitor tv = new TraceClassVisitor(cc, new PrintWriter(sw));
1146 
1147     // ADds oals
1148     WebServiceAnnotationAdapter cv
1149       = new WebServiceAnnotationAdapter(tv, cw, methodSignatureList, nameSpace, portTypeName, dir, unionTypes,interfaceTypes, allTypes);  
1150 
1151     String absPath = dir + File.separator
1152       + qualifiedJavaName.replace('.', File.separatorChar) + ".class";
1153 
1154     ClassReader cr = Util.getAsmCLassReader(absPath);
1155 
1156     cr.accept(cv, true);
1157     LOG.debug("ClassReader.accept ... done");
1158 
1159     LOG.debug("output of tracer during creation of class: " + absPath + "\n"
1160       + sw.toString());
1161 
1162     byte [] newBytecode = cw.toByteArray();
1163 
1164     Util.saveAsJavaClass(absPath, newBytecode);
1165     
1166     return cv.getExceptionsThrown(); 
1167   }
1168 
1169     /**
1170      * Bytecode manipulation. Adding the getter and setter methods for all the
1171      * public members. Initialize all the array. Add the methods toString() and
1172      * equals(Object).
1173      * 
1174      * @param className The class to manipulate.
1175      * @param classesDirName The directory where the class is located.
1176      * @param isException if the class is an exception
1177      * @param excludeType if The Type Any,Interface,Union BytecodeManipulatios has to be disabled  
1178      * 
1179      * @return The full class name.
1180      * 
1181      * @throws ClassGenerationException The class generation exception
1182      */
1183     private String tweakIdlToWsdlClasses(
1184             String className,
1185             String classesDirName, Map<String, UnionType> allUnionTypes, Map<String,String> fieldsUniontype,Map<String, InterfaceType> allInterfaceTypes, Map<String,String> fieldsInterfacetype, boolean isException,boolean excludeType) throws ClassGenerationException {
1186 
1187            	LOG.debug("CRB000562_tweakIdlToWsdlClasses_begin");
1188 
1189     		LOG.debug("CRB000563_tweakIdlToWsdlClasses_class_in_dir", 
1190         		new Object[]{className, classesDirName});
1191 
1192         ClassWriter  cw = new ClassWriter(true); // visitMaxs
1193         ClassVisitor cc = new CheckClassAdapter(cw);
1194         StringWriter sw = new StringWriter();
1195         ClassVisitor tv = new TraceClassVisitor(cc, new PrintWriter(sw));
1196 
1197         
1198         IdlToWsdlAdapter cv = new IdlToWsdlAdapter(tv, cw, className, allUnionTypes, fieldsUniontype,allInterfaceTypes,fieldsInterfacetype, isException,excludeType);
1199 
1200         ClassReader cr = Util.getAsmCLassReader(classesDirName, className);
1201 
1202         LOG.debug("getAsmCLassReader ... done");
1203 
1204         cr.accept(cv, true);
1205         LOG.debug("ClassReader.accept ... done");
1206 
1207         LOG.debug("output of tracer during creation of class: "
1208                 + className + "\n" + sw.toString());
1209 
1210         byte [] newBytecode = cw.toByteArray();
1211 
1212         // write class in the right place
1213 
1214         String relativeFileName = className.replace('/', File.separatorChar);
1215 
1216         Util.saveAsJavaClass(classesDirName, relativeFileName, newBytecode);
1217 
1218         
1219         
1220         LOG.debug("<<<<<<<<<< tweakIdlToWsdlClasses - end");
1221         return className.replace('/', '.');
1222     }
1223 
1224     // =================================
1225     //                         Utilities
1226     // =================================
1227 
1228     /**
1229     * This method replaces the dot with a '/'.
1230     *
1231     * @param s  The working path.
1232     *
1233     * @return   The new string.
1234     */
1235     private String replaceDotWithSlash(String s) {
1236         LOG.debug("replaceDotWithSlash. the input is " + s);
1237         if (s == null) {
1238             LOG.debug("replaceDotWithSlash. "
1239                     + "the input is null. returning empty String");
1240             return "";
1241         }
1242         // else
1243         if ("".equals(s)) {
1244             LOG.debug("replaceDotWithSlash. "
1245                     + "the input is an empty String. returning empty String");
1246             return "";
1247         }
1248         // else
1249         String res = s.replaceAll("\\.", "/");
1250         LOG.debug("replaceDotWithSlash. "
1251                 + "the input is " + s + " returning " + res);
1252         return res;
1253     }
1254 
1255     /**
1256     * This method find the classes with all the following properties:
1257     * - is an interface;
1258     * - is a org.omg.CORBA.Object;
1259     * - exists an associated Helper class;
1260     * - exists an associated Operations class.
1261 
1262     * @param classesDir    The directory to inspect.
1263     *
1264     * @return    The result.
1265     *
1266     * @throws ClassGenerationException  The class generation exception
1267     */
1268     private List<ClientCorbaClassesHolder> findGeneratedServices(
1269             String classesDir) throws ClassGenerationException {
1270 
1271         LOG.debug(">>>>>>>>>> findGeneratedServices - begin");
1272        
1273         urlClassLoader = null;
1274         String protocol = null;
1275         try {
1276 
1277             if (System.getProperty("os.name").indexOf("Win") >=0) {
1278                 protocol = "file:///";
1279             } else {
1280                 protocol = "file://";
1281             }
1282 
1283             File fcd = new File(classesDir);
1284             LOG.debug("ClassesDir.getAbsolutePath=" + fcd.getAbsolutePath());
1285 
1286             urlClassLoader = new URLClassLoader(
1287                 new URL[] { new URL(protocol + fcd.getAbsolutePath()  + "/") },
1288                 this.getClass().getClassLoader());
1289             
1290           
1291 
1292             LOG.debug("url classloader: "
1293                     + Arrays.asList(urlClassLoader.getURLs()));
1294         } catch (MalformedURLException e) {
1295             Object[] args = new Object[] {
1296                     protocol + new File(classesDir).getAbsolutePath() + "/" };
1297 
1298             LOG.error("CRB000526_Could_not_instantiate_the_url_class_loader",
1299                       args, e);
1300             throw new ClassGenerationException(
1301                     "CRB000526_Could_not_instantiate_the_url_class_loader",
1302                     args, e);
1303         }
1304 
1305         LOG.debug("classes dir: " + classesDir);
1306 
1307         List<Class> generatedClasses
1308             = Util.findGeneratedClasses(classesDir, urlClassLoader);
1309 
1310         LOG.debug("generated classes: " + generatedClasses);
1311         for (int i = 0; i < generatedClasses.size(); i++) {
1312           LOG.debug("CRB000564_Generated_class", 
1313         			new Object[] {generatedClasses.get(i)});
1314         }
1315 
1316         LOG.debug("<<<<<<<<<< findGeneratedServices - end");
1317         return filterInterfaceClasses(generatedClasses, urlClassLoader);
1318         // return filterInterfaceClasses(generatedClasses, originalClassLoader);
1319     }
1320     
1321     private void setOrginalClassLoader(String origclassesDir) throws ClassGenerationException{
1322     	 originalClassLoader=null;
1323     	 String protocol = null;
1324     	 try {
1325 
1326              if (System.getProperty("os.name").indexOf("Win") >=0) {
1327                  protocol = "file:///";
1328              } else {
1329                  protocol = "file://";
1330              }
1331 
1332              File fcd = new File(origclassesDir);
1333              LOG.debug("ClassesDir.getAbsolutePath=" + fcd.getAbsolutePath());
1334              
1335              originalClassLoader=new ChildFirstClassLoader(new URL[] { new URL(protocol + fcd.getAbsolutePath()  + "/") },
1336 					   this.getClass().getClassLoader());
1337              
1338                           
1339              LOG.debug("url classloader: "
1340                      + Arrays.asList(originalClassLoader.getURLs()));
1341          } catch (MalformedURLException e) {
1342              Object[] args = new Object[] {
1343                      protocol + new File(origclassesDir).getAbsolutePath() + "/" };
1344 
1345              LOG.error("CRB000526_Could_not_instantiate_the_class_loader",
1346                        args, e);
1347              throw new ClassGenerationException(
1348                      "CRB000526_Could_not_instantiate_the_class_loader",
1349                      args, e);
1350          }
1351     	 // Util.findGeneratedClasses(origclassesDir, originalClassLoader);
1352     	
1353     }
1354 
1355     /**
1356     * This method filters the list in input leaving only the classes with all
1357     * the following properties:
1358     * - is an interface;
1359     * - is a org.omg.CORBA.Object;
1360     * - exists an associated Helper class;
1361     * - exists an associated Operations class.
1362     *
1363     * @param    classes            The list to filter.
1364     * @param    classLoader        Used to instantiate the associated classes.
1365     *
1366     * @return    The list of the filtered classes.
1367     */
1368     private List<ClientCorbaClassesHolder> filterInterfaceClasses(
1369             List<Class> classes,
1370             ClassLoader classLoader) {
1371 
1372         LOG.debug(">>>>>>>>>> filterInterfaceClasses - begin");
1373 
1374         List<ClientCorbaClassesHolder> result
1375                 = new ArrayList<ClientCorbaClassesHolder>();
1376 
1377         for (Class clazz : classes) {
1378 
1379             // clazz is included if and only if is an interface and extends
1380             // org.omg.CORBA.Object
1381             if (clazz.isInterface()
1382                     && org.omg.CORBA.Object.class.isAssignableFrom(clazz)
1383                     && (! clazz.getName().startsWith("org.omg"))) {
1384 
1385                 /* IF (EXISTS clazzHelper) AND (EXISTS clazzOperations)
1386                 * THEN
1387                 *   list.add( {clazz, clazzHelper, clazzOperations} )
1388                 * ELSE
1389                 *   <<no operations to do>>
1390                 */
1391                 try {
1392                     LOG.debug("trying if [" + clazz.getName()
1393                             + "Helper] exists");
1394                     Class helperClass
1395                             = classLoader.loadClass(clazz.getName() + "Helper");
1396 
1397                     LOG.debug("trying if [" + clazz.getName()
1398                             + "Operations] exists");
1399                     Class operationsClass = classLoader.loadClass(
1400                             clazz.getName() + "Operations");
1401 
1402                     LOG.debug("adding " + clazz.getName()
1403                             + " to service interfaces");
1404 
1405                     ClientCorbaClassesHolder corbaClasses
1406                         = new ClientCorbaClassesHolder();
1407 
1408                     corbaClasses.setCorbaObjectClass(clazz);
1409                     corbaClasses.setOperationsClass(operationsClass);
1410                     corbaClasses.setHelperClass(helperClass);                    
1411 
1412                     LOG.debug("result.add - corbaClasses=" + corbaClasses);
1413                     result.add(corbaClasses);
1414                 } catch (ClassNotFoundException e) {
1415                     String className = clazz.getName();
1416 
1417                     LOG.error("CRB000527_Class_Helper_or_Operations_not_found",
1418                               new Object[] { className, className }, e);
1419                 }
1420             } else {
1421             	LOG.debug("CRB000565_Class_not_referred_to_corba_client", 
1422                 		new Object[]{clazz.getName()});
1423             }
1424         }
1425         LOG.debug("<<<<<<<<<< filterInterfaceClasses - end. result:" + result);
1426         return result;
1427     }
1428 
1429   
1430 
1431   /**
1432    * @return  the return
1433    */
1434     public URLClassLoader getUrlClassLoader() {
1435         return urlClassLoader;
1436     }
1437     
1438    /**
1439    * @return  the return
1440    */
1441     public ChildFirstClassLoader getOriginalClassLoader() {
1442         return originalClassLoader;
1443     }
1444 
1445 /**
1446  * @param workdirsrc                 The work dir src
1447  * @throws ClassGenerationException  The class generation exception
1448  */
1449   protected void addEnumClass(String workdirsrc) throws ClassGenerationException {
1450     String enumFileName
1451       = "/it/imolinfo/jbi4corba/test/webservice/generator/EchoComplexEnum.java";
1452 
1453     String filename = workdirsrc + enumFileName;
1454 
1455     String enumSource
1456       = "package it.imolinfo.jbi4corba.test.webservice.generator; "
1457       + "\n\n"
1458       + "public enum EchoComplexEnum implements org.omg.CORBA.portable.IDLEntity { "
1459       + "\n\n"
1460       + "E1, E2, E3;"
1461       + "\n\n"
1462       + "public int value() {return ordinal();} "
1463       + "\n\n"
1464       + "public static EchoComplexEnum from_int (int value) { return EchoComplexEnum.values()[value]; } "
1465       + "\n\n"
1466       + "}"
1467       ;
1468 
1469     try {
1470       PrintWriter pw
1471         = new PrintWriter(new BufferedWriter(new FileWriter(filename)));
1472       pw.println(enumSource);
1473       pw.flush();
1474       pw.close();
1475     } catch (IOException e) {
1476     	String msg=MESSAGES.getString("CRB000566_Failure_in_stopping_endpoint", 
1477     			new Object[] {e.getMessage()});
1478         LOG.error(msg,e);
1479         throw new ClassGenerationException(msg,e);
1480 
1481     }
1482   }
1483   
1484 
1485   
1486   
1487 }