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

« back to all changes in this revision

Viewing changes to mozilla/extensions/webservices/soap/src/nsSOAPUtils.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
/* ***** BEGIN LICENSE BLOCK *****
 
3
 * Version: NPL 1.1/GPL 2.0/LGPL 2.1
 
4
 *
 
5
 * The contents of this file are subject to the Netscape Public License
 
6
 * Version 1.1 (the "License"); you may not use this file except in
 
7
 * compliance with the License. You may obtain a copy of the License at
 
8
 * http://www.mozilla.org/NPL/
 
9
 *
 
10
 * Software distributed under the License is distributed on an "AS IS" basis,
 
11
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 
12
 * for the specific language governing rights and limitations under the
 
13
 * License.
 
14
 *
 
15
 * The Original Code is mozilla.org code.
 
16
 *
 
17
 * The Initial Developer of the Original Code is 
 
18
 * Netscape Communications Corporation.
 
19
 * Portions created by the Initial Developer are Copyright (C) 2001
 
20
 * the Initial Developer. All Rights Reserved.
 
21
 *
 
22
 * Contributor(s):
 
23
 *
 
24
 *
 
25
 * Alternatively, the contents of this file may be used under the terms of
 
26
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 
27
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 
28
 * in which case the provisions of the GPL or the LGPL are applicable instead
 
29
 * of those above. If you wish to allow use of your version of this file only
 
30
 * under the terms of either the GPL or the LGPL, and not to allow others to
 
31
 * use your version of this file under the terms of the NPL, indicate your
 
32
 * decision by deleting the provisions above and replace them with the notice
 
33
 * and other provisions required by the GPL or the LGPL. If you do not delete
 
34
 * the provisions above, a recipient may use your version of this file under
 
35
 * the terms of any one of the NPL, the GPL or the LGPL.
 
36
 *
 
37
 * ***** END LICENSE BLOCK ***** */
 
38
 
 
39
#include "nsSOAPUtils.h"
 
40
#include "nsIDOMText.h"
 
41
#include "nsISOAPEncoding.h"
 
42
#include "nsIDOMNamedNodeMap.h"
 
43
#include "nsIDOMAttr.h"
 
44
#include "nsCOMPtr.h"
 
45
#include "nsSOAPException.h"
 
46
 
 
47
nsSOAPStrings::nsSOAPStrings()
 
48
  : NS_LITERAL_STRING_INIT(kSOAPEnvURI1, "http://schemas.xmlsoap.org/soap/envelope/")
 
49
  , NS_LITERAL_STRING_INIT(kSOAPEnvURI2, "http://www.w3.org/2001/09/soap-envelope")
 
50
  , NS_LITERAL_STRING_INIT(kSOAPEncURI, "http://www.w3.org/2001/09/soap-encoding")
 
51
  , NS_LITERAL_STRING_INIT(kSOAPEncURI11, "http://schemas.xmlsoap.org/soap/encoding/")
 
52
  , NS_LITERAL_STRING_INIT(kXSIURI, "http://www.w3.org/2001/XMLSchema-instance")
 
53
  , NS_LITERAL_STRING_INIT(kXSURI, "http://www.w3.org/2001/XMLSchema")
 
54
  , NS_LITERAL_STRING_INIT(kXSIURI1999, "http://www.w3.org/1999/XMLSchema-instance")
 
55
  , NS_LITERAL_STRING_INIT(kXSURI1999, "http://www.w3.org/1999/XMLSchema")
 
56
  , NS_LITERAL_STRING_INIT(kSOAPEnvPrefix, "env")
 
57
  , NS_LITERAL_STRING_INIT(kSOAPEncPrefix, "enc")
 
58
  , NS_LITERAL_STRING_INIT(kXSIPrefix, "xsi")
 
59
  , NS_LITERAL_STRING_INIT(kXSITypeAttribute, "type")
 
60
  , NS_LITERAL_STRING_INIT(kXSPrefix, "xs")
 
61
  , NS_LITERAL_STRING_INIT(kEncodingStyleAttribute, "encodingStyle")
 
62
  , NS_LITERAL_STRING_INIT(kActorAttribute, "actor")
 
63
  , NS_LITERAL_STRING_INIT(kMustUnderstandAttribute, "mustUnderstand")
 
