~ubuntu-branches/ubuntu/precise/kompozer/precise

« back to all changes in this revision

Viewing changes to mozilla/extensions/webservices/wsdl/src/nsWSDLLoader.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Yarusso
  • Date: 2007-08-27 01:11:03 UTC
  • Revision ID: james.westby@ubuntu.com-20070827011103-2jgf4s6532gqu2ka
Tags: upstream-0.7.10
ImportĀ upstreamĀ versionĀ 0.7.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 
2
/*
 
3
 * The contents of this file are subject to the Mozilla Public
 
4
 * License Version 1.1 (the "License"); you may not use this file
 
5
 * except in compliance with the License. You may obtain a copy of
 
6
 * the License at http://www.mozilla.org/MPL/
 
7
 *
 
8
 * Software distributed under the License is distributed on an "AS
 
9
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 
10
 * implied. See the License for the specific language governing
 
11
 * rights and limitations under the License.
 
12
 *
 
13
 * The Original Code is Mozilla.
 
14
 *
 
15
 * The Initial Developer of the Original Code is Netscape
 
16
 * Communications.  Portions created by Netscape Communications are
 
17
 * Copyright (C) 2001 by Netscape Communications.  All
 
18
 * Rights Reserved.
 
19
 *
 
20
 * Contributor(s):
 
21
 *   Vidur Apparao <vidur@netscape.com> (original author)
 
22
 */
 
23
 
 
24
#include "nsWSDLLoader.h"
 
25
 
 
26
// loading includes
 
27
#include "nsIDOMEvent.h"
 
28
#include "nsIDOMEventTarget.h"
 
29
#include "nsNetUtil.h"
 
30
 
 
31
// content includes
 
32
#include "nsIContent.h"
 
33
#include "nsINodeInfo.h"
 
34
#include "nsIDOMDocument.h"
 
35
#include "nsIDOM3Node.h"
 
36
 
 
37
// string includes
 
38
#include "nsReadableUtils.h"
 
39
 
 
40
// XPConnect includes
 
41
#include "nsIXPConnect.h"
 
42
#include "nsIScriptSecurityManager.h"
 
43
#include "nsIPrincipal.h"
 
44
 
 
45
// XPCOM includes
 
46
#include "nsIServiceManager.h"
 
47
#include "nsIComponentManager.h"
 
48
 
 
49
// XMLExtras includes
 
50
#include "nsISOAPMessage.h"
 
51
 
 
52
// pref. includes
 
53
#include "nsIPrefService.h"
 
54
 
 
55
#define SCHEMA_2001_NAMESPACE "http://www.w3.org/2001/XMLSchema"
 
56
#define SCHEMA_1999_NAMESPACE "http://www.w3.org/1999/XMLSchema"
 
57
 
 
58
////////////////////////////////////////////////////////////
 
59
//
 
60
// nsWSDLAtoms implementation
 
61
//
 
62
////////////////////////////////////////////////////////////
 
63
 
 
64
// Statics
 
65
nsIAtom* nsWSDLAtoms::sDefinitions_atom = nsnull;
 
66
nsIAtom* nsWSDLAtoms::sImport_atom = nsnull;
 
67
nsIAtom* nsWSDLAtoms::sTypes_atom = nsnull;
 
68
nsIAtom* nsWSDLAtoms::sMessage_atom = nsnull;
 
69
nsIAtom* nsWSDLAtoms::sPortType_atom = nsnull;
 
70
nsIAtom* nsWSDLAtoms::sBinding_atom = nsnull;
 
71
nsIAtom* nsWSDLAtoms::sService_atom = nsnull;
 
72
nsIAtom* nsWSDLAtoms::sPort_atom = nsnull;
 
73
nsIAtom* nsWSDLAtoms::sOperation_atom = nsnull;
 
74
nsIAtom* nsWSDLAtoms::sPart_atom = nsnull;
 
75
nsIAtom* nsWSDLAtoms::sDocumentation_atom = nsnull;
 
76
nsIAtom* nsWSDLAtoms::sInput_atom = nsnull;
 
77
nsIAtom* nsWSDLAtoms::sOutput_atom = nsnull;
 
78
nsIAtom* nsWSDLAtoms::sFault_atom = nsnull;
 
79
 
 
80
nsIAtom* nsWSDLAtoms::sBody_atom = nsnull;
 
81
nsIAtom* nsWSDLAtoms::sHeader_atom = nsnull;
 
82
nsIAtom* nsWSDLAtoms::sHeaderFault_atom = nsnull;
 
83
nsIAtom* nsWSDLAtoms::sAddress_atom = nsnull;
 
84
 
 
85
nsIAtom* nsWSDLAtoms::sSchema_atom = nsnull;
 
86
 
 
87
#define SET_AND_CHECK_ATOM(_atom, _val)   \
 
88
  PR_BEGIN_MACRO                          \
 
89
    _atom = NS_NewAtom(_val);             \
 
90
    if (!_atom)                           \
 
91
      return NS_ERROR_OUT_OF_MEMORY;      \
 
92
  PR_END_MACRO
 
93
 
 
94
nsresult
 
95
nsWSDLAtoms::CreateWSDLAtoms()
 
96
{
 
97
  NS_ASSERTION(!sDefinitions_atom, "nsWSDLAtoms already created!");
 
98
 
 
99
  SET_AND_CHECK_ATOM(sDefinitions_atom,   "definitions");
 
100
  SET_AND_CHECK_ATOM(sImport_atom,        "import");
 
101
  SET_AND_CHECK_ATOM(sTypes_atom,         "types");
 
102
  SET_AND_CHECK_ATOM(sMessage_atom,       "message");
 
103
  SET_AND_CHECK_ATOM(sPortType_atom,      "portType");
 
104
  SET_AND_CHECK_ATOM(sBinding_atom,       "binding");
 
105
  SET_AND_CHECK_ATOM(sService_atom,       "service");
 
106
  SET_AND_CHECK_ATOM(sPort_atom,          "port");
 
107
  SET_AND_CHECK_ATOM(sOperation_atom,     "operation");
 
108
  SET_AND_CHECK_ATOM(sPart_atom,          "part");
 
109
  SET_AND_CHECK_ATOM(sDocumentation_atom, "documentation");
 
110
  SET_AND_CHECK_ATOM(sInput_atom,         "input");
 
111
  SET_AND_CHECK_ATOM(sOutput_atom,        "output");
 
112
  SET_AND_CHECK_ATOM(sFault_atom,         "fault");
 
113
 
 
114
  SET_AND_CHECK_ATOM(sBody_atom,          "body");
 
115
  SET_AND_CHECK_ATOM(sHeader_atom,        "header");
 
116
  SET_AND_CHECK_ATOM(sHeaderFault_atom,   "headerFault");
 
117
  SET_AND_CHECK_ATOM(sAddress_atom,       "address");
 
118
 
 
119
  SET_AND_CHECK_ATOM(sSchema_atom,        "schema");
 
120
 
 
121
  return NS_OK;
 
122
}
 
123
 
 
124
void
 
125
nsWSDLAtoms::DestroyWSDLAtoms()
 
126
{
 
127
  NS_IF_RELEASE(sDefinitions_atom);
 
128
  NS_IF_RELEASE(sImport_atom);
 
129
  NS_IF_RELEASE(sTypes_atom);
 
130
  NS_IF_RELEASE(sMessage_atom);
 
131
  NS_IF_RELEASE(sPortType_atom);
 
132
  NS_IF_RELEASE(sBinding_atom);
 
133
  NS_IF_RELEASE(sService_atom);
 
134
  NS_IF_RELEASE(sPort_atom);
 
135
  NS_IF_RELEASE(sOperation_atom);
 
136
  NS_IF_RELEASE(sPart_atom);
 
137
  NS_IF_RELEASE(sDocumentation_atom);
 
138
  NS_IF_RELEASE(sInput_atom);
 
139
  NS_IF_RELEASE(sOutput_atom);
 
140
  NS_IF_RELEASE(sFault_atom);
 
141
 
 
142
  NS_IF_RELEASE(sBody_atom);
 
143
  NS_IF_RELEASE(sHeader_atom);
 
144
  NS_IF_RELEASE(sHeaderFault_atom);
 
145
  NS_IF_RELEASE(sAddress_atom);
 
146
 
 
147
  NS_IF_RELEASE(sSchema_atom);
 
148
}
 
149
 
 
150
////////////////////////////////////////////////////////////
 
151
//
 
152
// nsWSDLLoader implementation
 
153
//
 
154
////////////////////////////////////////////////////////////
 
155
 
 
156
nsWSDLLoader::nsWSDLLoader()
 
157
{
 
158
}
 
159
 
 
160
nsWSDLLoader::~nsWSDLLoader()
 
161
{
 
162
}
 
163
 
 
164
NS_IMPL_ISUPPORTS1_CI(nsWSDLLoader, nsIWSDLLoader)
 
165
 
 
166
nsresult
 
167
nsWSDLLoader::Init()
 
168
{
 
169
  PRBool disabled = PR_FALSE;
 
170
  nsCOMPtr<nsIPrefBranch> prefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID));
 
