gecko-dev/java/webclient/src_moz/rdf_util.cpp
edburns%acm.org c2d7e96b90 The churn continues. After this checkin, BrowserControlFactoryTest
runs, but nothing else does.

As you all probably already know, all mozilla API calls have to happen
on the same thread.  For webclient, this will be the NativeEventThread.
This change-bundle does many many things, here are the main ones.

These changes are in concert with the checkin I just did to the diagram
at
<http://www.mozilla.org/projects/blackwood/webclient/design/20040306-webclient-2_0.zargo>.

M classes_spec/org/mozilla/webclient/impl/WrapperFactory.java
M classes_spec/org/mozilla/webclient/impl/wrapper_native/WrapperFactoryImpl.java

 * <p>This class is the hub of the startup and shutdown sequence for
 * Webclient.  It is a singleton and owns references to other app
 * singletons:</p>
 *
 * 	<ul>
 * 	  <li><p>{@link NativeEventThread}</p></li>
 *
 * 	  <li><p>{@link Bookmarks}</p></li>
 *
 * 	  <li><p>{@link Preferences}</p></li>
 *
 * 	  <li><p>{@link ProfileManager}</p></li>

 * 	  <li><p>the native object singleton corresponding to this java
 * 	  object (if necessary)</p></li>
 *
 *	</ul>
 *
 * <p>It maintains a set of {@link BrowserControlImpl} instances so that
 * we may return the native pointer for each one.</p>
 *
 * <p>This class is responsible for creating and initializing and
 * deleting {@link BrowserControlImpl} instances, as well as ensuring
 * that the native counterpart is proprely maintained in kind.</p>
 *
 * <p>This class has a tight contract with {@link
 * NativeEventThread}.</p>

- make BrowserControl creation and deletion part of this classes
  responsibilities.

- introduce NativeWrapperFactory concept.

- own the one and only NativeEventThread.

M classes_spec/org/mozilla/webclient/impl/wrapper_native/NativeEventThread.java

- make this a singleton.