64
  , NS_LITERAL_STRING_INIT(kEnvelopeTagName, "Envelope")
 
65
  , NS_LITERAL_STRING_INIT(kHeaderTagName, "Header")
 
66
  , NS_LITERAL_STRING_INIT(kBodyTagName, "Body")
 
67
  , NS_LITERAL_STRING_INIT(kFaultTagName, "Fault")
 
68
  , NS_LITERAL_STRING_INIT(kFaultCodeTagName, "faultcode")
 
69
  , NS_LITERAL_STRING_INIT(kFaultStringTagName, "faultstring")
 
70
  , NS_LITERAL_STRING_INIT(kFaultActorTagName, "faultactor")
 
71
  , NS_LITERAL_STRING_INIT(kFaultDetailTagName, "detail")
 
72
  , NS_LITERAL_STRING_INIT(kEncodingSeparator, "#")
 
73
  , NS_LITERAL_STRING_INIT(kQualifiedSeparator, ":")
 
74
  , NS_LITERAL_STRING_INIT(kXMLNamespaceNamespaceURI, "http://www.w3.org/2000/xmlns/")
 
75
  , NS_LITERAL_STRING_INIT(kXMLNamespaceURI, "http://www.w3.org/XML/1998/namespace")
 
76
  , NS_LITERAL_STRING_INIT(kXMLNamespacePrefix, "xmlns:")
 
77
  , NS_LITERAL_STRING_INIT(kXMLPrefix, "xml:")
 
78
  , NS_LITERAL_STRING_INIT(kTrue, "true")
 
79
  , NS_LITERAL_STRING_INIT(kTrueA, "1")
 
80
  , NS_LITERAL_STRING_INIT(kFalse, "false")
 
81
  , NS_LITERAL_STRING_INIT(kFalseA, "0")
 
82
  , NS_LITERAL_STRING_INIT(kVerifySourceHeader, "verifySource")
 
83
  , NS_LITERAL_STRING_INIT(kVerifySourceURI, "uri")
 
84
  , NS_LITERAL_STRING_INIT(kVerifySourceNamespaceURI, "urn:inet:www.mozilla.org:user-agent")
 
85
 
 
86
  , NS_LITERAL_STRING_INIT(kEmpty, "")
 
87
  , NS_LITERAL_STRING_INIT(kNull, "null")
 
88
  , NS_LITERAL_STRING_INIT(kSOAPArrayTypeAttribute, "arrayType")
 
89
  , NS_LITERAL_STRING_INIT(kSOAPArrayOffsetAttribute, "offset")
 
90
  , NS_LITERAL_STRING_INIT(kSOAPArrayPositionAttribute, "position")
 
91
  , NS_LITERAL_STRING_INIT(kAnyTypeSchemaType, "anyType")
 
92
  , NS_LITERAL_STRING_INIT(kAnySimpleTypeSchemaType, "anySimpleType")
 
93
  , NS_LITERAL_STRING_INIT(kArraySOAPType, "Array")
 
94
  , NS_LITERAL_STRING_INIT(kStructSOAPType, "Struct")
 
95
  , NS_LITERAL_STRING_INIT(kStringSchemaType, "string")
 
96
  , NS_LITERAL_STRING_INIT(kBooleanSchemaType, "boolean")
 
97
  , NS_LITERAL_STRING_INIT(kFloatSchemaType, "float")
 
98
  , NS_LITERAL_STRING_INIT(kDoubleSchemaType, "double")
 
99
  , NS_LITERAL_STRING_INIT(kLongSchemaType, "long")
 
100
  , NS_LITERAL_STRING_INIT(kIntSchemaType, "int")
 
101
  , NS_LITERAL_STRING_INIT(kShortSchemaType, "short")
 
102
  , NS_LITERAL_STRING_INIT(kByteSchemaType, "byte")
 
103
  , NS_LITERAL_STRING_INIT(kUnsignedLongSchemaType, "unsignedLong")
 
104
  , NS_LITERAL_STRING_INIT(kUnsignedIntSchemaType, "unsignedInt")
 
105
  , NS_LITERAL_STRING_INIT(kUnsignedShortSchemaType, "unsignedShort")
 