171
  if (prefBranch) {
 
172
    if (NS_FAILED(prefBranch->GetBoolPref("xml.xmlextras.soap.wsdl.disabled",
 
173
                                          &disabled))) {
 
174
      // We default to enabling WSDL, it'll only be disabled if
 
175
      // specificly disabled in the prefs.
 
176
      disabled = PR_FALSE;
 
177
    }
 
178
  }
 
179
 
 
180
  if (disabled) {
 
181
    return NS_ERROR_WSDL_NOT_ENABLED;
 
182
  }
 
183
 
 
184
  if (!nsWSDLAtoms::sDefinitions_atom) {
 
185
    nsresult rv = nsWSDLAtoms::CreateWSDLAtoms();
 
186
 
 
187
    if (NS_FAILED(rv)) {
 
188
      return rv;
 
189
    }
 
190
  }
 
191
 
 
192
  return NS_OK;
 
193
}
 
194
nsresult
 
195
nsWSDLLoader::GetResolvedURI(const nsAString& aWSDLURI, const char* aMethod,
 
196
                             nsIURI** aURI)
 
197
{
 
198
  nsresult rv;
 
199
  nsCOMPtr<nsIXPCNativeCallContext> cc;
 
200
  nsCOMPtr<nsIXPConnect> xpc(do_GetService(nsIXPConnect::GetCID()));
 
201
  if(xpc) {
 
202
    xpc->GetCurrentNativeCallContext(getter_AddRefs(cc));
 
203
  }
 
204
 
 
205
  if (cc) {
 
206
    JSContext* cx;
 
207
    rv = cc->GetJSContext(&cx);
 
208
    if (NS_FAILED(rv))
 
209
      return rv;
 
210
 
 
211
    nsCOMPtr<nsIScriptSecurityManager> secMan =
 
212
      do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
 
213
    if (NS_FAILED(rv))
 
214
      return rv;
 
215
 
 
216
    nsCOMPtr<nsIURI> baseURI;
 
217
    nsCOMPtr<nsIPrincipal> principal;
 
218
    rv = secMan->GetSubjectPrincipal(getter_AddRefs(principal));
 
219
    if (NS_SUCCEEDED(rv)) {
 
220
      principal->GetURI(getter_AddRefs(baseURI));
 
221
    }
 
222
 
 
223
    rv = NS_NewURI(aURI, aWSDLURI, nsnull, baseURI);
 
224
    if (NS_FAILED(rv))
 
225
      return rv;
 
226
 
 
227
    rv = secMan->CheckLoadURIFromScript(cx, *aURI);
 
228
    if (NS_FAILED(rv)) {
 
229
      // Security check failed. The above call set a JS exception. The
 
230
      // following lines ensure that the exception is propagated.
 
231
      cc->SetExceptionWasThrown(PR_TRUE);
 
232
      return rv;
 
233
    }
 
234
  }
 
235
  else {
 
236
    rv = NS_NewURI(aURI, aWSDLURI, nsnull);
 
237
    if (NS_FAILED(rv))
 
238
      return rv;
 
239
  }
 
240
 
 
241
  return NS_OK;
 
242
}
 
243
 
 
244
// Internal helper called by Load() and Loadasync(). If aListener is
 
245
// non-null, it's an async load, if it's null, it's sync.
 
246
nsresult
 
247
nsWSDLLoader::doLoad(const nsAString& wsdlURI, const nsAString& portName,
 
248
                     nsIWSDLLoadListener *aListener, nsIWSDLPort **_retval)
 
249
{
 
250
  nsCOMPtr<nsIURI> resolvedURI;
 
251
  nsresult rv = GetResolvedURI(wsdlURI, aListener ? "loadAsync" : "load",
 
252
                               getter_AddRefs(resolvedURI));
 
253
  if (NS_FAILED(rv)) {
 
254
    return rv;
 
255
  }
 
256
 
 
257
  nsCOMPtr<nsIDOMEventListener> listener;
 
258
  nsWSDLLoadRequest* request = new nsWSDLLoadRequest(!aListener, aListener,
 
259
                                                     portName);
 
260
  if (!request) {
 
261
    return NS_ERROR_OUT_OF_MEMORY;
 
262
  }
 
263
  listener = request;
 
264
 
 
265
  nsCAutoString spec;
 
266
  resolvedURI->GetSpec(spec);
 
267
 
 
268
  rv = request->LoadDefinition(NS_ConvertUTF8toUCS2(spec));
 
269
 
 
270
  if (NS_SUCCEEDED(rv) && !aListener) {
 
271
    request->GetPort(_retval);
 
272
  }
 
273
 
 
274
  return rv;
 
275
}
 
276
 
 
277
/* nsIWSDLService load (in AString wsdlURI, in AString portName); */
 
278
NS_IMETHODIMP
 
279
nsWSDLLoader::Load(const nsAString& wsdlURI, const nsAString& portName,
 
280
                   nsIWSDLPort **_retval)
 
281
{
 
282
  NS_ENSURE_ARG_POINTER(_retval);
 
283
  *_retval = nsnull;
 
284
 
 
285
  return doLoad(wsdlURI, portName, nsnull, _retval);
 
286
}
 
287
 
 
288
/* void loadAsync (in AString wsdlURI, in AString portName,
 
289
   in nsIWSDLLoadListener listener); */
 
290
NS_IMETHODIMP
 
291
nsWSDLLoader::LoadAsync(const nsAString& wsdlURI, const nsAString& portName,
 
292
                        nsIWSDLLoadListener *aListener)
 
293
{
 
294
  NS_ENSURE_ARG(aListener);
 
295
 
 
296
  return doLoad(wsdlURI, portName, aListener, nsnull);
 
297
}
 
298
 
 
299
////////////////////////////////////////////////////////////
 
300
//
 
301
// nsWSDLLoadRequest implementation
 
302
//
 
303
////////////////////////////////////////////////////////////
 
304
nsWSDLLoadRequest::nsWSDLLoadRequest(PRBool aIsSync,
 
305
                                     nsIWSDLLoadListener* aListener,
 
306
                                     const nsAString& aPortName)
 
307
  : mListener(aListener), mIsSync(aIsSync), mPortName(aPortName)
 
308
{
 
309
}
 
310
 
 
311
nsWSDLLoadRequest::~nsWSDLLoadRequest()
 
312
{
 
313
  while (GetCurrentContext() != nsnull) {
 
314
    PopContext();
 
315
  }
 
316
}
 
317
 
 
318
NS_IMPL_ISUPPORTS1(nsWSDLLoadRequest, nsIDOMEventListener)
 
319
 
 
320
static inline PRBool
 
321
IsElementOfNamespace(nsIDOMElement* aElement, const nsAString& aNamespace)
 
322
{
 
323
        nsAutoString namespaceURI;
 
324
        aElement->GetNamespaceURI(namespaceURI);
 
325
        return namespaceURI.Equals(aNamespace);
 
326
}
 
327
 
 
328
nsresult
 
329
nsWSDLLoadRequest::LoadDefinition(const nsAString& aURI)
 
