1998-12-24 08:07:14 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
|
|
*
|
|
|
|
* The contents of this file are subject to the Netscape Public License
|
|
|
|
* Version 1.0 (the "License"); you may not use this file except in
|
|
|
|
* compliance with the License. You may obtain a copy of the License at
|
|
|
|
* http://www.mozilla.org/NPL/
|
|
|
|
*
|
|
|
|
* Software distributed under the License is distributed on an "AS IS"
|
|
|
|
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
|
|
|
* the License for the specific language governing rights and limitations
|
|
|
|
* under the License.
|
|
|
|
*
|
|
|
|
* The Original Code is Mozilla Communicator client code.
|
|
|
|
*
|
|
|
|
* The Initial Developer of the Original Code is Netscape Communications
|
|
|
|
* Corporation. Portions created by Netscape are Copyright (C) 1998
|
|
|
|
* Netscape Communications Corporation. All Rights Reserved.
|
|
|
|
*/
|
|
|
|
|
1999-01-06 00:22:20 +03:00
|
|
|
/*
|
|
|
|
|
|
|
|
Implementations for a bunch of useful RDF utility routines. Many of
|
|
|
|
these will eventually be exported outside of RDF.DLL via the
|
|
|
|
nsIRDFService interface.
|
|
|
|
|
1999-02-16 22:30:04 +03:00
|
|
|
TO DO
|
|
|
|
|
|
|
|
1) Make this so that it doesn't permanently leak the RDF service
|
|
|
|
object.
|
|
|
|
|
|
|
|
2) Make container functions thread-safe. They currently don't ensure
|
|
|
|
that the RDF:nextVal property is maintained safely.
|
|
|
|
|
1999-01-06 00:22:20 +03:00
|
|
|
*/
|
|
|
|
|
1999-02-16 22:30:04 +03:00
|
|
|
#include "nsCOMPtr.h"
|
1998-12-24 08:07:14 +03:00
|
|
|
#include "nsIRDFCursor.h"
|
1999-01-20 04:42:13 +03:00
|
|
|
#include "nsIRDFDataSource.h"
|
1998-12-24 08:07:14 +03:00
|
|
|
#include "nsIRDFNode.h"
|
1999-01-05 06:53:15 +03:00
|
|
|
#include "nsIRDFService.h"
|
1999-01-12 22:41:06 +03:00
|
|
|
#include "nsIServiceManager.h"
|
|
|
|
#include "nsRDFCID.h"
|
1998-12-24 08:07:14 +03:00
|
|
|
#include "nsString.h"
|
1999-03-29 23:52:54 +04:00
|
|
|
#include "nsXPIDLString.h"
|
1999-01-22 09:48:25 +03:00
|
|
|
#include "plstr.h"
|
1999-02-16 22:30:04 +03:00
|
|
|
#include "prprf.h"
|
1998-12-24 08:07:14 +03:00
|
|
|
#include "rdfutil.h"
|
|
|
|
|
|
|
|
#include "rdf.h"
|
|
|
|
static const char kRDFNameSpaceURI[] = RDF_NAMESPACE_URI;
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
static NS_DEFINE_IID(kIRDFResourceIID, NS_IRDFRESOURCE_IID);
|
|
|
|
static NS_DEFINE_IID(kIRDFLiteralIID, NS_IRDFLITERAL_IID);
|
1999-01-12 22:41:06 +03:00
|
|
|
static NS_DEFINE_IID(kIRDFServiceIID, NS_IRDFSERVICE_IID);
|
|
|
|
|
|
|
|
static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
1999-01-22 09:48:25 +03:00
|
|
|
// XXX This'll permanently leak
|
1999-01-12 22:41:06 +03:00
|
|
|
static nsIRDFService* gRDFService = nsnull;
|
|
|
|
|
1999-01-22 09:48:25 +03:00
|
|
|
static nsIRDFResource* kRDF_instanceOf = nsnull;
|
|
|
|
static nsIRDFResource* kRDF_Bag = nsnull;
|
|
|
|
static nsIRDFResource* kRDF_Seq = nsnull;
|
|
|
|
static nsIRDFResource* kRDF_Alt = nsnull;
|
|
|
|
static nsIRDFResource* kRDF_nextVal = nsnull;
|
|
|
|
|
1999-01-12 22:41:06 +03:00
|
|
|
static nsresult
|
|
|
|
rdf_EnsureRDFService(void)
|
|
|
|
{
|
|
|
|
if (gRDFService)
|
|
|
|
return NS_OK;
|
|
|
|
|
1999-01-22 09:48:25 +03:00
|
|
|
nsresult rv;
|
|
|
|
|
1999-04-17 04:10:18 +04:00
|
|
|
rv = nsServiceManager::GetService(kRDFServiceCID,
|
|
|
|
kIRDFServiceIID,
|
|
|
|
(nsISupports**) &gRDFService);
|
1999-01-22 09:48:25 +03:00
|
|
|
|
1999-04-17 04:10:18 +04:00
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get RDF service");
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-01-22 09:48:25 +03:00
|
|
|
|
1999-04-17 04:10:18 +04:00
|
|
|
rv = gRDFService->GetResource(RDF_NAMESPACE_URI "instanceOf", &kRDF_instanceOf);
|
|
|
|
rv = gRDFService->GetResource(RDF_NAMESPACE_URI "Bag", &kRDF_Bag);
|
|
|
|
rv = gRDFService->GetResource(RDF_NAMESPACE_URI "Seq", &kRDF_Seq);
|
|
|
|
rv = gRDFService->GetResource(RDF_NAMESPACE_URI "Alt", &kRDF_Alt);
|
|
|
|
rv = gRDFService->GetResource(RDF_NAMESPACE_URI "nextVal", &kRDF_nextVal);
|
1999-01-22 09:48:25 +03:00
|
|
|
|
1999-04-17 04:10:18 +04:00
|
|
|
return NS_OK;
|
1999-01-12 22:41:06 +03:00
|
|
|
}
|
1998-12-24 08:07:14 +03:00
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
PRBool
|
1999-03-29 23:52:54 +04:00
|
|
|
rdf_IsOrdinalProperty(nsIRDFResource* aProperty)
|
1998-12-24 08:07:14 +03:00
|
|
|
{
|
1999-03-29 23:52:54 +04:00
|
|
|
nsXPIDLCString propertyStr;
|
|
|
|
if (NS_FAILED(aProperty->GetValue( getter_Copies(propertyStr) )))
|
1998-12-24 08:07:14 +03:00
|
|
|
return PR_FALSE;
|
|
|
|
|
1999-03-29 23:52:54 +04:00
|
|
|
if (PL_strncmp(propertyStr, kRDFNameSpaceURI, sizeof(kRDFNameSpaceURI) - 1) != 0)
|
1998-12-24 08:07:14 +03:00
|
|
|
return PR_FALSE;
|
|
|
|
|
1999-03-29 23:52:54 +04:00
|
|
|
const char* s = propertyStr;
|
1999-02-16 22:30:04 +03:00
|
|
|
s += sizeof(kRDFNameSpaceURI) - 1;
|
|
|
|
if (*s != '_')
|
1998-12-24 08:07:14 +03:00
|
|
|
return PR_FALSE;
|
|
|
|
|
1999-02-16 22:30:04 +03:00
|
|
|
++s;
|
|
|
|
while (*s) {
|
|
|
|
if (*s < '0' || *s > '9')
|
1998-12-24 08:07:14 +03:00
|
|
|
return PR_FALSE;
|
1999-02-16 22:30:04 +03:00
|
|
|
|
|
|
|
++s;
|
1998-12-24 08:07:14 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-02-16 22:30:04 +03:00
|
|
|
nsresult
|
|
|
|
rdf_OrdinalResourceToIndex(nsIRDFResource* aOrdinal, PRInt32* aIndex)
|
|
|
|
{
|
1999-03-29 23:52:54 +04:00
|
|
|
nsXPIDLCString ordinalStr;
|
|
|
|
if (NS_FAILED(aOrdinal->GetValue( getter_Copies(ordinalStr) )))
|
1999-02-16 22:30:04 +03:00
|
|
|
return PR_FALSE;
|
|
|
|
|
1999-03-29 23:52:54 +04:00
|
|
|
const char* s = ordinalStr;
|
1999-02-16 22:30:04 +03:00
|
|
|
if (PL_strncmp(s, kRDFNameSpaceURI, sizeof(kRDFNameSpaceURI) - 1) != 0) {
|
|
|
|
NS_ERROR("not an ordinal");
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
s += sizeof(kRDFNameSpaceURI) - 1;
|
|
|
|
if (*s != '_') {
|
|
|
|
NS_ERROR("not an ordinal");
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
PRInt32 index = 0;
|
|
|
|
|
|
|
|
++s;
|
|
|
|
while (*s) {
|
|
|
|
if (*s < '0' || *s > '9') {
|
|
|
|
NS_ERROR("not an ordinal");
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
index *= 10;
|
|
|
|
index += (*s - '0');
|
|
|
|
|
|
|
|
++s;
|
|
|
|
}
|
|
|
|
|
|
|
|
*aIndex = index;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
rdf_IndexToOrdinalResource(PRInt32 aIndex, nsIRDFResource** aOrdinal)
|
|
|
|
{
|
|
|
|
NS_PRECONDITION(aIndex > 0, "illegal value");
|
|
|
|
if (aIndex <= 0)
|
|
|
|
return NS_ERROR_ILLEGAL_VALUE;
|
|
|
|
|
|
|
|
// 16 digits should be plenty to hold a decimal version of a
|
|
|
|
// PRInt32.
|
|
|
|
char buf[sizeof(kRDFNameSpaceURI) + 16 + 1];
|
|
|
|
|
|
|
|
PL_strcpy(buf, kRDFNameSpaceURI);
|
|
|
|
buf[sizeof(kRDFNameSpaceURI) - 1] = '_';
|
|
|
|
|
|
|
|
PR_snprintf(buf + sizeof(kRDFNameSpaceURI), 16, "%ld", aIndex);
|
|
|
|
|
|
|
|
nsresult rv;
|
|
|
|
if (NS_FAILED(rv = rdf_EnsureRDFService()))
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
if (NS_FAILED(rv = gRDFService->GetResource(buf, aOrdinal))) {
|
|
|
|
NS_ERROR("unable to get ordinal resource");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-04-17 04:10:18 +04:00
|
|
|
static PRBool
|
|
|
|
rdf_IsA(nsIRDFDataSource* aDataSource, nsIRDFResource* aResource, nsIRDFResource* aType)
|
1999-01-22 09:48:25 +03:00
|
|
|
{
|
|
|
|
nsresult rv;
|
1999-04-17 04:10:18 +04:00
|
|
|
rv = rdf_EnsureRDFService();
|
|
|
|
if (NS_FAILED(rv)) return PR_FALSE;
|
1998-12-24 08:07:14 +03:00
|
|
|
|
1999-04-17 04:10:18 +04:00
|
|
|
PRBool result;
|
|
|
|
rv = aDataSource->HasAssertion(aResource, kRDF_instanceOf, aType, PR_TRUE, &result);
|
|
|
|
if (NS_FAILED(rv)) return PR_FALSE;
|
1999-01-22 01:24:32 +03:00
|
|
|
|
1999-01-22 09:48:25 +03:00
|
|
|
return result;
|
|
|
|
}
|
1999-01-22 01:24:32 +03:00
|
|
|
|
1999-01-22 09:48:25 +03:00
|
|
|
|
|
|
|
PRBool
|
1999-04-17 04:10:18 +04:00
|
|
|
rdf_IsContainer(nsIRDFDataSource* aDataSource, nsIRDFResource* aResource)
|
1998-12-24 08:07:14 +03:00
|
|
|
{
|
|
|
|
nsresult rv;
|
1999-04-17 04:10:18 +04:00
|
|
|
rv = rdf_EnsureRDFService();
|
|
|
|
if (NS_FAILED(rv)) return PR_FALSE;
|
1999-01-12 22:41:06 +03:00
|
|
|
|
1999-04-17 04:10:18 +04:00
|
|
|
if (rdf_IsA(aDataSource, aResource, kRDF_Bag) ||
|
|
|
|
rdf_IsA(aDataSource, aResource, kRDF_Seq) ||
|
|
|
|
rdf_IsA(aDataSource, aResource, kRDF_Alt)) {
|
|
|
|
return PR_TRUE;
|
1998-12-24 08:07:14 +03:00
|
|
|
}
|
|
|
|
else {
|
1999-04-17 04:10:18 +04:00
|
|
|
return PR_FALSE;
|
1998-12-24 08:07:14 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-04-17 04:10:18 +04:00
|
|
|
PRBool
|
|
|
|
rdf_IsBag(nsIRDFDataSource* aDataSource, nsIRDFResource* aResource)
|
1998-12-24 08:07:14 +03:00
|
|
|
{
|
|
|
|
nsresult rv;
|
1999-04-17 04:10:18 +04:00
|
|
|
rv = rdf_EnsureRDFService();
|
|
|
|
if (NS_FAILED(rv)) return PR_FALSE;
|
1999-01-12 22:41:06 +03:00
|
|
|
|
1999-04-17 04:10:18 +04:00
|
|
|
return rdf_IsA(aDataSource, aResource, kRDF_Bag);
|
1998-12-24 08:07:14 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-04-17 04:10:18 +04:00
|
|
|
PRBool
|
|
|
|
rdf_IsSeq(nsIRDFDataSource* aDataSource, nsIRDFResource* aResource)
|
|
|
|
{
|
1998-12-24 08:07:14 +03:00
|
|
|
nsresult rv;
|
1999-04-17 04:10:18 +04:00
|
|
|
rv = rdf_EnsureRDFService();
|
|
|
|
if (NS_FAILED(rv)) return PR_FALSE;
|
1999-01-12 22:41:06 +03:00
|
|
|
|
1999-04-17 04:10:18 +04:00
|
|
|
return rdf_IsA(aDataSource, aResource, kRDF_Seq);
|
1998-12-24 08:07:14 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-04-17 04:10:18 +04:00
|
|
|
PRBool
|
|
|
|
rdf_IsAlt(nsIRDFDataSource* aDataSource, nsIRDFResource* aResource)
|
|
|
|
{
|
1998-12-24 08:07:14 +03:00
|
|
|
nsresult rv;
|
1999-04-17 04:10:18 +04:00
|
|
|
rv = rdf_EnsureRDFService();
|
|
|
|
if (NS_FAILED(rv)) return PR_FALSE;
|
1999-01-12 22:41:06 +03:00
|
|
|
|
1999-04-17 04:10:18 +04:00
|
|
|
return rdf_IsA(aDataSource, aResource, kRDF_Alt);
|
1998-12-24 08:07:14 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
1999-04-17 04:10:18 +04:00
|
|
|
rdf_CreateAnonymousResource(const nsString& aContextURI, nsIRDFResource** aResult)
|
1998-12-24 08:07:14 +03:00
|
|
|
{
|
1999-01-22 09:48:25 +03:00
|
|
|
static PRUint32 gCounter = 0;
|
1998-12-24 08:07:14 +03:00
|
|
|
|
1999-01-12 22:41:06 +03:00
|
|
|
nsresult rv;
|
1999-04-17 04:10:18 +04:00
|
|
|
rv = rdf_EnsureRDFService();
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-01-12 22:41:06 +03:00
|
|
|
|
1999-01-22 09:48:25 +03:00
|
|
|
do {
|
|
|
|
nsAutoString s(aContextURI);
|
1999-01-26 04:23:55 +03:00
|
|
|
s.Append("#$");
|
1999-01-22 09:48:25 +03:00
|
|
|
s.Append(++gCounter, 10);
|
|
|
|
|
|
|
|
nsIRDFResource* resource;
|
|
|
|
if (NS_FAILED(rv = gRDFService->GetUnicodeResource(s, &resource)))
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
// XXX an ugly but effective way to make sure that this
|
|
|
|
// resource is really unique in the world.
|
|
|
|
nsrefcnt refcnt = resource->AddRef();
|
|
|
|
resource->Release();
|
|
|
|
|
|
|
|
if (refcnt == 2) {
|
1999-04-17 04:10:18 +04:00
|
|
|
*aResult = resource;
|
1999-01-22 09:48:25 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
} while (1);
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
PRBool
|
|
|
|
rdf_IsAnonymousResource(const nsString& aContextURI, nsIRDFResource* aResource)
|
|
|
|
{
|
|
|
|
nsresult rv;
|
1999-03-29 23:52:54 +04:00
|
|
|
nsXPIDLCString s;
|
|
|
|
if (NS_FAILED(rv = aResource->GetValue( getter_Copies(s) ))) {
|
1999-01-22 09:48:25 +03:00
|
|
|
NS_ASSERTION(PR_FALSE, "unable to get resource URI");
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
|
1999-03-29 23:52:54 +04:00
|
|
|
nsAutoString uri((const char*) s);
|
1999-01-22 09:48:25 +03:00
|
|
|
|
|
|
|
// Make sure that they have the same context (prefix)
|
|
|
|
if (uri.Find(aContextURI) != 0)
|
|
|
|
return PR_FALSE;
|
|
|
|
|
|
|
|
uri.Cut(0, aContextURI.Length());
|
|
|
|
|
|
|
|
// Anonymous resources look like the regexp "\$[0-9]+"
|
1999-01-26 04:23:55 +03:00
|
|
|
if (uri[0] != '#' || uri[1] != '$')
|
1999-01-22 09:48:25 +03:00
|
|
|
return PR_FALSE;
|
|
|
|
|
|
|
|
for (PRInt32 i = uri.Length() - 1; i >= 1; --i) {
|
|
|
|
if (uri[i] < '0' || uri[i] > '9')
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return PR_TRUE;
|
1998-12-24 08:07:14 +03:00
|
|
|
}
|
|
|
|
|
1999-01-22 09:48:25 +03:00
|
|
|
|
|
|
|
PR_EXTERN(nsresult)
|
|
|
|
rdf_PossiblyMakeRelative(const nsString& aContextURI, nsString& aURI)
|
|
|
|
{
|
|
|
|
// This implementation is extremely simple: no ".." or anything
|
|
|
|
// fancy like that. If the context URI is not a prefix of the URI
|
|
|
|
// in question, we'll just bail.
|
|
|
|
if (aURI.Find(aContextURI) != 0)
|
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
// Otherwise, pare down the target URI, removing the context URI.
|
|
|
|
aURI.Cut(0, aContextURI.Length());
|
1999-03-05 03:03:30 +03:00
|
|
|
|
|
|
|
if (aURI.First() == '#' || aURI.First() == '/')
|
|
|
|
aURI.Cut(0, 1);
|
|
|
|
|
1999-01-22 09:48:25 +03:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-02-17 14:09:57 +03:00
|
|
|
PR_EXTERN(nsresult)
|
|
|
|
rdf_PossiblyMakeAbsolute(const nsString& aContextURI, nsString& aURI)
|
|
|
|
{
|
|
|
|
PRInt32 index = aURI.Find(':');
|
1999-03-19 00:43:00 +03:00
|
|
|
if (index > 0 && index < 25 /* XXX */)
|
1999-02-17 14:09:57 +03:00
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
PRUnichar last = aContextURI.Last();
|
|
|
|
PRUnichar first = aURI.First();
|
|
|
|
|
|
|
|
nsAutoString result(aContextURI);
|
|
|
|
if (last == '#' || last == '/') {
|
|
|
|
if (first == '#') {
|
|
|
|
result.Truncate(result.Length() - 2);
|
|
|
|
}
|
|
|
|
result.Append(aURI);
|
|
|
|
}
|
|
|
|
else if (first == '#') {
|
|
|
|
result.Append(aURI);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
result.Append('#');
|
|
|
|
result.Append(aURI);
|
|
|
|
}
|
|
|
|
|
|
|
|
aURI = result;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-04-17 04:10:18 +04:00
|
|
|
|
|
|
|
static nsresult
|
|
|
|
rdf_MakeContainer(nsIRDFDataSource* aDataSource, nsIRDFResource* aContainer, nsIRDFResource* aType)
|
1998-12-24 08:07:14 +03:00
|
|
|
{
|
1999-04-17 04:10:18 +04:00
|
|
|
NS_ASSERTION(aDataSource != nsnull, "null ptr");
|
|
|
|
if (! aDataSource)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
1998-12-24 08:07:14 +03:00
|
|
|
|
1999-04-17 04:10:18 +04:00
|
|
|
NS_ASSERTION(aContainer != nsnull, "null ptr");
|
|
|
|
if (! aContainer)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
1998-12-24 08:07:14 +03:00
|
|
|
|
1999-04-17 04:10:18 +04:00
|
|
|
nsresult rv;
|
|
|
|
rv = aDataSource->Assert(aContainer, kRDF_instanceOf, aType, PR_TRUE);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1998-12-24 08:07:14 +03:00
|
|
|
|
1999-04-17 04:10:18 +04:00
|
|
|
nsCOMPtr<nsIRDFLiteral> nextVal;
|
|
|
|
rv = gRDFService->GetLiteral(nsAutoString("1"), getter_AddRefs(nextVal));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1998-12-24 08:07:14 +03:00
|
|
|
|
1999-04-17 04:10:18 +04:00
|
|
|
rv = aDataSource->Assert(aContainer, kRDF_nextVal, nextVal, PR_TRUE);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1998-12-24 08:07:14 +03:00
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
1999-04-17 04:10:18 +04:00
|
|
|
rdf_MakeBag(nsIRDFDataSource* aDataSource, nsIRDFResource* aBag)
|
1998-12-24 08:07:14 +03:00
|
|
|
{
|
|
|
|
nsresult rv;
|
1999-04-17 04:10:18 +04:00
|
|
|
rv = rdf_EnsureRDFService();
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1998-12-24 08:07:14 +03:00
|
|
|
|
1999-04-17 04:10:18 +04:00
|
|
|
return rdf_MakeContainer(aDataSource, aBag, kRDF_Bag);
|
1998-12-24 08:07:14 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
1999-04-17 04:10:18 +04:00
|
|
|
rdf_MakeSeq(nsIRDFDataSource* aDataSource, nsIRDFResource* aSeq)
|
1998-12-24 08:07:14 +03:00
|
|
|
{
|
|
|
|
nsresult rv;
|
1999-04-17 04:10:18 +04:00
|
|
|
rv = rdf_EnsureRDFService();
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1998-12-24 08:07:14 +03:00
|
|
|
|
1999-04-17 04:10:18 +04:00
|
|
|
return rdf_MakeContainer(aDataSource, aSeq, kRDF_Seq);
|
|
|
|
}
|
1998-12-24 08:07:14 +03:00
|
|
|
|
|
|
|
|
1999-04-17 04:10:18 +04:00
|
|
|
nsresult
|
|
|
|
rdf_MakeAlt(nsIRDFDataSource* aDataSource, nsIRDFResource* aAlt)
|
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
rv = rdf_EnsureRDFService();
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1998-12-24 08:07:14 +03:00
|
|
|
|
1999-04-17 04:10:18 +04:00
|
|
|
return rdf_MakeContainer(aDataSource, aAlt, kRDF_Alt);
|
1998-12-24 08:07:14 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-02-16 22:30:04 +03:00
|
|
|
static nsresult
|
|
|
|
rdf_ContainerSetNextValue(nsIRDFDataSource* aDataSource,
|
|
|
|
nsIRDFResource* aContainer,
|
|
|
|
PRInt32 aIndex)
|
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
if (NS_FAILED(rv = rdf_EnsureRDFService()))
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
// Remove the current value of nextVal, if there is one.
|
|
|
|
nsCOMPtr<nsIRDFNode> nextValNode;
|
|
|
|
if (NS_SUCCEEDED(rv = aDataSource->GetTarget(aContainer,
|
|
|
|
kRDF_nextVal,
|
|
|
|
PR_TRUE,
|
|
|
|
getter_AddRefs(nextValNode)))) {
|
|
|
|
if (NS_FAILED(rv = aDataSource->Unassert(aContainer, kRDF_nextVal, nextValNode))) {
|
|
|
|
NS_ERROR("unable to update nextVal");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
nsAutoString s;
|
|
|
|
s.Append(aIndex, 10);
|
|
|
|
|
|
|
|
nsCOMPtr<nsIRDFLiteral> nextVal;
|
|
|
|
if (NS_FAILED(rv = gRDFService->GetLiteral(s, getter_AddRefs(nextVal)))) {
|
|
|
|
NS_ERROR("unable to get nextVal literal");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1999-04-07 10:29:41 +04:00
|
|
|
rv = aDataSource->Assert(aContainer, kRDF_nextVal, nextVal, PR_TRUE);
|
|
|
|
if (rv != NS_RDF_ASSERTION_ACCEPTED) {
|
1999-02-16 22:30:04 +03:00
|
|
|
NS_ERROR("unable to update nextVal");
|
1999-04-07 10:29:41 +04:00
|
|
|
return NS_ERROR_FAILURE;
|
1999-02-16 22:30:04 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1998-12-24 08:07:14 +03:00
|
|
|
static nsresult
|
1999-04-16 12:39:02 +04:00
|
|
|
rdf_ContainerGetNextValue(nsIRDFDataSource* aDataSource,
|
|
|
|
nsIRDFResource* aContainer,
|
|
|
|
nsIRDFResource** aResult)
|
1998-12-24 08:07:14 +03:00
|
|
|
{
|
1999-04-16 12:39:02 +04:00
|
|
|
NS_PRECONDITION(aDataSource != nsnull, "null ptr");
|
|
|
|
if (! aDataSource)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
|
|
|
NS_PRECONDITION(aContainer != nsnull, "null ptr");
|
|
|
|
if (! aContainer)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
1998-12-24 08:07:14 +03:00
|
|
|
|
|
|
|
nsresult rv;
|
1999-04-16 12:39:02 +04:00
|
|
|
rv = rdf_EnsureRDFService();
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-01-12 22:41:06 +03:00
|
|
|
|
1998-12-24 08:07:14 +03:00
|
|
|
nsIRDFNode* nextValNode = nsnull;
|
|
|
|
nsIRDFLiteral* nextValLiteral = nsnull;
|
1999-03-29 23:52:54 +04:00
|
|
|
nsXPIDLString s;
|
1998-12-24 08:07:14 +03:00
|
|
|
nsAutoString nextValStr;
|
|
|
|
PRInt32 nextVal;
|
|
|
|
PRInt32 err;
|
|
|
|
|
|
|
|
// Get the next value, which hangs off of the bag via the
|
|
|
|
// RDF:nextVal property.
|
1999-04-16 12:39:02 +04:00
|
|
|
if (NS_FAILED(rv = aDataSource->GetTarget(aContainer, kRDF_nextVal, PR_TRUE, &nextValNode)))
|
1998-12-24 08:07:14 +03:00
|
|
|
goto done;
|
|
|
|
|
1999-04-16 12:39:02 +04:00
|
|
|
if (rv == NS_RDF_NO_VALUE) {
|
|
|
|
rv = NS_ERROR_UNEXPECTED;
|
1999-03-30 07:58:24 +04:00
|
|
|
goto done;
|
1999-04-16 12:39:02 +04:00
|
|
|
}
|
1999-03-30 07:58:24 +04:00
|
|
|
|
1998-12-24 08:07:14 +03:00
|
|
|
if (NS_FAILED(rv = nextValNode->QueryInterface(kIRDFLiteralIID, (void**) &nextValLiteral)))
|
|
|
|
goto done;
|
|
|
|
|
1999-03-29 23:52:54 +04:00
|
|
|
if (NS_FAILED(rv = nextValLiteral->GetValue( getter_Copies(s) )))
|
1998-12-24 08:07:14 +03:00
|
|
|
goto done;
|
|
|
|
|
1999-03-29 23:52:54 +04:00
|
|
|
nextValStr = (const PRUnichar*) s;
|
1998-12-24 08:07:14 +03:00
|
|
|
nextVal = nextValStr.ToInteger(&err);
|
|
|
|
if (NS_FAILED(err))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
// Generate a URI that we can return.
|
|
|
|
nextValStr = kRDFNameSpaceURI;
|
|
|
|
nextValStr.Append("_");
|
|
|
|
nextValStr.Append(nextVal, 10);
|
|
|
|
|
1999-04-16 12:39:02 +04:00
|
|
|
if (NS_FAILED(rv = gRDFService->GetUnicodeResource(nextValStr, aResult)))
|
1998-12-24 08:07:14 +03:00
|
|
|
goto done;
|
|
|
|
|
|
|
|
// Now increment the RDF:nextVal property.
|
1999-04-16 12:39:02 +04:00
|
|
|
if (NS_FAILED(rv = aDataSource->Unassert(aContainer, kRDF_nextVal, nextValLiteral)))
|
1998-12-24 08:07:14 +03:00
|
|
|
goto done;
|
|
|
|
|
|
|
|
NS_RELEASE(nextValLiteral);
|
|
|
|
|
|
|
|
++nextVal;
|
|
|
|
nextValStr.Truncate();
|
|
|
|
nextValStr.Append(nextVal, 10);
|
|
|
|
|
1999-01-12 22:41:06 +03:00
|
|
|
if (NS_FAILED(rv = gRDFService->GetLiteral(nextValStr, &nextValLiteral)))
|
1998-12-24 08:07:14 +03:00
|
|
|
goto done;
|
|
|
|
|
1999-04-16 12:39:02 +04:00
|
|
|
if (NS_FAILED(rv = aDataSource->Assert(aContainer, kRDF_nextVal, nextValLiteral, PR_TRUE)))
|
1998-12-24 08:07:14 +03:00
|
|
|
goto done;
|
|
|
|
|
|
|
|
done:
|
|
|
|
NS_IF_RELEASE(nextValLiteral);
|
|
|
|
NS_IF_RELEASE(nextValNode);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
1999-02-16 22:30:04 +03:00
|
|
|
|
|
|
|
|
1998-12-24 08:07:14 +03:00
|
|
|
nsresult
|
1999-04-16 12:39:02 +04:00
|
|
|
rdf_ContainerAppendElement(nsIRDFDataSource* aDataSource,
|
|
|
|
nsIRDFResource* aContainer,
|
|
|
|
nsIRDFNode* aElement)
|
1998-12-24 08:07:14 +03:00
|
|
|
{
|
1999-04-16 12:39:02 +04:00
|
|
|
NS_PRECONDITION(aDataSource != nsnull, "null ptr");
|
|
|
|
if (! aDataSource)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
1998-12-24 08:07:14 +03:00
|
|
|
|
1999-04-16 12:39:02 +04:00
|
|
|
NS_PRECONDITION(aContainer != nsnull, "null ptr");
|
|
|
|
if (! aContainer)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
1998-12-24 08:07:14 +03:00
|
|
|
|
1999-04-16 12:39:02 +04:00
|
|
|
NS_PRECONDITION(aElement != nsnull, "null ptr");
|
|
|
|
if (! aElement)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
1998-12-24 08:07:14 +03:00
|
|
|
|
1999-04-16 12:39:02 +04:00
|
|
|
NS_PRECONDITION(rdf_IsContainer(aDataSource, aContainer), "not a container");
|
1998-12-24 08:07:14 +03:00
|
|
|
|
1999-04-16 12:39:02 +04:00
|
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsIRDFResource> nextVal;
|
|
|
|
rv = rdf_ContainerGetNextValue(aDataSource, aContainer, getter_AddRefs(nextVal));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1998-12-24 08:07:14 +03:00
|
|
|
|
1999-04-16 12:39:02 +04:00
|
|
|
rv = aDataSource->Assert(aContainer, nextVal, aElement, PR_TRUE);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
return NS_OK;
|
1998-12-24 08:07:14 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
1999-02-16 22:30:04 +03:00
|
|
|
nsresult
|
|
|
|
rdf_ContainerRemoveElement(nsIRDFDataSource* aDataSource,
|
|
|
|
nsIRDFResource* aContainer,
|
|
|
|
nsIRDFNode* aElement)
|
|
|
|
{
|
|
|
|
NS_PRECONDITION(aDataSource != nsnull, "null ptr");
|
|
|
|
if (! aDataSource)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
|
|
|
NS_PRECONDITION(aContainer != nsnull, "null ptr");
|
|
|
|
if (! aContainer)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
|
|
|
NS_PRECONDITION(aElement != nsnull, "null ptr");
|
|
|
|
if (! aElement)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
// Create a cursor and grovel through the container looking for
|
|
|
|
// the specified element.
|
|
|
|
nsCOMPtr<nsIRDFAssertionCursor> elements;
|
|
|
|
if (NS_FAILED(rv = NS_NewContainerCursor(aDataSource,
|
|
|
|
aContainer,
|
|
|
|
getter_AddRefs(elements)))) {
|
|
|
|
NS_ERROR("unable to create container cursor");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1999-03-30 06:30:16 +04:00
|
|
|
while (1) {
|
|
|
|
rv = elements->Advance();
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
if (rv == NS_RDF_CURSOR_EMPTY)
|
|
|
|
break;
|
|
|
|
|
1999-02-16 22:30:04 +03:00
|
|
|
nsCOMPtr<nsIRDFNode> element;
|
1999-03-29 23:52:54 +04:00
|
|
|
if (NS_FAILED(rv = elements->GetTarget(getter_AddRefs(element)))) {
|
1999-02-16 22:30:04 +03:00
|
|
|
NS_ERROR("unable to read cursor");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1999-03-30 07:58:24 +04:00
|
|
|
NS_ASSERTION(rv != NS_RDF_NO_VALUE, "null item in cursor");
|
|
|
|
if (rv == NS_RDF_NO_VALUE)
|
|
|
|
continue;
|
|
|
|
|
1999-02-16 22:30:04 +03:00
|
|
|
PRBool eq;
|
|
|
|
if (NS_FAILED(rv = element->EqualsNode(aElement, &eq))) {
|
|
|
|
NS_ERROR("severe error on equality check");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (! eq)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
// Okay, we've found it.
|
|
|
|
|
|
|
|
// What was it's index?
|
|
|
|
nsCOMPtr<nsIRDFResource> ordinal;
|
1999-03-29 23:52:54 +04:00
|
|
|
if (NS_FAILED(rv = elements->GetLabel(getter_AddRefs(ordinal)))) {
|
1999-02-16 22:30:04 +03:00
|
|
|
NS_ERROR("unable to get element's ordinal index");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// First, remove the element.
|
|
|
|
if (NS_FAILED(rv = aDataSource->Unassert(aContainer, ordinal, element))) {
|
|
|
|
NS_ERROR("unable to remove element from the container");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
PRInt32 index;
|
|
|
|
if (NS_FAILED(rv = rdf_OrdinalResourceToIndex(ordinal, &index))) {
|
|
|
|
NS_ERROR("unable to convert ordinal URI to index");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now slide the rest of the collection backwards to fill in
|
|
|
|
// the gap.
|
1999-03-30 06:30:16 +04:00
|
|
|
while (1) {
|
|
|
|
rv = elements->Advance();
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
if (rv == NS_RDF_CURSOR_EMPTY)
|
|
|
|
break;
|
|
|
|
|
1999-03-29 23:52:54 +04:00
|
|
|
if (NS_FAILED(rv = elements->GetTarget(getter_AddRefs(element)))) {
|
1999-02-16 22:30:04 +03:00
|
|
|
NS_ERROR("unable to get element from cursor");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1999-03-30 07:58:24 +04:00
|
|
|
NS_ASSERTION(rv != NS_RDF_NO_VALUE, "null value in cursor");
|
|
|
|
if (rv == NS_RDF_NO_VALUE)
|
|
|
|
continue;
|
|
|
|
|
1999-03-29 23:52:54 +04:00
|
|
|
if (NS_FAILED(rv = elements->GetLabel(getter_AddRefs(ordinal)))) {
|
1999-02-16 22:30:04 +03:00
|
|
|
NS_ERROR("unable to get element's ordinal index");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NS_FAILED(rv = aDataSource->Unassert(aContainer, ordinal, element))) {
|
|
|
|
NS_ERROR("unable to remove element from the container");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NS_FAILED(rv = rdf_IndexToOrdinalResource(index, getter_AddRefs(ordinal)))) {
|
|
|
|
NS_ERROR("unable to construct ordinal resource");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1999-04-07 10:29:41 +04:00
|
|
|
rv = aDataSource->Assert(aContainer, ordinal, element, PR_TRUE);
|
|
|
|
if (rv != NS_RDF_ASSERTION_ACCEPTED) {
|
1999-02-16 22:30:04 +03:00
|
|
|
NS_ERROR("unable to add element to the container");
|
1999-04-07 10:29:41 +04:00
|
|
|
return NS_ERROR_FAILURE;
|
1999-02-16 22:30:04 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
++index;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Update the container's nextVal to reflect this mumbo jumbo
|
|
|
|
if (NS_FAILED(rv = rdf_ContainerSetNextValue(aDataSource, aContainer, index))) {
|
|
|
|
NS_ERROR("unable to update container's nextVal");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_WARNING("attempt to remove non-existant element from container");
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
rdf_ContainerInsertElementAt(nsIRDFDataSource* aDataSource,
|
|
|
|
nsIRDFResource* aContainer,
|
|
|
|
nsIRDFNode* aElement,
|
|
|
|
PRInt32 aIndex)
|
|
|
|
{
|
|
|
|
NS_PRECONDITION(aDataSource != nsnull, "null ptr");
|
|
|
|
if (! aDataSource)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
|
|
|
NS_PRECONDITION(aContainer != nsnull, "null ptr");
|
|
|
|
if (! aContainer)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
|
|
|
NS_PRECONDITION(aElement != nsnull, "null ptr");
|
|
|
|
if (! aElement)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
|
|
|
NS_PRECONDITION(aIndex >= 1, "illegal value");
|
|
|
|
if (aIndex < 1)
|
|
|
|
return NS_ERROR_ILLEGAL_VALUE;
|
|
|
|
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIRDFAssertionCursor> elements;
|
|
|
|
|
|
|
|
if (NS_FAILED(rv = NS_NewContainerCursor(aDataSource,
|
|
|
|
aContainer,
|
|
|
|
getter_AddRefs(elements)))) {
|
|
|
|
NS_ERROR("unable to create container cursor");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIRDFResource> ordinal;
|
|
|
|
PRInt32 index = 1;
|
|
|
|
|
|
|
|
// Advance the cursor to the aIndex'th element.
|
1999-03-30 06:30:16 +04:00
|
|
|
while (1) {
|
|
|
|
rv = elements->Advance();
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
if (rv == NS_RDF_CURSOR_EMPTY)
|
|
|
|
break;
|
|
|
|
|
1999-03-29 23:52:54 +04:00
|
|
|
if (NS_FAILED(rv = elements->GetLabel(getter_AddRefs(ordinal)))) {
|
1999-02-16 22:30:04 +03:00
|
|
|
NS_ERROR("unable to get element's ordinal index");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NS_FAILED(rv = rdf_OrdinalResourceToIndex(ordinal, &index))) {
|
|
|
|
NS_ERROR("unable to convert ordinal resource to index");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// XXX Use >= in case any "holes" exist...
|
|
|
|
if (index >= aIndex)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remember if we've exhausted the cursor: if so, this degenerates
|
|
|
|
// into a simple "append" operation.
|
1999-03-30 06:30:16 +04:00
|
|
|
PRBool cursorExhausted = (rv == NS_RDF_CURSOR_EMPTY);
|
1999-02-16 22:30:04 +03:00
|
|
|
|
|
|
|
// XXX Be paranoid: there may have been a "hole"
|
|
|
|
if (index > aIndex)
|
|
|
|
index = aIndex;
|
|
|
|
|
|
|
|
// If we ran all the way to the end of the cursor, then "index"
|
|
|
|
// will contain the ordinal value of the last element in the
|
|
|
|
// container. Increment it by one to get the position at which
|
|
|
|
// we'll want to insert it into the container.
|
|
|
|
if (cursorExhausted && aIndex > index) {
|
|
|
|
if (index != aIndex) {
|
|
|
|
// Sanity check only: aIndex was _way_ too large...
|
|
|
|
NS_WARNING("out of bounds");
|
|
|
|
}
|
|
|
|
|
|
|
|
++index;
|
|
|
|
}
|
|
|
|
|
|
|
|
// At this point "index" contains the index at which we want to
|
|
|
|
// insert the new element.
|
|
|
|
if (NS_FAILED(rv = rdf_IndexToOrdinalResource(index, getter_AddRefs(ordinal)))) {
|
|
|
|
NS_ERROR("unable to convert index to ordinal resource");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Insert it!
|
|
|
|
if (NS_FAILED(rv = aDataSource->Assert(aContainer, ordinal, aElement, PR_TRUE))) {
|
|
|
|
NS_ERROR("unable to add element to container");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now slide the rest of the container "up" by one...
|
|
|
|
if (! cursorExhausted) {
|
|
|
|
do {
|
1999-03-29 23:52:54 +04:00
|
|
|
if (NS_FAILED(rv = elements->GetLabel(getter_AddRefs(ordinal)))) {
|
1999-02-16 22:30:04 +03:00
|
|
|
NS_ERROR("unable to get element's ordinal index");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIRDFNode> element;
|
1999-03-29 23:52:54 +04:00
|
|
|
if (NS_FAILED(rv = elements->GetTarget(getter_AddRefs(element)))) {
|
1999-02-16 22:30:04 +03:00
|
|
|
NS_ERROR("unable to get element from cursor");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1999-03-30 07:58:24 +04:00
|
|
|
NS_ASSERTION(rv != NS_RDF_NO_VALUE, "null value in cursor");
|
|
|
|
if (rv == NS_RDF_NO_VALUE)
|
|
|
|
continue;
|
|
|
|
|
1999-02-16 22:30:04 +03:00
|
|
|
if (NS_FAILED(rv = aDataSource->Unassert(aContainer, ordinal, element))) {
|
|
|
|
NS_ERROR("unable to remove element from container");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NS_FAILED(rv = rdf_IndexToOrdinalResource(++index, getter_AddRefs(ordinal)))) {
|
|
|
|
NS_ERROR("unable to convert index to ordinal resource");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1999-04-07 10:29:41 +04:00
|
|
|
rv = aDataSource->Assert(aContainer, ordinal, element, PR_TRUE);
|
|
|
|
if (rv != NS_RDF_ASSERTION_ACCEPTED) {
|
1999-02-16 22:30:04 +03:00
|
|
|
NS_ERROR("unable to add element to container");
|
1999-04-07 10:29:41 +04:00
|
|
|
return NS_ERROR_FAILURE;
|
1999-02-16 22:30:04 +03:00
|
|
|
}
|
|
|
|
|
1999-03-30 06:30:16 +04:00
|
|
|
rv = elements->Advance();
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
if (rv == NS_RDF_CURSOR_EMPTY)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
while (1);
|
1999-02-16 22:30:04 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// Now update the container's nextVal
|
|
|
|
if (NS_FAILED(rv = rdf_ContainerSetNextValue(aDataSource, aContainer, ++index))) {
|
|
|
|
NS_ERROR("unable to update container's nextVal");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
rdf_ContainerIndexOf(nsIRDFDataSource* aDataSource,
|
|
|
|
nsIRDFResource* aContainer,
|
|
|
|
nsIRDFNode* aElement,
|
|
|
|
PRInt32* aIndex)
|
|
|
|
{
|
|
|
|
NS_PRECONDITION(aDataSource != nsnull, "null ptr");
|
|
|
|
if (! aDataSource)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
|
|
|
NS_PRECONDITION(aContainer != nsnull, "null ptr");
|
|
|
|
if (! aContainer)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
|
|
|
NS_PRECONDITION(aElement != nsnull, "null ptr");
|
|
|
|
if (! aElement)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
|
|
|
NS_PRECONDITION(aIndex != nsnull, "null ptr");
|
|
|
|
if (! aIndex)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIRDFAssertionCursor> elements;
|
|
|
|
if (NS_FAILED(rv = NS_NewContainerCursor(aDataSource,
|
|
|
|
aContainer,
|
|
|
|
getter_AddRefs(elements)))) {
|
|
|
|
NS_ERROR("unable to create container cursor");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Advance the cursor until we find the element we want
|
1999-03-30 06:30:16 +04:00
|
|
|
while (1) {
|
|
|
|
rv = elements->Advance();
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
if (rv == NS_RDF_CURSOR_EMPTY)
|
|
|
|
break;
|
|
|
|
|
1999-02-16 22:30:04 +03:00
|
|
|
nsCOMPtr<nsIRDFNode> element;
|
1999-03-29 23:52:54 +04:00
|
|
|
if (NS_FAILED(rv = elements->GetTarget(getter_AddRefs(element)))) {
|
1999-02-16 22:30:04 +03:00
|
|
|
NS_ERROR("unable to get element from cursor");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1999-03-30 07:58:24 +04:00
|
|
|
NS_ASSERTION(rv != NS_RDF_NO_VALUE, "null value in cursor");
|
|
|
|
if (rv == NS_RDF_NO_VALUE)
|
|
|
|
continue;
|
|
|
|
|
1999-02-16 22:30:04 +03:00
|
|
|
// Okay, we've found it.
|
|
|
|
nsCOMPtr<nsIRDFResource> ordinal;
|
1999-03-29 23:52:54 +04:00
|
|
|
if (NS_FAILED(rv = elements->GetLabel(getter_AddRefs(ordinal)))) {
|
1999-02-16 22:30:04 +03:00
|
|
|
NS_ERROR("unable to get element's ordinal index");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
PRInt32 index;
|
|
|
|
if (NS_FAILED(rv = rdf_OrdinalResourceToIndex(ordinal, &index))) {
|
|
|
|
NS_ERROR("unable to convert ordinal resource to index");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1999-02-19 05:53:45 +03:00
|
|
|
if (element != nsCOMPtr<nsIRDFNode>( do_QueryInterface(aElement)) )
|
1999-02-16 22:30:04 +03:00
|
|
|
continue;
|
|
|
|
|
|
|
|
*aIndex = index;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_WARNING("element not found");
|
|
|
|
*aIndex = -1;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|