зеркало из https://github.com/mozilla/pjs.git
629 строки
19 KiB
C++
629 строки
19 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
*
|
|
* The contents of this file are subject to the Mozilla Public
|
|
* License Version 1.1 (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/MPL/
|
|
*
|
|
* 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 RaptorCanvas.
|
|
*
|
|
* The Initial Developer of the Original Code is Kirk Baker and
|
|
* Ian Wilkinson. Portions created by Kirk Baker and Ian Wilkinson are
|
|
* Copyright (C) 1999 Kirk Baker and Ian Wilkinson. All
|
|
* Rights Reserved.
|
|
*
|
|
* Contributor(s): Ed Burns <edburns@acm.org>
|
|
*/
|
|
|
|
#include "rdf_util.h"
|
|
|
|
#include "ns_globals.h" // for prLogModuleInfo and gComponentManager
|
|
|
|
#include "nsIServiceManager.h"
|
|
|
|
#include "nsRDFCID.h" // for NS_RDFCONTAINER_CID
|
|
|
|
#include "prlog.h" // for PR_ASSERT
|
|
|
|
static PRBool rdf_inited = PR_FALSE;
|
|
|
|
nsCOMPtr<nsIRDFContainerUtils> gRDFCU = nsnull;
|
|
nsCOMPtr<nsIRDFService> gRDF = nsnull;
|
|
nsCOMPtr<nsIBookmarksService> gBookmarks = nsnull;
|
|
nsCOMPtr<nsIRDFDataSource> gBookmarksDataSource = nsnull;
|
|
|
|
nsCOMPtr<nsIRDFResource> kNC_BookmarksRoot = nsnull;
|
|
nsCOMPtr<nsIRDFResource> kNC_Name = nsnull;
|
|
nsCOMPtr<nsIRDFResource> kNC_URL = nsnull;
|
|
nsCOMPtr<nsIRDFResource> kNC_parent = nsnull;
|
|
nsCOMPtr<nsIRDFResource> kNC_Folder = nsnull;
|
|
nsCOMPtr<nsIRDFResource> kRDF_type = nsnull;
|
|
|
|
nsCOMPtr<nsIRDFResource> kNewFolderCommand;
|
|
nsCOMPtr<nsIRDFResource> kNewBookmarkCommand;
|
|
|
|
static NS_DEFINE_CID(kRDFContainerCID, NS_RDFCONTAINER_CID);
|
|
static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
|
|
static NS_DEFINE_CID(kRDFContainerUtilsCID, NS_RDFCONTAINERUTILS_CID);
|
|
|
|
nsresult rdf_InitRDFUtils()
|
|
{
|
|
nsresult rv = NS_ERROR_FAILURE;
|
|
|
|
if (rdf_inited) {
|
|
return NS_OK;
|
|
}
|
|
|
|
// Init the global instances
|
|
|
|
if (nsnull == gBookmarks) {
|
|
// Get the bookmarks service
|
|
gBookmarks = do_GetService(NS_BOOKMARKS_SERVICE_CONTRACTID, &rv);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
#ifdef _WIN32
|
|
|
|
// PENDING(edburns): HACK workaround for bug 59530. This
|
|
// workaround forces the nsBookmarksService to leak so that it
|
|
// never gets destructed, thus the timer never gets canceled and
|
|
// thus the fact that the static nsCOMPtr instance has gone away
|
|
// doesn't matter.
|
|
|
|
nsIBookmarksService *raw = (nsIBookmarksService *) gBookmarks.get();
|
|
raw->AddRef();
|
|
#endif
|
|
}
|
|
|
|
if (nsnull == gBookmarksDataSource) {
|
|
// get the bookmarks service as an RDFDataSource
|
|
rv = gBookmarks->QueryInterface(NS_GET_IID(nsIRDFDataSource),
|
|
getter_AddRefs(gBookmarksDataSource));
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
}
|
|
|
|
if (nsnull == gRDF) {
|
|
// get the RDF service
|
|
gRDF = do_GetService(kRDFServiceCID, &rv);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
}
|
|
|
|
if (nsnull == gRDFCU) {
|
|
// get the RDF service
|
|
gRDFCU = do_GetService(kRDFContainerUtilsCID, &rv);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
}
|
|
|
|
// init the properties
|
|
// find the nsIRDFResource for the bookmarks
|
|
if (nsnull == kNC_BookmarksRoot) {
|
|
rv = gRDF->GetResource(BOOKMARKS_URI,
|
|
getter_AddRefs(kNC_BookmarksRoot));
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
}
|
|
|
|
if (nsnull == kNC_Name) {
|
|
rv = gRDF->GetResource("http://home.netscape.com/NC-rdf#Name",
|
|
getter_AddRefs(kNC_Name));
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
}
|
|
|
|
if (nsnull == kNC_URL) {
|
|
rv = gRDF->GetResource("http://home.netscape.com/NC-rdf#URL",
|
|
getter_AddRefs(kNC_URL));
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
}
|
|
if (nsnull == kNC_parent) {
|
|
rv = gRDF->GetResource("http://home.netscape.com/NC-rdf#parent",
|
|
getter_AddRefs(kNC_parent));
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
}
|
|
if (nsnull == kNC_Folder) {
|
|
rv = gRDF->GetResource("http://home.netscape.com/NC-rdf#Folder",
|
|
getter_AddRefs(kNC_Folder));
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
}
|
|
|
|
if (nsnull == kRDF_type) {
|
|
rv = gRDF->GetResource("http://www.w3.org/1999/02/22-rdf-syntax-ns",
|
|
getter_AddRefs(kRDF_type));
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
}
|
|
if (nsnull == kNewFolderCommand) {
|
|
rv = gRDF->GetResource("http://home.netscape.com/NC-rdf#command?cmd=newfolder",
|
|
getter_AddRefs(kNewFolderCommand));
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
}
|
|
if (nsnull == kNewBookmarkCommand) {
|
|
rv = gRDF->GetResource("http://home.netscape.com/NC-rdf#command?cmd=newbookmark",
|
|
getter_AddRefs(kNewBookmarkCommand));
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
}
|
|
|
|
rdf_inited = PR_TRUE;
|
|
return rv;
|
|
}
|
|
|
|
void rdf_recursiveResourceTraversal(nsCOMPtr<nsIRDFResource> currentResource)
|
|
{
|
|
nsresult rv;
|
|
PRBool result;
|
|
const PRUnichar *textForNode = nsnull;
|
|
nsCOMPtr<nsISupports> supportsResult;
|
|
nsCOMPtr<nsIRDFNode> node;
|
|
nsCOMPtr<nsIRDFLiteral> literal;
|
|
nsCOMPtr<nsIRDFResource> childResource;
|
|
nsCOMPtr<nsIRDFContainer> container;
|
|
nsCOMPtr<nsISimpleEnumerator> elements;
|
|
|
|
// ASSERT(nsnull != gRDFCU)
|
|
|
|
rv = gRDFCU->IsContainer(gBookmarksDataSource, currentResource,
|
|
&result);
|
|
|
|
if (result) {
|
|
// It's a folder
|
|
|
|
rdf_printArcLabels(currentResource);
|
|
|
|
// see if it has a name target
|
|
|
|
rv = gBookmarksDataSource->GetTarget(currentResource,
|
|
kNC_Name, PR_TRUE,
|
|
getter_AddRefs(node));
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
// if so, make sure it's an nsIRDFLiteral
|
|
rv = node->QueryInterface(NS_GET_IID(nsIRDFLiteral),
|
|
getter_AddRefs(literal));
|
|
if (NS_SUCCEEDED(rv)) {
|
|
rv = literal->GetValueConst(&textForNode);
|
|
}
|
|
else {
|
|
if (prLogModuleInfo) {
|
|
PR_LOG(prLogModuleInfo, 3,
|
|
("recursiveResourceTraversal: node is not an nsIRDFLiteral.\n"));
|
|
}
|
|
}
|
|
|
|
}
|
|
else {
|
|
if (prLogModuleInfo) {
|
|
PR_LOG(prLogModuleInfo, 3,
|
|
("recursiveResourceTraversal: can't get name from currentResource.\n"));
|
|
}
|
|
}
|
|
|
|
PR_ASSERT(gComponentManager);
|
|
// get a container in order to recurr
|
|
rv = gComponentManager->
|
|
CreateInstance(kRDFContainerCID,
|
|
nsnull,
|
|
NS_GET_IID(nsIRDFContainer),
|
|
getter_AddRefs(container));
|
|
if (NS_FAILED(rv)) {
|
|
if (prLogModuleInfo) {
|
|
PR_LOG(prLogModuleInfo, 3,
|
|
("recursiveResourceTraversal: can't get a new container\n"));
|
|
}
|
|
return;
|
|
}
|
|
|
|
rv = container->Init(gBookmarksDataSource, currentResource);
|
|
if (NS_FAILED(rv)) {
|
|
if (prLogModuleInfo) {
|
|
PR_LOG(prLogModuleInfo, 3,
|
|
("recursiveResourceTraversal: can't init container\n"));
|
|
}
|
|
return;
|
|
}
|
|
|
|
// go over my children
|
|
rv = container->GetElements(getter_AddRefs(elements));
|
|
|
|
if (NS_FAILED(rv)) {
|
|
if (prLogModuleInfo) {
|
|
PR_LOG(prLogModuleInfo, 3,
|
|
("recursiveResourceTraversal: can't get elements from folder\n"));
|
|
}
|
|
return;
|
|
}
|
|
|
|
rv = elements->HasMoreElements(&result);
|
|
if (NS_FAILED(rv)) {
|
|
if (prLogModuleInfo) {
|
|
PR_LOG(prLogModuleInfo, 3,
|
|
("recursiveResourceTraversal: folder %s has no children.\n",
|
|
textForNode));
|
|
}
|
|
return;
|
|
}
|
|
while (result) {
|
|
rv = elements->GetNext(getter_AddRefs(supportsResult));
|
|
if (NS_FAILED(rv)) {
|
|
if (prLogModuleInfo) {
|
|
PR_LOG(prLogModuleInfo, 3,
|
|
("Exception: Can't get next from enumerator.\n"));
|
|
}
|
|
return;
|
|
}
|
|
|
|
// make sure it's an RDFResource
|
|
rv = supportsResult->QueryInterface(NS_GET_IID(nsIRDFResource),
|
|
getter_AddRefs(childResource));
|
|
if (NS_FAILED(rv)) {
|
|
if (prLogModuleInfo) {
|
|
PR_LOG(prLogModuleInfo, 3,
|
|
("Exception: next from enumerator is not an nsIRDFResource.\n"));
|
|
}
|
|
return;
|
|
}
|
|
|
|
rdf_recursiveResourceTraversal(childResource);
|
|
|
|
rv = elements->HasMoreElements(&result);
|
|
if (NS_FAILED(rv)) {
|
|
if (prLogModuleInfo) {
|
|
PR_LOG(prLogModuleInfo, 3,
|
|
("Exception: can't tell if we have more elements.\n"));
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
// It's a bookmark
|
|
printf("BOOKMARK:\n");
|
|
rdf_printArcLabels(currentResource);
|
|
|
|
// see if it has a URL target
|
|
|
|
rv = gBookmarksDataSource->GetTarget(currentResource,
|
|
kNC_URL, PR_TRUE,
|
|
getter_AddRefs(node));
|
|
if (NS_FAILED(rv)) {
|
|
if (prLogModuleInfo) {
|
|
PR_LOG(prLogModuleInfo, 3,
|
|
("recursiveResourceTraversal: can't get url from currentResource\n"));
|
|
}
|
|
return;
|
|
}
|
|
|
|
// if so, make sure it's an nsIRDFLiteral
|
|
rv = node->QueryInterface(NS_GET_IID(nsIRDFLiteral),
|
|
getter_AddRefs(literal));
|
|
if (NS_FAILED(rv)) {
|
|
if (prLogModuleInfo) {
|
|
PR_LOG(prLogModuleInfo, 3,
|
|
("recursiveResourceTraversal: node is not an nsIRDFLiteral.\n"));
|
|
}
|
|
return;
|
|
}
|
|
|
|
// get the value of the literal
|
|
rv = literal->GetValueConst(&textForNode);
|
|
if (NS_FAILED(rv)) {
|
|
if (prLogModuleInfo) {
|
|
PR_LOG(prLogModuleInfo, 3,
|
|
("recursiveResourceTraversal: node doesn't have a value.\n"));
|
|
}
|
|
return;
|
|
}
|
|
|
|
#if DEBUG_RAPTOR_CANVAS
|
|
if (prLogModuleInfo) {
|
|
PR_LOG(prLogModuleInfo, 3,
|
|
("\turl: %S\n", textForNode));
|
|
}
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void rdf_printArcLabels(nsCOMPtr<nsIRDFResource> currentResource)
|
|
{
|
|
if (!currentResource) {
|
|
if (prLogModuleInfo) {
|
|
PR_LOG(prLogModuleInfo, 3, ("resource: null\n"));
|
|
}
|
|
return;
|
|
}
|
|
|
|
nsCOMPtr<nsISimpleEnumerator> labels;
|
|
nsCOMPtr<nsISupports> supportsResult;
|
|
nsCOMPtr<nsIRDFResource> resourceResult;
|
|
nsresult rv;
|
|
PRBool result;
|
|
const char *arcLabel;
|
|
const char *currentResourceValue;
|
|
|
|
rv = currentResource->GetValueConst(¤tResourceValue);
|
|
if (NS_SUCCEEDED(rv)) {
|
|
if (prLogModuleInfo) {
|
|
PR_LOG(prLogModuleInfo, 3,
|
|
("resource: %s\n", currentResourceValue));
|
|
}
|
|
}
|
|
else {
|
|
if (prLogModuleInfo) {
|
|
PR_LOG(prLogModuleInfo, 3,
|
|
("printArcLabels: can't get value from current resource.\n"));
|
|
}
|
|
}
|
|
|
|
rv = gBookmarksDataSource->ArcLabelsOut(currentResource,
|
|
getter_AddRefs(labels));
|
|
|
|
if (NS_FAILED(rv)) {
|
|
if (prLogModuleInfo) {
|
|
PR_LOG(prLogModuleInfo, 3,
|
|
("printArcLabels: currentResource has no outgoing arcs.\n"));
|
|
}
|
|
return;
|
|
}
|
|
|
|
rv = labels->HasMoreElements(&result);
|
|
if (NS_FAILED(rv)) {
|
|
if (prLogModuleInfo) {
|
|
PR_LOG(prLogModuleInfo, 3,
|
|
("printArcLabels: can't get elements from currentResource's enum.\n"));
|
|
}
|
|
return;
|
|
}
|
|
|
|
while (result) {
|
|
rv = labels->GetNext(getter_AddRefs(supportsResult));
|
|
if (NS_FAILED(rv)) {
|
|
if (prLogModuleInfo) {
|
|
PR_LOG(prLogModuleInfo, 3,
|
|
("printArcLabels: Can't get next arc from enumerator.\n"));
|
|
}
|
|
return;
|
|
}
|
|
|
|
// make sure it's an RDFResource
|
|
rv = supportsResult->QueryInterface(NS_GET_IID(nsIRDFResource),
|
|
getter_AddRefs(resourceResult));
|
|
if (NS_SUCCEEDED(rv)) {
|
|
rv = resourceResult->GetValueConst(&arcLabel);
|
|
if (NS_SUCCEEDED(rv)) {
|
|
if (prLogModuleInfo) {
|
|
PR_LOG(prLogModuleInfo, 3,
|
|
("\tarc label: %s\n", arcLabel));
|
|
}
|
|
}
|
|
else {
|
|
if (prLogModuleInfo) {
|
|
PR_LOG(prLogModuleInfo, 3,
|
|
("printArcLabels: can't get value from current arc.\n"));
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
if (prLogModuleInfo) {
|
|
PR_LOG(prLogModuleInfo, 3,
|
|
("printArcLabels: next arc from enumerator is not an nsIRDFResource.\n"));
|
|
}
|
|
}
|
|
rv = labels->HasMoreElements(&result);
|
|
if (NS_FAILED(rv)) {
|
|
if (prLogModuleInfo) {
|
|
PR_LOG(prLogModuleInfo, 3,
|
|
("printArcLabels: can't get elements from currentResource's enum.\n"));
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
nsresult rdf_getChildAt(int index, nsIRDFResource *theParent,
|
|
nsIRDFResource **retval)
|
|
{
|
|
// Since there's no getChildAt type thing in RDF, we just get an
|
|
// enumeration and get the indexth child.
|
|
nsCOMPtr<nsIRDFResource> parent = theParent;
|
|
nsCOMPtr<nsIRDFContainer> container;
|
|
nsCOMPtr<nsISimpleEnumerator> elements;
|
|
nsCOMPtr<nsISupports> supportsResult;
|
|
nsCOMPtr<nsIRDFResource> childResource;
|
|
nsresult rv;
|
|
PRBool result, hasChildAtIndex = PR_FALSE;
|
|
*retval = nsnull;
|
|
PRInt32 i = 0;
|
|
|
|
rv = gRDFCU->IsContainer(gBookmarksDataSource, parent,
|
|
&result);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
if (PR_FALSE == result) {
|
|
return NS_OK;
|
|
}
|
|
|
|
PR_ASSERT(gComponentManager);
|
|
|
|
rv = gComponentManager->CreateInstance(kRDFContainerCID,
|
|
nsnull,
|
|
NS_GET_IID(nsIRDFContainer),
|
|
getter_AddRefs(container));
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
rv = container->Init(gBookmarksDataSource, parent);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
rv = container->GetElements(getter_AddRefs(elements));
|
|
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
rv = elements->HasMoreElements(&result);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
while (result) {
|
|
rv = elements->GetNext(getter_AddRefs(supportsResult));
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
if (index == i) {
|
|
hasChildAtIndex = PR_TRUE;
|
|
break;
|
|
}
|
|
i++;
|
|
rv = elements->HasMoreElements(&result);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
}
|
|
if (hasChildAtIndex) {
|
|
rv = supportsResult->QueryInterface(NS_GET_IID(nsIRDFResource),
|
|
getter_AddRefs(childResource));
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
*retval = childResource;
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult rdf_getChildCount(nsIRDFResource *theParent, PRInt32 *count)
|
|
{
|
|
nsresult rv;
|
|
nsCOMPtr<nsIRDFResource> parent = theParent;
|
|
nsCOMPtr<nsIRDFContainer> container;
|
|
PRBool result;
|
|
*count = 0;
|
|
|
|
rv = gRDFCU->IsContainer(gBookmarksDataSource, parent,
|
|
&result);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
if (PR_FALSE == result) {
|
|
return NS_OK;
|
|
}
|
|
PR_ASSERT(gComponentManager);
|
|
rv = gComponentManager->CreateInstance(kRDFContainerCID,
|
|
nsnull,
|
|
NS_GET_IID(nsIRDFContainer),
|
|
getter_AddRefs(container));
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
rv = container->Init(gBookmarksDataSource, parent);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
|
|
rv = container->GetCount(count);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult rdf_getIndexOfChild(nsIRDFResource *theParent,
|
|
nsIRDFResource *theChild,
|
|
PRInt32 *index)
|
|
{
|
|
nsCOMPtr<nsIRDFResource> parent = theParent;
|
|
nsCOMPtr<nsIRDFResource> child = theChild;
|
|
nsCOMPtr<nsIRDFContainer> container;
|
|
nsCOMPtr<nsISimpleEnumerator> elements;
|
|
nsCOMPtr<nsISupports> supportsResult;
|
|
nsresult rv;
|
|
PRBool result;
|
|
*index = -1;
|
|
PRInt32 i = 0;
|
|
|
|
rv = gRDFCU->IsContainer(gBookmarksDataSource, parent,
|
|
&result);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
if (PR_FALSE == result) {
|
|
return NS_OK;
|
|
}
|
|
PR_ASSERT(gComponentManager);
|
|
rv = gComponentManager->CreateInstance(kRDFContainerCID,
|
|
nsnull,
|
|
NS_GET_IID(nsIRDFContainer),
|
|
getter_AddRefs(container));
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
rv = container->Init(gBookmarksDataSource, parent);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
rv = container->GetElements(getter_AddRefs(elements));
|
|
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
rv = elements->HasMoreElements(&result);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
while (result) {
|
|
rv = elements->GetNext(getter_AddRefs(supportsResult));
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
if (supportsResult == child) {
|
|
*index = i;
|
|
rv = NS_OK;
|
|
break;
|
|
}
|
|
i++;
|
|
rv = elements->HasMoreElements(&result);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
}
|
|
return rv;
|
|
}
|