330
{
 
331
  nsresult rv;
 
332
 
 
333
  if (!mSchemaLoader) {
 
334
    mSchemaLoader = do_GetService(NS_SCHEMALOADER_CONTRACTID, &rv);
 
335
    if (NS_FAILED(rv)) {
 
336
      return rv;
 
337
    }
 
338
  }
 
339
 
 
340
  mRequest = do_CreateInstance(NS_XMLHTTPREQUEST_CONTRACTID, &rv);
 
341
  if (!mRequest) {
 
342
    return rv;
 
343
  }
 
344
 
 
345
  const nsAString& empty = EmptyString();
 
346
  rv = mRequest->OpenRequest(NS_LITERAL_CSTRING("GET"),
 
347
                             NS_ConvertUTF16toUTF8(aURI), !mIsSync, empty,
 
348
                             empty);
 
349
  if (NS_FAILED(rv)) {
 
350
    return rv;
 
351
  }
 
352
 
 
353
  // Force the mimetype of the returned stream to be xml.
 
354
  rv = mRequest->OverrideMimeType(NS_LITERAL_CSTRING("text/xml"));
 
355
  if (NS_FAILED(rv)) {
 
356
    return rv;
 
357
  }
 
358
 
 
359
  if (!mIsSync) {
 
360
    nsCOMPtr<nsIDOMEventTarget> target(do_QueryInterface(mRequest));
 
361
    if (!target) {
 
362
      return NS_ERROR_UNEXPECTED;
 
363
    }
 
364
 
 
365
    rv = target->AddEventListener(NS_LITERAL_STRING("load"), this, PR_FALSE);
 
366
    if (NS_FAILED(rv)) {
 
367
      return rv;
 
368
    }
 
369
 
 
370
    rv = target->AddEventListener(NS_LITERAL_STRING("error"), this, PR_FALSE);
 
371
    if (NS_FAILED(rv)) {
 
372
      return rv;
 
373
    }
 
374
  }
 
375
 
 
376
  rv = mRequest->Send(nsnull);
 
377
  if (NS_FAILED(rv)) {
 
378
    return rv;
 
379
  }
 
380
 
 
381
  if (mIsSync) {
 
382
    nsCOMPtr<nsIDOMDocument> document;
 
383
    rv = mRequest->GetResponseXML(getter_AddRefs(document));
 
384
    if (NS_FAILED(rv)) {
 
385
      return rv;
 
386
    }
 
387
 
 
388
    nsCOMPtr<nsIDOMElement> element;
 
389
    if (document)
 
390
      document->GetDocumentElement(getter_AddRefs(element));
 
391
    if (element) {
 
392
      if (IsElementOfNamespace(element,
 
393
                               NS_LITERAL_STRING(NS_WSDL_NAMESPACE))) {
 
394
        rv = PushContext(document, aURI);
 
395
        if (NS_FAILED(rv)) {
 
396
          return rv;
 
397
        }
 
398
 
 
399
        rv = ResumeProcessing();
 
400
 
 
401
        PopContext();
 
402
 
 
403
        if (NS_FAILED(rv)) {
 
404
          return rv;
 
405
        }
 
406
      }
 
407
      else if (IsElementOfNamespace(element,
 
408
                             NS_LITERAL_STRING(SCHEMA_2001_NAMESPACE)) ||
 
409
               IsElementOfNamespace(element,
 
410
                             NS_LITERAL_STRING(SCHEMA_1999_NAMESPACE))) {
 
411
        nsCOMPtr<nsISchema> schema;
 
412
        rv = mSchemaLoader->ProcessSchemaElement(element,
 
413
                                                 getter_AddRefs(schema));
 
414
        if (NS_FAILED(rv)) {
 
415
          return NS_ERROR_WSDL_SCHEMA_PROCESSING_ERROR;
 
416
        }
 
417
 
 
418
        nsAutoString targetNamespace;
 
419
        schema->GetTargetNamespace(targetNamespace);
 
420
 
 
421
        nsStringKey key(targetNamespace);
 
422
        mTypes.Put(&key, schema);
 
423
      }
 
424
      else {
 
425
        rv = NS_ERROR_WSDL_NOT_WSDL_ELEMENT; // element of unknown namespace
 
426
      }
 
427
    }
 
428
    else {
 
429
      return NS_ERROR_WSDL_NOT_WSDL_ELEMENT;
 
430
    }
 
431
  }
 
432
 
 
433
  return NS_OK;
 
434
}
 
435
 
 
436
nsresult
 
437
nsWSDLLoadRequest::ContineProcessingTillDone()
 
438
{
 
439
  nsresult rv;
 
440
  do {
 
441
    rv = ResumeProcessing();
 
442
 
 
443
    if (NS_FAILED(rv) || (rv == NS_ERROR_WSDL_LOADPENDING)) {
 
444
      break;
 
445
    }
 
446
 
 
447
    PopContext();
 
448
  } while (GetCurrentContext() != nsnull);
 
449
 
 
450
  return rv;
 
451
}
 
452
 
 
453
/* void handleEvent (in nsIDOMEvent event); */
 
454
NS_IMETHODIMP
 
455
nsWSDLLoadRequest::HandleEvent(nsIDOMEvent *event)
 
456
{
 
457
  nsresult rv;
 
458
  nsAutoString eventType;
 
459
 
 
460
  event->GetType(eventType);
 
461
 
 
462
  if (eventType.Equals(NS_LITERAL_STRING("load"))) {
 
463
    nsCOMPtr<nsIDOMDocument> document;
 
464
 
 
465
    rv = mRequest->GetResponseXML(getter_AddRefs(document));
 
466
    if (document) {
 
467
      nsCOMPtr<nsIDOMElement> element;
 
468
 
 
469
      document->GetDocumentElement(getter_AddRefs(element));
 
470
      if (element) {
 
471
        if (IsElementOfNamespace(element,
 
472
                                 NS_LITERAL_STRING(NS_WSDL_NAMESPACE))) {
 
473
          nsCOMPtr<nsIChannel> channel;
 
474
          nsCOMPtr<nsIURI> uri;
 
475
          nsCAutoString spec;
 
476
 
 
477
          mRequest->GetChannel(getter_AddRefs(channel));
 
478
 
 
479
          if (channel) {
 
480
            channel->GetURI(getter_AddRefs(uri));
 
481
            if (uri) {
 
482
              uri->GetSpec(spec);
 
483
            }
 
484
          }
 
485
 
 
486
          rv = PushContext(document, NS_ConvertUTF8toUCS2(spec));
 
487
 
 
488
          if (NS_SUCCEEDED(rv)) {
 
489
            rv = ContineProcessingTillDone();
 
490
          }
 
491
        }
 
492
        else if (IsElementOfNamespace(element,
 
493
                                NS_LITERAL_STRING(SCHEMA_2001_NAMESPACE)) ||
 
494
                 IsElementOfNamespace(element,
 
495
                                NS_LITERAL_STRING(SCHEMA_1999_NAMESPACE))) {
 
496
          nsCOMPtr<nsISchema> schema;
 
497
          rv = mSchemaLoader->ProcessSchemaElement(element,
 
498
                                                   getter_AddRefs(schema));
 
499
          if (NS_FAILED(rv)) {
 
500
            return NS_ERROR_WSDL_SCHEMA_PROCESSING_ERROR;
 
501
          }
 
502
 
 
503
          nsAutoString targetNamespace;
 
504
          schema->GetTargetNamespace(targetNamespace);
 
505
 
 
506
          nsStringKey key(targetNamespace);
 
507
          mTypes.Put(&key, schema);
 
508
 
 
509
          rv = ContineProcessingTillDone();
 
510
        }
 
511
        else {
 
512
          rv = NS_ERROR_WSDL_NOT_WSDL_ELEMENT; // element of unknown namespace
 
513
        }
 
514
      }
 
515
      else {
 
516
        rv = NS_ERROR_WSDL_NOT_WSDL_ELEMENT;
 
517
      }
 
518
    }
 
519
 
 
520
    if (NS_FAILED(rv)) {
 
521
      mListener->OnError(rv, NS_LITERAL_STRING("Failure processing WSDL document"));
 
522
      return NS_OK;
 
523
    }
 
524
  }
 
525
  else if (eventType.Equals(NS_LITERAL_STRING("error"))) {
 
526
    mListener->OnError(NS_ERROR_WSDL_LOADING_ERROR,
 
527
                       NS_LITERAL_STRING("Failure loading"));
 
528
    return NS_OK;
 
529
  }
 
530
 
 
531
  if (GetCurrentContext() == nsnull) {
 
532
    if (mPort) {
 
533
      mListener->OnLoad(mPort);
 
534
    }
 
535
    else {
 
536
      mListener->OnError(NS_ERROR_WSDL_BINDING_NOT_FOUND,
 
537
                         NS_LITERAL_STRING("Binding not found"));
 
538
    }
 
539
    mRequest = nsnull;
 
540
  }
 
541
 
 
542
  return NS_OK;
 
543
}
 
544
 
 
545
nsresult
 
546
nsWSDLLoadRequest::ResumeProcessing()
 
547
{
 
548
  nsresult rv = NS_OK;
 
549
 
 
550
  nsWSDLLoadingContext* context = GetCurrentContext();
 
551
  if (!context) {
 
552
    return NS_ERROR_UNEXPECTED;
 
553
  }
 
554
 
 
555
  nsCOMPtr<nsIDOMElement> element;
 
556
  context->GetRootElement(getter_AddRefs(element));
 
557
  PRUint32 childIndex = context->GetChildIndex();
 
558
 
 
559
  nsChildElementIterator iterator(element,
 
560
                                  NS_LITERAL_STRING(NS_WSDL_NAMESPACE));
 
561
  nsCOMPtr<nsIDOMElement> childElement;
 
562
  nsCOMPtr<nsIAtom> tagName;
 
563
 
 
564
  // If we don't yet have a port, find the service element, create one
 
565
  // and record the port's its binding name
 
566
  if (mBindingName.IsEmpty()) {
 
567
    // The service element tends to be at the end of WSDL files, so
 
568
    // this would be more efficient if we iterated from last to first
 
569
    // child...
 
570
    while (NS_SUCCEEDED(iterator.GetNextChild(getter_AddRefs(childElement),
 
571
                                              getter_AddRefs(tagName))) &&
 
572
           childElement) {
 
573
      if (tagName == nsWSDLAtoms::sService_atom) {
 
574
        rv = ProcessServiceElement(childElement);
 
575
        if (NS_FAILED(rv)) {
 
576
          return rv;
 
577
        }
 
578
      }
 
579
    }
 
580
  }
 
581
 
 
582
  iterator.Reset(childIndex);
 
583
  while (NS_SUCCEEDED(iterator.GetNextChild(getter_AddRefs(childElement),
 
584
                                            getter_AddRefs(tagName))) &&
 
585
         childElement) {
 
586
    if (tagName == nsWSDLAtoms::sImport_atom) {
 
587
      rv = ProcessImportElement(childElement,
 
588
                                iterator.GetCurrentIndex()+1);
 
589
      if (NS_FAILED(rv) ||
 
590
          (rv == NS_ERROR_WSDL_LOADPENDING)) {
 
591
        return rv;
 
592
      }
 
593
    }
 
594
    else if (tagName == nsWSDLAtoms::sTypes_atom) {
 
595
      rv = ProcessTypesElement(childElement);
 
596
      if (NS_FAILED(rv)) {
 
597
        return rv;
 
598
      }
 
599
    }
 
600
    else if (tagName == nsWSDLAtoms::sMessage_atom) {
 
601
      rv = ProcessMessageElement(childElement);
 
602
      if (NS_FAILED(rv)) {
 
603
        return rv;
 
604
      }
 
605
    }
 
606
    else if (tagName == nsWSDLAtoms::sPortType_atom) {
 
607
      rv = ProcessPortTypeElement(childElement);
 
608
      if (NS_FAILED(rv)) {
 
609
        return rv;
 
610
      }
 
611
    }
 
612
    else if (tagName == nsWSDLAtoms::sBinding_atom) {
 
613
      nsAutoString name, targetNamespace;
 
614
      childElement->GetAttribute(NS_LITERAL_STRING("name"), name);
 
615
      context->GetTargetNamespace(targetNamespace);
 
616
 
 
617
      // Only process binding for the requested port
 
618
      // XXX We should be checking the binding namespace as
 
619
      // well, but some authors are not qualifying their
 
620
      // binding names
 
621
      if (mBindingName.Equals(name)) {
 
622
        rv = ProcessBindingElement(childElement);
 
623
        if (NS_FAILED(rv)) {
 
624
          return rv;
 
625
        }
 
626
      }
 
627
    }
 
628
  }
 
629
 
 
630
  return rv;
 
631
}
 
