From 99a354e2b83d42476933c18d4f62f190fdb9d7e1 Mon Sep 17 00:00:00 2001 From: "waterson%netscape.com" Date: Fri, 4 Dec 1998 10:00:13 +0000 Subject: [PATCH] Initial revision. --- rdf/src/nsRDFHTMLDocument.cpp | 284 ++++++++++++++++++++++++++++++++++ rdf/src/nsRDFTreeDocument.cpp | 41 +++++ rdf/src/rdfutil.cpp | 123 +++++++++++++++ rdf/src/rdfutil.h | 55 +++++++ 4 files changed, 503 insertions(+) create mode 100644 rdf/src/nsRDFHTMLDocument.cpp create mode 100644 rdf/src/nsRDFTreeDocument.cpp create mode 100644 rdf/src/rdfutil.cpp create mode 100644 rdf/src/rdfutil.h 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__ + +