1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
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.
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
39 #include "nsISOAPParameter.h"
40 #include "nsSOAPMessage.h"
41 #include "nsISOAPEncoder.h"
42 #include "nsISOAPDecoder.h"
43 #include "nsSOAPEncoding.h"
44 #include "nsSOAPUtils.h"
45 #include "nsSOAPException.h"
46 #include "nsIServiceManager.h"
47 #include "nsIComponentManager.h"
48 #include "nsIDOMNodeList.h"
49 #include "nsISchema.h"
50 #include "nsISchemaLoader.h"
51 #include "nsSOAPUtils.h"
52 #include "nsReadableUtils.h"
53 #include "nsIClassInfoImpl.h"
56 // callback for deleting the encodings from the nsObjectHashtable, mEncodings,
57 // in the nsSOAPEncodingRegistry
59 static PRBool PR_CALLBACK
60 DeleteEncodingEntry(nsHashKey
*aKey
, void *aData
, void *aClosure
)
62 NS_DELETEXPCOM((nsSOAPEncoding
*)aData
);
67 // First the registry, which is shared between associated encodings
68 // but is never seen by xpconnect.
71 NS_IMPL_ISUPPORTS1(nsSOAPEncodingRegistry
, nsISOAPEncodingRegistry
)
73 nsSOAPEncodingRegistry::nsSOAPEncodingRegistry(nsISOAPEncoding
*aEncoding
)
74 : mEncodings(nsnull
, nsnull
, DeleteEncodingEntry
, nsnull
, 4)
77 aEncoding
->GetStyleURI(style
);
78 NS_ASSERTION(!style
.IsEmpty(), "nsSOAPEncoding Regsitry constructed without style");
80 nsStringKey
styleKey(style
);
81 mEncodings
.Put(&styleKey
, aEncoding
);
85 nsSOAPEncodingRegistry::GetAssociatedEncoding(const nsAString
& aStyleURI
,
87 nsISOAPEncoding
**aEncoding
)
89 NS_SOAP_ENSURE_ARG_STRING(aStyleURI
);
90 NS_ENSURE_ARG_POINTER(aEncoding
);
92 nsStringKey
styleKey(aStyleURI
);
93 *aEncoding
= (nsISOAPEncoding
*) mEncodings
.Get(&styleKey
);
95 nsCOMPtr
<nsISOAPEncoding
> defaultEncoding
;
96 nsCAutoString
encodingContractid(NS_SOAPENCODING_CONTRACTID_PREFIX
);
97 AppendUTF16toUTF8(aStyleURI
, encodingContractid
);
98 defaultEncoding
= do_GetService(encodingContractid
.get());
99 if (defaultEncoding
|| aCreateIf
) {
100 nsCOMPtr
<nsISOAPEncoding
> encoding
= new nsSOAPEncoding(aStyleURI
,this,defaultEncoding
);
101 *aEncoding
= encoding
;
103 NS_ADDREF(*aEncoding
);
104 mEncodings
.Put(&styleKey
, encoding
);
107 return NS_ERROR_FAILURE
;
112 // need to AddRef the *-style pointer coming from mEncodings
113 NS_ADDREF(*aEncoding
);
119 nsSOAPEncodingRegistry::SetSchemaCollection(nsISchemaCollection
*
122 NS_ENSURE_ARG(aSchemaCollection
);
123 mSchemaCollection
= aSchemaCollection
;
128 nsSOAPEncodingRegistry::GetSchemaCollection(nsISchemaCollection
**
131 NS_ENSURE_ARG_POINTER(aSchemaCollection
);
132 if (!mSchemaCollection
) {
134 nsCOMPtr
<nsISchemaLoader
> loader
=
135 do_GetService(NS_SCHEMALOADER_CONTRACTID
, &rv
);
138 mSchemaCollection
= do_QueryInterface(loader
);
139 if (!mSchemaCollection
)
140 return NS_ERROR_FAILURE
;
142 *aSchemaCollection
= mSchemaCollection
;
143 NS_ADDREF(*aSchemaCollection
);
148 // Second, the encodings themselves.
150 NS_IMPL_CI_INTERFACE_GETTER1(nsSOAPEncoding
, nsISOAPEncoding
)
151 NS_IMPL_QUERY_INTERFACE1_CI(nsSOAPEncoding
, nsISOAPEncoding
)
153 // Due to circular referencing with the registry we abdicate all ref counting
154 // to the registry itself. When the registry reaches zero it destroys all
155 // the encodings with itself.
156 NS_IMETHODIMP_(nsrefcnt
)
157 nsSOAPEncoding::AddRef(void)
160 return mRegistry
->AddRef();
164 NS_IMETHODIMP_(nsrefcnt
)
165 nsSOAPEncoding::Release()
168 return mRegistry
->Release();
172 nsSOAPEncoding::nsSOAPEncoding() : mEncoders(),
177 mStyleURI
.Assign(gSOAPStrings
->kSOAPEncURI11
);
178 mRegistry
= new nsSOAPEncodingRegistry(this);
179 mDefaultEncoding
= do_GetService(NS_DEFAULTSOAPENCODING_1_1_CONTRACTID
);
182 nsSOAPEncoding::nsSOAPEncoding(const nsAString
& aStyleURI
,
183 nsSOAPEncodingRegistry
* aRegistry
,
184 nsISOAPEncoding
* aDefaultEncoding
)
190 mStyleURI
.Assign(aStyleURI
);
191 mRegistry
= aRegistry
;
192 mDefaultEncoding
= aDefaultEncoding
;
196 nsSOAPEncoding::SetSchemaCollection(nsISchemaCollection
*
199 NS_ENSURE_ARG(aSchemaCollection
);
201 return NS_ERROR_FAILURE
;
202 return mRegistry
->SetSchemaCollection(aSchemaCollection
);
206 nsSOAPEncoding::GetSchemaCollection(nsISchemaCollection
**
209 NS_ENSURE_ARG_POINTER(aSchemaCollection
);
211 return NS_ERROR_FAILURE
;
212 return mRegistry
->GetSchemaCollection(aSchemaCollection
);
215 /* readonly attribute AString styleURI; */
216 NS_IMETHODIMP
nsSOAPEncoding::GetStyleURI(nsAString
& aStyleURI
)
218 aStyleURI
.Assign(mStyleURI
);
222 /* nsISOAPEncoding getAssociatedEncoding (in AString aStyleURI, in boolean aCreateIf); */
224 nsSOAPEncoding::GetAssociatedEncoding(const nsAString
& aStyleURI
,
226 nsISOAPEncoding
** _retval
)
228 NS_SOAP_ENSURE_ARG_STRING(aStyleURI
);
229 NS_ENSURE_ARG_POINTER(_retval
);
231 return NS_ERROR_FAILURE
;
232 return mRegistry
->GetAssociatedEncoding(aStyleURI
, aCreateIf
, _retval
);
235 /* nsISOAPEncoder setEncoder (in AString aKey, in nsISOAPEncoder aEncoder); */
237 nsSOAPEncoding::SetEncoder(const nsAString
& aKey
,
238 nsISOAPEncoder
* aEncoder
)
240 NS_SOAP_ENSURE_ARG_STRING(aKey
);
241 NS_ENSURE_ARG(aEncoder
);
242 nsStringKey
nameKey(aKey
);
244 mEncoders
.Put(&nameKey
, aEncoder
, nsnull
);
246 mEncoders
.Remove(&nameKey
, nsnull
);
251 /* nsISOAPEncoder getEncoder (in AString aKey); */
253 nsSOAPEncoding::GetEncoder(const nsAString
& aKey
,
254 nsISOAPEncoder
** _retval
)
256 NS_SOAP_ENSURE_ARG_STRING(aKey
);
257 NS_ENSURE_ARG_POINTER(_retval
);
258 nsStringKey
nameKey(aKey
);
259 *_retval
= (nsISOAPEncoder
*) mEncoders
.Get(&nameKey
);
260 if (*_retval
== nsnull
&& mDefaultEncoding
) {
261 return mDefaultEncoding
->GetEncoder(aKey
, _retval
);
266 /* nsISOAPDecoder setDecoder (in AString aKey, in nsISOAPDecoder aDecoder); */
268 nsSOAPEncoding::SetDecoder(const nsAString
& aKey
,
269 nsISOAPDecoder
* aDecoder
)
271 NS_SOAP_ENSURE_ARG_STRING(aKey
);
272 NS_ENSURE_ARG(aDecoder
);
273 nsStringKey
nameKey(aKey
);
275 mDecoders
.Put(&nameKey
, aDecoder
, nsnull
);
277 mDecoders
.Remove(&nameKey
, nsnull
);
282 /* nsISOAPDecoder getDecoder (in AString aKey); */
284 nsSOAPEncoding::GetDecoder(const nsAString
& aKey
,
285 nsISOAPDecoder
** _retval
)
287 NS_SOAP_ENSURE_ARG_STRING(aKey
);
288 NS_ENSURE_ARG_POINTER(_retval
);
289 nsStringKey
nameKey(aKey
);
290 *_retval
= (nsISOAPDecoder
*) mDecoders
.Get(&nameKey
);
291 if (*_retval
== nsnull
&& mDefaultEncoding
) {
292 return mDefaultEncoding
->GetDecoder(aKey
, _retval
);
297 /* nsIDOMElement encode (in nsIVariant aSource, in AString aNamespaceURI, in AString aName, in nsISchemaType aSchemaType, in nsISOAPAttachments aAttachments, in nsIDOMElement aDestination); */
299 nsSOAPEncoding::Encode(nsIVariant
* aSource
,
300 const nsAString
& aNamespaceURI
,
301 const nsAString
& aName
,
302 nsISchemaType
* aSchemaType
,
303 nsISOAPAttachments
* aAttachments
,
304 nsIDOMElement
* aDestination
,
305 nsIDOMElement
** _retval
)
307 NS_ENSURE_ARG(aSource
);
308 NS_ENSURE_ARG_POINTER(_retval
);
310 nsCOMPtr
<nsISOAPEncoder
> encoder
;
311 nsresult rv
= GetDefaultEncoder(getter_AddRefs(encoder
));
315 return encoder
->Encode(this, aSource
, aNamespaceURI
, aName
,
316 aSchemaType
, aAttachments
, aDestination
,
320 return SOAP_EXCEPTION(NS_ERROR_NOT_IMPLEMENTED
,"SOAP_DEFAULT_ENCODER", "Encoding style does not have a default encoder.");
323 /* nsIVariant decode (in nsIDOMElement aSource, in nsISchemaType aSchemaType, in nsISOAPAttachments aAttachments); */
325 nsSOAPEncoding::Decode(nsIDOMElement
* aSource
,
326 nsISchemaType
* aSchemaType
,
327 nsISOAPAttachments
* aAttachments
,
328 nsIVariant
** _retval
)
330 NS_ENSURE_ARG(aSource
);
331 NS_ENSURE_ARG_POINTER(_retval
);
332 nsCOMPtr
<nsISOAPDecoder
> decoder
;
333 nsresult rv
= GetDefaultDecoder(getter_AddRefs(decoder
));
337 return decoder
->Decode(this, aSource
, aSchemaType
, aAttachments
,
341 return SOAP_EXCEPTION(NS_ERROR_NOT_IMPLEMENTED
,"SOAP_DEFAULT_ENCODER", "Encoding style does not have a default decoder.");
344 /* attribute nsISOAPEncoder defaultEncoder; */
346 nsSOAPEncoding::GetDefaultEncoder(nsISOAPEncoder
* *aDefaultEncoder
)
348 NS_ENSURE_ARG_POINTER(aDefaultEncoder
);
349 if (mDefaultEncoding
&& !mDefaultEncoder
) {
350 return mDefaultEncoding
->GetDefaultEncoder(aDefaultEncoder
);
352 *aDefaultEncoder
= mDefaultEncoder
;
353 NS_IF_ADDREF(*aDefaultEncoder
);
358 nsSOAPEncoding::SetDefaultEncoder(nsISOAPEncoder
* aDefaultEncoder
)
360 mDefaultEncoder
= aDefaultEncoder
;
364 /* attribute nsISOAPDecoder defaultDecoder; */
366 nsSOAPEncoding::GetDefaultDecoder(nsISOAPDecoder
* *aDefaultDecoder
)
368 NS_ENSURE_ARG_POINTER(aDefaultDecoder
);
369 if (mDefaultEncoding
&& !mDefaultDecoder
) {
370 return mDefaultEncoding
->GetDefaultDecoder(aDefaultDecoder
);
372 *aDefaultDecoder
= mDefaultDecoder
;
373 NS_IF_ADDREF(*aDefaultDecoder
);
378 nsSOAPEncoding::SetDefaultDecoder(nsISOAPDecoder
* aDefaultDecoder
)
380 mDefaultDecoder
= aDefaultDecoder
;
385 nsSOAPEncoding::MapSchemaURI(const nsAString
& aExternalURI
,
386 const nsAString
& aInternalURI
,
390 if (aExternalURI
.IsEmpty() || aInternalURI
.IsEmpty()) // Permit no empty URIs.
391 return SOAP_EXCEPTION(NS_ERROR_ILLEGAL_VALUE
,"SOAP_SCHEMA_URI_MAPPING", "No schema URI mapping possible of empty strings.");
392 nsStringKey
externalKey(aExternalURI
);
393 if (mMappedExternal
.Exists(&externalKey
)) {
394 *_retval
= PR_FALSE
; // Do not permit duplicate external
398 nsStringKey
internalKey(aInternalURI
);
399 if (mMappedInternal
.Exists(&internalKey
)) {
400 *_retval
= PR_FALSE
; // Do not permit duplicate internal
404 nsCOMPtr
<nsIWritableVariant
> p
=
405 do_CreateInstance(NS_VARIANT_CONTRACTID
, &rc
);
408 rc
= p
->SetAsAString(aExternalURI
);
411 mMappedInternal
.Put(&internalKey
, p
);
414 nsCOMPtr
<nsIWritableVariant
> p
=
415 do_CreateInstance(NS_VARIANT_CONTRACTID
, &rc
);
418 rc
= p
->SetAsAString(aInternalURI
);
421 mMappedExternal
.Put(&externalKey
, p
);
427 /* boolean unmapSchemaURI (in AString aExternalURI); */
428 NS_IMETHODIMP
nsSOAPEncoding::UnmapSchemaURI(const nsAString
& aExternalURI
, PRBool
*_retval
)
430 nsStringKey
externalKey(aExternalURI
);
431 nsCOMPtr
<nsIVariant
> internal
= dont_AddRef(static_cast<nsIVariant
*>(mMappedExternal
.Get(&externalKey
)));
433 nsAutoString internalstr
;
434 nsresult rc
= internal
->GetAsAString(internalstr
);
437 nsStringKey
internalKey(internalstr
);
438 mMappedExternal
.Remove(&externalKey
);
439 mMappedInternal
.Remove(&internalKey
);
450 /* AString getInternalSchemaURI (in AString aExternalURI); */
451 NS_IMETHODIMP
nsSOAPEncoding::GetInternalSchemaURI(const nsAString
& aExternalURI
, nsAString
& _retval
)
453 if (mMappedExternal
.Count()) {
454 nsStringKey
externalKey(aExternalURI
);
455 nsCOMPtr
<nsIVariant
> internal
= dont_AddRef(static_cast<nsIVariant
*>(mMappedExternal
.Get(&externalKey
)));
457 return internal
->GetAsAString(_retval
);
460 if (mDefaultEncoding
) {
461 return mDefaultEncoding
->GetInternalSchemaURI(aExternalURI
, _retval
);
463 _retval
.Assign(aExternalURI
);
467 /* AString getExternalSchemaURI (in AString aInternalURI); */
468 NS_IMETHODIMP
nsSOAPEncoding::GetExternalSchemaURI(const nsAString
& aInternalURI
, nsAString
& _retval
)
470 if (mMappedInternal
.Count()) {
471 nsStringKey
internalKey(aInternalURI
);
472 nsCOMPtr
<nsIVariant
> external
= dont_AddRef(static_cast<nsIVariant
*>(mMappedInternal
.Get(&internalKey
)));
474 return external
->GetAsAString(_retval
);
477 if (mDefaultEncoding
) {
478 return mDefaultEncoding
->GetExternalSchemaURI(aInternalURI
, _retval
);
480 _retval
.Assign(aInternalURI
);