632
 
 
633
nsresult
 
634
nsWSDLLoadRequest::GetPort(nsIWSDLPort** aPort)
 
635
{
 
636
  *aPort = mPort;
 
637
  NS_IF_ADDREF(*aPort);
 
638
 
 
639
  return NS_OK;
 
640
}
 
641
 
 
642
nsresult
 
643
nsWSDLLoadRequest::PushContext(nsIDOMDocument* aDocument,
 
644
                               const nsAString& aURISpec)
 
645
{
 
646
  nsWSDLLoadingContext* context = new nsWSDLLoadingContext(aDocument,
 
647
                                                           aURISpec);
 
648
  if (!context) {
 
649
    return NS_ERROR_OUT_OF_MEMORY;
 
650
  }
 
651
 
 
652
  mContextStack.AppendElement((void*)context);
 
653
 
 
654
  return NS_OK;
 
655
}
 
656
 
 
657
nsWSDLLoadingContext*
 
658
nsWSDLLoadRequest::GetCurrentContext()
 
659
{
 
660
  PRUint32 count = mContextStack.Count();
 
661
  if (count > 0) {
 
662
    return NS_STATIC_CAST(nsWSDLLoadingContext*,
 
663
                          mContextStack.ElementAt(count-1));
 
664
  }
 
665
 
 
666
  return nsnull;
 
667
}
 
668
 
 
669
void
 
670
nsWSDLLoadRequest::PopContext()
 
671
{
 
672
  PRUint32 count = mContextStack.Count();
 
673
  if (count > 0) {
 
674
    nsWSDLLoadingContext* context =
 
675
      NS_STATIC_CAST(nsWSDLLoadingContext*, mContextStack.ElementAt(count-1));
 
676
    delete context;
 
677
    mContextStack.RemoveElementAt(count-1);
 
678
  }
 
679
}
 
680
 
 
681
nsresult
 
682
nsWSDLLoadRequest::GetSchemaElement(const nsAString& aName,
 
683
                                    const nsAString& aNamespace,
 
684
                                    nsISchemaElement** aSchemaComponent)
 
685
{
 
686
  nsStringKey key(aNamespace);
 
687
  nsCOMPtr<nsISupports> sup = dont_AddRef(mTypes.Get(&key));
 
688
  nsCOMPtr<nsISchema> schema(do_QueryInterface(sup));
 
689
  if (!schema) {
 
690
    return NS_ERROR_WSDL_UNKNOWN_SCHEMA_COMPONENT;
 
691
  }
 
692
 
 
693
  nsCOMPtr<nsISchemaElement> element;
 
694
  schema->GetElementByName(aName, getter_AddRefs(element));
 
695
  if (!element) {
 
696
    return NS_ERROR_WSDL_UNKNOWN_SCHEMA_COMPONENT;
 
697
  }
 
698
 
 
699
  *aSchemaComponent = element;
 
700
  NS_IF_ADDREF(*aSchemaComponent);
 
701
 
 
702
  return NS_OK;
 
703
}
 
704
 
 
705
nsresult
 
706
nsWSDLLoadRequest::GetSchemaType(const nsAString& aName,
 
707
                                 const nsAString& aNamespace,
 
708
                                 nsISchemaType** aSchemaComponent)
 
709
{
 
710
  if (aNamespace.Equals(NS_LITERAL_STRING(SCHEMA_2001_NAMESPACE)) ||
 
711
      aNamespace.Equals(NS_LITERAL_STRING(SCHEMA_1999_NAMESPACE))) {
 
712
    nsCOMPtr<nsISchemaCollection> collection(do_QueryInterface(mSchemaLoader));
 
713
    return collection->GetType(aName, aNamespace, aSchemaComponent);
 
714
  }
 
715
 
 
716
  nsStringKey key(aNamespace);
 
717
  nsCOMPtr<nsISupports> sup = dont_AddRef(mTypes.Get(&key));
 
718
  nsCOMPtr<nsISchema> schema(do_QueryInterface(sup));
 
719
  if (!schema) {
 
720
    return NS_ERROR_WSDL_UNKNOWN_SCHEMA_COMPONENT;
 
721
  }
 
722
 
 
723
  nsCOMPtr<nsISchemaType> type;
 
724
  schema->GetTypeByName(aName, getter_AddRefs(type));
 
725
  if (!type) {
 
726
    return NS_ERROR_WSDL_UNKNOWN_SCHEMA_COMPONENT;
 
727
  }
 
728
 
 
729
  *aSchemaComponent = type;
 
730
  NS_IF_ADDREF(*aSchemaComponent);
 
731
 
 
732
  return NS_OK;
 
733
}
 
734
 
 
735
nsresult
 
736
nsWSDLLoadRequest::GetMessage(const nsAString& aName,
 
737
                              const nsAString& aNamespace,
 
738
                              nsIWSDLMessage** aMessage)
 
739
{
 
740
  nsAutoString keyStr(aName);
 
741
  keyStr.Append(aNamespace);
 
742
 
 
743
  nsStringKey key(keyStr);
 
744
 
 
745
  nsCOMPtr<nsISupports> sup = dont_AddRef(mMessages.Get(&key));
 
746
  nsCOMPtr<nsIWSDLMessage> message(do_QueryInterface(sup));
 
747
  if (!message) {
 
748
    return NS_ERROR_WSDL_UNKNOWN_WSDL_COMPONENT;
 
749
  }
 
750
 
 
751
  *aMessage = message;
 
752
  NS_IF_ADDREF(*aMessage);
 
753
 
 
754
  return NS_OK;
 
755
}
 
756
 
 
757
nsresult
 
758
nsWSDLLoadRequest::GetPortType(const nsAString& aName,
 
759
                               const nsAString& aNamespace,
 
760
                               nsIWSDLPort** aPort)
 
761
{
 
762
  nsAutoString keyStr(aName);
 
763
  keyStr.Append(aNamespace);
 
764
 
 
765
  nsStringKey key(keyStr);
 
766
 
 
767
  nsCOMPtr<nsISupports> sup = dont_AddRef(mPortTypes.Get(&key));
 
768
  nsCOMPtr<nsIWSDLPort> port(do_QueryInterface(sup));
 
769
  if (!port) {
 
770
    return NS_ERROR_WSDL_UNKNOWN_WSDL_COMPONENT;
 
771
  }
 
772
 
 
773
  *aPort = port;
 
774
  NS_IF_ADDREF(*aPort);
 
775
 
 
776
  return NS_OK;
 
777
}
 
778
 
 
779
static nsresult
 
780
ParseQualifiedName(nsIDOMElement* aContext, const nsAString& aQualifiedName,
 
781
                   nsAString& aPrefix, nsAString& aLocalName,
 
782
                   nsAString& aNamespaceURI)
 
783
{
 
784
  nsReadingIterator<PRUnichar> pos, begin, end;
 
785
 
 
786
  aQualifiedName.BeginReading(begin);
 
787
  aQualifiedName.EndReading(end);
 
788
  pos = begin;
 
789
 
 
790
  if (FindCharInReadable(PRUnichar(':'), pos, end)) {
 
791
    CopyUnicodeTo(begin, pos, aPrefix);
 
792
    CopyUnicodeTo(++pos, end, aLocalName);
 
793
  }
 
794
  else {
 
795
    CopyUnicodeTo(begin, end, aLocalName);
 
796
  }
 
797
 
 
798
  nsCOMPtr<nsIDOM3Node> node(do_QueryInterface(aContext));
 
799
  if (!node) {
 
800
    return NS_ERROR_UNEXPECTED;
 
801
  }
 
802
 
 
803
  return node->LookupNamespaceURI(aPrefix, aNamespaceURI);
 
804
}
 
