Source Code Cross Referenced for Wsdl2Js.java in  » J2EE » Pustefix » de » schlund » pfixcore » webservice » jaxws » generate » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » J2EE » Pustefix » de.schlund.pfixcore.webservice.jaxws.generate 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * This file is part of PFIXCORE.
003:         *
004:         * PFIXCORE is free software; you can redistribute it and/or modify
005:         * it under the terms of the GNU Lesser General Public License as published by
006:         * the Free Software Foundation; either version 2 of the License, or
007:         * (at your option) any later version.
008:         *
009:         * PFIXCORE is distributed in the hope that it will be useful,
010:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
011:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
012:         * GNU Lesser General Public License for more details.
013:         *
014:         * You should have received a copy of the GNU Lesser General Public License
015:         * along with PFIXCORE; if not, write to the Free Software
016:         * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
017:         *
018:         */
019:        package de.schlund.pfixcore.webservice.jaxws.generate;
020:
021:        import java.io.File;
022:        import java.io.FileInputStream;
023:        import java.io.FileOutputStream;
024:        import java.io.IOException;
025:        import java.util.ArrayList;
026:        import java.util.HashMap;
027:        import java.util.Iterator;
028:        import java.util.List;
029:        import java.util.Map;
030:        import java.util.regex.Matcher;
031:        import java.util.regex.Pattern;
032:
033:        import javax.wsdl.Binding;
034:        import javax.wsdl.BindingOperation;
035:        import javax.wsdl.Definition;
036:        import javax.wsdl.Input;
037:        import javax.wsdl.Message;
038:        import javax.wsdl.Operation;
039:        import javax.wsdl.Output;
040:        import javax.wsdl.Part;
041:        import javax.wsdl.Port;
042:        import javax.wsdl.Service;
043:        import javax.wsdl.Types;
044:        import javax.wsdl.extensions.ExtensibilityElement;
045:        import javax.wsdl.extensions.schema.Schema;
046:        import javax.wsdl.extensions.schema.SchemaImport;
047:        import javax.wsdl.extensions.soap.SOAPAddress;
048:        import javax.wsdl.factory.WSDLFactory;
049:        import javax.wsdl.xml.WSDLReader;
050:        import javax.xml.namespace.QName;
051:
052:        import org.w3c.dom.Element;
053:        import org.w3c.dom.NamedNodeMap;
054:        import org.w3c.dom.Node;
055:        import org.w3c.dom.NodeList;
056:        import org.xml.sax.InputSource;
057:
058:        import com.ibm.wsdl.util.xml.DOMUtils;
059:
060:        import de.schlund.pfixcore.webservice.Constants;
061:        import de.schlund.pfixcore.webservice.jsgen.JsBlock;
062:        import de.schlund.pfixcore.webservice.jsgen.JsClass;
063:        import de.schlund.pfixcore.webservice.jsgen.JsMethod;
064:        import de.schlund.pfixcore.webservice.jsgen.JsParam;
065:        import de.schlund.pfixcore.webservice.jsgen.JsStatement;
066:
067:        /**
068:         * This class generates a Javascript stub file from a WSDL description.
069:         *
070:         * @author mleidig@schlund.de
071:         */
072:        public class Wsdl2Js {
073:
074:            private final static Pattern PREFIXPATTERN = Pattern
075:                    .compile("(\\w+):(\\w+)");
076:            private final static String XMLNS_SCHEMA = "http://www.w3.org/2001/XMLSchema";
077:            private final static String XMLNS_JAXB_ARRAY = "http://jaxb.dev.java.net/array";
078:
079:            private File outputFile;
080:            private File inputFile;
081:
082:            private Map<QName, Element> schemaComplexTypes;
083:            private Map<QName, QName> schemaElementsToTypes;
084:
085:            private HashMap<QName, String> typeInfoMap;
086:            private ArrayList<String> typeInfoList;
087:            private ArrayList<String> popInfoList;
088:
089:            /**
090:             * Set WSDL input file
091:             */
092:            public void setInputFile(File inputFile) {
093:                this .inputFile = inputFile;
094:            }
095:
096:            /**
097:             * Set Javascript output file
098:             */
099:            public void setOutputFile(File outputFile) {
100:                this .outputFile = outputFile;
101:            }
102:
103:            /**
104:             * Generate Javascript stub file from WSDL file 
105:             */
106:            public void generate() throws Wsdl2JsException, IOException {
107:                if (inputFile == null)
108:                    throw new Wsdl2JsException("No WSDL input file specified");
109:                if (outputFile == null)
110:                    throw new Wsdl2JsException("No JS output file specified");
111:                if (!inputFile.exists())
112:                    throw new Wsdl2JsException("WSDL input file doesn't exist");
113:                Definition def = null;
114:                try {
115:                    WSDLFactory wf = WSDLFactory.newInstance();
116:                    WSDLReader wr = wf.newWSDLReader();
117:                    wr.setFeature("javax.wsdl.verbose", false);
118:                    wr.setFeature("javax.wsdl.importDocuments", true);
119:                    InputSource inSrc = new InputSource(new FileInputStream(
120:                            inputFile));
121:                    def = wr.readWSDL(inputFile.getParentFile().toURI()
122:                            .toString(), inSrc);
123:                } catch (Exception x) {
124:                    throw new Wsdl2JsException("Error reading WSDL from: "
125:                            + inputFile.getAbsolutePath(), x);
126:                }
127:                typeInfoMap = new HashMap<QName, String>();
128:                popInfoList = new ArrayList<String>();
129:                typeInfoList = new ArrayList<String>();
130:                readSchema(def.getTypes());
131:                Iterator<?> srvIt = def.getServices().values().iterator();
132:                if (srvIt.hasNext()) {
133:                    Service service = (Service) srvIt.next();
134:                    Iterator<?> prtIt = service.getPorts().values().iterator();
135:                    if (prtIt.hasNext()) {
136:                        Port port = (Port) prtIt.next();
137:                        String stubClass = Constants.STUBGEN_DEFAULT_JSNAMESPACE
138:                                + service.getQName().getLocalPart();
139:                        JsParam[] constParams = new JsParam[] { new JsParam(
140:                                "cbObj") };
141:                        JsClass jsClass = new JsClass(stubClass, "SOAP_Stub",
142:                                constParams);
143:                        JsBlock block = jsClass.getConstructorBody();
144:                        block
145:                                .addStatement(new JsStatement(
146:                                        "this._cbObj=cbObj"));
147:                        block.addStatement(new JsStatement("this._setURL(\""
148:                                + getAddressLocation(port) + "\")"));
149:                        Binding binding = port.getBinding();
150:                        Iterator<?> bopIt = binding.getBindingOperations()
151:                                .iterator();
152:                        while (bopIt.hasNext()) {
153:                            BindingOperation bop = (BindingOperation) bopIt
154:                                    .next();
155:                            Operation op = bop.getOperation();
156:                            try {
157:                                JsMethod jsMethod = new JsMethod(jsClass, op
158:                                        .getName());
159:                                JsBlock jsBlock = jsMethod.getBody();
160:                                jsBlock.addStatement(new JsStatement(
161:                                        "var call=this._createCall()"));
162:                                jsBlock
163:                                        .addStatement(new JsStatement(
164:                                                "call.setTargetNamespace(this._targetNamespace)"));
165:                                jsBlock.addStatement(new JsStatement(
166:                                        "call.setOperationName(\""
167:                                                + jsMethod.getName() + "\")"));
168:                                //get input params
169:                                Input input = op.getInput();
170:                                Message inputMsg = input.getMessage();
171:                                Part inputPart = inputMsg.getPart("parameters");
172:                                if (inputPart != null) {
173:                                    QName typeName = schemaElementsToTypes
174:                                            .get(inputPart.getElementName());
175:                                    Element typeElem = schemaComplexTypes
176:                                            .get(typeName);
177:                                    Element[] children = getSchemaChildren(typeElem);
178:                                    if (children.length > 1
179:                                            || (children.length == 1 && !children[0]
180:                                                    .getLocalName().equals(
181:                                                            "sequence")))
182:                                        throw new Wsdl2JsException(
183:                                                "Expected only single sequence child element for complexType: "
184:                                                        + typeName);
185:                                    children = getSchemaChildren(children[0]);
186:                                    for (int paraNo = 0; paraNo < children.length; paraNo++) {
187:                                        if (!children[paraNo].getLocalName()
188:                                                .equals("element"))
189:                                            throw new Wsdl2JsException(
190:                                                    "Expected only element children within sequence of complexType: "
191:                                                            + typeName);
192:                                        String name = children[paraNo]
193:                                                .getAttribute("name");
194:                                        JsParam jsParam = new JsParam(name);
195:                                        jsMethod.addParam(jsParam);
196:                                        String info = createTypeInfo(children[paraNo]);
197:                                        jsBlock.addStatement(new JsStatement(
198:                                                "call.addParameter(\"" + name
199:                                                        + "\"," + info + ")"));
200:                                    }
201:                                }
202:                                jsBlock.addStatement(new JsStatement(
203:                                        "this._extractCallback(call,arguments,"
204:                                                + jsMethod.getParams().length
205:                                                + ")"));
206:                                //get return param
207:                                Output output = op.getOutput();
208:                                Message outputMsg = output.getMessage();
209:                                Part outputPart = outputMsg
210:                                        .getPart("parameters");
211:                                if (outputPart != null) {
212:                                    QName typeName = schemaElementsToTypes
213:                                            .get(outputPart.getElementName());
214:                                    Element typeElem = schemaComplexTypes
215:                                            .get(typeName);
216:                                    Element[] children = getSchemaChildren(typeElem);
217:                                    if (children.length > 1
218:                                            || (children.length == 1 && !children[0]
219:                                                    .getLocalName().equals(
220:                                                            "sequence")))
221:                                        throw new Wsdl2JsException(
222:                                                "Expected only single sequence child element for complexType: "
223:                                                        + typeName);
224:                                    children = getSchemaChildren(children[0]);
225:                                    if (children.length > 1)
226:                                        throw new Wsdl2JsException(
227:                                                "Expected only one or none return parameters");
228:                                    if (children.length == 1) {
229:                                        String info = createTypeInfo(children[0]);
230:                                        jsBlock.addStatement(new JsStatement(
231:                                                "call.setReturnType(" + info
232:                                                        + ")"));
233:                                    }
234:                                }
235:                                jsBlock
236:                                        .addStatement(new JsStatement(
237:                                                "return call.invoke("
238:                                                        + jsMethod
239:                                                                .getParamList()
240:                                                        + ")"));
241:                                jsClass.addMethod(jsMethod);
242:                            } catch (Wsdl2JsTypeException x) {
243:                                System.out.println("WARNING: Skip method '"
244:                                        + op.getName() + "' as signature "
245:                                        + "contains unsupported type '"
246:                                        + x.getTypeName() + "'.");
247:                            }
248:                        }
249:                        block.addStatement(new JsStatement(
250:                                "this._targetNamespace=\""
251:                                        + def.getTargetNamespace() + "\""));
252:                        for (int i = 0; i < typeInfoList.size(); i++) {
253:                            block.addStatement(new JsStatement(
254:                                    "this._typeInfos[" + i + "]="
255:                                            + (String) typeInfoList.get(i)));
256:                        }
257:                        for (int i = 0; i < popInfoList.size(); i++) {
258:                            block.addStatement(new JsStatement(
259:                                    (String) popInfoList.get(i)));
260:                        }
261:                        jsClass.printCode(new FileOutputStream(outputFile));
262:                    }
263:                }
264:            }
265:
266:            /**
267:             * Get endpoint location URI from WSDL port
268:             */
269:            private String getAddressLocation(Port port)
270:                    throws Wsdl2JsException {
271:                Iterator<?> it = port.getExtensibilityElements().iterator();
272:                while (it.hasNext()) {
273:                    ExtensibilityElement elem = (ExtensibilityElement) it
274:                            .next();
275:                    if (elem instanceof  SOAPAddress) {
276:                        SOAPAddress adr = (SOAPAddress) elem;
277:                        return adr.getLocationURI();
278:                    }
279:                }
280:                throw new Wsdl2JsException(
281:                        "No soap address binding found for port " + port);
282:            }
283:
284:            /**
285:             * Create type description JS code for the the given schema element
286:             */
287:            private String createTypeInfo(Element element)
288:                    throws Wsdl2JsException {
289:                if (!(element.getNamespaceURI().equals(XMLNS_SCHEMA) && element
290:                        .getLocalName().equals("element")))
291:                    throw new IllegalArgumentException(
292:                            "Expected element declaration as argument");
293:                if (isElementArray(element)) {
294:                    ArrayInfo arrayInfo = getArrayInfoFromElement(element);
295:                    QName compType = arrayInfo.arrayType;
296:                    int dim = arrayInfo.arrayDim;
297:                    String name = compType.getLocalPart();
298:                    for (int i = 0; i < dim; i++)
299:                        name += "Array";
300:                    String nsuri = compType.getNamespaceURI();
301:                    if (compType.getNamespaceURI().equals(XMLNS_SCHEMA))
302:                        nsuri = XMLNS_JAXB_ARRAY;
303:                    QName arrType = new QName(nsuri, name);
304:                    String ret = typeInfoMap.get(arrType);
305:                    if (ret == null) {
306:                        int ind = typeInfoList.size();
307:                        String info = "\"\"";
308:                        typeInfoList.add(info);
309:                        ret = "this._typeInfos[" + ind + "]";
310:                        typeInfoMap.put(arrType, ret);
311:                        String ainf = createJsTypeInfo(arrayInfo.arrayType);
312:                        String pop = ret + ".populate(" + ainf + ","
313:                                + arrayInfo.arrayDim + ")";
314:                        popInfoList.add(pop);
315:                        String qn = createJsQName(arrType);
316:                        info = "new SOAP_ArrayInfo(" + qn + ")";
317:                        typeInfoList.set(ind, info);
318:                    }
319:                    return ret;
320:                } else {
321:
322:                    String type = element.getAttribute("type");
323:                    QName qname = getQName(type, element);
324:
325:                    return createJsTypeInfo(qname);
326:                }
327:            }
328:
329:            /**
330:             * Create type description JS code for the the given schema type
331:             */
332:            private String createJsTypeInfo(QName type) throws Wsdl2JsException {
333:                String ret = typeInfoMap.get(type);
334:                if (ret == null) {
335:                    int ind = typeInfoList.size();
336:                    ret = "this._typeInfos[" + ind + "]";
337:                    typeInfoMap.put(type, ret);
338:                    String info = "\"\"";
339:                    typeInfoList.add(info);
340:                    if (type.getNamespaceURI().equals(Constants.XMLNS_XSD)) {
341:                        info = "new SOAP_TypeInfo(" + createJsQName(type) + ")";
342:                    } else if (type.getLocalPart().equals("hashMap")) {
343:                        throw new Wsdl2JsTypeException(type);
344:                    } else {
345:                        Element ctypeElem = (Element) schemaComplexTypes
346:                                .get(type);
347:                        if (ctypeElem != null) {
348:                            if (isComplexTypeArray(ctypeElem)) {
349:                                String qn = createJsQName(type);
350:                                ArrayInfo arrayInfo = getArrayInfoFromComplexType(ctypeElem);
351:                                String ainf = createJsTypeInfo(arrayInfo.arrayType);
352:                                String pop = ret + ".populate(" + ainf + ","
353:                                        + arrayInfo.arrayDim + ")";
354:                                popInfoList.add(pop);
355:                                info = "new SOAP_ArrayInfo(" + qn + ")";
356:                            } else {
357:                                info = "new SOAP_BeanInfo("
358:                                        + createJsQName(type) + ")";
359:                                String pop = ret + ".populate(new Array(";
360:                                String memberList = getMemberInfos(ctypeElem);
361:                                pop += memberList;
362:                                pop += "))";
363:                                popInfoList.add(pop);
364:                            }
365:                        } else
366:                            throw new Wsdl2JsException("Type '" + type
367:                                    + "' not found within WSDL types section."
368:                                    + " ->" + type.getNamespaceURI());
369:                    }
370:                    typeInfoList.set(ind, info);
371:                }
372:                return ret;
373:            }
374:
375:            /**
376:             * Create QName instance JS code (using JS constant for schema namespace)
377:             */
378:            private String createJsQName(QName name) {
379:                String nsuri = "";
380:                if (name.getNamespaceURI().equals(Constants.XMLNS_XSD))
381:                    nsuri = "XML_NS_XSD";
382:                else
383:                    nsuri = "\"" + name.getNamespaceURI() + "\"";
384:                return "new XML_QName(" + nsuri + ",\"" + name.getLocalPart()
385:                        + "\")";
386:            }
387:
388:            /**
389:             * Stores top-level schema elements and complexTypes in maps (for all imported schemas)
390:             */
391:            private void readSchema(Types wsdlTypes) throws Wsdl2JsException {
392:                schemaComplexTypes = new HashMap<QName, Element>();
393:                schemaElementsToTypes = new HashMap<QName, QName>();
394:                if (wsdlTypes != null) {
395:                    List<?> schemaList = wsdlTypes.getExtensibilityElements();
396:                    Iterator<?> schemaIt = schemaList.iterator();
397:                    while (schemaIt.hasNext()) {
398:                        ExtensibilityElement extElem = (ExtensibilityElement) schemaIt
399:                                .next();
400:                        if (extElem instanceof  Schema) {
401:                            Schema schema = (Schema) extElem;
402:                            readSchema(schema);
403:                        }
404:                    }
405:                }
406:            }
407:
408:            /**
409:             * Stores top-level schema elements and complexTypes in maps (for a single schema)
410:             */
411:            private void readSchema(Schema schema) throws Wsdl2JsException {
412:                // Process imported schemas
413:                Map<?, ?> imports = schema.getImports();
414:                Iterator<?> impIt = imports.keySet().iterator();
415:                while (impIt.hasNext()) {
416:                    String targetNS = (String) impIt.next();
417:                    List<?> list = (List<?>) imports.get(targetNS);
418:                    Iterator<?> listIt = list.iterator();
419:                    while (listIt.hasNext()) {
420:                        Object obj = listIt.next();
421:                        if (obj instanceof  SchemaImport) {
422:                            SchemaImport schemaImp = (SchemaImport) obj;
423:                            Schema refSchema = schemaImp.getReferencedSchema();
424:                            readSchema(refSchema);
425:                        }
426:                    }
427:                }
428:                // Process schema type definitions
429:                NodeList nodes = schema.getElement().getChildNodes();
430:                for (int i = 0; i < nodes.getLength(); i++) {
431:                    Node node = nodes.item(i);
432:                    if (node.getNodeType() == Node.ELEMENT_NODE
433:                            && node.getNamespaceURI().equals(
434:                                    Constants.XMLNS_XSD)) {
435:                        if (node.getLocalName().equals("complexType")) {
436:                            Element typeElem = (Element) node;
437:                            String name = typeElem.getAttribute("name");
438:                            String targetNS = schema.getElement().getAttribute(
439:                                    "targetNamespace");
440:                            QName qname = new QName(targetNS, name);
441:                            schemaComplexTypes.put(qname, typeElem);
442:                        } else if (node.getLocalName().equals("element")) {
443:                            Element elemElem = (Element) node;
444:                            String name = elemElem.getAttribute("name");
445:                            String targetNS = schema.getElement().getAttribute(
446:                                    "targetNamespace");
447:                            String type = elemElem.getAttribute("type");
448:                            Matcher matcher = PREFIXPATTERN.matcher(type);
449:                            if (!matcher.matches())
450:                                throw new Wsdl2JsException(
451:                                        "Element type value isn't prefixed: "
452:                                                + type);
453:                            String prefix = matcher.group(1);
454:                            String localName = matcher.group(2);
455:                            String nsuri = DOMUtils.getNamespaceURIFromPrefix(
456:                                    elemElem, prefix);
457:                            if (nsuri == null)
458:                                throw new Wsdl2JsException(
459:                                        "No namespace declaration found for prefix: "
460:                                                + prefix);
461:                            QName elemQName = new QName(targetNS, name);
462:                            QName typeQName = new QName(nsuri, localName);
463:                            schemaElementsToTypes.put(elemQName, typeQName);
464:                        }
465:                    }
466:                }
467:            }
468:
469:            /**
470:             * Check if complexType declaration represents an array
471:             */
472:            private boolean isComplexTypeArray(Element complexType) {
473:                if (!(complexType.getNamespaceURI().equals(XMLNS_SCHEMA) && complexType
474:                        .getLocalName().equals("complexType")))
475:                    throw new IllegalArgumentException(
476:                            "Expected complex type declaration element as argument");
477:                Element[] elems = getSchemaChildren(complexType);
478:                if (elems.length == 1
479:                        && elems[0].getLocalName().equals("sequence")) {
480:                    elems = getSchemaChildren(elems[0]);
481:                    if (elems.length == 1
482:                            && elems[0].getLocalName().equals("element")) {
483:                        String min = elems[0].getAttribute("minOccurs");
484:                        String max = elems[0].getAttribute("maxOccurs");
485:                        if (min != null && max != null && min.equals("0")
486:                                && max.equals("unbounded"))
487:                            return true;
488:                    }
489:                }
490:                return false;
491:            }
492:
493:            /**
494:             * Check if element declaration represents an array
495:             */
496:            private boolean isElementArray(Element element) {
497:                if (!(element.getNamespaceURI().equals(XMLNS_SCHEMA) && element
498:                        .getLocalName().equals("element")))
499:                    throw new IllegalArgumentException(
500:                            "Expected element declaration as argument");
501:                String min = element.getAttribute("minOccurs");
502:                String max = element.getAttribute("maxOccurs");
503:                if (min != null && max != null && min.equals("0")
504:                        && max.equals("unbounded"))
505:                    return true;
506:                return false;
507:            }
508:
509:            /**
510:             * Extract array information from complexType
511:             */
512:            private ArrayInfo getArrayInfoFromComplexType(Element complexType)
513:                    throws Wsdl2JsException {
514:                if (!(complexType.getNamespaceURI().equals(XMLNS_SCHEMA) && complexType
515:                        .getLocalName().equals("complexType")))
516:                    throw new IllegalArgumentException(
517:                            "Expected complex type declaration element as argument");
518:                Element[] elems = getSchemaChildren(complexType);
519:                if (elems.length == 1
520:                        && elems[0].getLocalName().equals("sequence")) {
521:                    elems = getSchemaChildren(elems[0]);
522:                    if (elems.length == 1
523:                            && elems[0].getLocalName().equals("element")) {
524:                        if (isElementArray(elems[0])) {
525:                            return getArrayInfoFromElement(elems[0]);
526:                        }
527:                    }
528:                }
529:                throw new IllegalArgumentException(
530:                        "Expected complex type declaration representing an array");
531:            }
532:
533:            /**
534:             * Extract array information from element
535:             */
536:            private ArrayInfo getArrayInfoFromElement(Element element)
537:                    throws Wsdl2JsException {
538:                if (!(element.getNamespaceURI().equals(XMLNS_SCHEMA) && element
539:                        .getLocalName().equals("element")))
540:                    throw new IllegalArgumentException(
541:                            "Expected element declaration as argument");
542:                if (!isElementArray(element))
543:                    throw new IllegalArgumentException(
544:                            "Expected element declaration representing an array");
545:                String compType = element.getAttribute("type");
546:                Matcher mat = PREFIXPATTERN.matcher(compType);
547:                if (!mat.matches())
548:                    throw new Wsdl2JsException(
549:                            "Expected prefixed element array component type: "
550:                                    + compType);
551:                String compPrefix = mat.group(1);
552:                String compLocalName = mat.group(2);
553:                String compNSUri = DOMUtils.getNamespaceURIFromPrefix(element,
554:                        compPrefix);
555:                QName compQName = new QName(compNSUri, compLocalName);
556:                Element complexType = (Element) schemaComplexTypes
557:                        .get(compQName);
558:                if (complexType != null) {
559:                    if (isComplexTypeArray(complexType)) {
560:                        ArrayInfo compInfo = getArrayInfoFromComplexType(complexType);
561:                        ArrayInfo info = new ArrayInfo(compInfo.arrayType,
562:                                compInfo.arrayDim + 1);
563:                        return info;
564:                    } else
565:                        return new ArrayInfo(compQName, 1);
566:                } else
567:                    return new ArrayInfo(compQName, 1);
568:            }
569:
570:            /**
571:             * Create type description JS code for a bean using its complexType definition
572:             */
573:            private String getMemberInfos(Element complexType)
574:                    throws Wsdl2JsException {
575:                if (!(complexType.getNamespaceURI().equals(XMLNS_SCHEMA) && complexType
576:                        .getLocalName().equals("complexType")))
577:                    throw new IllegalArgumentException(
578:                            "Expected complex type declaration element as argument: "
579:                                    + getXMLString(complexType));
580:                Element modelElem = getFirstSchemaChild(complexType);
581:                if (modelElem != null) {
582:                    if (modelElem.getLocalName().equals("sequence")) {
583:                        return getSequenceMemberInfos(modelElem);
584:                    } else if (modelElem.getLocalName()
585:                            .equals("complexContent")) {
586:                        Element extElem = getFirstSchemaChild(modelElem);
587:                        if (extElem != null
588:                                && extElem.getLocalName().equals("extension")) {
589:                            String base = extElem.getAttribute("base");
590:                            QName qname = getQName(base, extElem);
591:                            Element baseElem = (Element) schemaComplexTypes
592:                                    .get(qname);
593:                            String baseInfos = getMemberInfos(baseElem);
594:                            Element seqElem = getFirstSchemaChild(extElem);
595:                            if (seqElem != null
596:                                    && seqElem.getLocalName()
597:                                            .equals("sequence")) {
598:                                String infos = getSequenceMemberInfos(seqElem);
599:                                if (infos.length() > 0
600:                                        && baseInfos.length() > 0) {
601:                                    infos = infos + "," + baseInfos;
602:                                } else {
603:                                    infos = infos + baseInfos;
604:                                }
605:                                return infos;
606:                            } else
607:                                throw new Wsdl2JsException(
608:                                        "Illegal 'extension' content: "
609:                                                + complexType
610:                                                        .getAttribute("name"));
611:                        } else
612:                            throw new Wsdl2JsException(
613:                                    "Illegal 'complexContent': "
614:                                            + complexType.getAttribute("name"));
615:                    } else
616:                        throw new Wsdl2JsException("Illegal content model: "
617:                                + complexType.getAttribute("name"));
618:                } else
619:                    throw new Wsdl2JsException(
620:                            "XML Schema child expected below complex type: "
621:                                    + getXMLString(complexType));
622:            }
623:
624:            /**
625:             * Create type description JS code for a bean using its sequence definition
626:             */
627:            private String getSequenceMemberInfos(Element sequence)
628:                    throws Wsdl2JsException {
629:                if (!(sequence.getNamespaceURI().equals(XMLNS_SCHEMA) && sequence
630:                        .getLocalName().equals("sequence")))
631:                    throw new IllegalArgumentException(
632:                            "Expected sequence declaration element as argument");
633:                String memberList = "";
634:                Element[] elems = getSchemaChildren(sequence);
635:                for (int i = 0; i < elems.length; i++) {
636:                    Element elem = elems[i];
637:                    if (elem.getLocalName().equals("element")) {
638:                        String name = elem.getAttribute("name");
639:                        String typeInfo = createTypeInfo(elem);
640:                        memberList += "\"" + name + "\"," + typeInfo;
641:                        if (i < elems.length - 1)
642:                            memberList += ",";
643:                    }
644:                }
645:                return memberList;
646:            }
647:
648:            /**
649:             * Create a QName object from a prefixed value (the passed element is used for namespace resolution)
650:             */
651:            private QName getQName(String value, Element element)
652:                    throws Wsdl2JsException {
653:                Matcher matcher = PREFIXPATTERN.matcher(value);
654:                if (!matcher.matches())
655:                    throw new Wsdl2JsException("Value isn't prefixed: " + value);
656:                String prefix = matcher.group(1);
657:                String localName = matcher.group(2);
658:                String nsuri = DOMUtils.getNamespaceURIFromPrefix(element,
659:                        prefix);
660:                return new QName(nsuri, localName);
661:            }
662:
663:            /**
664:             * Return the first schema child element
665:             */
666:            private Element getFirstSchemaChild(Element parent) {
667:                NodeList nl = parent.getChildNodes();
668:                for (int i = 0; i < nl.getLength(); i++) {
669:                    Node n = nl.item(i);
670:                    if (n.getNodeType() == Node.ELEMENT_NODE
671:                            && n.getNamespaceURI().equals(Constants.XMLNS_XSD)) {
672:                        return (Element) n;
673:                    }
674:                }
675:                return null;
676:            }
677:
678:            /**
679:             * Return an array of all schema child elements
680:             */
681:            private Element[] getSchemaChildren(Element parent) {
682:                List<Element> al = new ArrayList<Element>();
683:                NodeList nl = parent.getChildNodes();
684:                for (int i = 0; i < nl.getLength(); i++) {
685:                    Node n = nl.item(i);
686:                    if (n.getNodeType() == Node.ELEMENT_NODE
687:                            && n.getNamespaceURI().equals(Constants.XMLNS_XSD)) {
688:                        al.add((Element) n);
689:                    }
690:                }
691:                Element[] elems = new Element[al.size()];
692:                al.toArray(elems);
693:                return elems;
694:            }
695:
696:            /**
697:             * Create string representation of the XML element
698:             */
699:            private String getXMLString(Element element) {
700:                StringBuilder sb = new StringBuilder();
701:                getXMLString(element, sb);
702:                return sb.toString();
703:            }
704:
705:            /**
706:             * Create string representation of the XML element by walking down the DOM tree
707:             */
708:            private void getXMLString(Element element, StringBuilder sb) {
709:                sb.append("<");
710:                sb.append(element.getLocalName());
711:                NamedNodeMap attrs = element.getAttributes();
712:                for (int i = 0; i < attrs.getLength(); i++) {
713:                    Node node = attrs.item(i);
714:                    sb.append(" ");
715:                    sb.append(node.getNodeName());
716:                    sb.append("=\"");
717:                    sb.append(node.getNodeValue());
718:                    sb.append("\"");
719:                }
720:                if (element.hasChildNodes()) {
721:                    sb.append(">");
722:                    NodeList nodes = element.getChildNodes();
723:                    for (int i = 0; i < nodes.getLength(); i++) {
724:                        if (nodes.item(i).getNodeType() == Node.ELEMENT_NODE) {
725:                            Element child = (Element) nodes.item(i);
726:                            getXMLString(child, sb);
727:                        }
728:                    }
729:                    sb.append("</");
730:                    sb.append(element.getLocalName());
731:                    sb.append(">");
732:                } else {
733:                    sb.append("/>");
734:                }
735:            }
736:
737:            /**
738:             * Helper class for storing information while traversing array schema definitions
739:             */
740:            class ArrayInfo {
741:
742:                QName arrayType;
743:                int arrayDim;
744:
745:                ArrayInfo(QName arrayType, int arrayDim) {
746:                    this.arrayType = arrayType;
747:                    this.arrayDim = arrayDim;
748:                }
749:
750:            }
751:
752:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.