106
  , NS_LITERAL_STRING_INIT(kUnsignedByteSchemaType, "unsignedByte")
 
107
  , NS_LITERAL_STRING_INIT(kNormalizedStringSchemaType, "normalizedString")
 
108
  , NS_LITERAL_STRING_INIT(kTokenSchemaType, "token")
 
109
  , NS_LITERAL_STRING_INIT(kNameSchemaType, "Name")
 
110
  , NS_LITERAL_STRING_INIT(kNCNameSchemaType, "NCName")
 
111
  , NS_LITERAL_STRING_INIT(kDecimalSchemaType, "decimal")
 
112
  , NS_LITERAL_STRING_INIT(kIntegerSchemaType, "integer")
 
113
  , NS_LITERAL_STRING_INIT(kNonPositiveIntegerSchemaType, "nonPositiveInteger")
 
114
  , NS_LITERAL_STRING_INIT(kNonNegativeIntegerSchemaType, "nonNegativeInteger")
 
115
{
 
116
  kSOAPEnvURI[0] = &kSOAPEnvURI1;
 
117
  kSOAPEnvURI[1] = &kSOAPEnvURI2;
 
118
}
 
119
 
 
120
void nsSOAPUtils::GetSpecificChildElement(nsISOAPEncoding * aEncoding,
 
121
                                          nsIDOMElement * aParent,
 
122
                                          const nsAString & aNamespace,
 
123
                                          const nsAString & aType,
 
124
                                          nsIDOMElement * *aElement)
 
125
{
 
126
  nsCOMPtr < nsIDOMElement > sibling;
 
127
 
 
128
  *aElement = nsnull;
 
129
  GetFirstChildElement(aParent, getter_AddRefs(sibling));
 
130
  if (sibling) {
 
131
    GetSpecificSiblingElement(aEncoding, sibling, aNamespace, aType, aElement);
 
132
  }
 
133
}
 
134
 
 
135
void nsSOAPUtils::GetSpecificSiblingElement(nsISOAPEncoding * aEncoding,
 
136
                                            nsIDOMElement * aSibling,
 
137
                                            const nsAString & aNamespace,
 
138
                                            const nsAString & aType,
 
139
                                            nsIDOMElement * *aElement)
 
140
{
 
141
  nsCOMPtr < nsIDOMElement > sibling;
 
142
 
 
143
  *aElement = nsnull;
 
144
  sibling = aSibling;
 
145
  do {
 
146
    nsAutoString name, namespaceURI;
 
147
    sibling->GetLocalName(name);
 
148
    if (name.Equals(aType)) {
 
149
      if (aEncoding) {
 
150
        nsAutoString temp;
 
151
        sibling->GetNamespaceURI(temp);
 
152
        aEncoding->GetInternalSchemaURI(temp, namespaceURI);
 
153
      }
 
154
      else {
 
155
        sibling->GetNamespaceURI(namespaceURI);
 
156
      }
 
157
      if (namespaceURI.Equals(aNamespace)) {
 
158
        *aElement = sibling;
 
159
        NS_ADDREF(*aElement);
 
160
        return;
 
161
      }
 
162
    }
 
163
    nsCOMPtr < nsIDOMElement > temp = sibling;
 
164
    GetNextSiblingElement(temp, getter_AddRefs(sibling));
 
165
  } while (sibling);
 
166
}
 
167
 
 
168
void nsSOAPUtils::GetFirstChildElement(nsIDOMElement * aParent,
 
169
                                       nsIDOMElement ** aElement)
 
170
{
 
171
  nsCOMPtr < nsIDOMNode > child;
 
172
 
 
173
  *aElement = nsnull;
 
174
  aParent->GetFirstChild(getter_AddRefs(child));
 
175
  while (child) {
 
176
    PRUint16 type;
 
177
    child->GetNodeType(&type);
 
178
    if (nsIDOMNode::ELEMENT_NODE == type) {
 
179
      child->QueryInterface(NS_GET_IID(nsIDOMElement), (void **) aElement);
 
180
      break;
 
181
    }
 
182
    nsCOMPtr < nsIDOMNode > temp = child;
 
183
    GetNextSibling(temp, getter_AddRefs(child));
 
184
  }
 
185
}
 