805
 
 
806
 
 
807
nsresult
 
808
nsWSDLLoadRequest::ProcessImportElement(nsIDOMElement* aElement,
 
809
                                        PRUint32 aIndex)
 
810
{
 
811
  nsresult rv = NS_OK;
 
812
 
 
813
  // XXX Is there a need to record the namespace? Can it be different
 
814
  // from the targetNamespace of the imported file?
 
815
 
 
816
  nsAutoString location, documentLocation;
 
817
  aElement->GetAttribute(NS_LITERAL_STRING("location"), location);
 
818
 
 
819
  nsWSDLLoadingContext* context = GetCurrentContext();
 
820
  if (!context) {
 
821
    return NS_ERROR_UNEXPECTED;
 
822
  }
 
823
  context->GetDocumentLocation(documentLocation);
 
824
 
 
825
  nsCOMPtr<nsIURI> uri, baseURI;
 
826
  rv = NS_NewURI(getter_AddRefs(baseURI), documentLocation);
 
827
  if (NS_FAILED(rv)) {
 
828
    return rv;
 
829
  }
 
830
 
 
831
  rv = NS_NewURI(getter_AddRefs(uri), location, nsnull, baseURI);
 
832
  if (NS_FAILED(rv)) {
 
833
    return rv;
 
834
  }
 
835
 
 
836
  // Fix ( bug 202478 ) a potential stack overflow by 
 
837
  // preventing the wsdl file from loading if it was  
 
838
  // already loaded via the import element.
 
839
  PRUint32 count = mImportList.Count();
 
840
  PRUint32 i;
 
841
  for (i = 0; i < count; i++) {
 
842
    PRBool equal;  
 
843
    mImportList[i]->Equals(uri, &equal);
 
844
    if (equal) {
 
845
      // Looks like this uri has already been loaded.
 
846
      // Loading it again will end up in an infinite loop.
 
847
      return NS_ERROR_WSDL_RECURSIVE_IMPORT;
 
848
    }
 
849
  }
 
850
 
 
851
  mImportList.AppendObject(uri);
 
852
  
 
853
  nsCAutoString spec;
 
854
  uri->GetSpec(spec);
 
855
 
 
856
  rv = LoadDefinition(NS_ConvertUTF8toUCS2(spec.get()));
 
857
  if (NS_FAILED(rv)) {
 
858
    return rv;
 
859
  }
 
860
 
 
861
  if (!mIsSync) {
 
862
    context->SetChildIndex(aIndex);
 
863
    return NS_ERROR_WSDL_LOADPENDING;
 
864
  }
 
865
 
 
866
  return NS_OK;
 
867
}
 
868
 
 
869
nsresult
 
870
nsWSDLLoadRequest::ProcessTypesElement(nsIDOMElement* aElement)
 
871
{
 
872
  static const char* kSchemaNamespaces[] =
 
873
    {
 
874
      SCHEMA_1999_NAMESPACE,
 
875
      SCHEMA_2001_NAMESPACE
 
876
    };
 
877
  static const PRUint32 kSchemaNamespacesLength =
 
878
    sizeof(kSchemaNamespaces) / sizeof(const char*);
 
879
 
 
880
  nsresult rv = NS_OK;
 
881
 
 
882
  nsChildElementIterator iterator(aElement,
 
883
                                  kSchemaNamespaces, kSchemaNamespacesLength);
 
884
  nsCOMPtr<nsIDOMElement> childElement;
 
885
  nsCOMPtr<nsIAtom> tagName;
 
886
 
 
887
  while (NS_SUCCEEDED(iterator.GetNextChild(getter_AddRefs(childElement),
 
888
                                            getter_AddRefs(tagName))) &&
 
889
         childElement) {
 
890
    if (tagName == nsWSDLAtoms::sSchema_atom) {
 
891
      nsCOMPtr<nsISchema> schema;
 
892
      rv = mSchemaLoader->ProcessSchemaElement(childElement,
 
893
                                               getter_AddRefs(schema));
 
894
      if (NS_FAILED(rv)) {
 
895
        return NS_ERROR_WSDL_SCHEMA_PROCESSING_ERROR;
 
896
      }
 
897
 
 
898
      nsAutoString targetNamespace;
 
899
      schema->GetTargetNamespace(targetNamespace);
 
900
 
 
901
      nsStringKey key(targetNamespace);
 
902
      mTypes.Put(&key, schema);
 
903
    }
 
904
  }
 
905
 
 
906
  return NS_OK;
 
907
}
 
908
 
 
909
nsresult
 
910
nsWSDLLoadRequest::ProcessAbstractPartElement(nsIDOMElement* aElement,
 
911
                                              nsWSDLMessage* aMessage)
 
912
{
 
913
  nsresult rv = NS_OK;
 
914
 
 
915
  nsAutoString name;
 
916
  aElement->GetAttribute(NS_LITERAL_STRING("name"), name);
 
917
 
 
918
  nsCOMPtr<nsIWSDLPart> part;
 
919
  nsWSDLPart* partInst = new nsWSDLPart(name);
 
920
  if (!partInst) {
 
921
    return NS_ERROR_OUT_OF_MEMORY;
 
922
  }
 
923
  part = partInst;
 
924
 
 
925
  nsCOMPtr<nsISchemaComponent> schemaComponent;
 
926
  nsAutoString elementQName, typeQName;
 
927
  aElement->GetAttribute(NS_LITERAL_STRING("element"), elementQName);
 
928
  aElement->GetAttribute(NS_LITERAL_STRING("type"), typeQName);
 
929
 
 
930
  if (!elementQName.IsEmpty()) {
 
931
    nsAutoString elementPrefix, elementLocalName, elementNamespace;
 
932
 
 
933
    rv = ParseQualifiedName(aElement, elementQName, elementPrefix,
 
934
                            elementLocalName, elementNamespace);
 
935
    if (NS_FAILED(rv)) {
 
936
      return rv;
 
937
    }
 
938
 
 
939
    nsCOMPtr<nsISchemaElement> schemaElement;
 
940
    rv = GetSchemaElement(elementLocalName, elementNamespace,
 
941
                          getter_AddRefs(schemaElement));
 
942
    if (NS_FAILED(rv)) {
 
943
      return rv;
 
944
    }
 
945
 
 
946
    schemaComponent = schemaElement;
 
947
  }
 
948
  else if (!typeQName.IsEmpty()) {
 
949
    nsAutoString typePrefix, typeLocalName, typeNamespace;
 
950
 
 
951
    rv = ParseQualifiedName(aElement, typeQName, typePrefix, typeLocalName,
 
952
                            typeNamespace);
 
953
    if (NS_FAILED(rv)) {
 
954
      return rv;
 
955
    }
 
956
 
 
957
    nsCOMPtr<nsISchemaType> schemaType;
 
958
    rv = GetSchemaType(typeLocalName, typeNamespace,
 
959
                       getter_AddRefs(schemaType));
 
960
    if (NS_FAILED(rv)) {
 
961
      return rv;
 
962
    }
 
963
 
 
964
    schemaComponent = schemaType;
 
965
  }
 
966
 
 
967
  partInst->SetTypeInfo(typeQName, elementQName, schemaComponent);
 
968
  aMessage->AddPart(part);
 
969
 
 
970
  return NS_OK;
 
971
}
 
972
 
 
973
nsresult
 
974
nsWSDLLoadRequest::ProcessMessageElement(nsIDOMElement* aElement)
 
975
{
 
976
  nsresult rv = NS_OK;
 
977
 
 
978
  nsAutoString name;
 
979
  aElement->GetAttribute(NS_LITERAL_STRING("name"), name);
 
980
 
 
981
  nsCOMPtr<nsIWSDLMessage> message;
 
982
  nsWSDLMessage* messageInst = new nsWSDLMessage(name);
 
983
  if (!messageInst) {
 
984
    return NS_ERROR_OUT_OF_MEMORY;
 
985
  }
 
986
  message = messageInst;
 
987
 
 
988
  nsChildElementIterator iterator(aElement,
 
989
                                  NS_LITERAL_STRING(NS_WSDL_NAMESPACE));
 
990
  nsCOMPtr<nsIDOMElement> childElement;
 
991
  nsCOMPtr<nsIAtom> tagName;
 
992
 
 
993
  while (NS_SUCCEEDED(iterator.GetNextChild(getter_AddRefs(childElement),
 
994
                                            getter_AddRefs(tagName))) &&
 
995
         childElement) {
 
996
    if (tagName == nsWSDLAtoms::sDocumentation_atom) {
 
997
      messageInst->SetDocumentationElement(childElement);
 
998
    }
 
999
    else if (tagName == nsWSDLAtoms::sPart_atom) {
 
1000
      rv = ProcessAbstractPartElement(childElement, messageInst);
 
1001
      if (NS_FAILED(rv)) {
 
1002
        return rv;
 
1003
      }
 
1004
    }
 
1005
  }
 
1006
 
 
1007
  nsAutoString targetNamespace;
 
1008
  nsWSDLLoadingContext* context = GetCurrentContext();
 
1009
  if (!context) {
 
1010
    return NS_ERROR_UNEXPECTED;
 
1011
  }
 
1012
  context->GetTargetNamespace(targetNamespace);
 
1013
 
 
1014
  name.Append(targetNamespace);
 
1015
  nsStringKey key(name);
 
1016
  mMessages.Put(&key, message);
 
1017
 
 
1018
  return NS_OK;
 
1019
}
 
