Return-Path: Delivered-To: apmail-xml-axis-dev-archive@xml.apache.org Received: (qmail 60295 invoked by uid 500); 10 Oct 2001 20:38:32 -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 60286 invoked from network); 10 Oct 2001 20:38:32 -0000 Date: Wed, 10 Oct 2001 13:37:40 -0700 From: Ravi Kumar Subject: Re: TypeFactory, namespace and packages To: axis-dev@xml.apache.org Message-id: <3BC4B193.6513DF7F@borland.com> Organization: Inprise Corporation MIME-version: 1.0 X-Mailer: Mozilla 4.7 [en] (WinNT; U) Content-type: text/plain; charset=us-ascii Content-transfer-encoding: 7BIT X-Accept-Language: en References: <47FD4196C273D411950300508BCF1978013B1C89@S0001EXC0006> X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N OK, I won't. BTW, here is the relevant code from Wsdl2Java case PACKAGE_OPT: String packageName = option.getArgument(); if (packageName == null) emitter.generatePackageName(true); else emitter.setPackageName(packageName); break; That basically means that packageName can never be null. And the code in Emitter private void setup() { // Generate package name if desired if (packageName == null && bGeneratePackageName) { makePackageName(); } ........ } expects bGeneratePackageName to be set. So, I suggest that we wack the bGeneratePackageName completely. The downside is that the generated code must allways be in some package or the other. Rgds Ravi JBuilder R&D Tom Jordahl wrote: > Ravi, > > The ARGUMENT_OPTIONAL switch on the Excalibur command line parsing > doesn't work well or as expected. > > There is no way to differentiate between: > wsdl2java -p file://foo > and > wsdl2java -p foo file://foo > > Please don't use this setting. > > -- > Tom Jordahl > > -----Original Message----- > From: Ravi Kumar [mailto:rkumar@borland.com] > Sent: Tuesday, October 09, 2001 12:35 AM > To: axis-dev@xml.apache.org > 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(); > > > } > > >