- remove dependencies on BrowserControl and nativeBrowserControl

 * <p>This is a singleton class.  All native events pass thru this class
 * by virtue of the {@link #pushRunnable} or {@link pushNotifyRunnable}
 * methods.</p>

- remove listener logic.  This'll go into EventRegistration, where it
  belongs.

A src_moz/NativeWrapperFactory.cpp
A src_moz/NativeWrapperFactory.h

- takes the place of the old WebclientContext

- is now a class

M classes_spec/org/mozilla/webclient/impl/BrowserControlImpl.java

- this no longer destroys the nativeBrowserControl.  That is now done by
  WrapperFactoryImpl.

M classes_spec/org/mozilla/webclient/impl/WebclientFactoryImpl.java

- no longer maintain browserControlCount.

M classes_spec/org/mozilla/webclient/impl/wrapper_native/BookmarksImpl.java
M classes_spec/org/mozilla/webclient/impl/wrapper_native/NavigationImpl.java
M classes_spec/org/mozilla/webclient/impl/wrapper_native/PreferencesImpl.java
M classes_spec/org/mozilla/webclient/impl/wrapper_native/ProfileManagerImpl.java

- rename NativeContext to NativeWrapperFactory, to illustrate its
  singletonness.

M classes_spec/org/mozilla/webclient/impl/wrapper_native/EventRegistrationImpl.java

- comment out a bunch of stuff in anticipation of the new threading
  model, currently being fleshed out.

M classes_spec/org/mozilla/webclient/impl/wrapper_native/ImplObjectNative.java

- NativeEventThread is singleton

M src_moz/BookmarksImpl.cpp
M src_moz/PreferencesImpl.cpp
M src_moz/ProfileManagerImpl.cpp
M src_moz/RDFEnumeration.cpp
M src_moz/RDFTreeNode.cpp

- rename WebclientContext to NativeWrapperFactory.

M src_moz/EmbedWindow.cpp

-  mBaseWindow->Destroy();
+  if (mBaseWindow) {
+      mBaseWindow->Destroy();
+  }

M src_moz/Makefile.in

- Bring back NavigationImpl

- add NativeWrapperFactory.

M src_moz/NativeBrowserControl.cpp
M src_moz/NativeBrowserControl.h

- move event queue and java related stuff to NativeWrapperFactory.  This
  class is now essentially a copy of EmbedPrivate in GtkEmbed.

M src_moz/NativeEventThread.cpp

- remove methods, most of it has moved to
  WrapperFactoryImpl/NativeWrapperFactory.

M src_moz/NavigationImpl.cpp

- comment out all methods but LoadURI.

M src_moz/WrapperFactoryImpl.cpp

- take functionality over from NativeEventThread.

M src_moz/ns_util.cpp
M src_moz/ns_util.h

- the eventQueue is owned by NativeWrapperFactory now.

M src_moz/rdf_util.cpp
M src_share/jni_util.cpp

- make all exceptions RuntimeExceptions, so they can be thrown from a
  Runnable.

M test/automated/src/classes/org/mozilla/webclient/impl/wrapper_native/WrapperFactoryImplTest.java

- comment out the meat of this test until I figure out how to test it.

M test/automated/src/test/BrowserControlFactoryTest_correct

- new content.
2004-04-15 22:58:08 +00:00

650 lines
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
#include "nsString.h"
#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; // PENDING(edburns): this should be in NativeWrapperFactory
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_startup()
{
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(nsDependentCString(BOOKMARKS_URI),
getter_AddRefs(kNC_BookmarksRoot));
if (NS_FAILED(rv)) {
return rv;
}
}
if (nsnull == kNC_Name) {
rv = gRDF->GetResource(NS_LITERAL_CSTRING("http://home.netscape.com/NC-rdf#Name"),
getter_AddRefs(kNC_Name));
if (NS_FAILED(rv)) {
return rv;
}
}
if (nsnull == kNC_URL) {
rv = gRDF->GetResource(NS_LITERAL_CSTRING("http://home.netscape.com/NC-rdf#URL"),
getter_AddRefs(kNC_URL));
if (NS_FAILED(rv)) {
return rv;
}
}
if (nsnull == kNC_parent) {
rv = gRDF->GetResource(NS_LITERAL_CSTRING("http://home.netscape.com/NC-rdf#parent"),
getter_AddRefs(kNC_parent));
if (NS_FAILED(rv)) {
return rv;
}
}
if (nsnull == kNC_Folder) {
rv = gRDF->GetResource(NS_LITERAL_CSTRING("http://home.netscape.com/NC-rdf#Folder"),
getter_AddRefs(kNC_Folder));
if (NS_FAILED(rv)) {
return rv;
}
}
if (nsnull == kRDF_type) {
rv = gRDF->GetResource(NS_LITERAL_CSTRING("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(NS_LITERAL_CSTRING("http://home.netscape.com/NC-rdf#command?cmd=newfolder"),
getter_AddRefs(kNewFolderCommand));
if (NS_FAILED(rv)) {
return rv;
}
}
if (nsnull == kNewBookmarkCommand) {
rv = gRDF->GetResource(NS_LITERAL_CSTRING("http://home.netscape.com/NC-rdf#command?cmd=newbookmark"),
getter_AddRefs(kNewBookmarkCommand));
if (NS_FAILED(rv)) {
return rv;
}
}
rv = gBookmarks->ReadBookmarks(&rdf_inited);
return rv;
}
nsresult rdf_shutdown()
{
kNewBookmarkCommand = nsnull;
kNewFolderCommand = nsnull;
kRDF_type = nsnull;
kNC_Folder = nsnull;
kNC_parent = nsnull;
kNC_URL = nsnull;
kNC_Name = nsnull;
kNC_BookmarksRoot = nsnull;
gRDFCU = nsnull;
gRDF = nsnull;
gBookmarksDataSource = nsnull;
#ifdef _WIN32
nsIBookmarksService *raw = (nsIBookmarksService *) gBookmarks.get();
raw->Release();
#endif
gBookmarks = nsnull;
return NS_OK;
}
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"));
}
}
// get a container in order to recurr
container = do_CreateInstance(kRDFContainerCID);
if (!container) {
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(&currentResourceValue);
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;
}
container = do_CreateInstance(kRDFContainerCID);
if (!container) {
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;
}
container = do_CreateInstance(kRDFContainerCID);
if (!container) {
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;
}
container = do_CreateInstance(kRDFContainerCID);
if (container) {
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;
}