186
 
 
187
void nsSOAPUtils::GetNextSiblingElement(nsIDOMElement * aStart,
 
188
                                        nsIDOMElement ** aElement)
 
189
{
 
190
  nsCOMPtr < nsIDOMNode > sibling;
 
191
 
 
192
  *aElement = nsnull;
 
193
  GetNextSibling(aStart, getter_AddRefs(sibling));
 
194
  while (sibling) {
 
195
    PRUint16 type;
 
196
    sibling->GetNodeType(&type);
 
197
    if (nsIDOMNode::ELEMENT_NODE == type) {
 
198
      sibling->QueryInterface(NS_GET_IID(nsIDOMElement),
 
199
                              (void **) aElement);
 
200
      break;
 
201
    }
 
202
    nsCOMPtr < nsIDOMNode > temp = sibling;
 
203
    GetNextSibling(temp, getter_AddRefs(sibling));
 
204
  }
 
205
}
 
206
 
 
207
nsresult
 
208
    nsSOAPUtils::GetElementTextContent(nsIDOMElement * aElement,
 
209
                                       nsAString & aText)
 
210
{
 
211
  aText.Truncate();
 
212
  nsCOMPtr < nsIDOMNode > child;
 
213
  nsAutoString rtext;
 
214
  aElement->GetFirstChild(getter_AddRefs(child));
 
215
  while (child) {
 
216
    PRUint16 type;
 
217
    child->GetNodeType(&type);
 
218
    if (nsIDOMNode::TEXT_NODE == type
 
219
        || nsIDOMNode::CDATA_SECTION_NODE == type) {
 
220
      nsCOMPtr < nsIDOMText > text = do_QueryInterface(child);
 
221
      nsAutoString data;
 
222
      text->GetData(data);
 
223
      rtext.Append(data);
 
224
    } else if (nsIDOMNode::ELEMENT_NODE == type) {
 
225
      return SOAP_EXCEPTION(NS_ERROR_ILLEGAL_VALUE,"SOAP_UNEXPECTED_ELEMENT", "Unable to retrieve simple content because a child element was present.");
 
226
    }
 
227
    nsCOMPtr < nsIDOMNode > temp = child;
 
228
    GetNextSibling(temp, getter_AddRefs(child));
 
229
  }
 
230
  aText.Assign(rtext);
 
231
  return NS_OK;
 
232
}
 
233
 
 
234
PRBool nsSOAPUtils::HasChildElements(nsIDOMElement * aElement)
 
235
{
 
236
  nsCOMPtr < nsIDOMNode > child;
 
237
 
 
238
  aElement->GetFirstChild(getter_AddRefs(child));
 
239
  while (child) {
 
240
    PRUint16 type;
 
241
    child->GetNodeType(&type);
 
242
    if (nsIDOMNode::ELEMENT_NODE == type) {
 
243
      return PR_TRUE;
 
244
    }
 
245
    nsCOMPtr < nsIDOMNode > temp = child;
 
246
    GetNextSibling(temp, getter_AddRefs(child));
 
247
  }
 
248
 
 
249
  return PR_FALSE;
 
250
}
 
251
 
 
252
void nsSOAPUtils::GetNextSibling(nsIDOMNode * aSibling,
 
253
                                 nsIDOMNode ** aNext)
 
254
{
 
255
  nsCOMPtr < nsIDOMNode > last;
 
256
  nsCOMPtr < nsIDOMNode > current;
 
257
  PRUint16 type;
 
258
 
 
259
  *aNext = nsnull;
 
260
  last = aSibling;
 
261
 
 
262
  last->GetNodeType(&type);
 
263
  if (nsIDOMNode::ENTITY_REFERENCE_NODE == type) {
 
264
    last->GetFirstChild(getter_AddRefs(current));
 
265
    if (!last) {
 
266
      last->GetNextSibling(getter_AddRefs(current));
 
267
    }
 
268
  } else {
 
269
    last->GetNextSibling(getter_AddRefs(current));
 
270
  }
 
271
  while (!current) {
 
272
    last->GetParentNode(getter_AddRefs(current));
 
273
    current->GetNodeType(&type);
 
274
    if (nsIDOMNode::ENTITY_REFERENCE_NODE == type) {
 
275
      last = current;
 
276
      last->GetNextSibling(getter_AddRefs(current));
 
277
    } else {
 
278
      current = nsnull;
 
279
      break;
 
280
    }
 
281
  }
 
282
  *aNext = current;
 
283
  NS_IF_ADDREF(*aNext);
 
284
}
 