1020
 
 
1021
nsresult
 
1022
nsWSDLLoadRequest::ProcessOperationComponent(nsIDOMElement* aElement,
 
1023
                                             nsIWSDLMessage** aMessage)
 
1024
{
 
1025
  nsresult rv;
 
1026
 
 
1027
  nsAutoString messageQName, messagePrefix, messageLocalName, messageNamespace;
 
1028
  aElement->GetAttribute(NS_LITERAL_STRING("message"), messageQName);
 
1029
 
 
1030
  rv = ParseQualifiedName(aElement, messageQName, messagePrefix,
 
1031
                          messageLocalName, messageNamespace);
 
1032
  if (NS_FAILED(rv)) {
 
1033
    return rv;
 
1034
  }
 
1035
 
 
1036
  rv = GetMessage(messageLocalName, messageNamespace, aMessage);
 
1037
  if (NS_FAILED(rv)) {
 
1038
    // XXX It seem that some WSDL authors eliminate prefixes
 
1039
    // from qualified names in attribute values, assuming that
 
1040
    // the names will resolve to the targetNamespace, while
 
1041
    // they should technically resolve to the default namespace.
 
1042
    if (messagePrefix.IsEmpty()) {
 
1043
      nsAutoString targetNamespace;
 
1044
      nsWSDLLoadingContext* context = GetCurrentContext();
 
1045
      if (!context) {
 
1046
        return NS_ERROR_UNEXPECTED;
 
1047
      }
 
1048
      context->GetTargetNamespace(targetNamespace);
 
1049
      rv = GetMessage(messageLocalName, targetNamespace, aMessage);
 
1050
      if (NS_FAILED(rv)) {
 
1051
        return rv;
 
1052
      }
 
1053
    }
 
1054
  }
 
1055
 
 
1056
  return NS_OK;
 
1057
}
 
1058
 
 
1059
nsresult
 
1060
nsWSDLLoadRequest::ProcessAbstractOperation(nsIDOMElement* aElement,
 
1061
                                            nsWSDLPort* aPort)
 
1062
{
 
1063
  nsresult rv = NS_OK;
 
1064
 
 
1065
  nsAutoString name;
 
1066
  aElement->GetAttribute(NS_LITERAL_STRING("name"), name);
 
1067
 
 
1068
  nsCOMPtr<nsIWSDLOperation> operation;
 
1069
  nsWSDLOperation* operationInst = new nsWSDLOperation(name);
 
1070
  if (!operationInst) {
 
1071
    return NS_ERROR_OUT_OF_MEMORY;
 
1072
  }
 
1073
  operation = operationInst;
 
1074
 
 
1075
  nsAutoString parameterOrder;
 
1076
  aElement->GetAttribute(NS_LITERAL_STRING("parameterOrder"), parameterOrder);
 
1077
  if (!parameterOrder.IsEmpty()) {
 
1078
    nsReadingIterator<PRUnichar> start, end, delimiter;
 
1079
    parameterOrder.BeginReading(start);
 
1080
    parameterOrder.EndReading(end);
 
1081
 
 
1082
    PRBool found;
 
1083
    do {
 
1084
      delimiter = start;
 
1085
 
 
1086
      // Find the next delimiter
 
1087
      found = FindCharInReadable(PRUnichar(' '), delimiter, end);
 
1088
 
 
1089
      // Use the string from the current start position to the
 
1090
      // delimiter.
 
1091
      nsAutoString paramName;
 
1092
      CopyUnicodeTo(start, delimiter, paramName);
 
1093
 
 
1094
      if (!paramName.IsEmpty()) {
 
1095
        operationInst->AddParameter(paramName);
 
1096
      }
 
1097
 
 
1098
      // If we did find a delimiter, advance past it
 
1099
      if (found) {
 
1100
        start = delimiter;
 
1101
        ++start;
 
1102
      }
 
1103
    } while (found);
 
1104
  }
 
1105
 
 
1106
  nsChildElementIterator iterator(aElement,
 
1107
                                  NS_LITERAL_STRING(NS_WSDL_NAMESPACE));
 
1108
  nsCOMPtr<nsIDOMElement> childElement;
 
1109
  nsCOMPtr<nsIAtom> tagName;
 
1110
 
 
1111
  while (NS_SUCCEEDED(iterator.GetNextChild(getter_AddRefs(childElement),
 
1112
                                            getter_AddRefs(tagName))) &&
 
1113
         childElement) {
 
1114
    nsCOMPtr<nsIWSDLMessage> message;
 
1115
    if (tagName == nsWSDLAtoms::sDocumentation_atom) {
 
1116
      operationInst->SetDocumentationElement(childElement);
 
1117
    }
 
1118
    else if (tagName == nsWSDLAtoms::sInput_atom) {
 
1119
      rv = ProcessOperationComponent(childElement, getter_AddRefs(message));
 
1120
      if (NS_FAILED(rv)) {
 
1121
        return rv;
 
1122
      }
 
1123
      operationInst->SetInput(message);
 
1124
    }
 
1125
    else if (tagName == nsWSDLAtoms::sOutput_atom) {
 
1126
      rv = ProcessOperationComponent(childElement, getter_AddRefs(message));
 
1127
      if (NS_FAILED(rv)) {
 
1128
        return rv;
 
1129
      }
 
1130
      operationInst->SetOutput(message);
 
1131
    }
 
1132
    else if (tagName == nsWSDLAtoms::sFault_atom) {
 
1133
      rv = ProcessOperationComponent(childElement, getter_AddRefs(message));
 
1134
      if (NS_FAILED(rv)) {
 
1135
        return rv;
 
1136
      }
 
1137
      operationInst->AddFault(message);
 
1138
    }
 
1139
  }
 
1140
 
 
1141
  aPort->AddOperation(operation);
 
1142
 
 
1143
  return NS_OK;
 
1144
}
 
1145
 
 
1146
nsresult
 
1147
nsWSDLLoadRequest::ProcessPortTypeElement(nsIDOMElement* aElement)
 
1148
{
 
1149
  nsresult rv = NS_OK;
 
1150
 
 
1151
  nsAutoString name;
 
1152
  aElement->GetAttribute(NS_LITERAL_STRING("name"), name);
 
1153
 
 
1154
  nsCOMPtr<nsIWSDLPort> port;
 
1155
  nsWSDLPort* portInst = new nsWSDLPort(name);
 
1156
  if (!portInst) {
 
1157
    return NS_ERROR_OUT_OF_MEMORY;
 
1158
  }
 
1159
  port = portInst;
 
1160
 
 
1161
  nsChildElementIterator iterator(aElement,
 
1162
                                  NS_LITERAL_STRING(NS_WSDL_NAMESPACE));
 
1163
  nsCOMPtr<nsIDOMElement> childElement;
 
1164
  nsCOMPtr<nsIAtom> tagName;
 
1165
 
 
1166
  while (NS_SUCCEEDED(iterator.GetNextChild(getter_AddRefs(childElement),
 
1167
                                            getter_AddRefs(tagName))) &&
 
1168
         childElement) {
 
1169
    if (tagName == nsWSDLAtoms::sDocumentation_atom) {
 
1170
      portInst->SetDocumentationElement(childElement);
 
1171
    }
 
1172
    else if (tagName == nsWSDLAtoms::sOperation_atom) {
 
1173
      rv = ProcessAbstractOperation(childElement, portInst);
 
1174
      if (NS_FAILED(rv)) {
 
1175
        return rv;
 
1176
      }
 
1177
    }
 
1178
  }
 
1179
 
 
1180
  nsAutoString targetNamespace;
 
1181
  nsWSDLLoadingContext* context = GetCurrentContext();
 
1182
  if (!context) {
 
1183
    return NS_ERROR_UNEXPECTED;
 
1184
  }
 
1185
  context->GetTargetNamespace(targetNamespace);
 
1186
 
 
1187
  name.Append(targetNamespace);
 
1188
  nsStringKey key(name);
 
1189
  mPortTypes.Put(&key, port);
 
1190
 
 
1191
  return NS_OK;
 
1192
}
 
1193
 
 
1194
nsresult
 
1195
nsWSDLLoadRequest::ProcessMessageBinding(nsIDOMElement* aElement,
 
1196
                                         nsIWSDLMessage* aMessage)
 
