diff --git a/rdf/src/nsRDFHTMLDocument.cpp b/rdf/src/nsRDFHTMLDocument.cpp
new file mode 100644
index 000000000000..ff7db2499c8c
--- /dev/null
+++ b/rdf/src/nsRDFHTMLDocument.cpp
@@ -0,0 +1,284 @@
+/* -*- 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.
+ */
+
+/*
+
+ This builds an HTML-like model, complete with text nodes, that can
+ be displayed in a vanilla HTML content viewer. You can apply CSS2
+ styles to the text, etc.
+
+ */
+
+#include "nsIRDFContent.h"
+#include "nsIRDFCursor.h"
+#include "nsIRDFDataBase.h"
+#include "nsIRDFNode.h"
+#include "nsIRDFResourceManager.h"
+#include "nsIServiceManager.h"
+#include "nsISupportsArray.h"
+#include "nsITextContent.h"
+#include "nsLayoutCID.h"
+#include "nsRDFCID.h"
+#include "nsRDFDocument.h"
+#include "rdfutil.h"
+
+////////////////////////////////////////////////////////////////////////
+
+static NS_DEFINE_IID(kIContentIID, NS_ICONTENT_IID);
+static NS_DEFINE_IID(kIDocumentIID, NS_IDOCUMENT_IID);
+static NS_DEFINE_IID(kIRDFResourceManagerIID, NS_IRDFRESOURCEMANAGER_IID);
+static NS_DEFINE_IID(kITextContentIID, NS_ITEXT_CONTENT_IID); // XXX grr...
+
+static NS_DEFINE_CID(kRDFResourceManagerCID, NS_RDFRESOURCEMANAGER_CID);
+static NS_DEFINE_CID(kTextNodeCID, NS_TEXTNODE_CID);
+
+////////////////////////////////////////////////////////////////////////
+
+class RDFHTMLDocumentImpl : public nsRDFDocument {
+public:
+ RDFHTMLDocumentImpl();
+ virtual ~RDFHTMLDocumentImpl();
+
+ // nsIRDFDocument interface
+ NS_IMETHOD CreateChildren(nsIRDFNode* resource, nsISupportsArray* children);
+
+protected:
+ nsresult NewChild(nsIRDFNode* resource,
+ nsIRDFContent*& result,
+ PRBool childrenMustBeGenerated);
+
+ nsresult CreateChild(nsIRDFNode* property,
+ nsIRDFNode* value,
+ nsIRDFContent*& result);
+};
+
+////////////////////////////////////////////////////////////////////////
+
+RDFHTMLDocumentImpl::RDFHTMLDocumentImpl(void)
+{
+}
+
+RDFHTMLDocumentImpl::~RDFHTMLDocumentImpl(void)
+{
+}
+
+NS_IMETHODIMP
+RDFHTMLDocumentImpl::CreateChildren(nsIRDFNode* resource, nsISupportsArray* children)
+{
+ nsresult rv;
+
+ NS_ASSERTION(mDB, "not initialized");
+ if (! mDB)
+ return NS_ERROR_NOT_INITIALIZED;
+
+ nsIRDFResourceManager* mgr;
+ if (NS_FAILED(rv = nsServiceManager::GetService(kRDFResourceManagerCID,
+ kIRDFResourceManagerIID,
+ (nsISupports**) &mgr)))
+ return rv;
+
+ nsIRDFCursor* properties = nsnull;
+ PRBool moreProperties;
+
+#ifdef ONLY_CREATE_RDF_CONTAINERS_AS_CONTENT
+ if (! rdf_IsContainer(mgr, mDB, resource))
+ goto done;
+#endif
+
+ // Create a cursor that'll enumerate all of the outbound arcs
+ if (NS_FAILED(rv = mDB->ArcLabelsOut(resource, properties)))
+ goto done;
+
+ while (NS_SUCCEEDED(rv = properties->HasMoreElements(moreProperties)) && moreProperties) {
+ nsIRDFNode* property = nsnull;
+ PRBool tv;
+
+ if (NS_FAILED(rv = properties->GetNext(property, tv /* ignored */)))
+ break;
+
+ nsAutoString uri;
+ if (NS_FAILED(rv = property->GetStringValue(uri))) {
+ NS_RELEASE(property);
+ break;
+ }
+
+#ifdef ONLY_CREATE_RDF_CONTAINERS_AS_CONTENT
+ if (! rdf_IsOrdinalProperty(uri)) {
+ NS_RELEASE(property);
+ continue;
+ }
+#endif
+
+ // Create a second cursor that'll enumerate all of the values
+ // for all of the arcs.
+ nsIRDFCursor* values;
+ if (NS_FAILED(rv = mDB->GetTargets(resource, property, PR_TRUE, values))) {
+ NS_RELEASE(property);
+ break;
+ }
+
+ PRBool moreValues;
+ while (NS_SUCCEEDED(rv = values->HasMoreElements(moreValues)) && moreValues) {
+ nsIRDFNode* value = nsnull;
+ if (NS_FAILED(rv = values->GetNext(value, tv /* ignored */)))
+ break;
+
+ // XXX At this point, we need to decide exactly what kind
+ // of kid to create in the content model. For example, for
+ // leaf nodes, we probably want to create some kind of
+ // text element.
+ nsIRDFContent* child;
+ if (NS_FAILED(rv = CreateChild(property, value, child))) {
+ NS_RELEASE(value);
+ break;
+ }
+
+ // And finally, add the child into the content model
+ children->AppendElement(child);
+
+ NS_RELEASE(child);
+ NS_RELEASE(value);
+ }
+
+ NS_RELEASE(values);
+ NS_RELEASE(property);
+
+ if (NS_FAILED(rv))
+ break;
+ }
+
+done:
+ NS_IF_RELEASE(properties);
+ nsServiceManager::ReleaseService(kRDFResourceManagerCID, mgr);
+
+ return rv;
+}
+
+
+
+nsresult
+RDFHTMLDocumentImpl::NewChild(nsIRDFNode* resource,
+ nsIRDFContent*& result,
+ PRBool childrenMustBeGenerated)
+{
+ nsresult rv;
+
+ nsIRDFContent* child;
+ if (NS_FAILED(rv = NS_NewRDFElement(&child)))
+ return rv;
+
+ if (NS_FAILED(rv = child->Init(this, resource, childrenMustBeGenerated))) {
+ NS_RELEASE(child);
+ return rv;
+ }
+
+ result = child;
+ return NS_OK;
+}
+
+
+nsresult
+RDFHTMLDocumentImpl::CreateChild(nsIRDFNode* property,
+ nsIRDFNode* value,
+ nsIRDFContent*& result)
+{
+ nsresult rv;
+ nsIRDFContent* child = nsnull;
+ nsIRDFContent* grandchild = nsnull;
+ nsIContent* grandchild2 = nsnull;
+ nsITextContent* text = nsnull;
+ nsIDocument* doc = nsnull;
+ nsAutoString v;
+
+ // Construct a new child node. We will explicitly be generating
+ // all of this node's kids, so set the
+ // "children-must-be-generated" flag to false.
+ if (NS_FAILED(rv = NewChild(property, child, PR_FALSE)))
+ goto error;
+
+ // If this is NOT a resource, then construct a grandchild which is
+ // just a vanilla text node.
+ if (! rdf_IsResource(value)) {
+ if (NS_FAILED(rv = value->GetStringValue(v)))
+ goto error;
+
+ if (NS_FAILED(rv = nsRepository::CreateInstance(kTextNodeCID,
+ nsnull,
+ kIContentIID,
+ (void**) &grandchild2)))
+ goto error;
+
+ if (NS_FAILED(rv = QueryInterface(kIDocumentIID, (void**) &doc)))
+ goto error;
+
+ if (NS_FAILED(rv = grandchild2->SetDocument(doc, PR_FALSE)))
+ goto error;
+
+ NS_RELEASE(doc);
+
+ if (NS_FAILED(rv = grandchild2->QueryInterface(kITextContentIID, (void**) &text)))
+ goto error;
+
+ if (NS_FAILED(rv = text->SetText(v.GetUnicode(), v.Length(), PR_FALSE)))
+ goto error;
+
+ NS_RELEASE(text);
+
+ // hook it up to the child
+ if (NS_FAILED(rv = grandchild2->SetParent(child)))
+ goto error;
+
+ if (NS_FAILED(rv = child->AppendChildTo(NS_STATIC_CAST(nsIContent*, grandchild2), PR_TRUE)))
+ goto error;
+ }
+
+ // Construct a grandchild which is another RDF resource node. This
+ // node *will* need to recursively generate its children on
+ // demand, so set the children-must-be-generated flag to true.
+ if (NS_FAILED(rv = NewChild(value, grandchild, PR_TRUE)))
+ goto error;
+
+ if (NS_FAILED(rv = child->AppendChildTo(NS_STATIC_CAST(nsIContent*, grandchild), PR_TRUE)))
+ goto error;
+
+ // whew!
+ result = child;
+ return NS_OK;
+
+error:
+ NS_IF_RELEASE(text);
+ NS_IF_RELEASE(doc);
+ NS_IF_RELEASE(grandchild);
+ NS_IF_RELEASE(child);
+ return rv;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+
+nsresult NS_NewRDFHTMLDocument(nsIRDFDocument** result)
+{
+ nsIRDFDocument* doc = new RDFHTMLDocumentImpl();
+ if (! doc)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ NS_ADDREF(doc);
+ *result = doc;
+ return NS_OK;
+}
diff --git a/rdf/src/nsRDFTreeDocument.cpp b/rdf/src/nsRDFTreeDocument.cpp
new file mode 100644
index 000000000000..6ec0d6ff8f16
--- /dev/null
+++ b/rdf/src/nsRDFTreeDocument.cpp
@@ -0,0 +1,41 @@
+/* -*- 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.
+ */
+
+#include "nsIRDFContent.h"
+#include "nsIRDFCursor.h"
+#include "nsIRDFDataBase.h"
+#include "nsIRDFNode.h"
+#include "nsIRDFResourceManager.h"
+#include "nsIServiceManager.h"
+#include "nsISupportsArray.h"
+#include "nsLayoutCID.h"
+#include "nsRDFCID.h"
+#include "nsRDFDocument.h"
+#include "rdfutil.h"
+
+// XXX just a stub for now.
+
+nsresult NS_NewRDFTreeDocument(nsIRDFDocument** result)
+{
+ *result = nsnull;
+ return NS_NOINTERFACE;
+}
+
+
+
diff --git a/rdf/src/rdfutil.cpp b/rdf/src/rdfutil.cpp
new file mode 100644
index 000000000000..c087fbc58469
--- /dev/null
+++ b/rdf/src/rdfutil.cpp
@@ -0,0 +1,123 @@
+/* -*- 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.
+ */
+
+#include "nsIRDFDataBase.h"
+#include "nsIRDFNode.h"
+#include "nsIRDFResourceManager.h"
+#include "nsString.h"
+#include "rdfutil.h"
+
+////////////////////////////////////////////////////////////////////////
+// RDF core vocabulary
+
+#include "rdf.h"
+#define RDF_NAMESPACE_URI "http://www.w3.org/TR/WD-rdf-syntax#"
+static const char kRDFNameSpaceURI[] = RDF_NAMESPACE_URI;
+DEFINE_RDF_VOCAB(RDF_NAMESPACE_URI, RDF, Alt);
+DEFINE_RDF_VOCAB(RDF_NAMESPACE_URI, RDF, Bag);
+DEFINE_RDF_VOCAB(RDF_NAMESPACE_URI, RDF, Description);
+DEFINE_RDF_VOCAB(RDF_NAMESPACE_URI, RDF, ID);
+DEFINE_RDF_VOCAB(RDF_NAMESPACE_URI, RDF, RDF);
+DEFINE_RDF_VOCAB(RDF_NAMESPACE_URI, RDF, Seq);
+DEFINE_RDF_VOCAB(RDF_NAMESPACE_URI, RDF, about);
+DEFINE_RDF_VOCAB(RDF_NAMESPACE_URI, RDF, aboutEach);
+DEFINE_RDF_VOCAB(RDF_NAMESPACE_URI, RDF, bagID);
+DEFINE_RDF_VOCAB(RDF_NAMESPACE_URI, RDF, instanceOf);
+DEFINE_RDF_VOCAB(RDF_NAMESPACE_URI, RDF, li);
+DEFINE_RDF_VOCAB(RDF_NAMESPACE_URI, RDF, resource);
+
+////////////////////////////////////////////////////////////////////////
+
+PRBool
+rdf_IsOrdinalProperty(const nsString& uri)
+{
+ if (uri.Find(kRDFNameSpaceURI) != 0)
+ return PR_FALSE;
+
+ nsAutoString tag(uri);
+ tag.Cut(0, sizeof(kRDFNameSpaceURI) - 1);
+
+ if (tag[0] != '_')
+ return PR_FALSE;
+
+ for (PRInt32 i = tag.Length() - 1; i >= 1; --i) {
+ if (tag[i] < '0' || tag[i] > '9')
+ return PR_FALSE;
+ }
+
+ return PR_TRUE;
+}
+
+
+PRBool
+rdf_IsContainer(nsIRDFResourceManager* mgr,
+ nsIRDFDataBase* db,
+ nsIRDFNode* resource)
+{
+ PRBool result = PR_FALSE;
+
+ nsIRDFNode* RDF_instanceOf = nsnull;
+ nsIRDFNode* RDF_Bag = nsnull;
+
+ nsresult rv;
+ if (NS_FAILED(rv = mgr->GetNode(kURIRDF_instanceOf, RDF_instanceOf)))
+ goto done;
+
+ if (NS_FAILED(rv = mgr->GetNode(kURIRDF_Bag, RDF_Bag)))
+ goto done;
+
+ rv = db->HasAssertion(resource, RDF_instanceOf, RDF_Bag, PR_TRUE, result);
+
+done:
+ NS_IF_RELEASE(RDF_Bag);
+ NS_IF_RELEASE(RDF_instanceOf);
+ return result;
+}
+
+
+// A complete hack that looks at the string value of a node and
+// guesses if it's a resource
+PRBool
+rdf_IsResource(nsIRDFNode* node)
+{
+ nsresult rv;
+ nsAutoString v;
+
+ if (NS_FAILED(rv = node->GetStringValue(v)))
+ return PR_FALSE;
+
+ PRInt32 index;
+
+ // A URI needs a colon.
+ index = v.Find(':');
+ if (index < 0)
+ return PR_FALSE;
+
+ // Assume some sane maximum for protocol specs
+#define MAX_PROTOCOL_SPEC 10
+ if (index > MAX_PROTOCOL_SPEC)
+ return PR_FALSE;
+
+ // It can't have spaces or newlines or tabs
+ if (v.Find(' ') > 0 || v.Find('\n') > 0 || v.Find('\t') > 0)
+ return PR_FALSE;
+
+ return PR_TRUE;
+}
+
diff --git a/rdf/src/rdfutil.h b/rdf/src/rdfutil.h
new file mode 100644
index 000000000000..208bf43fd98d
--- /dev/null
+++ b/rdf/src/rdfutil.h
@@ -0,0 +1,55 @@
+/* -*- 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.
+ */
+
+#ifndef rdfutil_h__
+#define rdfutil_h__
+
+#include "prtypes.h"
+
+class nsIRDFDataBase;
+class nsIRDFNode;
+class nsIRDFResourceManager;
+class nsString;
+
+/**
+ * Returns PR_TRUE if the URI is an RDF ordinal property; e.g., rdf:_1,
+ * rdf:_2, etc.
+ */
+PRBool
+rdf_IsOrdinalProperty(const nsString& uri);
+
+
+/**
+ * Returns PR_TRUE if the resource is a container resource; e.g., an
+ * rdf:Bag.
+ */
+PRBool
+rdf_IsContainer(nsIRDFResourceManager* mgr,
+ nsIRDFDataBase* db,
+ nsIRDFNode* resource);
+
+/**
+ * Tries to guess whether the specified node is a resource or a literal.
+ */
+PRBool
+rdf_IsResource(nsIRDFNode* node);
+
+#endif // rdfutil_h__
+
+