285
 
 
286
nsresult
 
287
    nsSOAPUtils::GetNamespaceURI(nsISOAPEncoding * aEncoding,
 
288
                                 nsIDOMElement * aScope,
 
289
                                 const nsAString & aQName,
 
290
                                 nsAString & aURI)
 
291
{
 
292
  aURI.Truncate();
 
293
  PRInt32 i = aQName.FindChar(':');
 
294
  if (i < 0) {
 
295
    return NS_OK;
 
296
  }
 
297
  nsAutoString prefix;
 
298
  prefix = Substring(aQName, 0, i);
 
299
 
 
300
  nsAutoString result;
 
301
  if (prefix.Equals(gSOAPStrings->kXMLPrefix)) {
 
302
    result.Assign(gSOAPStrings->kXMLNamespaceURI);
 
303
  }
 
304
  else {
 
305
 
 
306
    nsresult rc;
 
307
    nsCOMPtr < nsIDOMNode > current = aScope;
 
308
    nsCOMPtr < nsIDOMNamedNodeMap > attrs;
 
309
    nsCOMPtr < nsIDOMNode > temp;
 
310
    nsAutoString value;
 
311
    while (current) {
 
312
      rc = current->GetAttributes(getter_AddRefs(attrs));
 
313
      if (NS_FAILED(rc))
 
314
        return rc;
 
315
      if (attrs) {
 
316
        rc = attrs->GetNamedItemNS(gSOAPStrings->kXMLNamespaceNamespaceURI, prefix,
 
317
                                   getter_AddRefs(temp));
 
318
        if (NS_FAILED(rc))
 
319
          return rc;
 
320
        if (temp) {
 
321
          rc = temp->GetNodeValue(result);
 
322
          if (NS_FAILED(rc))
 
323
            return rc;
 
324
          break;
 
325
        }
 
326
      }
 
327
      rc = current->GetParentNode(getter_AddRefs(temp));
 
328
      if (NS_FAILED(rc))
 
329
        return rc;
 
330
      current = temp;
 
331
    }
 
332
    if (!current)
 
333
      return SOAP_EXCEPTION(NS_ERROR_FAILURE,"SOAP_NAMESPACE", "Unable to resolve prefix in attribute value to namespace URI");
 
334
  }
 
335
  if (aEncoding) {
 
336
    return aEncoding->GetInternalSchemaURI(result,aURI);
 
337
  }
 
338
  aURI.Assign(result);
 
339
  return NS_OK;
 
340
}
 
341
 
 
342
nsresult
 
343
    nsSOAPUtils::GetLocalName(const nsAString & aQName,
 
344
                              nsAString & aLocalName)
 
345
{
 
346
  PRInt32 i = aQName.FindChar(':');
 
347
  if (i < 0)
 
348
    aLocalName = aQName;
 
349
  else
 
350
    aLocalName = Substring(aQName, i+1, aQName.Length() - (i+1));
 
351
  return NS_OK;
 
352
}
 
353
 
 
354
nsresult
 
355
    nsSOAPUtils::MakeNamespacePrefix(nsISOAPEncoding * aEncoding,
 
356
                                     nsIDOMElement * aScope,
 
357
                                     const nsAString & aURI,
 
358
                                     nsAString & aPrefix)
 