1197
{
 
1198
 
 
1199
  nsChildElementIterator iterator(aElement,
 
1200
                                  NS_LITERAL_STRING(NS_WSDL_SOAP_NAMESPACE));
 
1201
  nsCOMPtr<nsIDOMElement> childElement;
 
1202
  nsCOMPtr<nsIAtom> tagName;
 
1203
 
 
1204
  while (NS_SUCCEEDED(iterator.GetNextChild(getter_AddRefs(childElement),
 
1205
                                            getter_AddRefs(tagName))) &&
 
1206
         childElement) {
 
1207
    if (tagName == nsWSDLAtoms::sBody_atom) {
 
1208
      nsAutoString partsStr, useStr, encodingStyle, namespaceStr;
 
1209
      childElement->GetAttribute(NS_LITERAL_STRING("parts"), partsStr);
 
1210
      childElement->GetAttribute(NS_LITERAL_STRING("use"), useStr);
 
1211
      childElement->GetAttribute(NS_LITERAL_STRING("encodingStyle"),
 
1212
                                 encodingStyle);
 
1213
      childElement->GetAttribute(NS_LITERAL_STRING("namespace"), namespaceStr);
 
1214
 
 
1215
      PRUint16 use = nsISOAPPartBinding::USE_LITERAL;
 
1216
      if (useStr.Equals(NS_LITERAL_STRING("encoded"))) {
 
1217
        use = nsISOAPPartBinding::USE_ENCODED;
 
1218
      }
 
1219
 
 
1220
      nsCOMPtr<nsISOAPMessageBinding> messageBinding;
 
1221
      nsSOAPMessageBinding* messageBindingInst =
 
1222
        new nsSOAPMessageBinding(namespaceStr);
 
1223
      if (!messageBindingInst) {
 
1224
        return NS_ERROR_OUT_OF_MEMORY;
 
1225
      }
 
1226
      messageBinding = messageBindingInst;
 
1227
      nsWSDLMessage* messageInst = NS_REINTERPRET_CAST(nsWSDLMessage*,
 
1228
                                                       aMessage);
 
1229
      messageInst->SetBinding(messageBinding);
 
1230
 
 
1231
      nsCOMPtr<nsISOAPPartBinding> binding;
 
1232
      nsSOAPPartBinding* bindingInst =
 
1233
        new nsSOAPPartBinding(nsISOAPPartBinding::LOCATION_BODY, use,
 
1234
                              encodingStyle, namespaceStr);
 
1235
      if (!bindingInst) {
 
1236
        return NS_ERROR_OUT_OF_MEMORY;
 
1237
      }
 
1238
      binding = bindingInst;
 
1239
 
 
1240
      nsCOMPtr<nsIWSDLPart> part;
 
1241
      nsWSDLPart* partInst;
 
1242
      // If there is no explicit parts attribute, this binding applies
 
1243
      // to all the parts.
 
1244
      if (partsStr.IsEmpty()) {
 
1245
        PRUint32 index, count;
 
1246
 
 
1247
        aMessage->GetPartCount(&count);
 
1248
        for (index = 0; index < count; index++) {
 
1249
          aMessage->GetPart(index, getter_AddRefs(part));
 
1250
          partInst = NS_REINTERPRET_CAST(nsWSDLPart*, part.get());
 
1251
          if (partInst) {
 
1252
            partInst->SetBinding(binding);
 
1253
          }
 
1254
        }
 
1255
      }
 
1256
      else {
 
1257
        nsReadingIterator<PRUnichar> start, end, delimiter;
 
1258
        partsStr.BeginReading(start);
 
1259
        partsStr.EndReading(end);
 
1260
 
 
1261
        PRBool found;
 
1262
        do {
 
1263
          delimiter = start;
 
1264
 
 
1265
          // Find the next delimiter
 
1266
          found = FindCharInReadable(PRUnichar(' '), delimiter, end);
 
1267
 
 
1268
          // Use the string from the current start position to the
 
1269
          // delimiter.
 
1270
          nsAutoString partName;
 
1271
          CopyUnicodeTo(start, delimiter, partName);
 
1272
 
 
1273
          if (!partName.IsEmpty()) {
 
1274
            aMessage->GetPartByName(partName, getter_AddRefs(part));
 
1275
            partInst = NS_REINTERPRET_CAST(nsWSDLPart*, part.get());
 
1276
            if (partInst) {
 
1277
              partInst->SetBinding(binding);
 
1278
            }
 
1279
          }
 
1280
 
 
1281
          // If we did find a delimiter, advance past it
 
1282
          if (found) {
 
1283
            start = delimiter;
 
1284
            ++start;
 
1285
          }
 
1286
        } while (found);
 
1287
      }
 
1288
    }
 
1289
  }
 
1290
 
 
1291
  return NS_OK;
 
1292
}
 
1293
 
 
1294
nsresult
 
1295
nsWSDLLoadRequest::ProcessOperationBinding(nsIDOMElement* aElement,
 
1296
                                           nsIWSDLPort* aPort)
 
1297
{
 
1298
  nsresult rv = NS_OK;
 
1299
 
 
1300
  nsAutoString name;
 
1301
  aElement->GetAttribute(NS_LITERAL_STRING("name"), name);
 
1302
 
 
1303
  nsCOMPtr<nsIWSDLOperation> operation;
 
1304
  aPort->GetOperationByName(name, getter_AddRefs(operation));
 
1305
  if (!operation) {
 
1306
    return NS_ERROR_WSDL_UNKNOWN_WSDL_COMPONENT;
 
1307
  }
 
1308
  nsWSDLOperation* operationInst = NS_REINTERPRET_CAST(nsWSDLOperation*,
 
1309
                                                       operation.get());
 
1310
 
 
1311
  nsCOMPtr<nsISOAPOperationBinding> binding;
 
1312
  nsSOAPOperationBinding* bindingInst = new nsSOAPOperationBinding();
 
1313
  if (!bindingInst) {
 
1314
    return NS_ERROR_OUT_OF_MEMORY;
 
1315
  }
 
1316
  binding = bindingInst;
 
1317
 
 
1318
  nsChildElementIterator iterator(aElement);
 
1319
  nsCOMPtr<nsIDOMElement> childElement;
 
1320
  nsCOMPtr<nsIAtom> tagName;
 
1321
 
 
1322
  while (NS_SUCCEEDED(iterator.GetNextChild(getter_AddRefs(childElement),
 
1323
                                            getter_AddRefs(tagName))) &&
 
1324
         childElement) {
 
1325
    if ((tagName == nsWSDLAtoms::sDocumentation_atom) &&
 
1326
        IsElementOfNamespace(childElement,
 
1327
                             NS_LITERAL_STRING(NS_WSDL_NAMESPACE))) {
 
1328
      bindingInst->SetDocumentationElement(childElement);
 
1329
    }
 
1330
    else if ((tagName == nsWSDLAtoms::sOperation_atom) &&
 
1331
             IsElementOfNamespace(childElement,
 
1332
                                  NS_LITERAL_STRING(NS_WSDL_SOAP_NAMESPACE))) {
 
1333
      nsAutoString action, style;
 
1334
      childElement->GetAttribute(NS_LITERAL_STRING("soapAction"), action);
 
1335
      childElement->GetAttribute(NS_LITERAL_STRING("style"), style);
 
1336
 
 
1337
      bindingInst->SetSoapAction(action);
 
1338
      if (style.Equals(NS_LITERAL_STRING("rpc"))) {
 
1339
        bindingInst->SetStyle(nsISOAPPortBinding::STYLE_RPC);
 
1340
      }
 
1341
      else if (style.Equals(NS_LITERAL_STRING("document"))) {
 
1342
        bindingInst->SetStyle(nsISOAPPortBinding::STYLE_DOCUMENT);
 
1343
      }
 
1344
      // If one isn't explicitly specified, we inherit from the port
 
1345
      else {
 
1346
        nsCOMPtr<nsIWSDLBinding> portBinding;
 
1347
        aPort->GetBinding(getter_AddRefs(portBinding));
 
1348
        nsCOMPtr<nsISOAPPortBinding> soapPortBinding =
 
1349
          do_QueryInterface(portBinding);
 
1350
        if (soapPortBinding) {
 
1351
          PRUint16 styleVal;
 
1352
          soapPortBinding->GetStyle(&styleVal);
 
1353
          bindingInst->SetStyle(styleVal);
 
1354
        }
 
1355
      }
 
1356
    }
 
1357
    else if ((tagName == nsWSDLAtoms::sInput_atom) &&
 
1358
             IsElementOfNamespace(childElement,
 
1359
                                  NS_LITERAL_STRING(NS_WSDL_NAMESPACE))) {
 
1360
      nsCOMPtr<nsIWSDLMessage> input;
 
1361
 
 
1362
      operation->GetInput(getter_AddRefs(input));
 
1363
      rv = ProcessMessageBinding(childElement, input);
 
1364
      if (NS_FAILED(rv)) {
 
1365
        return rv;
 
1366
      }
 
1367
    }
 
1368
    else if ((tagName == nsWSDLAtoms::sOutput_atom) &&
 
1369
             IsElementOfNamespace(childElement,
 
1370
                                  NS_LITERAL_STRING(NS_WSDL_NAMESPACE))) {
 
1371
      nsCOMPtr<nsIWSDLMessage> output;
 
1372
 
 
1373
      operation->GetOutput(getter_AddRefs(output));
 
1374
      rv = ProcessMessageBinding(childElement, output);
 
1375
      if (NS_FAILED(rv)) {
 
1376
        return rv;
 
1377
      }
 
1378
    }
 
1379
    else if ((tagName == nsWSDLAtoms::sFault_atom) &&
 
1380
             IsElementOfNamespace(childElement,
 
1381
                                  NS_LITERAL_STRING(NS_WSDL_NAMESPACE))) {
 
1382
      // XXX TO BE IMPLEMENTED
 
1383
    }
 
1384
  }
 
1385
 
 
1386
  operationInst->SetBinding(binding);
 
1387
 
 
1388
  return NS_OK;
 
1389
 
 
1390
}
 
