Back to index

lightning-sunbird  0.9+nobinonly
nsUpdateNotification.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 Communicator client code, released
00016  * March 31, 1998.
00017  *
00018  * The Initial Developer of the Original Code is
00019  * Netscape Communications Corporation.
00020  * Portions created by the Initial Developer are Copyright (C) 1998-1999
00021  * the Initial Developer. All Rights Reserved.
00022  *
00023  * Contributor(s):
00024  *   Doug Turner <dougt@netscape.com>
00025  *   Pierre Phaneuf <pp@ludusdesign.com>
00026  *
00027  * Alternatively, the contents of this file may be used under the terms of
00028  * either of the GNU General Public License Version 2 or later (the "GPL"),
00029  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00030  * in which case the provisions of the GPL or the LGPL are applicable instead
00031  * of those above. If you wish to allow use of your version of this file only
00032  * under the terms of either the GPL or the LGPL, and not to allow others to
00033  * use your version of this file under the terms of the MPL, indicate your
00034  * decision by deleting the provisions above and replace them with the notice
00035  * and other provisions required by the GPL or the LGPL. If you do not delete
00036  * the provisions above, a recipient may use your version of this file under
00037  * the terms of any one of the MPL, the GPL or the LGPL.
00038  *
00039  * ***** END LICENSE BLOCK ***** */
00040 
00041 
00042 #include "nsUpdateNotification.h"
00043 
00044 #include "nsISupports.h"
00045 #include "nsIServiceManager.h"
00046 #include "nsCOMPtr.h"
00047 #include "nsIComponentManager.h"
00048 #include "nsIGenericFactory.h"
00049 #include "nsIRDFContainer.h"
00050 #include "nsIRDFDataSource.h"
00051 #include "nsIRDFService.h"
00052 #include "nsIRDFRemoteDataSource.h"
00053 #include "nsRDFCID.h"
00054 #include "nsIRDFXMLSink.h"
00055 
00056 #include "nsIPrefBranch.h"
00057 #include "nsIPrefService.h"
00058 #include "nsISoftwareUpdate.h"
00059 
00060 #define NC_RDF_NAME                "http://home.netscape.com/NC-rdf#name"
00061 #define NC_RDF_SOURCE                     "http://home.netscape.com/NC-rdf#source"
00062 #define NC_RDF_URL                        "http://home.netscape.com/NC-rdf#url"
00063 #define NC_RDF_CHILD               "http://home.netscape.com/NC-rdf#child"
00064 
00065 #define NC_RDF_NOTIFICATION_ROOT   "http://home.netscape.com/NC-rdf#SoftwareNotificationRoot"
00066 #define NC_XPI_SOURCES              "http://home.netscape.com/NC-rdf#SoftwareUpdateDataSources"
00067 #define NC_XPI_PACKAGES             "http://home.netscape.com/NC-rdf#SoftwarePackages"
00068 
00069 #define NC_XPI_TITLE        "http://home.netscape.com/NC-rdf#title"
00070 #define NC_XPI_REGKEY       "http://home.netscape.com/NC-rdf#registryKey"
00071 #define NC_XPI_VERSION      "http://home.netscape.com/NC-rdf#version"
00072 #define NC_XPI_DESCRIPTION  "http://home.netscape.com/NC-rdf#description"
00073 
00074 static NS_DEFINE_CID(kRDFServiceCID,   NS_RDFSERVICE_CID);
00075 static NS_DEFINE_CID(kRDFContainerCID, NS_RDFCONTAINER_CID);
00076 
00077 nsIRDFResource* nsXPINotifierImpl::kXPI_NotifierSources = nsnull;
00078 nsIRDFResource* nsXPINotifierImpl::kXPI_NotifierPackages = nsnull;
00079 nsIRDFResource* nsXPINotifierImpl::kXPI_NotifierPackage_Title = nsnull;
00080 nsIRDFResource* nsXPINotifierImpl::kXPI_NotifierPackage_Version = nsnull;
00081 nsIRDFResource* nsXPINotifierImpl::kXPI_NotifierPackage_Description = nsnull;
00082 nsIRDFResource* nsXPINotifierImpl::kXPI_NotifierPackage_RegKey = nsnull;
00083 
00084 nsIRDFResource* nsXPINotifierImpl::kNC_NotificationRoot = nsnull;
00085 nsIRDFResource* nsXPINotifierImpl::kNC_Source = nsnull;
00086 nsIRDFResource* nsXPINotifierImpl::kNC_Name = nsnull;
00087 nsIRDFResource* nsXPINotifierImpl::kNC_URL = nsnull;
00088 nsIRDFResource* nsXPINotifierImpl::kNC_Child = nsnull;
00089 
00090 
00091 nsXPINotifierImpl::nsXPINotifierImpl()
00092     : mRDF(nsnull)
00093 {
00094     mPendingRefreshes = 0;
00095 
00096     static NS_DEFINE_CID(kRDFInMemoryDataSourceCID, NS_RDFINMEMORYDATASOURCE_CID);
00097     
00098     mNotifications = do_CreateInstance(kRDFInMemoryDataSourceCID);
00099 }
00100 
00101 
00102 nsXPINotifierImpl::~nsXPINotifierImpl()
00103 {
00104     NS_IF_RELEASE(mRDF);
00105 
00106     NS_IF_RELEASE(kXPI_NotifierSources);
00107     NS_IF_RELEASE(kXPI_NotifierPackages);
00108     NS_IF_RELEASE(kXPI_NotifierPackage_Title);
00109     NS_IF_RELEASE(kXPI_NotifierPackage_Version);
00110     NS_IF_RELEASE(kXPI_NotifierPackage_Description);
00111     NS_IF_RELEASE(kXPI_NotifierPackage_RegKey);
00112 
00113        NS_IF_RELEASE(kNC_NotificationRoot);
00114     NS_IF_RELEASE(kNC_Source);
00115        NS_IF_RELEASE(kNC_Name);
00116        NS_IF_RELEASE(kNC_URL);
00117        NS_IF_RELEASE(kNC_Child);
00118 }
00119 
00120 
00121 NS_IMPL_ISUPPORTS2(nsXPINotifierImpl, nsIRDFXMLSinkObserver, nsIUpdateNotification)
00122 
00123 
00124 nsresult
00125 nsXPINotifierImpl::NotificationEnabled(PRBool* aReturn)
00126 {
00127     *aReturn = PR_FALSE;
00128 
00129     nsCOMPtr<nsIPrefBranch> prefBranch = do_GetService(NS_PREFSERVICE_CONTRACTID);
00130 
00131     if ( prefBranch )
00132     {
00133         PRBool value;
00134         // check to see if we are on.
00135         nsresult rv = prefBranch->GetBoolPref( (const char*) XPINSTALL_NOTIFICATIONS_ENABLE, &value);
00136 
00137         if (NS_SUCCEEDED(rv) && value)
00138         {
00139             // check to see the last time we did anything.  Since flash does not have a persistant
00140             // way to do poll invervals longer than a session, we will implemented that here by using the
00141             // preferences.  
00142 
00143             PRInt32 intervalHours = 0;
00144             
00145             PRTime now            = 0;
00146             PRInt32 nowSec        = 0;
00147 
00148             PRInt32 lastTime      = 0;
00149             
00150             rv = prefBranch->GetIntPref(XPINSTALL_NOTIFICATIONS_INTERVAL, &intervalHours);
00151 
00152             if (NS_FAILED(rv))
00153             {
00154                 intervalHours = 7*24;  // default at once a week
00155                 rv = prefBranch->SetIntPref(XPINSTALL_NOTIFICATIONS_INTERVAL, intervalHours);
00156             }
00157 
00158             rv = prefBranch->GetIntPref(XPINSTALL_NOTIFICATIONS_LASTDATE, &lastTime);
00159     
00160             now = PR_Now();
00161 
00162             // nowSec = now / 1000000
00163             LL_DIV(nowSec, now, 1000000);
00164 
00165             if (NS_FAILED(rv) || lastTime == 0)
00166             {
00167                 rv = prefBranch->SetIntPref(XPINSTALL_NOTIFICATIONS_LASTDATE, nowSec);
00168                 return NS_OK;
00169             }
00170             
00171             if ((lastTime + (intervalHours*60*24)) <= nowSec)
00172             {
00173                 *aReturn = PR_TRUE;
00174             }
00175         }
00176     }
00177     
00178     return NS_OK;
00179 }
00180 
00181 nsresult
00182 nsXPINotifierImpl::Init()
00183 {
00184     PRBool enabled;
00185 
00186     NotificationEnabled(&enabled);
00187 
00188     if (!enabled)
00189         return NS_ERROR_FAILURE;
00190     
00191     if (mNotifications == nsnull)
00192         return NS_ERROR_FAILURE;
00193 
00194     nsresult rv;
00195     nsCOMPtr<nsIRDFDataSource> distributors;
00196     nsCOMPtr<nsIRDFContainer> distributorsContainer;
00197     nsCOMPtr <nsISimpleEnumerator> distributorEnumerator;
00198     PRBool moreElements;
00199     
00200     // Read the distributor registry
00201     rv = CallGetService(kRDFServiceCID, &mRDF);
00202     if (NS_FAILED(rv)) return rv;
00203     
00204     if (! kXPI_NotifierSources)
00205        {
00206           mRDF->GetResource(NC_XPI_SOURCES,       &kXPI_NotifierSources);
00207        mRDF->GetResource(NC_XPI_PACKAGES,      &kXPI_NotifierPackages);
00208        mRDF->GetResource(NC_XPI_TITLE,         &kXPI_NotifierPackage_Title);
00209        mRDF->GetResource(NC_XPI_VERSION,       &kXPI_NotifierPackage_Version);
00210        mRDF->GetResource(NC_XPI_DESCRIPTION,   &kXPI_NotifierPackage_Description);
00211        mRDF->GetResource(NC_XPI_REGKEY,        &kXPI_NotifierPackage_RegKey);
00212 
00213        mRDF->GetResource(NC_RDF_NOTIFICATION_ROOT,  &kNC_NotificationRoot);
00214        
00215        mRDF->GetResource(NC_RDF_SOURCE,             &kNC_Source);
00216           mRDF->GetResource(NC_RDF_NAME,               &kNC_Name);
00217           mRDF->GetResource(NC_RDF_URL,                &kNC_URL);
00218           mRDF->GetResource(NC_RDF_CHILD,              &kNC_Child);
00219 
00220        }
00221 
00222     rv = OpenRemoteDataSource(BASE_DATASOURCE_URL, PR_TRUE, getter_AddRefs(distributors));
00223     if (NS_FAILED(rv)) return rv;
00224 
00225     distributorsContainer = do_CreateInstance(kRDFContainerCID, &rv);
00226     if (NS_SUCCEEDED(rv))
00227     {
00228         rv = distributorsContainer->Init(distributors, kXPI_NotifierSources);
00229         
00230         if (NS_SUCCEEDED(rv))
00231         {
00232             rv = distributorsContainer->GetElements(getter_AddRefs(distributorEnumerator));
00233 
00234             if (NS_SUCCEEDED(rv))
00235             {
00236                 distributorEnumerator->HasMoreElements(&moreElements);
00237                 while (moreElements) 
00238                 {
00239                     nsCOMPtr<nsISupports> i;
00240                     rv = distributorEnumerator->GetNext(getter_AddRefs(i));
00241                     if (NS_FAILED(rv)) break;
00242 
00243                     nsCOMPtr<nsIRDFResource> aDistributor(do_QueryInterface(i, &rv));
00244                     if (NS_FAILED(rv)) break;
00245 
00246                     char* uri;
00247                     nsCOMPtr<nsIRDFDataSource> remoteDatasource;
00248                     aDistributor->GetValue(&uri);
00249 
00250                     rv = OpenRemoteDataSource(uri, PR_FALSE, getter_AddRefs(remoteDatasource));
00251                                    nsMemory::Free(uri);
00252                     if (NS_FAILED(rv)) break;
00253                     
00254                     distributorEnumerator->HasMoreElements(&moreElements);
00255                 }
00256             }
00257         }
00258     }
00259     return NS_OK;
00260 }
00261 
00262 
00263 PRBool 
00264 nsXPINotifierImpl::IsNewerOrUninstalled(const char* regKey, const char* versionString)
00265 {
00266     PRBool needJar = PR_FALSE;
00267 
00268     REGERR status = VR_ValidateComponent( (char*) regKey );
00269 
00270     if ( status == REGERR_NOFIND || status == REGERR_NOFILE )
00271     {
00272         // either component is not in the registry or it's a file
00273         // node and the physical file is missing
00274         needJar = PR_TRUE;
00275     }
00276     else
00277     {
00278         VERSION oldVersion;
00279 
00280         status = VR_GetVersion( (char*)regKey, &oldVersion );
00281         
00282         if ( status != REGERR_OK )
00283         {
00284             needJar = PR_TRUE;
00285         }
00286         else 
00287         {
00288             VERSION newVersion;
00289 
00290             StringToVersionNumbers(versionString, &(newVersion).major, &(newVersion).minor, &(newVersion).release, &(newVersion).build);
00291             
00292             if ( CompareVersions(&oldVersion, &newVersion) < 0 )
00293                 needJar = PR_TRUE;
00294         }
00295     }
00296     return needJar;
00297 }
00298 
00299 
00300 PRInt32
00301 nsXPINotifierImpl::CompareVersions(VERSION *oldversion, VERSION *newVersion)
00302 {
00303     PRInt32 diff;
00304     
00305     if ( oldversion->major == newVersion->major ) 
00306     {
00307         if ( oldversion->minor == newVersion->minor ) 
00308         {
00309             if ( oldversion->release == newVersion->release ) 
00310             {
00311                 if ( oldversion->build == newVersion->build )
00312                     diff = 0;
00313                 else if ( oldversion->build > newVersion->build )
00314                     diff = 1;
00315                 else
00316                     diff = -1;
00317             }
00318             else if ( oldversion->release > newVersion->release )
00319                 diff = 1;
00320             else
00321                 diff = -1;
00322         }
00323         else if (  oldversion->minor > newVersion->minor )
00324             diff = 1;
00325         else
00326             diff = -1;
00327     }
00328     else if ( oldversion->major > newVersion->major )
00329         diff = 1;
00330     else
00331         diff = -1;
00332 
00333     return diff;
00334 }
00335 
00336 
00337 void
00338 nsXPINotifierImpl::StringToVersionNumbers(const nsString& version, int32 *aMajor, int32 *aMinor, int32 *aRelease, int32 *aBuild)    
00339 {
00340     PRInt32 errorCode;
00341 
00342     int dot = version.FindChar('.', 0);
00343     
00344     if ( dot == -1 ) 
00345     {
00346         *aMajor = version.ToInteger(&errorCode);
00347     }
00348     else  
00349     {
00350         nsString majorStr;
00351         version.Mid(majorStr, 0, dot);
00352         *aMajor  = majorStr.ToInteger(&errorCode);
00353 
00354         int prev = dot+1;
00355         dot = version.FindChar('.',prev);
00356         if ( dot == -1 ) 
00357         {
00358             nsString minorStr;
00359             version.Mid(minorStr, prev, version.Length() - prev);
00360             *aMinor = minorStr.ToInteger(&errorCode);
00361         }
00362         else 
00363         {
00364             nsString minorStr;
00365             version.Mid(minorStr, prev, dot - prev);
00366             *aMinor = minorStr.ToInteger(&errorCode);
00367 
00368             prev = dot+1;
00369             dot = version.FindChar('.',prev);
00370             if ( dot == -1 ) 
00371             {
00372                 nsString releaseStr;
00373                 version.Mid(releaseStr, prev, version.Length() - prev);
00374                 *aRelease = releaseStr.ToInteger(&errorCode);
00375             }
00376             else 
00377             {
00378                 nsString releaseStr;
00379                 version.Mid(releaseStr, prev, dot - prev);
00380                 *aRelease = releaseStr.ToInteger(&errorCode);
00381     
00382                 prev = dot+1;
00383                 if ( version.Length() > dot ) 
00384                 {
00385                     nsString buildStr;
00386                     version.Mid(buildStr, prev, version.Length() - prev);
00387                     *aBuild = buildStr.ToInteger(&errorCode);
00388                }
00389             }
00390         }
00391     }
00392 }
00393 
00394 nsresult
00395 nsXPINotifierImpl::OpenRemoteDataSource(const char* aURL, PRBool blocking, nsIRDFDataSource** aResult)
00396 {
00397     static NS_DEFINE_CID(kRDFXMLDataSourceCID, NS_RDFXMLDATASOURCE_CID);
00398     nsresult rv;
00399 
00400     nsCOMPtr<nsIRDFRemoteDataSource> remote = do_CreateInstance(kRDFXMLDataSourceCID, &rv);
00401     if (NS_FAILED(rv)) return rv;
00402 
00403     rv = remote->Init(aURL);
00404     if (NS_SUCCEEDED(rv)) 
00405     {
00406         if (! blocking)
00407         {
00408             nsCOMPtr<nsIRDFXMLSink> sink = do_QueryInterface(remote, &rv);
00409             if (NS_FAILED(rv)) return rv;
00410 
00411             rv = sink->AddXMLSinkObserver(this);
00412             if (NS_FAILED(rv)) return rv;
00413         }
00414 
00415         rv = remote->Refresh(blocking);
00416         if (NS_FAILED(rv)) return rv;
00417 
00418         nsCOMPtr<nsIRDFDataSource> result = do_QueryInterface(remote, &rv);
00419         *aResult = result;
00420         NS_IF_ADDREF(*aResult);
00421         return rv;
00422     }
00423     else 
00424     {
00425         // we've already loaded this datasource. use cached copy
00426         return mRDF->GetDataSource(aURL, aResult);
00427     }
00428 }
00429 
00430 
00431 NS_IMETHODIMP
00432 nsXPINotifierImpl::New(nsISupports* aOuter, REFNSIID aIID, void** aResult)
00433 {
00434     NS_PRECONDITION(aOuter == nsnull, "no aggregation");
00435     if (aOuter)
00436         return NS_ERROR_NO_AGGREGATION;
00437 
00438     nsXPINotifierImpl* result = new nsXPINotifierImpl();
00439     if (! result)
00440         return NS_ERROR_OUT_OF_MEMORY;
00441 
00442     NS_ADDREF(result); // stabilize
00443 
00444     nsresult rv;
00445     rv = result->Init();
00446     if (NS_SUCCEEDED(rv)) {
00447         rv = result->QueryInterface(aIID, aResult);
00448     }
00449 
00450     NS_RELEASE(result);
00451     return rv;
00452 }
00453 
00454 
00455 NS_IMETHODIMP
00456 nsXPINotifierImpl::OnBeginLoad(nsIRDFXMLSink *aSink)
00457 {
00458     return NS_OK;
00459 }
00460 
00461 NS_IMETHODIMP
00462 nsXPINotifierImpl::OnInterrupt(nsIRDFXMLSink *aSink)
00463 {
00464     return NS_OK;
00465 }
00466 NS_IMETHODIMP
00467 nsXPINotifierImpl::OnResume(nsIRDFXMLSink *aSink)
00468 {
00469     return NS_OK;
00470 }
00471 
00472 NS_IMETHODIMP
00473 nsXPINotifierImpl::OnEndLoad(nsIRDFXMLSink *aSink)
00474 {
00475     nsresult rv;
00476 
00477     (void) aSink->RemoveXMLSinkObserver(this);
00478 
00479     nsCOMPtr<nsIRDFDataSource> distributorDataSource = do_QueryInterface(aSink, &rv);
00480     if (NS_FAILED(rv)) return rv;
00481 
00482     nsCOMPtr <nsISimpleEnumerator> packageEnumerator;
00483     PRBool moreElements;
00484 
00485     nsCOMPtr<nsIRDFContainer> distributorContainer =
00486             do_CreateInstance(kRDFContainerCID, &rv);
00487     if (NS_SUCCEEDED(rv))
00488     {
00489         rv = distributorContainer->Init(distributorDataSource, kXPI_NotifierPackages);
00490         if (NS_SUCCEEDED(rv))
00491         {
00492             rv = distributorContainer->GetElements(getter_AddRefs(packageEnumerator));
00493             if (NS_SUCCEEDED(rv))
00494             {
00495                 packageEnumerator->HasMoreElements(&moreElements);
00496                 while (moreElements) 
00497                 {
00498                     nsCOMPtr<nsISupports> i;
00499 
00500                     rv = packageEnumerator->GetNext(getter_AddRefs(i));
00501                     if (NS_FAILED(rv)) break;
00502 
00503                     nsCOMPtr<nsIRDFResource> aPackage(do_QueryInterface(i, &rv));
00504                     if (NS_FAILED(rv)) break;
00505     
00506                     
00507                     // Get the version information
00508                     nsCOMPtr<nsIRDFNode> versionNode;
00509                     distributorDataSource->GetTarget(aPackage, 
00510                                                      kXPI_NotifierPackage_Version, 
00511                                                      PR_TRUE, 
00512                                                      getter_AddRefs(versionNode));
00513 
00514                     nsCOMPtr<nsIRDFLiteral> version(do_QueryInterface(versionNode, &rv));
00515                     if (NS_FAILED(rv)) break;
00516 
00517                     // Get the regkey information
00518                     nsCOMPtr<nsIRDFNode> regkeyNode;
00519                     distributorDataSource->GetTarget(aPackage, 
00520                                                      kXPI_NotifierPackage_RegKey, 
00521                                                      PR_TRUE, 
00522                                                      getter_AddRefs(regkeyNode));
00523 
00524                     nsCOMPtr<nsIRDFLiteral> regkey(do_QueryInterface(regkeyNode, &rv));
00525                     if (NS_FAILED(rv)) break;
00526 
00527                     // convert them into workable nsAutoStrings
00528                     PRUnichar* regkeyCString;
00529                     regkey->GetValue(&regkeyCString);
00530                     nsString regKeyString(regkeyCString);
00531                     
00532                     PRUnichar* versionCString;
00533                     version->GetValue(&versionCString);
00534                     nsString versionString(versionCString);
00535                                    nsMemory::Free(versionCString);
00536                                    nsMemory::Free(regkeyCString);
00537 
00538                     // check to see if this software title should be "flashed"
00539                     if (IsNewerOrUninstalled(NS_ConvertUCS2toUTF8(regKeyString).get(), NS_ConvertUCS2toUTF8(versionString).get()))
00540                     {
00541                         //assert into flash
00542                         
00543                         nsCOMPtr<nsIRDFNode> urlNode;
00544                         distributorDataSource->GetTarget(kXPI_NotifierPackages, 
00545                                                          kNC_URL, 
00546                                                          PR_TRUE, 
00547                                                          getter_AddRefs(urlNode));
00548 
00549                         nsCOMPtr<nsIRDFLiteral> url(do_QueryInterface(urlNode, &rv));
00550                         if (NS_FAILED(rv)) break;
00551 
00552 
00553                         nsCOMPtr<nsIRDFNode> titleNode;
00554                         distributorDataSource->GetTarget(kXPI_NotifierPackages, 
00555                                                          kXPI_NotifierPackage_Title, 
00556                                                          PR_TRUE, 
00557                                                          getter_AddRefs(titleNode));
00558 
00559                         nsCOMPtr<nsIRDFLiteral> title(do_QueryInterface(titleNode, &rv));
00560                         if (NS_FAILED(rv)) break;
00561 
00562                         nsCOMPtr<nsIRDFDataSource> ds = do_QueryInterface(mNotifications);
00563 
00564                         ds->Assert(aPackage, kNC_Name, title, PR_TRUE);
00565                         ds->Assert(aPackage, kNC_URL, url, PR_TRUE);
00566 
00567                         ds->Assert(kNC_NotificationRoot, kNC_Child, aPackage, PR_TRUE);
00568                         break;
00569 
00570                     }
00571                 }
00572             }
00573         }
00574     }
00575        VR_Close();
00576     return NS_OK;
00577 }
00578 
00579 
00580 NS_IMETHODIMP
00581 nsXPINotifierImpl::OnError(nsIRDFXMLSink *aSink, nsresult aResult, const PRUnichar* aErrorMsg)
00582 {
00583     (void) aSink->RemoveXMLSinkObserver(this);
00584     return NS_OK;
00585 }
00586 
00587 
00588 NS_IMETHODIMP
00589 nsXPINotifierImpl::DisplayUpdateDialog(void)
00590 {
00591     nsresult rv;
00592     nsCOMPtr <nsISimpleEnumerator> packages;
00593     PRBool moreElements;
00594 
00595     nsCOMPtr<nsIRDFDataSource> ds = do_QueryInterface(mNotifications, &rv);
00596 
00597     if (NS_SUCCEEDED(rv))
00598     {
00599         rv = ds->GetAllResources(getter_AddRefs(packages));
00600         if (NS_SUCCEEDED(rv))
00601         {
00602             packages->HasMoreElements(&moreElements);
00603             while (moreElements) 
00604             {
00605                 nsCOMPtr<nsISupports> i;
00606 
00607                 rv = packages->GetNext(getter_AddRefs(i));
00608                 if (NS_FAILED(rv)) break;
00609 
00610                 nsCOMPtr<nsIRDFResource> aPackage(do_QueryInterface(i, &rv));
00611                 if (NS_FAILED(rv)) break;
00612 
00613                 
00614                 // Get the version information
00615                 nsCOMPtr<nsIRDFNode> name;
00616                 ds->GetTarget(aPackage, 
00617                               nsXPINotifierImpl::kNC_Name, 
00618                               PR_TRUE, 
00619                               getter_AddRefs(name));
00620 
00621                 nsCOMPtr<nsIRDFLiteral> nameLiteral = do_QueryInterface(name, &rv);
00622                 if (NS_FAILED(rv)) break;
00623             }
00624         }
00625     }
00626     return rv;
00627 }
00628 
00629 
00630