359
{
 
360
//  This may change for level 3 serialization, so be sure to gut this
 
361
//  and call the standardized level 3 method when it is available.
 
362
  nsAutoString externalURI;
 
363
  if (aEncoding) {
 
364
    nsresult rc = aEncoding->GetExternalSchemaURI(aURI,externalURI);
 
365
    if (NS_FAILED(rc))
 
366
      return rc;
 
367
  }
 
368
  else {
 
369
    externalURI.Assign(aURI);
 
370
  }
 
371
  aPrefix.Truncate();
 
372
  if (externalURI.IsEmpty())
 
373
    return NS_OK;
 
374
  if (externalURI.Equals(gSOAPStrings->kXMLNamespaceURI)) {
 
375
    aPrefix.Assign(gSOAPStrings->kXMLPrefix);
 
376
    return NS_OK;
 
377
  }
 
378
  nsCOMPtr < nsIDOMNode > current = aScope;
 
379
  nsCOMPtr < nsIDOMNamedNodeMap > attrs;
 
380
  nsCOMPtr < nsIDOMNode > temp;
 
381
  nsAutoString tstr;
 
382
  nsresult rc;
 
383
  PRUint32 maxns = 0;                //  Keep track of max generated NS
 
384
  for (;;) {
 
385
    rc = current->GetAttributes(getter_AddRefs(attrs));
 
386
    if (NS_FAILED(rc))
 
387
      return rc;
 
388
    if (attrs) {
 
389
      PRUint32 i;
 
390
      PRUint32 count;
 
391
      rc = attrs->GetLength(&count);
 
392
      if (NS_FAILED(rc))
 
393
        return PR_FALSE;
 
394
      for (i = 0;i < count;i++) {
 
395
        attrs->Item(i, getter_AddRefs(temp));
 
396
        if (!temp)
 
397
          break;
 
398
        temp->GetNamespaceURI(tstr);
 
399
        if (!tstr.Equals(gSOAPStrings->kXMLNamespaceNamespaceURI))
 
400
          continue;
 
401
        temp->GetNodeValue(tstr);
 
402
        if (tstr.Equals(externalURI)) {
 
403
          nsAutoString prefix;
 
404
          rc = temp->GetLocalName(prefix);
 
405
          if (NS_FAILED(rc))
 
406
            return rc;
 
407
          nsCOMPtr < nsIDOMNode > check = aScope;
 
408
          PRBool hasDecl;
 
409
          nsCOMPtr < nsIDOMElement > echeck;
 
410
          while (check != current) {        // Make sure prefix is not overridden
 
411
            echeck = do_QueryInterface(check);
 
412
            if (echeck) {
 
413
              rc = echeck->
 
414
                  HasAttributeNS(gSOAPStrings->kXMLNamespaceNamespaceURI, prefix,
 
415
                                 &hasDecl);
 
416
              if (NS_FAILED(rc))
 
417
                return rc;
 
418
              if (hasDecl)
 
419
                break;
 
420
              echeck->GetParentNode(getter_AddRefs(check));
 
421
            }
 
422
          }
 
423
          if (check == current) {
 
424
            aPrefix.Assign(prefix);
 
425
            return NS_OK;
 
426
          }
 
427
        }
 
428
        rc = temp->GetLocalName(tstr);
 
429
        if (NS_FAILED(rc))
 
430
          return rc;
 
431
        else {                        //  Decode the generated namespace into a number
 
432
          nsReadingIterator < PRUnichar > i1;
 
433
          nsReadingIterator < PRUnichar > i2;
 
434
          tstr.BeginReading(i1);
 
435
          tstr.EndReading(i2);
 
436
          if (i1 == i2 || *i1 != 'n')
 
437
            continue;
 
438
          i1++;
 
439
          if (i1 == i2 || *i1 != 's')
 
440
            continue;
 
441
          i1++;
 
442
          PRUint32 n = 0;
 
443
          while (i1 != i2) {
 
444
            PRUnichar c = *i1;
 
445
            i1++;
 
446
            if (c < '0' || c > '9') {
 
447
              n = 0;
 
448
              break;
 
449
            }
 
450
            n = n * 10 + (c - '0');
 
451
          }
 
452
          if (n > maxns)
 
453
            maxns = n;
 
454
        }
 
455
      }
 
456
    }
 
457
    current->GetParentNode(getter_AddRefs(temp));
 
458
    if (temp)
 
459
      current = temp;
 
460
    else
 
461
      break;
 
462
  }
 
463
// Create a unique prefix...
 
464
  PRUint32 len = 3;
 
465
  PRUint32 c = maxns + 1;
 
466
  while (c >= 10) {
 
467
    c = c / 10;
 
468
    len++;
 
469
  }
 
470
// Set the length and write it backwards since that's the easiest way..
 
471
  aPrefix.SetLength(len);
 
472
  nsWritingIterator < PRUnichar > i2;
 
473
  aPrefix.EndWriting(i2);
 
474
  c = maxns + 1;
 
475
  while (c > 0) {
 
476
    PRUint32 r = c % 10;
 
477
    c = c / 10;
 
478
    i2--;
 
479
    *i2 = (PRUnichar) (r + '0');
 
480
  }
 
481
  i2--;
 
482
  *i2 = 's';
 
483
  i2--;
 
484
  *i2 = 'n';
 
485
 
 
486
  // Declare the fabricated prefix
 
487
  if (aScope) {
 
488
    tstr.Assign(gSOAPStrings->kXMLNamespacePrefix);
 
489
    tstr.Append(aPrefix);
 
490
    rc = aScope->SetAttributeNS(gSOAPStrings->kXMLNamespaceNamespaceURI,
 
491
                                tstr, externalURI);
 
492
  }
 
493
  return NS_OK;
 
494
}
 
