Return-Path: Delivered-To: apmail-xml-axis-dev-archive@xml.apache.org Received: (qmail 27191 invoked by uid 500); 9 Oct 2001 13:53:53 -0000 Mailing-List: contact axis-dev-help@xml.apache.org; run by ezmlm Precedence: bulk Reply-To: axis-dev@xml.apache.org list-help: list-unsubscribe: list-post: Delivered-To: mailing list axis-dev@xml.apache.org Received: (qmail 26994 invoked from network); 9 Oct 2001 13:53:37 -0000 Importance: Normal Subject: Re: TypeFactory, namespace and packages To: axis-dev@xml.apache.org X-Mailer: Lotus Notes Release 5.0.7 March 21, 2001 Message-ID: From: "Russell Butek" Date: Tue, 9 Oct 2001 08:53:09 -0500 X-MIMETrack: Serialize by Router on D04NMS23/04/M/IBM(Release 5.0.8 |June 18, 2001) at 10/09/2001 09:52:59 AM MIME-Version: 1.0 Content-type: text/plain; charset=us-ascii X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N Ravi, I don't want you to think we're ignoring you. This looks like good stuff. But I'm wrapped up in another task at the moment and I won't be able to look closely at your work today. Tom's out sick, so I don't know when he'd be able to look at it, either. By the way, I'll be on vacation Oct 11-16. It's iffy whether I'll be able to address your stuff before I go, though I hope to. Russell Butek butek@us.ibm.com Ravi Kumar on 10/08/2001 11:34:58 PM Please respond to axis-dev@xml.apache.org To: axis-dev@xml.apache.org cc: Subject: Re: TypeFactory, namespace and packages An updated patch. changes from the last patch are: 1. The portTypes, stubs and skeletons already use qualified type names, so removed the imports 2. Fixed a problem in my previous change with invalid definition element at setup 3. makePackageName should handle hyphen conversions and urn:xyz format 4. Wsdl2Java should allow for optional packagenames so that autogeneration will kick in Rgds Ravi Ravi Kumar wrote: > My comments below. > > Russell Butek wrote: > > > Can I claim that this isn't a bug? Just something we haven't done yet? > > Totally. > Actually it would be a very good idea to create a TODO just for the Wsdl2Java. > At the minimum, it will serve as a "feature list" clearly identifying what it > supported and more importantly what is not. Is there a required / optional list > in the JAX-RPC spec, whcih could serve as a starter for this purpose? > > > > > You've opened a can of worms, Ravi. > > > > sorry :-) > hopefully, I will find some time to pitch in too! > > > > > In short, a WSDL doc might contain any number of namespaces, but Wsdl2java > > can only handle one. We need some way to associate each namespace with a > > package name. This has been discussed a bit on the side, but the > > discussions never got anywhere. > > > > First question: should we even pursue doing the 'right' thing? Is this a > > typical scenario that we have to handle? Or will just about everyone put > > everything that's in a single WSDL doc into the same namespace? My > > personal opinion: we have to do the right thing. > > > > Certainly agree -- need to do the right thing. > > > > > Second question, assuming you answered "yes" to the first: how do we do > > the right thing? Lots of ways: we could drop the --package argument > > altogether and let Wsdl2java always come up with its own mapping - some > > folks won't like that; we could make the user enter all mappings like " > > --NStoPackage =,=" or whatever, > > but then what if they forgot one? throw an exception? query the user for > > it (yuck - you just blew automated scripts out the window)? we could make > > the user put the mappings in a properties file. Other options? > > > > Take at a look at my patch. > > My approach is that the user can override only the top level package (as it is > now). Others are based on autogeneration from the respective > targetNameSpace(s). > > BTW, there is one more piece incomplete. > All references to types, both in the portType's and in other types needs to be > always fully qualified. For now, I am just importing all of them and that's > obviously no good. If we agree, thus far, I can go ahead and fix it tommorow > > > > > Russell Butek > > butek@us.ibm.com > > > > Ravi Kumar on 10/08/2001 02:29:36 PM > > > > Please respond to axis-dev@xml.apache.org > > > > To: axis-dev > > cc: > > Subject: TypeFactory, namespace and packages > > > > Below is the types section from a WSDL. Notice two schema nodes with > > with same complex type names (phone) but with different targetNameSpaces > > (nameSpace1 and nameSpace2). > > > > There should be no name conflicts in the generated code, as they both > > are scoped to belong in different packages (based on targetNameSpace). > > > > But the TypeFactory implementation ignores the namespace to package > > mapping completely as it doesn't initialize the mapNamespaceToPackage > > > > To fix this (if it is ineed a bug), a few changes need to be made > > > > Let me know, I can submit a patch > > > > Rgds > > Ravi > > > > Change1 > > --------- > > TypeFactory.getJavaName() { > > .... > > map(qName.getNameSpaceURI); > > > > ... > > } > > > > TypeFacory void map (String namespace) { > > if (mapNamespaceToPackage.get(nameSpace) == null) { > > mapNamespaceToPackage.put(namespace, > > Utils.generatePackageName(nameSpace); > > } > > } > > > > Change 2 > > ---------- > > Move the Emitter->makePackageName logic to Utils.generatePackegeName > > > > Changes 3 > > ---------- > > Emitter->writeXXXType needs to pass the > > private PrintWriter printWriter(String name, String packageName) > > throws IOException > > { > > ..... > > String pkgDirName = packageDirName; > > if (packageName == null) { > > pkgDirName = packageName.replace('.', '/'); > > } > > .... > > } > > > > change 4 > > --------- > > Emitter should call > > TypeFactory.map(targetNameSpace, packageName) > > with either the user given or auto generated packageName > > > > > > > xmlns:xsd="http://www.w3.org/2001/XMLSchema"> > > > > > > > > > > > > > > > > > xmlns:xsd="http://www.w3.org/2001/XMLSchema"> > > > > > > > > > > > > > > > > ------------------------------------------------------------------------ > Index: Emitter.java > =================================================================== > RCS file: /home/cvspublic/xml-axis/java/src/org/apache/axis/wsdl/Emitter.java,v > retrieving revision 1.38 > diff -r1.38 Emitter.java > 194a195 > > emitFactory.map(def.getTargetNamespace(), packageName); > 490a492 > > writeTypeImports(fileName, interfacePW); > 515a518 > > > 518a522 > > writeTypeImports(fileName, interfacePW); > 894a899 > > writeTypeImports(fileName, pw); > 969a975 > > writeTypeImports(stubFileName, stubPW); > 1040a1047 > > writeTypeImports(skelFileName, skelPW); > 1059a1067 > > writeTypeImports(implFileName, implPW); > 1423a1432 > > writeTypeImports(fileName, servicePW); > 1762c1771 > < PrintWriter typePW = printWriter(fileName); > --- > > PrintWriter typePW = printWriter(fileName, type.getJavaPackageName()); > 1766c1775 > < writeFileHeader(fileName, typePW); > --- > > writeFileHeader(fileName, type.getJavaPackageName(), typePW); > 1824c1833 > < PrintWriter typePW = printWriter(fileName); > --- > > PrintWriter typePW = printWriter(fileName, eType.getJavaPackageName()); > 1828c1837 > < writeFileHeader(fileName, typePW); > --- > > writeFileHeader(fileName, eType.getJavaPackageName(), typePW); > 1847c1856 > < PrintWriter pw = printWriter(fileName); > --- > > PrintWriter pw = printWriter(fileName, type.getJavaPackageName ()); > 1851c1860 > < writeFileHeader(fileName, pw); > --- > > writeFileHeader(fileName, type.getJavaPackageName(), pw); > 1899,1900c1908,1919 > < if (outputDir == null) { > < return new PrintWriter(new FileWriter(packageDirName + name)); > --- > > return printWriter(name, null); > > } // printWriter > > > > /** > > * Get a PrintWriter attached to a file with the given name. The location of this file > > * is determined from the values of outputDir and packageDirName. > > */ > > private PrintWriter printWriter(String name, String packageName) throws IOException > > { > > String pkgDirName = packageDirName; > > if (packageName != null) { > > pkgDirName = packageName.replace('.', '/'); > 1902,1903c1921,1935 > < else { > < return new PrintWriter(new FileWriter(outputDir + File.separatorChar + packageDirName + name)); > --- > > > > File dir = null; > > if (pkgDirName != null) { > > if (outputDir == null) > > dir = new File(pkgDirName); > > else > > dir = new File(outputDir, pkgDirName); > > if (!dir.exists()) { > > StringTokenizer st = new StringTokenizer(pkgDirName, "/"); > > dir = new File(outputDir); > > while (st.hasMoreTokens()) { > > dir = new File(dir, st.nextToken()); > > dir.mkdir(); > > } > > } > 1904a1937,1938 > > > > return new PrintWriter(new FileWriter(new File(dir, name))); > 2026a2061,2070 > > private void writeTypeImports(String filename, PrintWriter pw) { > > String[] pkgs = emitFactory.getAllPackages(); > > if (pkgs != null) { > > for (int i = 0; i < pkgs.length; i++) { > > if (!pkgs[i].equals(packageName)) > > pw.println("import " + pkgs[i] + ".*;"); > > } > > } > > } > > > 2047,2059c2091,2102 > < private void makePackageName() > < { > < String hostname = null; > < > < // get the target namespace of the document > < String namespace = def.getTargetNamespace(); > < try { > < hostname = new URL(namespace).getHost(); > < } > < catch (MalformedURLException e) { > < // do nothing > < return; > < } > --- > > /** > > * Write a common header, including the package name (if any) to the > > * provided stream > > */ > > private void writeFileHeader(String filename, String pkgName, PrintWriter pw) { > > pw.println("/**"); > > pw.println(" * " + filename); > > pw.println(" *"); > > pw.println(" * This file was auto-generated from WSDL"); > > pw.println(" * by the Apache Axis Wsdl2java emitter."); > > pw.println(" */"); > > pw.println(); > 2061,2063c2104,2109 > < // if we didn't file a hostname, bail > < if (hostname == null) { > < return; > --- > > // print package declaration > > if (pkgName == null) { > > if (packageName != null) { > > pw.println("package " + packageName + ";"); > > pw.println(); > > } > 2065,2082c2111,2113 > < > < // tokenize the hostname and reverse it > < StringTokenizer st = new StringTokenizer( hostname, "." ); > < String[] words = new String[ st.countTokens() ]; > < for(int i = 0; i < words.length; ++i) > < words[i] = st.nextToken(); > < > < StringBuffer sb = new StringBuffer(80); > < for(int i = words.length-1; i >= 0; --i) { > < String word = words[i]; > < // seperate with dot > < if( i != words.length-1 ) > < sb.append('.'); > < > < // convert digits to underscores > < if( Character.isDigit(word.charAt(0)) ) > < sb.append('_'); > < sb.append( word ); > --- > > else { > > pw.println("package " + pkgName + ";"); > > pw.println(); > 2084c2115,2120 > < setPackageName(sb.toString()); > --- > > } > > > > private void makePackageName() > > { > > String pkgName = Utils.makePackageName(def.getTargetNamespace ()); > > setPackageName(pkgName); > > Index: TypeFactory.java > =================================================================== > RCS file: /home/cvspublic/xml-axis/java/src/org/apache/axis/wsdl/TypeFactory.java,v > retrieving revision 1.3 > diff -r1.3 TypeFactory.java > 84a85,97 > > // /** > > // * Invoke this method to associate a namespace URI with a autogenerated Java Package > > // * name, if an entry is not already present > > // * > > // */ > > // > > > > public void map (String namespace) { > > if (mapNamespaceToPackage.get(namespace) == null) { > > mapNamespaceToPackage.put(namespace, Utils.makePackageName(namespace)); > > } > > } > > > 91a105,116 > > public String[] getAllPackages() { > > if (mapNamespaceToPackage.size() <= 0) { > > return null; > > } > > String[] pkgs = new String[mapNamespaceToPackage.size()]; > > Object[] obj = mapNamespaceToPackage.values().toArray(); > > for (int i = 0; i < pkgs.length; i++) { > > pkgs[i] = (String)obj[i]; > > } > > return pkgs; > > } > > > 99a125,128 > > public void buildTypes(Class cls) { > > > > } > > > 349a379 > > map(qName.getNamespaceURI()); > > Index: Utils.java > =================================================================== > RCS file: /home/cvspublic/xml-axis/java/src/org/apache/axis/wsdl/Utils.java,v > retrieving revision 1.3 > diff -r1.3 Utils.java > 59a60,64 > > > > import java.net.MalformedURLException; > > import java.net.URL; > > import java.util.StringTokenizer; > > > 61c66 > < * This class contains static utility methods for the emitter. > --- > > * This class contains static utility methods for the emitter. > 72c77 > < > --- > > > 78,79c83,84 > < } // capitalize > < > --- > > } // capitalize > > > 99c104 > < > --- > > > 108c113 > < > --- > > > 119c124 > < > --- > > > 144c149 > < > --- > > > 158c163 > < // the complexType may be anonymous, which is why the getScopedAttribute > --- > > // the complexType may be anonymous, which is why the getScopedAttribute > 207c212 > < > --- > > > 227a233,272 > > > > public static String makePackageName(String namespace) > > { > > String hostname = null; > > > > // get the target namespace of the document > > try { > > hostname = new URL(namespace).getHost(); > > } > > catch (MalformedURLException e) { > > // do nothing > > return null; > > } > > > > // if we didn't file a hostname, bail > > if (hostname == null) { > > return null; > > } > > > > // tokenize the hostname and reverse it > > StringTokenizer st = new StringTokenizer( hostname, "." ); > > String[] words = new String[ st.countTokens() ]; > > for(int i = 0; i < words.length; ++i) > > words[i] = st.nextToken(); > > > > StringBuffer sb = new StringBuffer(80); > > for(int i = words.length-1; i >= 0; --i) { > > String word = words[i]; > > // seperate with dot > > if( i != words.length-1 ) > > sb.append('.'); > > > > // convert digits to underscores > > if( Character.isDigit(word.charAt(0)) ) > > sb.append('_'); > > sb.append( word ); > > } > > return sb.toString(); > > } > > Index: Emitter.java =================================================================== RCS file: /home/cvspublic/xml-axis/java/src/org/apache/axis/wsdl/Emitter.java,v retrieving revision 1.38 diff -r1.38 Emitter.java 178d177 < setup(); 180a180 > setup(); 194a195 > emitFactory.map(def.getTargetNamespace(), packageName); 515a517 > 1762c1764 < PrintWriter typePW = printWriter(fileName); --- > PrintWriter typePW = printWriter(fileName, type.getJavaPackageName()); 1766c1768 < writeFileHeader(fileName, typePW); --- > writeFileHeader(fileName, type.getJavaPackageName(), typePW); 1824c1826 < PrintWriter typePW = printWriter(fileName); --- > PrintWriter typePW = printWriter(fileName, eType.getJavaPackageName()); 1828c1830 < writeFileHeader(fileName, typePW); --- > writeFileHeader(fileName, eType.getJavaPackageName(), typePW); 1847c1849 < PrintWriter pw = printWriter(fileName); --- > PrintWriter pw = printWriter(fileName, type.getJavaPackageName ()); 1851c1853 < writeFileHeader(fileName, pw); --- > writeFileHeader(fileName, type.getJavaPackageName(), pw); 1899,1900c1901,1912 < if (outputDir == null) { < return new PrintWriter(new FileWriter(packageDirName + name)); --- > return printWriter(name, null); > } // printWriter > > /** > * Get a PrintWriter attached to a file with the given name. The location of this file > * is determined from the values of outputDir and packageDirName. > */ > private PrintWriter printWriter(String name, String packageName) throws IOException > { > String pkgDirName = packageDirName; > if (packageName != null) { > pkgDirName = packageName.replace('.', '/'); 1902,1903c1914,1928 < else { < return new PrintWriter(new FileWriter(outputDir + File.separatorChar + packageDirName + name)); --- > > File dir = null; > if (pkgDirName != null) { > if (outputDir == null) > dir = new File(pkgDirName); > else > dir = new File(outputDir, pkgDirName); > if (!dir.exists()) { > StringTokenizer st = new StringTokenizer(pkgDirName, "/"); > dir = new File(outputDir); > while (st.hasMoreTokens()) { > dir = new File(dir, st.nextToken()); > dir.mkdir(); > } > } 1904a1930,1931 > > return new PrintWriter(new FileWriter(new File(dir, name))); 2026a2054 > 2047,2059c2075,2086 < private void makePackageName() < { < String hostname = null; < < // get the target namespace of the document < String namespace = def.getTargetNamespace(); < try { < hostname = new URL(namespace).getHost(); < } < catch (MalformedURLException e) { < // do nothing < return; < } --- > /** > * Write a common header, including the package name (if any) to the > * provided stream > */ > private void writeFileHeader(String filename, String pkgName, PrintWriter pw) { > pw.println("/**"); > pw.println(" * " + filename); > pw.println(" *"); > pw.println(" * This file was auto-generated from WSDL"); > pw.println(" * by the Apache Axis Wsdl2java emitter."); > pw.println(" */"); > pw.println(); 2061,2063c2088,2093 < // if we didn't file a hostname, bail < if (hostname == null) { < return; --- > // print package declaration > if (pkgName == null) { > if (packageName != null) { > pw.println("package " + packageName + ";"); > pw.println(); > } 2065,2082c2095,2097 < < // tokenize the hostname and reverse it < StringTokenizer st = new StringTokenizer( hostname, "." ); < String[] words = new String[ st.countTokens() ]; < for(int i = 0; i < words.length; ++i) < words[i] = st.nextToken(); < < StringBuffer sb = new StringBuffer(80); < for(int i = words.length-1; i >= 0; --i) { < String word = words[i]; < // seperate with dot < if( i != words.length-1 ) < sb.append('.'); < < // convert digits to underscores < if( Character.isDigit(word.charAt(0)) ) < sb.append('_'); < sb.append( word ); --- > else { > pw.println("package " + pkgName + ";"); > pw.println(); 2084c2099,2104 < setPackageName(sb.toString()); --- > } > > private void makePackageName() > { > String pkgName = Utils.makePackageName(def.getTargetNamespace()); > setPackageName(pkgName); Index: Utils.java =================================================================== RCS file: /home/cvspublic/xml-axis/java/src/org/apache/axis/wsdl/Utils.java,v retrieving revision 1.3 diff -r1.3 Utils.java 59a60,64 > > import java.net.MalformedURLException; > import java.net.URL; > import java.util.StringTokenizer; > 61c66 < * This class contains static utility methods for the emitter. --- > * This class contains static utility methods for the emitter. 72c77 < --- > 78,79c83,84 < } // capitalize < --- > } // capitalize > 99c104 < --- > 108c113 < --- > 119c124 < --- > 144c149 < --- > 158c163 < // the complexType may be anonymous, which is why the getScopedAttribute --- > // the complexType may be anonymous, which is why the getScopedAttribute 207c212 < --- > 227a233,278 > > public static String makePackageName(String namespace) > { > String hostname = null; > > // get the target namespace of the document > try { > hostname = new URL(namespace).getHost(); > } > catch (MalformedURLException e) { > if (namespace.indexOf(":") > -1) { > hostname = namespace.substring(namespace.indexOf(":") + 1); > if (hostname.indexOf("/") > -1) > hostname = hostname.substring(0, hostname.indexOf("/") ); > } > } > > // if we didn't file a hostname, bail > if (hostname == null) { > return null; > } > > //convert illegal java identifier > hostname = hostname.replace('-', '_'); > > // tokenize the hostname and reverse it > StringTokenizer st = new StringTokenizer( hostname, "." ); > String[] words = new String[ st.countTokens() ]; > for(int i = 0; i < words.length; ++i) > words[i] = st.nextToken(); > > StringBuffer sb = new StringBuffer(80); > for(int i = words.length-1; i >= 0; --i) { > String word = words[i]; > // seperate with dot > if( i != words.length-1 ) > sb.append('.'); > > // convert digits to underscores > if( Character.isDigit(word.charAt(0)) ) > sb.append('_'); > sb.append( word ); > } > return sb.toString(); > } > Index: Wsdl2java.java =================================================================== RCS file: /home/cvspublic/xml-axis/java/src/org/apache/axis/wsdl/Wsdl2java.java,v retrieving revision 1.15 diff -r1.15 Wsdl2java.java 108c108 < CLOptionDescriptor.ARGUMENT_REQUIRED, --- > CLOptionDescriptor.ARGUMENT_OPTIONAL, Index: TypeFactory.java =================================================================== RCS file: /home/cvspublic/xml-axis/java/src/org/apache/axis/wsdl/TypeFactory.java,v retrieving revision 1.3 diff -r1.3 TypeFactory.java 84a85,97 > // /** > // * Invoke this method to associate a namespace URI with a autogenerated Java Package > // * name, if an entry is not already present > // * > // */ > // > > public void map (String namespace) { > if (mapNamespaceToPackage.get(namespace) == null) { > mapNamespaceToPackage.put(namespace, Utils.makePackageName(namespace)); > } > } > 91a105,116 > public String[] getAllPackages() { > if (mapNamespaceToPackage.size() <= 0) { > return null; > } > String[] pkgs = new String[mapNamespaceToPackage.size()]; > Object[] obj = mapNamespaceToPackage.values().toArray(); > for (int i = 0; i < pkgs.length; i++) { > pkgs[i] = (String)obj[i]; > } > return pkgs; > } > 99a125,128 > public void buildTypes(Class cls) { > > } > 349a379 > map(qName.getNamespaceURI());