Back to index

lightning-sunbird  0.9+nobinonly
nsRDFDataSourceDS.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Pierre Phaneuf <pp@ludusdesign.com>
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either of the GNU General Public License Version 2 or later (the "GPL"),
00027  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 
00040 #include "nsCRT.h"
00041 #include "nsCOMPtr.h"
00042 
00043 #include "nsIRDFService.h"
00044 #include "nsRDFCID.h"
00045 #include "nsIRDFDataSource.h"
00046 #include "nsIRDFRemoteDataSource.h"
00047 #include "rdf.h"
00048 
00049 #include "nsIServiceManager.h"
00050 
00051 #include "nsEnumeratorUtils.h"
00052 
00053 #include "nsXPIDLString.h"
00054 
00055 #ifdef NS_DEBUG
00056 #include <stdio.h>
00057 #endif
00058 
00082 #define NS_RDF_DSDS_NAMESPACE_URI "http://www.mozilla.org/rdf/vocab/dsds#"
00083 #define NS_RDF_ARCSOUT NS_RDF_DSDS_NAMESPACE_URI "arcsout"
00084 #define NS_RDF_ARCSIN NS_RDF_DSDS_NAMESPACE_URI "arcsin"
00085 #define NS_RDF_SUBJECT NS_RDF_DSDS_NAMESPACE_URI "subject"
00086 #define NS_RDF_PREDICATE NS_RDF_DSDS_NAMESPACE_URI "predicate"
00087 #define NS_RDF_OBJECT NS_RDF_DSDS_NAMESPACE_URI "object"
00088 
00089 #define NC_RDF_Name  NC_NAMESPACE_URI "Name"
00090 #define NC_RDF_Value NC_NAMESPACE_URI "Value"
00091 #define NC_RDF_Child NC_NAMESPACE_URI "child"
00092 
00093 static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
00094 
00095 class nsRDFDataSourceDataSource :
00096     public nsIRDFDataSource,
00097     public nsIRDFRemoteDataSource {
00098 public: 
00099   NS_DECL_ISUPPORTS
00100   NS_DECL_NSIRDFDATASOURCE
00101   NS_DECL_NSIRDFREMOTEDATASOURCE
00102 
00103   nsRDFDataSourceDataSource();
00104   virtual ~nsRDFDataSourceDataSource();
00105   
00106 private:
00107   nsCString mURI;
00108   nsCOMPtr<nsIRDFDataSource> mDataSource;
00109 
00110   static nsIRDFResource* kNC_Name;
00111   static nsIRDFResource* kNC_Value;
00112   static nsIRDFResource* kNC_Child;
00113   
00114 };
00115 
00116 nsIRDFResource* nsRDFDataSourceDataSource::kNC_Name=nsnull;
00117 nsIRDFResource* nsRDFDataSourceDataSource::kNC_Value=nsnull;
00118 nsIRDFResource* nsRDFDataSourceDataSource::kNC_Child=nsnull;
00119 
00120 
00121 nsRDFDataSourceDataSource::nsRDFDataSourceDataSource()
00122 {
00123 }
00124 
00125 nsRDFDataSourceDataSource::~nsRDFDataSourceDataSource()
00126 {
00127 }
00128 
00129 
00130 NS_IMPL_ISUPPORTS2(nsRDFDataSourceDataSource,
00131                    nsIRDFDataSource,
00132                    nsIRDFRemoteDataSource)
00133 
00134 
00138 /* readonly attribute boolean loaded; */
00139 NS_IMETHODIMP nsRDFDataSourceDataSource::GetLoaded(PRBool *aLoaded)
00140 {
00141     nsCOMPtr<nsIRDFRemoteDataSource> remote =
00142         do_QueryInterface(mDataSource);
00143     if (remote) {
00144         return remote->GetLoaded(aLoaded);
00145     }
00146     *aLoaded = PR_TRUE;
00147     return NS_OK;
00148 }
00149 
00150 /* void Init (in string uri); */
00151 NS_IMETHODIMP
00152 nsRDFDataSourceDataSource::Init(const char *uri)
00153 {
00154   nsresult rv;
00155 
00156   mURI = uri;
00157 
00158   // cut off "rdf:datasource?"
00159   NS_NAMED_LITERAL_CSTRING(prefix, "rdf:datasource");
00160   nsCAutoString mInnerURI;
00161   mInnerURI = Substring(mURI, prefix.Length() + 1);
00162   // bail if datasorce is empty or we're trying to inspect ourself
00163   if (mInnerURI.IsEmpty() || mInnerURI == prefix) {
00164       mURI.Truncate();
00165       return NS_ERROR_INVALID_ARG;
00166   }
00167   nsCOMPtr<nsIRDFService> rdf(do_GetService(kRDFServiceCID, &rv));
00168   rv = rdf->GetDataSource(mInnerURI.get(), getter_AddRefs(mDataSource));
00169   if (NS_FAILED(rv)) {
00170       mURI.Truncate();
00171       NS_WARNING("Could not get inner datasource");
00172       return rv;
00173   }
00174 
00175   // get RDF resources
00176   
00177   if (!kNC_Name) {
00178     rdf->GetResource(NS_LITERAL_CSTRING(NC_RDF_Name), &kNC_Name);
00179     rdf->GetResource(NS_LITERAL_CSTRING(NC_RDF_Child), &kNC_Child);
00180     rdf->GetResource(NS_LITERAL_CSTRING(NC_RDF_Value), &kNC_Value);
00181   }
00182 
00183 #ifdef DEBUG_alecf
00184   printf("nsRDFDataSourceDataSource::Init(%s)\n", uri);
00185 #endif
00186   
00187   return NS_OK;
00188 }
00189 
00190 /* void Refresh (in boolean aBlocking); */
00191 NS_IMETHODIMP nsRDFDataSourceDataSource::Refresh(PRBool aBlocking)
00192 {
00193     nsCOMPtr<nsIRDFRemoteDataSource> remote =
00194         do_QueryInterface(mDataSource);
00195     if (remote) {
00196         return remote->Refresh(aBlocking);
00197     }
00198     return NS_OK;
00199 }
00200 
00201 /* void Flush (); */
00202 NS_IMETHODIMP nsRDFDataSourceDataSource::Flush()
00203 {
00204     return NS_ERROR_NOT_IMPLEMENTED;
00205 }
00206 
00207 /* void FlushTo (in string aURI); */
00208 NS_IMETHODIMP nsRDFDataSourceDataSource::FlushTo(const char *aURI)
00209 {
00210     return NS_ERROR_NOT_IMPLEMENTED;
00211 }
00212 
00217 /* readonly attribute string URI; */
00218 NS_IMETHODIMP
00219 nsRDFDataSourceDataSource::GetURI(char * *aURI)
00220 {
00221 #ifdef DEBUG_alecf
00222   printf("nsRDFDataSourceDataSource::GetURI()\n");
00223 #endif
00224   *aURI = ToNewCString(mURI);
00225   
00226   return NS_OK;
00227 }
00228 
00229 /* nsIRDFResource GetSource (in nsIRDFResource aProperty, in nsIRDFNode aTarget, in boolean aTruthValue); */
00230 NS_IMETHODIMP
00231 nsRDFDataSourceDataSource::GetSource(nsIRDFResource *aProperty,
00232                                      nsIRDFNode *aTarget,
00233                                      PRBool aTruthValue,
00234                                      nsIRDFResource **_retval)
00235 {
00236   return NS_RDF_NO_VALUE;
00237 }
00238 
00239 /* nsISimpleEnumerator GetSources (in nsIRDFResource aProperty, in nsIRDFNode aTarget, in boolean aTruthValue); */
00240 NS_IMETHODIMP
00241 nsRDFDataSourceDataSource::GetSources(nsIRDFResource *aProperty,
00242                                       nsIRDFNode *aTarget,
00243                                       PRBool aTruthValue,
00244                                       nsISimpleEnumerator **_retval)
00245 {
00246   return NS_RDF_NO_VALUE;
00247 }
00248 
00249 /* nsIRDFNode GetTarget (in nsIRDFResource aSource, in nsIRDFResource aProperty, in boolean aTruthValue); */
00250 NS_IMETHODIMP
00251 nsRDFDataSourceDataSource::GetTarget(nsIRDFResource *aSource,
00252                                      nsIRDFResource *aProperty,
00253                                      PRBool aTruthValue,
00254                                      nsIRDFNode **_retval)
00255 {
00256 #ifdef DEBUG_alecf
00257   nsXPIDLCString sourceval;
00258   nsXPIDLCString propval;
00259   aSource->GetValue(getter_Copies(sourceval));
00260   aProperty->GetValue(getter_Copies(propval));
00261   printf("GetTarget(%s, %s,..)\n", (const char*)sourceval,
00262          (const char*)propval);
00263 #endif
00264 
00265   return NS_OK;
00266 }
00267 
00268 /* nsISimpleEnumerator GetTargets (in nsIRDFResource aSource, in nsIRDFResource aProperty, in boolean aTruthValue); */
00269 NS_IMETHODIMP
00270 nsRDFDataSourceDataSource::GetTargets(nsIRDFResource *aSource,
00271                                       nsIRDFResource *aProperty,
00272                                       PRBool aTruthValue,
00273                                       nsISimpleEnumerator **_retval)
00274 {
00275   nsXPIDLCString sourceval;
00276   aSource->GetValue(getter_Copies(sourceval));
00277   nsXPIDLCString propval;
00278   aProperty->GetValue(getter_Copies(propval));
00279 #ifdef DEBUG_alecf
00280   printf("GetTargets(%s, %s,..)\n", (const char*)sourceval,
00281          (const char*)propval);
00282 #endif
00283   
00284   nsresult rv;
00285   PRBool isProp;
00286   nsCOMPtr<nsISupportsArray> arcs;
00287   nsISimpleEnumerator *enumerator;
00288   
00289   if (NS_SUCCEEDED(aProperty->EqualsNode(kNC_Child, &isProp)) &&
00290       isProp) {
00291 
00292     // here we need to determine if we need to extract out the source
00293     // or use aSource?
00294     if (StringBeginsWith(sourceval, NS_LITERAL_CSTRING("dsresource:"))) {
00295       // somehow get the source
00296       // XXX ? rv = mDataSource->ArcLabelsOut(realsource, &enumerator);      
00297       rv = mDataSource->ArcLabelsOut(aSource, &enumerator);      
00298     } else {
00299       rv = mDataSource->ArcLabelsOut(aSource, &enumerator);
00300     }
00301     // enumerate all the children and create the composite resources
00302     PRBool hasMoreArcs=PR_FALSE;
00303 
00304     rv = enumerator->HasMoreElements(&hasMoreArcs);
00305     while (NS_SUCCEEDED(rv) && hasMoreArcs) {
00306       
00307       // get the next arc
00308       nsCOMPtr<nsISupports> arcSupports;
00309       rv = enumerator->GetNext(getter_AddRefs(arcSupports));
00310       nsCOMPtr<nsIRDFResource> arc = do_QueryInterface(arcSupports, &rv);
00311 
00312       // get all the resources on the ends of the arc arcs
00313       nsCOMPtr<nsISimpleEnumerator> targetEnumerator;
00314       rv = mDataSource->GetTargets(aSource, arc, PR_TRUE,
00315                                    getter_AddRefs(targetEnumerator));
00316 
00317       PRBool hasMoreTargets;
00318       rv = targetEnumerator->HasMoreElements(&hasMoreTargets);
00319       while (NS_SUCCEEDED(rv) && hasMoreTargets) {
00320         // get the next target
00321         nsCOMPtr<nsISupports> targetSupports;
00322         rv = enumerator->GetNext(getter_AddRefs(targetSupports));
00323         nsCOMPtr<nsIRDFResource> target=do_QueryInterface(targetSupports, &rv);
00324 
00325         // now we have an (arc, target) tuple that will be our node
00326         // arc will become #Name
00327         // target will become #Value
00328 #ifdef DEBUG_alecf
00329         nsXPIDLString arcValue;
00330         nsXPIDLString targetValue;
00331 
00332         arc->GetValue(getter_Copies(arcValue));
00333         target->GetValue(getter_Copies(targetValue));
00334         printf("#child of %s:\n\t%s = %s\n",
00335                (const char*)sourceval
00336 #endif
00337 
00338       }
00339       
00340       rv = enumerator->HasMoreElements(&hasMoreArcs);
00341     }
00342     
00343   } else if (NS_SUCCEEDED(aProperty->EqualsNode(kNC_Name, &isProp)) &&
00344              isProp) {
00345     if (StringBeginsWith(sourceval, NS_LITERAL_CSTRING("dsresource:"))) {
00346       // extract out the name
00347 
00348     }
00349     
00350   } else if (NS_SUCCEEDED(aProperty->EqualsNode(kNC_Value, &isProp)) &&
00351              isProp) {
00352 
00353 
00354   } else {
00355     rv = NS_NewISupportsArray(getter_AddRefs(arcs));
00356     if (NS_FAILED(rv)) return rv;
00357     
00358     nsArrayEnumerator* cursor =
00359       new nsArrayEnumerator(arcs);
00360 
00361     if (!cursor) return NS_ERROR_OUT_OF_MEMORY;
00362     
00363     *_retval = cursor;
00364     NS_ADDREF(*_retval);
00365   }
00366   
00367   return NS_OK;
00368 }
00369 
00370 /* void Assert (in nsIRDFResource aSource, in nsIRDFResource aProperty, in nsIRDFNode aTarget, in boolean aTruthValue); */
00371 NS_IMETHODIMP
00372 nsRDFDataSourceDataSource::Assert(nsIRDFResource *aSource, nsIRDFResource *aProperty, nsIRDFNode *aTarget, PRBool aTruthValue)
00373 {
00374   return NS_RDF_NO_VALUE;
00375 }
00376 
00377 /* void Unassert (in nsIRDFResource aSource, in nsIRDFResource aProperty, in nsIRDFNode aTarget); */
00378 NS_IMETHODIMP
00379 nsRDFDataSourceDataSource::Unassert(nsIRDFResource *aSource, nsIRDFResource *aProperty, nsIRDFNode *aTarget)
00380 {
00381   return NS_RDF_NO_VALUE;
00382 }
00383 
00384 /* boolean HasAssertion (in nsIRDFResource aSource, in nsIRDFResource aProperty, in nsIRDFNode aTarget, in boolean aTruthValue); */
00385 NS_IMETHODIMP
00386 nsRDFDataSourceDataSource::HasAssertion(nsIRDFResource *aSource, nsIRDFResource *aProperty, nsIRDFNode *aTarget, PRBool aTruthValue, PRBool *_retval)
00387 {
00388   return NS_RDF_NO_VALUE;
00389 }
00390 
00391 /* void AddObserver (in nsIRDFObserver aObserver); */
00392 NS_IMETHODIMP
00393 nsRDFDataSourceDataSource::AddObserver(nsIRDFObserver *aObserver)
00394 {
00395   return NS_RDF_NO_VALUE;
00396 }
00397 
00398 /* void RemoveObserver (in nsIRDFObserver aObserver); */
00399 NS_IMETHODIMP
00400 nsRDFDataSourceDataSource::RemoveObserver(nsIRDFObserver *aObserver)
00401 {
00402   return NS_RDF_NO_VALUE;
00403 }
00404 
00405 /* nsISimpleEnumerator ArcLabelsIn (in nsIRDFNode aNode); */
00406 NS_IMETHODIMP
00407 nsRDFDataSourceDataSource::ArcLabelsIn(nsIRDFNode *aNode, nsISimpleEnumerator **_retval)
00408 {
00409   return NS_RDF_NO_VALUE;
00410 }
00411 
00412 /* nsISimpleEnumerator ArcLabelsOut (in nsIRDFResource aSource); */
00413 NS_IMETHODIMP
00414 nsRDFDataSourceDataSource::ArcLabelsOut(nsIRDFResource *aSource,
00415                                         nsISimpleEnumerator **_retval)
00416 {
00417   nsresult rv=NS_OK;
00418   
00419   nsCOMPtr<nsISupportsArray> arcs;
00420   rv = NS_NewISupportsArray(getter_AddRefs(arcs));
00421   
00422   if (NS_FAILED(rv)) return rv;
00423   nsXPIDLCString sourceval;
00424   aSource->GetValue(getter_Copies(sourceval));
00425   
00426 #ifdef DEBUG_alecf
00427   printf("ArcLabelsOut(%s)\n", (const char*)sourceval);
00428 #endif
00429   
00430   arcs->AppendElement(kNC_Name);
00431   arcs->AppendElement(kNC_Value);
00432   arcs->AppendElement(kNC_Child);
00433 
00434   nsArrayEnumerator* cursor =
00435     new nsArrayEnumerator(arcs);
00436 
00437   if (!cursor) return NS_ERROR_OUT_OF_MEMORY;
00438   
00439   NS_ADDREF(cursor);
00440   *_retval = cursor;
00441 
00442   return NS_OK;
00443 }
00444 
00445 /* nsISimpleEnumerator GetAllResources (); */
00446 NS_IMETHODIMP
00447 nsRDFDataSourceDataSource::GetAllResources(nsISimpleEnumerator **_retval)
00448 {
00449   return NS_RDF_NO_VALUE;
00450 }
00451 
00452 /* boolean IsCommandEnabled (in nsISupportsArray aSources, in nsIRDFResource aCommand, in nsISupportsArray aArguments); */
00453 NS_IMETHODIMP
00454 nsRDFDataSourceDataSource::IsCommandEnabled(nsISupportsArray * aSources, nsIRDFResource *aCommand, nsISupportsArray * aArguments, PRBool *_retval)
00455 {
00456   return NS_RDF_NO_VALUE;
00457 }
00458 
00459 /* void DoCommand (in nsISupportsArray aSources, in nsIRDFResource aCommand, in nsISupportsArray aArguments); */
00460 NS_IMETHODIMP
00461 nsRDFDataSourceDataSource::DoCommand(nsISupportsArray * aSources, nsIRDFResource *aCommand, nsISupportsArray * aArguments)
00462 {
00463   return NS_RDF_NO_VALUE;
00464 }
00465 
00466 /* void beginUpdateBatch (); */
00467 NS_IMETHODIMP
00468 nsRDFDataSourceDataSource::BeginUpdateBatch()
00469 {
00470   return NS_OK;
00471 }
00472 
00473 /* void endUpdateBatch (); */
00474 NS_IMETHODIMP
00475 nsRDFDataSourceDataSource::EndUpdateBatch()
00476 {
00477   return NS_OK;
00478 }
00479 
00480 nsresult
00481 NS_NewRDFDataSourceDataSource(nsISupports *, const nsIID& iid,
00482                               void ** result)
00483 
00484 {
00485   nsRDFDataSourceDataSource * dsds = new nsRDFDataSourceDataSource();
00486   if (!dsds) return NS_ERROR_NOT_INITIALIZED;
00487   return dsds->QueryInterface(iid, result);
00488   
00489 }