495
 
 
496
/**
 
497
 * Get an attribute, keeping in mind that input NamespaceURIs
 
498
 * may have all been mapped, so we don't know exactly what
 
499
 * we are looking for.  First, directly lookup what tyis type
 
500
 * outputs as.  If that fails, then loop through all attributes
 
501
 * looking for one that matches after mapping to internal types.
 
502
 * Fortunately, where these are used there are not many attributes.
 
503
 */
 
504
PRBool nsSOAPUtils::GetAttribute(nsISOAPEncoding *aEncoding,
 
505
                                  nsIDOMElement * aElement,
 
506
                                  const nsAString & aNamespaceURI,
 
507
                                  const nsAString & aLocalName,
 
508
                                  nsAString & aValue)
 
509
{
 
510
  nsAutoString value;
 
511
  nsresult rc = aEncoding->GetExternalSchemaURI(aNamespaceURI, value);  //  Try most-likely result first.
 
512
  if (NS_FAILED(rc))
 
513
    return PR_FALSE;
 
514
  {
 
515
    nsCOMPtr<nsIDOMAttr> attr;
 
516
    rc = aElement->GetAttributeNodeNS(value, aLocalName, getter_AddRefs(attr));
 
517
    if (NS_FAILED(rc))
 
518
      return PR_FALSE;
 
519
    if (attr) {
 
520
      rc = attr->GetNodeValue(aValue);
 
521
      if (NS_FAILED(rc))
 
522
        return PR_FALSE;
 
523
      return PR_TRUE;
 
524
    }
 
525
  }
 
526
  nsCOMPtr<nsIDOMNamedNodeMap> attrs;
 
527
  rc = aElement->GetAttributes(getter_AddRefs(attrs));
 
528
  if (NS_FAILED(rc))
 
529
    return PR_FALSE;
 
530
  PRUint32 count;
 
531
  rc = attrs->GetLength(&count);
 
532
  if (NS_FAILED(rc))
 
533
    return PR_FALSE;
 
534
  PRUint32 i;
 
535
  for (i = 0; i < count; i++) {
 
536
    nsCOMPtr<nsIDOMNode> attrnode;
 
537
    rc = attrs->Item(i, getter_AddRefs(attrnode));
 
538
    if (NS_FAILED(rc))
 
539
      return PR_FALSE;
 
540
    rc = attrnode->GetLocalName(value);
 
541
    if (NS_FAILED(rc))
 
542
      return PR_FALSE;
 
543
    if (!aLocalName.Equals(value))
 
544
      continue;
 
545
    rc = attrnode->GetNamespaceURI(value);
 
546
    if (NS_FAILED(rc))
 
547
      return PR_FALSE;
 
548
    nsAutoString internal;
 
549
    rc = aEncoding->GetInternalSchemaURI(value, internal);
 
550
    if (NS_FAILED(rc))
 
551
      return PR_FALSE;
 
552
    if (!aNamespaceURI.Equals(internal))
 
553
      continue;
 
554
    rc = attrnode->GetNodeValue(aValue);
 
555
    if (NS_FAILED(rc))
 
556
      return PR_FALSE;
 
557
    return PR_TRUE;
 
558
  }
 
559
  SetAStringToNull(aValue);
 
560
  return PR_FALSE;
 
561
}