1391
 
 
1392
nsresult
 
1393
nsWSDLLoadRequest::ProcessBindingElement(nsIDOMElement* aElement)
 
1394
{
 
1395
  nsresult rv = NS_OK;
 
1396
 
 
1397
  nsAutoString name;
 
1398
  aElement->GetAttribute(NS_LITERAL_STRING("name"), name);
 
1399
 
 
1400
  PRBool foundSOAPBinding;
 
1401
  nsCOMPtr<nsIWSDLBinding> binding;
 
1402
  nsSOAPPortBinding* bindingInst = new nsSOAPPortBinding(name);
 
1403
  if (!bindingInst) {
 
1404
    return NS_ERROR_OUT_OF_MEMORY;
 
1405
  }
 
1406
  binding = bindingInst;
 
1407
  bindingInst->SetAddress(mAddress);
 
1408
 
 
1409
  nsCOMPtr<nsIWSDLPort> port;
 
1410
  nsAutoString typeQName, typePrefix, typeLocalName, typeNamespace;
 
1411
  aElement->GetAttribute(NS_LITERAL_STRING("type"), typeQName);
 
1412
  rv = ParseQualifiedName(aElement, typeQName, typePrefix, typeLocalName,
 
1413
                          typeNamespace);
 
1414
  if (NS_FAILED(rv)) {
 
1415
    return rv;
 
1416
  }
 
1417
 
 
1418
  rv = GetPortType(typeLocalName, typeNamespace, getter_AddRefs(port));
 
1419
  if (NS_FAILED(rv)) {
 
1420
    // XXX It seem that some WSDL authors eliminate prefixes
 
1421
    // from qualified names in attribute values, assuming that
 
1422
    // the names will resolve to the targetNamespace, while
 
1423
    // they should technically resolve to the default namespace.
 
1424
    if (typePrefix.IsEmpty()) {
 
1425
      nsWSDLLoadingContext* context = GetCurrentContext();
 
1426
      if (!context) {
 
1427
        return NS_ERROR_UNEXPECTED;
 
1428
      }
 
1429
 
 
1430
      nsAutoString targetNamespace;
 
1431
      context->GetTargetNamespace(targetNamespace);
 
1432
      rv = GetPortType(typeLocalName, targetNamespace, getter_AddRefs(port));
 
1433
      if (NS_FAILED(rv)) {
 
1434
        return rv;    // Can't find a port type of the specified name
 
1435
      }
 
1436
    }
 
1437
  }
 
1438
 
 
1439
  nsChildElementIterator iterator(aElement);
 
1440
  nsCOMPtr<nsIDOMElement> childElement;
 
1441
  nsCOMPtr<nsIAtom> tagName;
 
1442
 
 
1443
  while (NS_SUCCEEDED(iterator.GetNextChild(getter_AddRefs(childElement),
 
1444
                                            getter_AddRefs(tagName))) &&
 
1445
         childElement) {
 
1446
    if ((tagName == nsWSDLAtoms::sDocumentation_atom) &&
 
1447
        IsElementOfNamespace(childElement,
 
1448
                             NS_LITERAL_STRING(NS_WSDL_NAMESPACE))) {
 
1449
      bindingInst->SetDocumentationElement(childElement);
 
1450
    }
 
1451
    else if ((tagName == nsWSDLAtoms::sBinding_atom) &&
 
1452
             IsElementOfNamespace(childElement,
 
1453
                                  NS_LITERAL_STRING(NS_WSDL_SOAP_NAMESPACE))) {
 
1454
      // XXX There should be different namespaces for newer versions
 
1455
      // of SOAP.
 
1456
      bindingInst->SetSoapVersion(nsISOAPPortBinding::SOAP_VERSION_1_1);
 
1457
 
 
1458
      nsAutoString style, transport;
 
1459
      childElement->GetAttribute(NS_LITERAL_STRING("style"), style);
 
1460
      childElement->GetAttribute(NS_LITERAL_STRING("transport"), transport);
 
1461
 
 
1462
      if (style.Equals(NS_LITERAL_STRING("rpc"))) {
 
1463
        bindingInst->SetStyle(nsISOAPPortBinding::STYLE_RPC);
 
1464
      }
 
1465
      else if (style.Equals(NS_LITERAL_STRING("document"))) {
 
1466
        bindingInst->SetStyle(nsISOAPPortBinding::STYLE_DOCUMENT);
 
1467
      }
 
1468
      bindingInst->SetTransport(transport);
 
1469
      foundSOAPBinding = PR_TRUE;
 
1470
    }
 
1471
    else if ((tagName == nsWSDLAtoms::sOperation_atom) &&
 
1472
             IsElementOfNamespace(childElement,
 
1473
                                  NS_LITERAL_STRING(NS_WSDL_NAMESPACE))) {
 
1474
      rv = ProcessOperationBinding(childElement, port);
 
1475
      if (NS_FAILED(rv)) {
 
1476
        return rv;
 
1477
      }
 
1478
    }
 
1479
  }
 
1480
 
 
1481
  if (!foundSOAPBinding) {
 
1482
    // If we don't have a SOAP binding, we can't continue
 
1483
    return NS_ERROR_WSDL_BINDING_NOT_FOUND;
 
1484
  }
 
1485
  nsWSDLPort* portInst = NS_REINTERPRET_CAST(nsWSDLPort*, port.get());
 
1486
  portInst->SetBinding(binding);
 
1487
 
 
1488
  mPort = port;
 
1489
 
 
1490
  return NS_OK;
 
1491
}
 
1492
 
 
1493
nsresult
 
1494
nsWSDLLoadRequest::ProcessPortBinding(nsIDOMElement* aElement)
 
1495
{
 
1496
  nsChildElementIterator iterator(aElement);
 
1497
  nsCOMPtr<nsIDOMElement> childElement;
 
1498
  nsCOMPtr<nsIAtom> tagName;
 
1499
 
 
1500
  while (NS_SUCCEEDED(iterator.GetNextChild(getter_AddRefs(childElement),
 
1501
                                            getter_AddRefs(tagName))) &&
 
1502
         childElement) {
 
1503
    if ((tagName == nsWSDLAtoms::sAddress_atom) &&
 
1504
        IsElementOfNamespace(childElement,
 
1505
                             NS_LITERAL_STRING(NS_WSDL_SOAP_NAMESPACE))) {
 
1506
      childElement->GetAttribute(NS_LITERAL_STRING("location"), mAddress);
 
1507
    }
 
1508
  }
 
1509
 
 
1510
  return NS_OK;
 
1511
}
 
1512
 
 
1513
nsresult
 
1514
nsWSDLLoadRequest::ProcessServiceElement(nsIDOMElement* aElement)
 
1515
{
 
1516
  nsresult rv;
 
1517
 
 
1518
  nsChildElementIterator iterator(aElement,
 
1519
                                  NS_LITERAL_STRING(NS_WSDL_NAMESPACE));
 
1520
  nsCOMPtr<nsIDOMElement> childElement;
 
1521
  nsCOMPtr<nsIAtom> tagName;
 
1522
 
 
1523
  while (NS_SUCCEEDED(iterator.GetNextChild(getter_AddRefs(childElement),
 
1524
                                            getter_AddRefs(tagName))) &&
 
1525
         childElement) {
 
1526
    if (tagName == nsWSDLAtoms::sPort_atom) {
 
1527
      nsAutoString name;
 
1528
      childElement->GetAttribute(NS_LITERAL_STRING("name"), name);
 
1529
      if (name.Equals(mPortName)) {
 
1530
        nsAutoString bindingQName, bindingPrefix;
 
1531
 
 
1532
        childElement->GetAttribute(NS_LITERAL_STRING("binding"), bindingQName);
 
1533
        rv = ParseQualifiedName(childElement, bindingQName, bindingPrefix,
 
1534
                                mBindingName, mBindingNamespace);
 
1535
        if (NS_FAILED(rv)) {
 
1536
          return rv; // binding of an unknown namespace
 
1537
        }
 
1538
 
 
1539
        rv = ProcessPortBinding(childElement);
 
1540
        if (NS_FAILED(rv)) {
 
1541
          return rv;
 
1542
        }
 
1543
 
 
1544
        break;
 
1545
      }
 
1546
    }
 
1547
  }
 
1548
 
 
1549
  return NS_OK;
 
1550
}