Back to index

lightning-sunbird  0.9+nobinonly
wspfactory.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 2001
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   John Bandhauer (jband@netscape.com)
00024  *   Vidur Apparao (vidur@netscape.com)
00025  *
00026  * Alternatively, the contents of this file may be used under the terms of
00027  * either the GNU General Public License Version 2 or later (the "GPL"), or
00028  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00029  * in which case the provisions of the GPL or the LGPL are applicable instead
00030  * of those above. If you wish to allow use of your version of this file only
00031  * under the terms of either the GPL or the LGPL, and not to allow others to
00032  * use your version of this file under the terms of the MPL, indicate your
00033  * decision by deleting the provisions above and replace them with the notice
00034  * and other provisions required by the GPL or the LGPL. If you do not delete
00035  * the provisions above, a recipient may use your version of this file under
00036  * the terms of any one of the MPL, the GPL or the LGPL.
00037  *
00038  * ***** END LICENSE BLOCK ***** */
00039 
00040 #include "wspprivate.h"
00041 
00042 // NSPR includes
00043 #include "prprf.h"
00044 #include "nsIWebServiceErrorHandler.h"
00045 
00046 /***************************************************************************/
00047 class WSPAsyncProxyCreator : public nsIWSDLLoadListener
00048 {
00049 public:
00050   WSPAsyncProxyCreator();
00051   virtual ~WSPAsyncProxyCreator();
00052 
00053   NS_DECL_ISUPPORTS
00054   NS_DECL_NSIWSDLLOADLISTENER
00055   NS_DECL_NSIWEBSERVICEERRORHANDLER
00056 
00057   nsresult Run(const nsAString & wsdlURL, const nsAString & portname,
00058                const nsAString & qualifier, PRBool isAsync,
00059                nsIWebServiceProxyCreationListener* aListener);
00060 
00061 private:
00062   nsString mWSDLURL;
00063   nsString mPortName;
00064   nsString mQualifier;
00065   PRBool   mIsAsync;
00066   nsCOMPtr<nsIWebServiceProxyCreationListener> mListener;
00067 };
00068 
00069 WSPAsyncProxyCreator::WSPAsyncProxyCreator()
00070 {
00071 }
00072 
00073 WSPAsyncProxyCreator::~WSPAsyncProxyCreator()
00074 {
00075   // do nothing...
00076 }
00077 
00078 NS_IMPL_ISUPPORTS2(WSPAsyncProxyCreator,
00079                    nsIWSDLLoadListener,
00080                    nsIWebServiceErrorHandler)
00081 
00082 nsresult
00083 WSPAsyncProxyCreator::Run(const nsAString& wsdlURL, const nsAString& portname,
00084                           const nsAString& qualifier, PRBool isAsync,
00085                           nsIWebServiceProxyCreationListener* aListener)
00086 {
00087   mWSDLURL   = wsdlURL;
00088   mPortName  = portname;
00089   mQualifier = qualifier;
00090   mIsAsync   = isAsync;
00091   mListener  = aListener;
00092 
00093   nsresult rv;
00094   nsCOMPtr<nsIWSDLLoader> loader =
00095     do_CreateInstance(NS_WSDLLOADER_CONTRACTID, &rv);
00096   if (!loader) {
00097     return rv;
00098   }
00099 
00100   rv = loader->LoadAsync(mWSDLURL, mPortName, this);
00101   if (NS_FAILED(rv)) {
00102     return rv;
00103   }
00104 
00105   return NS_OK;
00106 }
00107 
00108 /* void onLoad (in nsIWSDLPort port); */
00109 NS_IMETHODIMP
00110 WSPAsyncProxyCreator::OnLoad(nsIWSDLPort *port)
00111 {
00112   nsresult rv;
00113 
00114   nsCOMPtr<nsIWSPInterfaceInfoService> iis =
00115     do_GetService(NS_WSP_INTERFACEINFOSERVICE_CONTRACTID, &rv);
00116   if (NS_FAILED(rv)) {
00117     return OnError(rv,
00118                    NS_LITERAL_STRING("Can't get nsIWSPInterfaceInfoService"));
00119   }
00120   nsCOMPtr<nsIInterfaceInfoManager> manager;
00121   nsCOMPtr<nsIInterfaceInfo> iinfo;
00122 
00123   rv = iis->InfoForPort(port, mWSDLURL, mQualifier, mIsAsync,
00124                         getter_AddRefs(manager), getter_AddRefs(iinfo));
00125   if (NS_FAILED(rv)) {
00126     return OnError(rv,
00127                    NS_LITERAL_STRING("Couldn't find interface info for port"));
00128   }
00129 
00130   nsCOMPtr<nsIWebServiceProxy> proxy =
00131     do_CreateInstance(NS_WEBSERVICEPROXY_CONTRACTID, &rv);
00132   if (NS_FAILED(rv)) {
00133     return OnError(rv, NS_LITERAL_STRING("Couldn't create proxy"));
00134   }
00135 
00136   // XXX We want to pass the manager too.
00137   rv = proxy->Init(port, iinfo, manager, mQualifier, mIsAsync);
00138   if (NS_FAILED(rv)) {
00139     return OnError(rv, NS_LITERAL_STRING("Couldn't init proxy"));
00140   }
00141 
00142   mListener->OnLoad(proxy);
00143   return NS_OK;
00144 }
00145 
00146 /* void onError (in nsresult status, in AString statusMessage); */
00147 NS_IMETHODIMP
00148 WSPAsyncProxyCreator::OnError(nsresult status, const nsAString & statusMessage)
00149 {
00150   // XXX need to build an exception. It would be nice to have a generic
00151   // exception class!
00152 
00153   nsCOMPtr<nsIException> e = new WSPException(status, 
00154     NS_ConvertUCS2toUTF8(statusMessage).get(), nsnull);
00155   if (!e) {
00156     return NS_ERROR_OUT_OF_MEMORY;
00157   }
00158 
00159   mListener->OnError(e);
00160   return NS_OK;
00161 }
00162 
00163 
00164 /***************************************************************************/
00165 
00166 WSPFactory::WSPFactory()
00167 {
00168 }
00169 
00170 WSPFactory::~WSPFactory()
00171 {
00172 }
00173 
00174 NS_IMPL_ISUPPORTS1_CI(WSPFactory, nsIWebServiceProxyFactory)
00175 
00176 /* nsIWebServiceProxy createProxy (in AString wsdlURL, in AString portname, in AString qualifier, in boolean isAsync); */
00177 NS_IMETHODIMP
00178 WSPFactory::CreateProxy(const nsAString & wsdlURL,
00179                         const nsAString & portname,
00180                         const nsAString & qualifier,
00181                         PRBool isAsync,
00182                         nsIWebServiceProxy **_retval)
00183 {
00184   return NS_ERROR_NOT_IMPLEMENTED;
00185 }
00186 
00187 /* void createProxyAsync (in AString wsdlURL, in AString portname, in AString qualifier, in boolean isAsync, in nsIWebServiceProxyCreationListener listener); */
00188 NS_IMETHODIMP
00189 WSPFactory::CreateProxyAsync(const nsAString& wsdlURL,
00190                              const nsAString& portname,
00191                              const nsAString& qualifier, PRBool isAsync,
00192                              nsIWebServiceProxyCreationListener *listener)
00193 {
00194   if (!listener) {
00195     // A listener is required.
00196     return NS_ERROR_NULL_POINTER;
00197   }
00198 
00199   nsCOMPtr<WSPAsyncProxyCreator> creator = new WSPAsyncProxyCreator();
00200   if(!creator)
00201     return NS_ERROR_OUT_OF_MEMORY;
00202   nsresult rv = creator->Run(wsdlURL, portname, qualifier, isAsync, listener);
00203   if (rv == NS_ERROR_WSDL_NOT_ENABLED)
00204     rv = creator->OnError(rv, NS_LITERAL_STRING("WSDL not enabled"));
00205   return rv;
00206 }
00207 
00208 
00209 #define P2M_ESCAPE_CHARACTER '_'
00210 
00211 nsresult
00212 WSPFactory::C2XML(const nsACString& aCIdentifier,
00213                   nsAString& aXMLIdentifier)
00214 {
00215   nsReadingIterator<char> current, end;
00216 
00217   aXMLIdentifier.Truncate();
00218   aCIdentifier.BeginReading(current);
00219   aCIdentifier.EndReading(end);
00220 
00221   while (current != end) {
00222     char ch = *current++;
00223     PRUnichar uch;
00224     if (ch == P2M_ESCAPE_CHARACTER) {
00225       // Grab the next 4 characters that make up the
00226       // escape sequence
00227       PRUint16 i;
00228       PRUint16 acc = 0;
00229       for (i = 0; (i < 4) && (current != end); i++) {
00230         acc <<= 4;
00231         ch = *current++;
00232         if (('0' <= ch) && (ch <= '9')) {
00233           acc += ch - '0';
00234         }
00235         else if (('a' <= ch) && (ch <= 'f')) {
00236           acc += ch - ('a' - 10);
00237         }
00238         else if (('A' <= ch) && (ch <= 'F')) {
00239           acc += ch - ('A' - 10);
00240         }
00241         else {
00242           return NS_ERROR_FAILURE;
00243         }
00244       }
00245 
00246       // If we didn't get through the entire escape sequence, then
00247       // it's an error.
00248       if (i < 4) {
00249         return NS_ERROR_FAILURE;
00250       }
00251 
00252       uch = PRUnichar(acc);
00253     }
00254     else {
00255       uch = PRUnichar(ch);
00256     }
00257     aXMLIdentifier.Append(uch);
00258   }
00259 
00260   return NS_OK;
00261 }
00262 
00263 void
00264 WSPFactory::XML2C(const nsAString& aXMLIndentifier,
00265                   nsACString& aCIdentifier)
00266 {
00267   nsReadingIterator<PRUnichar> current, end;
00268 
00269   aCIdentifier.Truncate();
00270   aXMLIndentifier.BeginReading(current);
00271   aXMLIndentifier.EndReading(end);
00272 
00273   while (current != end) {
00274     PRUnichar uch = *current++;
00275     if (((PRUnichar('a') <= uch) && (uch <= PRUnichar('z'))) ||
00276         ((PRUnichar('A') <= uch) && (uch <= PRUnichar('Z'))) ||
00277         ((PRUnichar('0') <= uch) && (uch <= PRUnichar('9')))) {
00278       // Casting is safe since we know that it's an ASCII character
00279       aCIdentifier.Append(char(uch));
00280     }
00281     else {
00282       // Escape the character and append to the string
00283       char buf[6];
00284       buf[0] = P2M_ESCAPE_CHARACTER;
00285 
00286       for (int i = 3; i >= 0; i--) {
00287         PRUint16 v = (uch >> 4*i) & 0xf;
00288         buf[4-i] = (char) (v + ((v > 9) ? 'a'-10 : '0'));
00289       }
00290 
00291       buf[5] = 0;
00292 
00293       aCIdentifier.Append(buf, 5);
00294     }
00295   }
00296 }