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
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/
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
15
* The Original Code is mozilla.org code.
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.
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.
37
* ***** END LICENSE BLOCK ***** */
39
#include "nsSOAPUtils.h"
40
#include "nsIDOMText.h"
41
#include "nsISOAPEncoding.h"
42
#include "nsIDOMNamedNodeMap.h"
43
#include "nsIDOMAttr.h"
45
#include "nsSOAPException.h"
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")
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")
116
kSOAPEnvURI[0] = &kSOAPEnvURI1;
117
kSOAPEnvURI[1] = &kSOAPEnvURI2;
120
void nsSOAPUtils::GetSpecificChildElement(nsISOAPEncoding * aEncoding,
121
nsIDOMElement * aParent,
122
const nsAString & aNamespace,
123
const nsAString & aType,
124
nsIDOMElement * *aElement)
126
nsCOMPtr < nsIDOMElement > sibling;
129
GetFirstChildElement(aParent, getter_AddRefs(sibling));
131
GetSpecificSiblingElement(aEncoding, sibling, aNamespace, aType, aElement);
135
void nsSOAPUtils::GetSpecificSiblingElement(nsISOAPEncoding * aEncoding,
136
nsIDOMElement * aSibling,
137
const nsAString & aNamespace,
138
const nsAString & aType,
139
nsIDOMElement * *aElement)
141
nsCOMPtr < nsIDOMElement > sibling;
146
nsAutoString name, namespaceURI;
147
sibling->GetLocalName(name);
148
if (name.Equals(aType)) {
151
sibling->GetNamespaceURI(temp);
152
aEncoding->GetInternalSchemaURI(temp, namespaceURI);
155
sibling->GetNamespaceURI(namespaceURI);
157
if (namespaceURI.Equals(aNamespace)) {
159
NS_ADDREF(*aElement);
163
nsCOMPtr < nsIDOMElement > temp = sibling;
164
GetNextSiblingElement(temp, getter_AddRefs(sibling));
168
void nsSOAPUtils::GetFirstChildElement(nsIDOMElement * aParent,
169
nsIDOMElement ** aElement)
171
nsCOMPtr < nsIDOMNode > child;
174
aParent->GetFirstChild(getter_AddRefs(child));
177
child->GetNodeType(&type);
178
if (nsIDOMNode::ELEMENT_NODE == type) {
179
child->QueryInterface(NS_GET_IID(nsIDOMElement), (void **) aElement);
182
nsCOMPtr < nsIDOMNode > temp = child;
183
GetNextSibling(temp, getter_AddRefs(child));
187
void nsSOAPUtils::GetNextSiblingElement(nsIDOMElement * aStart,
188
nsIDOMElement ** aElement)
190
nsCOMPtr < nsIDOMNode > sibling;
193
GetNextSibling(aStart, getter_AddRefs(sibling));
196
sibling->GetNodeType(&type);
197
if (nsIDOMNode::ELEMENT_NODE == type) {
198
sibling->QueryInterface(NS_GET_IID(nsIDOMElement),
202
nsCOMPtr < nsIDOMNode > temp = sibling;
203
GetNextSibling(temp, getter_AddRefs(sibling));
208
nsSOAPUtils::GetElementTextContent(nsIDOMElement * aElement,
212
nsCOMPtr < nsIDOMNode > child;
214
aElement->GetFirstChild(getter_AddRefs(child));
217
child->GetNodeType(&type);
218
if (nsIDOMNode::TEXT_NODE == type
219
|| nsIDOMNode::CDATA_SECTION_NODE == type) {
220
nsCOMPtr < nsIDOMText > text = do_QueryInterface(child);
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.");
227
nsCOMPtr < nsIDOMNode > temp = child;
228
GetNextSibling(temp, getter_AddRefs(child));
234
PRBool nsSOAPUtils::HasChildElements(nsIDOMElement * aElement)
236
nsCOMPtr < nsIDOMNode > child;
238
aElement->GetFirstChild(getter_AddRefs(child));
241
child->GetNodeType(&type);
242
if (nsIDOMNode::ELEMENT_NODE == type) {
245
nsCOMPtr < nsIDOMNode > temp = child;
246
GetNextSibling(temp, getter_AddRefs(child));
252
void nsSOAPUtils::GetNextSibling(nsIDOMNode * aSibling,
255
nsCOMPtr < nsIDOMNode > last;
256
nsCOMPtr < nsIDOMNode > current;
262
last->GetNodeType(&type);
263
if (nsIDOMNode::ENTITY_REFERENCE_NODE == type) {
264
last->GetFirstChild(getter_AddRefs(current));
266
last->GetNextSibling(getter_AddRefs(current));
269
last->GetNextSibling(getter_AddRefs(current));
272
last->GetParentNode(getter_AddRefs(current));
273
current->GetNodeType(&type);
274
if (nsIDOMNode::ENTITY_REFERENCE_NODE == type) {
276
last->GetNextSibling(getter_AddRefs(current));
283
NS_IF_ADDREF(*aNext);
287
nsSOAPUtils::GetNamespaceURI(nsISOAPEncoding * aEncoding,
288
nsIDOMElement * aScope,
289
const nsAString & aQName,
293
PRInt32 i = aQName.FindChar(':');
298
prefix = Substring(aQName, 0, i);
301
if (prefix.Equals(gSOAPStrings->kXMLPrefix)) {
302
result.Assign(gSOAPStrings->kXMLNamespaceURI);
307
nsCOMPtr < nsIDOMNode > current = aScope;
308
nsCOMPtr < nsIDOMNamedNodeMap > attrs;
309
nsCOMPtr < nsIDOMNode > temp;
312
rc = current->GetAttributes(getter_AddRefs(attrs));
316
rc = attrs->GetNamedItemNS(gSOAPStrings->kXMLNamespaceNamespaceURI, prefix,
317
getter_AddRefs(temp));
321
rc = temp->GetNodeValue(result);
327
rc = current->GetParentNode(getter_AddRefs(temp));
333
return SOAP_EXCEPTION(NS_ERROR_FAILURE,"SOAP_NAMESPACE", "Unable to resolve prefix in attribute value to namespace URI");
336
return aEncoding->GetInternalSchemaURI(result,aURI);
343
nsSOAPUtils::GetLocalName(const nsAString & aQName,
344
nsAString & aLocalName)
346
PRInt32 i = aQName.FindChar(':');
350
aLocalName = Substring(aQName, i+1, aQName.Length() - (i+1));
355
nsSOAPUtils::MakeNamespacePrefix(nsISOAPEncoding * aEncoding,
356
nsIDOMElement * aScope,
357
const nsAString & aURI,
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;
364
nsresult rc = aEncoding->GetExternalSchemaURI(aURI,externalURI);
369
externalURI.Assign(aURI);
372
if (externalURI.IsEmpty())
374
if (externalURI.Equals(gSOAPStrings->kXMLNamespaceURI)) {
375
aPrefix.Assign(gSOAPStrings->kXMLPrefix);
378
nsCOMPtr < nsIDOMNode > current = aScope;
379
nsCOMPtr < nsIDOMNamedNodeMap > attrs;
380
nsCOMPtr < nsIDOMNode > temp;
383
PRUint32 maxns = 0; // Keep track of max generated NS
385
rc = current->GetAttributes(getter_AddRefs(attrs));
391
rc = attrs->GetLength(&count);
394
for (i = 0;i < count;i++) {
395
attrs->Item(i, getter_AddRefs(temp));
398
temp->GetNamespaceURI(tstr);
399
if (!tstr.Equals(gSOAPStrings->kXMLNamespaceNamespaceURI))
401
temp->GetNodeValue(tstr);
402
if (tstr.Equals(externalURI)) {
404
rc = temp->GetLocalName(prefix);
407
nsCOMPtr < nsIDOMNode > check = aScope;
409
nsCOMPtr < nsIDOMElement > echeck;
410
while (check != current) { // Make sure prefix is not overridden
411
echeck = do_QueryInterface(check);
414
HasAttributeNS(gSOAPStrings->kXMLNamespaceNamespaceURI, prefix,
420
echeck->GetParentNode(getter_AddRefs(check));
423
if (check == current) {
424
aPrefix.Assign(prefix);
428
rc = temp->GetLocalName(tstr);
431
else { // Decode the generated namespace into a number
432
nsReadingIterator < PRUnichar > i1;
433
nsReadingIterator < PRUnichar > i2;
434
tstr.BeginReading(i1);
436
if (i1 == i2 || *i1 != 'n')
439
if (i1 == i2 || *i1 != 's')
446
if (c < '0' || c > '9') {
450
n = n * 10 + (c - '0');
457
current->GetParentNode(getter_AddRefs(temp));
463
// Create a unique prefix...
465
PRUint32 c = maxns + 1;
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);
479
*i2 = (PRUnichar) (r + '0');
486
// Declare the fabricated prefix
488
tstr.Assign(gSOAPStrings->kXMLNamespacePrefix);
489
tstr.Append(aPrefix);
490
rc = aScope->SetAttributeNS(gSOAPStrings->kXMLNamespaceNamespaceURI,
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.
504
PRBool nsSOAPUtils::GetAttribute(nsISOAPEncoding *aEncoding,
505
nsIDOMElement * aElement,
506
const nsAString & aNamespaceURI,
507
const nsAString & aLocalName,
511
nsresult rc = aEncoding->GetExternalSchemaURI(aNamespaceURI, value); // Try most-likely result first.
515
nsCOMPtr<nsIDOMAttr> attr;
516
rc = aElement->GetAttributeNodeNS(value, aLocalName, getter_AddRefs(attr));
520
rc = attr->GetNodeValue(aValue);
526
nsCOMPtr<nsIDOMNamedNodeMap> attrs;
527
rc = aElement->GetAttributes(getter_AddRefs(attrs));
531
rc = attrs->GetLength(&count);
535
for (i = 0; i < count; i++) {
536
nsCOMPtr<nsIDOMNode> attrnode;
537
rc = attrs->Item(i, getter_AddRefs(attrnode));
540
rc = attrnode->GetLocalName(value);
543
if (!aLocalName.Equals(value))
545
rc = attrnode->GetNamespaceURI(value);
548
nsAutoString internal;
549
rc = aEncoding->GetInternalSchemaURI(value, internal);
552
if (!aNamespaceURI.Equals(internal))
554
rc = attrnode->GetNodeValue(aValue);
559
SetAStringToNull(aValue);