зеркало из https://github.com/mozilla/pjs.git
Implemented RDF container support and improved support for 'anonymous' resources for output of RDF/XML. Cleaned up common RDF vocabularies, placing #defines into rdf.h.
This commit is contained in:
Родитель
3f64184685
Коммит
d1f68358c9
|
@ -75,6 +75,10 @@ public:
|
|||
* Determine if two resources are identical.
|
||||
*/
|
||||
NS_IMETHOD EqualsResource(const nsIRDFResource* resource, PRBool* result) const = 0;
|
||||
|
||||
/**
|
||||
* Determine if two resources are identical.
|
||||
*/
|
||||
NS_IMETHOD EqualsString(const char* uri, PRBool* result) const = 0;
|
||||
};
|
||||
|
||||
|
|
|
@ -47,6 +47,13 @@
|
|||
static const char* kURI##prefix##_##name = ##namespace #name ;\
|
||||
static const char* kTag##prefix##_##name = kURI##prefix##_##name## + sizeof(##namespace) - 1
|
||||
|
||||
/**
|
||||
* Core RDF vocabularies that we use to infer semantic actions
|
||||
*/
|
||||
#define RDF_NAMESPACE_URI "http://www.w3.org/TR/WD-rdf-syntax#"
|
||||
#define WEB_NAMESPACE_URI "http://home.netscape.com/WEB-rdf#"
|
||||
#define NC_NAMESPACE_URI "http://home.netscape.com/NC-rdf#"
|
||||
|
||||
|
||||
/**
|
||||
* @name Standard RDF error codes
|
||||
|
|
|
@ -63,7 +63,6 @@ static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
|
|||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#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, nextVal); // ad hoc way to make containers fast
|
||||
|
||||
|
|
|
@ -42,8 +42,6 @@
|
|||
does namespaces: should we storing tag/namespace pairs instead of
|
||||
the entire URI in the elements?
|
||||
|
||||
3) Write a test harness.
|
||||
|
||||
*/
|
||||
|
||||
#include "nsIContentSink.h"
|
||||
|
@ -71,7 +69,6 @@ static const char kNameSpaceDef[] = "xmlns";
|
|||
// RDF core vocabulary
|
||||
|
||||
#include "rdf.h"
|
||||
#define RDF_NAMESPACE_URI "http://www.w3.org/TR/WD-rdf-syntax#"
|
||||
DEFINE_RDF_VOCAB(RDF_NAMESPACE_URI, RDF, Alt);
|
||||
DEFINE_RDF_VOCAB(RDF_NAMESPACE_URI, RDF, Bag);
|
||||
DEFINE_RDF_VOCAB(RDF_NAMESPACE_URI, RDF, Description);
|
||||
|
@ -121,7 +118,7 @@ rdf_EntityToUnicode(const char* buf)
|
|||
(buf[2] == 'p' || buf[2] == 'P'))
|
||||
return PRUnichar('&');
|
||||
|
||||
PR_ASSERT(0); // XXX this is a named entity that I can't handle...
|
||||
NS_NOTYETIMPLEMENTED("this is a named entity that I can't handle...");
|
||||
return PRUnichar('?');
|
||||
}
|
||||
|
||||
|
@ -245,6 +242,7 @@ rdf_StripAndConvert(nsString& aResult)
|
|||
else if (e == '{') {
|
||||
// Convert a script entity
|
||||
// XXX write me!
|
||||
NS_NOTYETIMPLEMENTED("convert a script entity");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -307,13 +305,6 @@ rdf_FullyQualifyURI(const nsIURL* base, nsString& spec)
|
|||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class nsIURL;
|
||||
class nsVoidArray;
|
||||
class nsIRDFResource;
|
||||
class nsIRDFDataSource;
|
||||
class nsIRDFService;
|
||||
class nsINameSpaceManager;
|
||||
|
||||
typedef enum {
|
||||
eRDFContentSinkState_InProlog,
|
||||
eRDFContentSinkState_InDocumentElement,
|
||||
|
@ -386,8 +377,8 @@ protected:
|
|||
nsString& rProperty);
|
||||
|
||||
// RDF-specific parsing
|
||||
nsresult GetIdAboutAttribute(const nsIParserNode& aNode, nsString& rResource);
|
||||
nsresult GetResourceAttribute(const nsIParserNode& aNode, nsString& rResource);
|
||||
nsresult GetIdAboutAttribute(const nsIParserNode& aNode, nsIRDFResource** aResource);
|
||||
nsresult GetResourceAttribute(const nsIParserNode& aNode, nsIRDFResource** aResource);
|
||||
nsresult AddProperties(const nsIParserNode& aNode, nsIRDFResource* aSubject);
|
||||
|
||||
virtual nsresult OpenRDF(const nsIParserNode& aNode);
|
||||
|
@ -931,8 +922,8 @@ RDFContentSinkImpl::FlushText(PRBool aCreateTextNode, PRBool* aDidFlush)
|
|||
|
||||
void
|
||||
RDFContentSinkImpl::SplitQualifiedName(const nsString& aQualifiedName,
|
||||
PRInt32& rNameSpaceID,
|
||||
nsString& rProperty)
|
||||
PRInt32& rNameSpaceID,
|
||||
nsString& rProperty)
|
||||
{
|
||||
rProperty = aQualifiedName;
|
||||
nsIAtom* prefix = CutNameSpacePrefix(rProperty);
|
||||
|
@ -943,13 +934,14 @@ RDFContentSinkImpl::SplitQualifiedName(const nsString& aQualifiedName,
|
|||
|
||||
nsresult
|
||||
RDFContentSinkImpl::GetIdAboutAttribute(const nsIParserNode& aNode,
|
||||
nsString& rResource)
|
||||
nsIRDFResource** aResource)
|
||||
{
|
||||
// This corresponds to the dirty work of production [6.5]
|
||||
nsAutoString k;
|
||||
nsAutoString attr;
|
||||
PRInt32 nameSpaceID;
|
||||
PRInt32 ac = aNode.GetAttributeCount();
|
||||
nsresult rv;
|
||||
|
||||
for (PRInt32 i = 0; i < ac; i++) {
|
||||
// Get upper-cased key
|
||||
|
@ -963,44 +955,47 @@ RDFContentSinkImpl::GetIdAboutAttribute(const nsIParserNode& aNode,
|
|||
// first thing that was specified and ignore the other.
|
||||
|
||||
if (attr.Equals(kTagRDF_about)) {
|
||||
rResource = aNode.GetValueAt(i);
|
||||
rdf_StripAndConvert(rResource);
|
||||
nsAutoString uri = aNode.GetValueAt(i);
|
||||
rdf_StripAndConvert(uri);
|
||||
|
||||
return NS_OK;
|
||||
return mRDFService->GetUnicodeResource(uri, aResource);
|
||||
}
|
||||
|
||||
if (attr.Equals(kTagRDF_ID)) {
|
||||
PRUnichar* str;
|
||||
mDocumentURL->ToString(&str);
|
||||
rResource = str;
|
||||
delete str;
|
||||
const char* docURI;
|
||||
mDocumentURL->GetSpec(&docURI);
|
||||
|
||||
if (NS_FAILED(rv = mRDFService->GetResource(docURI, aResource)))
|
||||
return rv;
|
||||
|
||||
nsAutoString uri(docURI);
|
||||
nsAutoString tag = aNode.GetValueAt(i);
|
||||
rdf_StripAndConvert(tag);
|
||||
|
||||
if (rResource.Last() != '#' && tag.First() != '#')
|
||||
rResource.Append('#');
|
||||
if (uri.Last() != '#' && tag.First() != '#')
|
||||
uri.Append('#');
|
||||
|
||||
rResource.Append(tag);
|
||||
return NS_OK;
|
||||
uri.Append(tag);
|
||||
|
||||
return mRDFService->GetUnicodeResource(uri, aResource);
|
||||
}
|
||||
|
||||
// XXX we don't deal with aboutEach...
|
||||
if (attr.Equals(kTagRDF_aboutEach)) {
|
||||
// XXX we don't deal with aboutEach...
|
||||
NS_NOTYETIMPLEMENTED("RDF:aboutEach is not understood at this time");
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, we couldn't find anything, so just gensym one...
|
||||
PRUnichar* str;
|
||||
mDocumentURL->ToString(&str);
|
||||
rResource = str;
|
||||
delete str;
|
||||
rResource.Append("#anonymous$");
|
||||
rResource.Append(mGenSym++, 10);
|
||||
return NS_OK;
|
||||
const char* url;
|
||||
mDocumentURL->GetSpec(&url);
|
||||
return rdf_CreateAnonymousResource(url, aResource);
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
RDFContentSinkImpl::GetResourceAttribute(const nsIParserNode& aNode,
|
||||
nsString& rResource)
|
||||
nsIRDFResource** aResource)
|
||||
{
|
||||
nsAutoString k;
|
||||
nsAutoString attr;
|
||||
|
@ -1019,15 +1014,15 @@ RDFContentSinkImpl::GetResourceAttribute(const nsIParserNode& aNode,
|
|||
// first thing that was specified and ignore the other.
|
||||
|
||||
if (attr.Equals(kTagRDF_resource)) {
|
||||
rResource = aNode.GetValueAt(i);
|
||||
rdf_StripAndConvert(rResource);
|
||||
nsAutoString uri = aNode.GetValueAt(i);
|
||||
rdf_StripAndConvert(uri);
|
||||
|
||||
// XXX Take the URI and make it fully qualified by
|
||||
// sticking it into the document's URL. This may not be
|
||||
// appropriate...
|
||||
rdf_FullyQualifyURI(mDocumentURL, rResource);
|
||||
rdf_FullyQualifyURI(mDocumentURL, uri);
|
||||
|
||||
return NS_OK;
|
||||
return mRDFService->GetUnicodeResource(uri, aResource);
|
||||
}
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
|
@ -1035,7 +1030,7 @@ RDFContentSinkImpl::GetResourceAttribute(const nsIParserNode& aNode,
|
|||
|
||||
nsresult
|
||||
RDFContentSinkImpl::AddProperties(const nsIParserNode& aNode,
|
||||
nsIRDFResource* aSubject)
|
||||
nsIRDFResource* aSubject)
|
||||
{
|
||||
// Add tag attributes to the content attributes
|
||||
nsAutoString k, v;
|
||||
|
@ -1113,12 +1108,8 @@ RDFContentSinkImpl::OpenObject(const nsIParserNode& aNode)
|
|||
|
||||
// Figure out the URI of this object, and create an RDF node for it.
|
||||
nsresult rv;
|
||||
nsAutoString uri;
|
||||
if (NS_FAILED(rv = GetIdAboutAttribute(aNode, uri)))
|
||||
return rv;
|
||||
|
||||
nsIRDFResource* rdfResource;
|
||||
if (NS_FAILED(rv = mRDFService->GetUnicodeResource(uri, &rdfResource)))
|
||||
if (NS_FAILED(rv = GetIdAboutAttribute(aNode, &rdfResource)))
|
||||
return rv;
|
||||
|
||||
// If we're in a member or property element, then this is the cue
|
||||
|
@ -1223,29 +1214,27 @@ RDFContentSinkImpl::OpenProperty(const nsIParserNode& aNode)
|
|||
if (NS_FAILED(rv = mRDFService->GetUnicodeResource(ns, &rdfProperty)))
|
||||
return rv;
|
||||
|
||||
nsAutoString resourceURI;
|
||||
if (NS_SUCCEEDED(GetResourceAttribute(aNode, resourceURI))) {
|
||||
nsIRDFResource* rdfResource;
|
||||
if (NS_SUCCEEDED(GetResourceAttribute(aNode, &rdfResource))) {
|
||||
// They specified an inline resource for the value of this
|
||||
// property. Create an RDF resource for the inline resource
|
||||
// URI, add the properties to it, and attach the inline
|
||||
// resource to its parent.
|
||||
nsIRDFResource* rdfResource;
|
||||
if (NS_SUCCEEDED(rv = mRDFService->GetUnicodeResource(resourceURI, &rdfResource))) {
|
||||
if (NS_SUCCEEDED(rv = AddProperties(aNode, rdfResource))) {
|
||||
rv = rdf_Assert(mDataSource,
|
||||
GetContextElement(0),
|
||||
rdfProperty,
|
||||
rdfResource);
|
||||
}
|
||||
if (NS_SUCCEEDED(rv = AddProperties(aNode, rdfResource))) {
|
||||
rv = rdf_Assert(mDataSource,
|
||||
GetContextElement(0),
|
||||
rdfProperty,
|
||||
rdfResource);
|
||||
}
|
||||
|
||||
// XXX ignore any failure from above...
|
||||
PR_ASSERT(rv == NS_OK);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "problem adding properties");
|
||||
|
||||
// XXX Technically, we should _not_ fall through here and push
|
||||
// the element onto the stack: this is supposed to be a closed
|
||||
// node. But right now I'm lazy and the code will just Do The
|
||||
// Right Thing so long as the RDF is well-formed.
|
||||
NS_RELEASE(rdfResource);
|
||||
}
|
||||
|
||||
// Push the element onto the context stack and change state.
|
||||
|
@ -1280,20 +1269,17 @@ RDFContentSinkImpl::OpenMember(const nsIParserNode& aNode)
|
|||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsresult rv;
|
||||
nsAutoString resourceURI;
|
||||
if (NS_SUCCEEDED(rv = GetResourceAttribute(aNode, resourceURI))) {
|
||||
nsIRDFResource* resource;
|
||||
if (NS_SUCCEEDED(rv = GetResourceAttribute(aNode, &resource))) {
|
||||
// Okay, this node has an RDF:resource="..." attribute. That
|
||||
// means that it's a "referenced item," as covered in [6.29].
|
||||
|
||||
nsIRDFResource* resource;
|
||||
if (NS_SUCCEEDED(rv = mRDFService->GetUnicodeResource(resourceURI, &resource))) {
|
||||
rv = rdf_ContainerAddElement(mDataSource, container, resource);
|
||||
}
|
||||
rv = rdf_ContainerAddElement(mDataSource, container, resource);
|
||||
|
||||
// XXX Technically, we should _not_ fall through here and push
|
||||
// the element onto the stack: this is supposed to be a closed
|
||||
// node. But right now I'm lazy and the code will just Do The
|
||||
// Right Thing so long as the RDF is well-formed.
|
||||
NS_RELEASE(resource);
|
||||
}
|
||||
|
||||
// Change state. Pushing a null context element is a bit weird,
|
||||
|
|
|
@ -31,10 +31,7 @@
|
|||
open an arbitrary nsIOutputStream on *any* URL, and Netlib could
|
||||
just do the magic.
|
||||
|
||||
2) This does not currently output RDF container constructs
|
||||
properly. To do this, we just need to implement SerializeContainer().
|
||||
|
||||
3) Implement a more terse output for "typed" nodes; that is, instead
|
||||
2) Implement a more terse output for "typed" nodes; that is, instead
|
||||
of "RDF:Description RDF:type='ns:foo'", just output "ns:foo".
|
||||
|
||||
*/
|
||||
|
@ -88,6 +85,13 @@ static NS_DEFINE_CID(kRDFContentSinkCID, NS_RDFCONTENTSINK_CID);
|
|||
static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
|
||||
static NS_DEFINE_CID(kWellFormedDTDCID, NS_WELLFORMEDDTD_CID);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Vocabulary stuff
|
||||
#include "rdf.h"
|
||||
DEFINE_RDF_VOCAB(RDF_NAMESPACE_URI, RDF, instanceOf);
|
||||
DEFINE_RDF_VOCAB(RDF_NAMESPACE_URI, RDF, nextVal);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// FileOutputStreamImpl
|
||||
|
||||
|
@ -414,7 +418,11 @@ RDFXMLDataSourceImpl::RDFXMLDataSourceImpl(void)
|
|||
// Initialize the name space stuff to know about any "standard"
|
||||
// namespaces that we want to look the same in all the RDF/XML we
|
||||
// generate.
|
||||
AddNameSpace(NS_NewAtom("RDF"), "http://www.w3.org/TR/WD-rdf-syntax#");
|
||||
//
|
||||
// XXX this is a bit of a hack, because technically, the document
|
||||
// should've defined the RDF namespace to be _something_, and we
|
||||
// should just look at _that_ and use it. Oh well.
|
||||
AddNameSpace(NS_NewAtom("RDF"), RDF_NAMESPACE_URI);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1058,8 +1066,6 @@ RDFXMLDataSourceImpl::SerializeAssertion(nsIOutputStream* aStream,
|
|||
rdf_BlockingWrite(aStream, "\"", 1);
|
||||
}
|
||||
|
||||
rdf_BlockingWrite(aStream, ">", 1);
|
||||
|
||||
nsIRDFResource* resource;
|
||||
nsIRDFLiteral* literal;
|
||||
|
||||
|
@ -1070,7 +1076,14 @@ RDFXMLDataSourceImpl::SerializeAssertion(nsIOutputStream* aStream,
|
|||
nsAutoString escaped(uri);
|
||||
rdf_EscapeAmpersands(escaped);
|
||||
|
||||
const char* docURI;
|
||||
mInner->GetURI(&docURI);
|
||||
rdf_PossiblyMakeRelative(docURI, escaped);
|
||||
|
||||
rdf_BlockingWrite(aStream, " RDF:resource=\"");
|
||||
rdf_BlockingWrite(aStream, escaped);
|
||||
rdf_BlockingWrite(aStream, "\"/>\n", 4);
|
||||
|
||||
NS_RELEASE(resource);
|
||||
}
|
||||
else if (NS_SUCCEEDED(aValue->QueryInterface(kIRDFLiteralIID, (void**) &literal))) {
|
||||
|
@ -1081,7 +1094,11 @@ RDFXMLDataSourceImpl::SerializeAssertion(nsIOutputStream* aStream,
|
|||
rdf_EscapeAmpersands(s); // do these first!
|
||||
rdf_EscapeAngleBrackets(s);
|
||||
|
||||
rdf_BlockingWrite(aStream, ">", 1);
|
||||
rdf_BlockingWrite(aStream, s);
|
||||
rdf_BlockingWrite(aStream, "</", 2);
|
||||
rdf_BlockingWrite(aStream, tag);
|
||||
rdf_BlockingWrite(aStream, ">\n", 2);
|
||||
|
||||
NS_RELEASE(literal);
|
||||
}
|
||||
|
@ -1090,10 +1107,6 @@ RDFXMLDataSourceImpl::SerializeAssertion(nsIOutputStream* aStream,
|
|||
NS_ASSERTION(PR_FALSE, "huh?");
|
||||
}
|
||||
|
||||
rdf_BlockingWrite(aStream, "</", 2);
|
||||
rdf_BlockingWrite(aStream, tag);
|
||||
rdf_BlockingWrite(aStream, ">\n", 2);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1222,7 +1235,7 @@ RDFXMLDataSourceImpl::SerializeMember(nsIOutputStream* aStream,
|
|||
if (NS_SUCCEEDED(rv = literal->GetValue(&value))) {
|
||||
rdf_BlockingWrite(aStream, " <RDF:li>");
|
||||
rdf_BlockingWrite(aStream, value);
|
||||
rdf_BlockingWrite(aStream, " </RDF:li>\n");
|
||||
rdf_BlockingWrite(aStream, "</RDF:li>\n");
|
||||
}
|
||||
NS_RELEASE(literal);
|
||||
}
|
||||
|
@ -1247,24 +1260,57 @@ nsresult
|
|||
RDFXMLDataSourceImpl::SerializeContainer(nsIOutputStream* aStream,
|
||||
nsIRDFResource* aContainer)
|
||||
{
|
||||
static const char kRDFOpenSeq[] = " <RDF:Seq RDF:ID=\"";
|
||||
static const char kRDFOpenBag[] = " <RDF:Bag RDF:ID=\"";
|
||||
static const char kRDFOpenAlt[] = " <RDF:Alt RDF:ID=\"";
|
||||
|
||||
static const char kRDFCloseSeq[] = " </RDF:Seq>\n";
|
||||
static const char kRDFCloseBag[] = " </RDF:Bag>\n";
|
||||
static const char kRDFCloseAlt[] = " </RDF:Alt>\n";
|
||||
static const char kRDFBag[] = "RDF:Bag";
|
||||
static const char kRDFSeq[] = "RDF:Seq";
|
||||
static const char kRDFAlt[] = "RDF:Alt";
|
||||
|
||||
nsresult rv;
|
||||
const char* tag;
|
||||
|
||||
// XXX decide if it's a sequence, bag, or alternation. Print
|
||||
// the appropriate tag-open sequence HERE.
|
||||
// Decide if it's a sequence, bag, or alternation, and print the
|
||||
// appropriate tag-open sequence
|
||||
|
||||
if (rdf_IsBag(mInner, aContainer)) {
|
||||
tag = kRDFBag;
|
||||
}
|
||||
else if (rdf_IsSeq(mInner, aContainer)) {
|
||||
tag = kRDFSeq;
|
||||
}
|
||||
else if (rdf_IsAlt(mInner, aContainer)) {
|
||||
tag = kRDFAlt;
|
||||
}
|
||||
else {
|
||||
NS_ASSERTION(PR_FALSE, "huh? this is _not_ a container.");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
rdf_BlockingWrite(aStream, " <", 3);
|
||||
rdf_BlockingWrite(aStream, tag);
|
||||
|
||||
|
||||
// Unfortunately, we always need to print out the identity of the
|
||||
// resource, even if was constructed "anonymously". We need to do
|
||||
// this because we never really know who else might be referring
|
||||
// to it...
|
||||
|
||||
const char* docURI;
|
||||
mInner->GetURI(&docURI);
|
||||
|
||||
const char* s;
|
||||
if (NS_SUCCEEDED(aContainer->GetValue(&s))) {
|
||||
nsAutoString uri(s);
|
||||
rdf_PossiblyMakeRelative(docURI, uri);
|
||||
rdf_BlockingWrite(aStream, " RDF:ID=\"", 9);
|
||||
rdf_BlockingWrite(aStream, uri);
|
||||
rdf_BlockingWrite(aStream, "\"", 1);
|
||||
}
|
||||
|
||||
rdf_BlockingWrite(aStream, ">\n", 2);
|
||||
|
||||
// XXX decide if it's an anonymous bag, or a named one. If it's
|
||||
// named, then print out its identity HERE.
|
||||
|
||||
// We iterate through all of the arcs, in case someone has applied
|
||||
// properties to the bag itself.
|
||||
|
||||
nsIRDFArcsOutCursor* arcs;
|
||||
if (NS_FAILED(rv = mInner->ArcLabelsOut(aContainer, &arcs)))
|
||||
return rv;
|
||||
|
@ -1281,9 +1327,26 @@ static const char kRDFCloseAlt[] = " </RDF:Alt>\n";
|
|||
rv = SerializeMember(aStream, aContainer, property);
|
||||
}
|
||||
else {
|
||||
rv = SerializeProperty(aStream, aContainer, property);
|
||||
}
|
||||
do {
|
||||
PRBool eq;
|
||||
|
||||
// don't serialize RDF:instanceOf -- it's implicit in the tag
|
||||
if (NS_FAILED(rv = property->EqualsString(kURIRDF_instanceOf, &eq)))
|
||||
break;
|
||||
|
||||
if (eq)
|
||||
break;
|
||||
|
||||
// don't serialize RDF:nextVal -- it's internal state
|
||||
if (NS_FAILED(rv = property->EqualsString(kURIRDF_nextVal, &eq)))
|
||||
break;
|
||||
|
||||
if (eq)
|
||||
break;
|
||||
|
||||
rv = SerializeProperty(aStream, aContainer, property);
|
||||
} while (0);
|
||||
}
|
||||
|
||||
NS_RELEASE(property);
|
||||
if (NS_FAILED(rv))
|
||||
|
@ -1294,6 +1357,13 @@ static const char kRDFCloseAlt[] = " </RDF:Alt>\n";
|
|||
rv = NS_OK;
|
||||
|
||||
NS_RELEASE(arcs);
|
||||
|
||||
|
||||
// close the container tag
|
||||
rdf_BlockingWrite(aStream, " </", 4);
|
||||
rdf_BlockingWrite(aStream, tag);
|
||||
rdf_BlockingWrite(aStream, ">\n", 2);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,13 +32,13 @@
|
|||
#include "nsIServiceManager.h"
|
||||
#include "nsRDFCID.h"
|
||||
#include "nsString.h"
|
||||
#include "plstr.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);
|
||||
|
@ -65,17 +65,56 @@ static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
|
|||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// XXX This'll permanently leak
|
||||
static nsIRDFService* gRDFService = nsnull;
|
||||
|
||||
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;
|
||||
|
||||
static nsresult
|
||||
rdf_EnsureRDFService(void)
|
||||
{
|
||||
if (gRDFService)
|
||||
return NS_OK;
|
||||
|
||||
return nsServiceManager::GetService(kRDFServiceCID,
|
||||
kIRDFServiceIID,
|
||||
(nsISupports**) &gRDFService);
|
||||
nsresult rv;
|
||||
|
||||
if (NS_FAILED(rv = nsServiceManager::GetService(kRDFServiceCID,
|
||||
kIRDFServiceIID,
|
||||
(nsISupports**) &gRDFService)))
|
||||
goto done;
|
||||
|
||||
if (NS_FAILED(rv = gRDFService->GetResource(kURIRDF_instanceOf, &kRDF_instanceOf)))
|
||||
goto done;
|
||||
|
||||
if (NS_FAILED(rv = gRDFService->GetResource(kURIRDF_Bag, &kRDF_Bag)))
|
||||
goto done;
|
||||
|
||||
if (NS_FAILED(rv = gRDFService->GetResource(kURIRDF_Seq, &kRDF_Seq)))
|
||||
goto done;
|
||||
|
||||
if (NS_FAILED(rv = gRDFService->GetResource(kURIRDF_Alt, &kRDF_Alt)))
|
||||
goto done;
|
||||
|
||||
if (NS_FAILED(rv = gRDFService->GetResource(kURIRDF_nextVal, &kRDF_nextVal)))
|
||||
goto done;
|
||||
|
||||
done:
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_IF_RELEASE(kRDF_nextVal);
|
||||
NS_IF_RELEASE(kRDF_Alt);
|
||||
NS_IF_RELEASE(kRDF_Seq);
|
||||
NS_IF_RELEASE(kRDF_Bag);
|
||||
|
||||
if (gRDFService) {
|
||||
nsServiceManager::ReleaseService(kRDFServiceCID, gRDFService);
|
||||
gRDFService = nsnull;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
@ -107,72 +146,70 @@ rdf_IsOrdinalProperty(const nsIRDFResource* property)
|
|||
}
|
||||
|
||||
|
||||
// XXX This'll permanently leak RDF_Alt, RDF_Seq, RDF_Bag, and
|
||||
// RDF_instanceOf. Since we do it a lot, it seems like it's worth it.
|
||||
|
||||
PRBool
|
||||
rdf_IsContainer(nsIRDFDataSource* ds,
|
||||
nsIRDFResource* resource)
|
||||
{
|
||||
PRBool result = PR_FALSE;
|
||||
if (rdf_IsBag(ds, resource) ||
|
||||
rdf_IsSeq(ds, resource) ||
|
||||
rdf_IsAlt(ds, resource)) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
else {
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static nsIRDFResource* RDF_instanceOf = nsnull;
|
||||
static nsIRDFResource* RDF_Bag = nsnull;
|
||||
static nsIRDFResource* RDF_Seq = nsnull;
|
||||
static nsIRDFResource* RDF_Alt = nsnull;
|
||||
PRBool
|
||||
rdf_IsBag(nsIRDFDataSource* aDataSource,
|
||||
nsIRDFResource* aResource)
|
||||
{
|
||||
PRBool result = PR_FALSE;
|
||||
|
||||
nsresult rv;
|
||||
if (NS_FAILED(rv = rdf_EnsureRDFService()))
|
||||
goto done;
|
||||
|
||||
if (! RDF_instanceOf) {
|
||||
if (NS_FAILED(rv = gRDFService->GetResource(kURIRDF_instanceOf, &RDF_instanceOf)))
|
||||
goto done;
|
||||
}
|
||||
|
||||
// bag?
|
||||
if (! RDF_Bag) {
|
||||
if (NS_FAILED(rv = gRDFService->GetResource(kURIRDF_Bag, &RDF_Bag)))
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv = ds->HasAssertion(resource, RDF_instanceOf, RDF_Bag, PR_TRUE, &result)))
|
||||
goto done;
|
||||
|
||||
if (result)
|
||||
goto done;
|
||||
|
||||
// sequence?
|
||||
if (! RDF_Seq) {
|
||||
if (NS_FAILED(rv = gRDFService->GetResource(kURIRDF_Seq, &RDF_Seq)))
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv = ds->HasAssertion(resource, RDF_instanceOf, RDF_Seq, PR_TRUE, &result)))
|
||||
goto done;
|
||||
|
||||
if (result)
|
||||
goto done;
|
||||
|
||||
// alternation?
|
||||
if (! RDF_Alt) {
|
||||
if (NS_FAILED(rv = gRDFService->GetResource(kURIRDF_Alt, &RDF_Alt)))
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv = ds->HasAssertion(resource, RDF_instanceOf, RDF_Alt, PR_TRUE, &result)))
|
||||
goto done;
|
||||
rv = aDataSource->HasAssertion(aResource, kRDF_instanceOf, kRDF_Bag, PR_TRUE, &result);
|
||||
|
||||
done:
|
||||
// XXX permanent leak
|
||||
//NS_IF_RELEASE(RDF_Alt);
|
||||
//NS_IF_RELEASE(RDF_Seq);
|
||||
//NS_IF_RELEASE(RDF_Bag);
|
||||
//NS_IF_RELEASE(RDF_instanceOf);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
PRBool
|
||||
rdf_IsSeq(nsIRDFDataSource* aDataSource,
|
||||
nsIRDFResource* aResource)
|
||||
{
|
||||
PRBool result = PR_FALSE;
|
||||
|
||||
nsresult rv;
|
||||
if (NS_FAILED(rv = rdf_EnsureRDFService()))
|
||||
goto done;
|
||||
|
||||
rv = aDataSource->HasAssertion(aResource, kRDF_instanceOf, kRDF_Seq, PR_TRUE, &result);
|
||||
|
||||
done:
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
PRBool
|
||||
rdf_IsAlt(nsIRDFDataSource* aDataSource,
|
||||
nsIRDFResource* aResource)
|
||||
{
|
||||
PRBool result = PR_FALSE;
|
||||
|
||||
nsresult rv;
|
||||
if (NS_FAILED(rv = rdf_EnsureRDFService()))
|
||||
goto done;
|
||||
|
||||
rv = aDataSource->HasAssertion(aResource, kRDF_instanceOf, kRDF_Alt, PR_TRUE, &result);
|
||||
|
||||
done:
|
||||
return result;
|
||||
}
|
||||
|
||||
// A complete hack that looks at the string value of a node and
|
||||
// guesses if it's a resource
|
||||
static PRBool
|
||||
|
@ -377,20 +414,83 @@ rdf_Assert(nsIRDFDataSource* ds,
|
|||
|
||||
|
||||
nsresult
|
||||
rdf_CreateAnonymousResource(nsIRDFResource** result)
|
||||
rdf_CreateAnonymousResource(const nsString& aContextURI, nsIRDFResource** result)
|
||||
{
|
||||
static PRUint32 gCounter = 0;
|
||||
|
||||
nsAutoString s = "$";
|
||||
s.Append(++gCounter, 10);
|
||||
static PRUint32 gCounter = 0;
|
||||
|
||||
nsresult rv;
|
||||
if (NS_FAILED(rv = rdf_EnsureRDFService()))
|
||||
return rv;
|
||||
|
||||
return gRDFService->GetUnicodeResource(s, result);
|
||||
do {
|
||||
nsAutoString s(aContextURI);
|
||||
s.Append('$');
|
||||
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) {
|
||||
*result = resource;
|
||||
break;
|
||||
}
|
||||
} while (1);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool
|
||||
rdf_IsAnonymousResource(const nsString& aContextURI, nsIRDFResource* aResource)
|
||||
{
|
||||
nsresult rv;
|
||||
const char* s;
|
||||
if (NS_FAILED(rv = aResource->GetValue(&s))) {
|
||||
NS_ASSERTION(PR_FALSE, "unable to get resource URI");
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsAutoString uri(s);
|
||||
|
||||
// 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]+"
|
||||
if (uri[0] != '$')
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
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());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
rdf_MakeBag(nsIRDFDataSource* ds,
|
||||
nsIRDFResource* bag)
|
||||
|
@ -466,7 +566,6 @@ rdf_ContainerGetNextValue(nsIRDFDataSource* ds,
|
|||
if (NS_FAILED(rv = rdf_EnsureRDFService()))
|
||||
return rv;
|
||||
|
||||
nsIRDFResource* RDF_nextVal = nsnull;
|
||||
nsIRDFNode* nextValNode = nsnull;
|
||||
nsIRDFLiteral* nextValLiteral = nsnull;
|
||||
const PRUnichar* s;
|
||||
|
@ -476,10 +575,7 @@ rdf_ContainerGetNextValue(nsIRDFDataSource* ds,
|
|||
|
||||
// Get the next value, which hangs off of the bag via the
|
||||
// RDF:nextVal property.
|
||||
if (NS_FAILED(rv = gRDFService->GetResource(kURIRDF_nextVal, &RDF_nextVal)))
|
||||
goto done;
|
||||
|
||||
if (NS_FAILED(rv = ds->GetTarget(container, RDF_nextVal, PR_TRUE, &nextValNode)))
|
||||
if (NS_FAILED(rv = ds->GetTarget(container, kRDF_nextVal, PR_TRUE, &nextValNode)))
|
||||
goto done;
|
||||
|
||||
if (NS_FAILED(rv = nextValNode->QueryInterface(kIRDFLiteralIID, (void**) &nextValLiteral)))
|
||||
|
@ -502,7 +598,7 @@ rdf_ContainerGetNextValue(nsIRDFDataSource* ds,
|
|||
goto done;
|
||||
|
||||
// Now increment the RDF:nextVal property.
|
||||
if (NS_FAILED(rv = ds->Unassert(container, RDF_nextVal, nextValLiteral)))
|
||||
if (NS_FAILED(rv = ds->Unassert(container, kRDF_nextVal, nextValLiteral)))
|
||||
goto done;
|
||||
|
||||
NS_RELEASE(nextValLiteral);
|
||||
|
@ -514,13 +610,12 @@ rdf_ContainerGetNextValue(nsIRDFDataSource* ds,
|
|||
if (NS_FAILED(rv = gRDFService->GetLiteral(nextValStr, &nextValLiteral)))
|
||||
goto done;
|
||||
|
||||
if (NS_FAILED(rv = rdf_Assert(ds, container, RDF_nextVal, nextValLiteral)))
|
||||
if (NS_FAILED(rv = rdf_Assert(ds, container, kRDF_nextVal, nextValLiteral)))
|
||||
goto done;
|
||||
|
||||
done:
|
||||
NS_IF_RELEASE(nextValLiteral);
|
||||
NS_IF_RELEASE(nextValNode);
|
||||
NS_IF_RELEASE(RDF_nextVal);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
|
@ -53,6 +53,17 @@ PR_EXTERN(PRBool)
|
|||
rdf_IsContainer(nsIRDFDataSource* db,
|
||||
nsIRDFResource* resource);
|
||||
|
||||
PR_EXTERN(PRBool)
|
||||
rdf_IsBag(nsIRDFDataSource* aDataSource,
|
||||
nsIRDFResource* aResource);
|
||||
|
||||
PR_EXTERN(PRBool)
|
||||
rdf_IsSeq(nsIRDFDataSource* aDataSource,
|
||||
nsIRDFResource* aResource);
|
||||
|
||||
PR_EXTERN(PRBool)
|
||||
rdf_IsAlt(nsIRDFDataSource* aDataSource,
|
||||
nsIRDFResource* aResource);
|
||||
|
||||
/**
|
||||
* Various utilities routines for making assertions in a data source
|
||||
|
@ -105,8 +116,20 @@ rdf_Assert(nsIRDFDataSource* ds,
|
|||
* resource URI.
|
||||
*/
|
||||
PR_EXTERN(nsresult)
|
||||
rdf_CreateAnonymousResource(nsIRDFResource** result);
|
||||
rdf_CreateAnonymousResource(const nsString& aContextURI, nsIRDFResource** result);
|
||||
|
||||
/**
|
||||
* Determine if a resource is an "anonymous" resource that we've constructed
|
||||
* ourselves.
|
||||
*/
|
||||
PR_EXTERN(PRBool)
|
||||
rdf_IsAnonymousResource(const nsString& aContextURI, nsIRDFResource* aResource);
|
||||
|
||||
/**
|
||||
* Try to convert the absolute URL into a relative URL.
|
||||
*/
|
||||
PR_EXTERN(nsresult)
|
||||
rdf_PossiblyMakeRelative(const nsString& aContextURI, nsString& aURI);
|
||||
|
||||
/**
|
||||
* Create a bag resource.
|
||||
|
|
|
@ -1658,8 +1658,8 @@ RDFDocumentImpl::IsTreeProperty(nsIRDFResource* aProperty, PRBool* aResult) cons
|
|||
const char* p;
|
||||
aProperty->GetValue(&p);
|
||||
nsAutoString s(p);
|
||||
if (s.Equals("http://home.netscape.com/NC-rdf#child") ||
|
||||
s.Equals("http://home.netscape.com/NC-rdf#Folder")) {
|
||||
if (s.Equals(NC_NAMESPACE_URI "child") ||
|
||||
s.Equals(NC_NAMESPACE_URI "Folder")) {
|
||||
*aResult = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -45,7 +45,6 @@
|
|||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define NC_NAMESPACE_URI "http://home.netscape.com/NC-rdf#"
|
||||
DEFINE_RDF_VOCAB(NC_NAMESPACE_URI, NC, Columns);
|
||||
DEFINE_RDF_VOCAB(NC_NAMESPACE_URI, NC, Column);
|
||||
DEFINE_RDF_VOCAB(NC_NAMESPACE_URI, NC, Title);
|
||||
|
|
|
@ -47,7 +47,6 @@ static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
|
|||
|
||||
static const char kURINC_BookmarksRoot[] = "NC:BookmarksRoot"; // XXX?
|
||||
|
||||
#define NC_NAMESPACE_URI "http://home.netscape.com/NC-rdf#"
|
||||
DEFINE_RDF_VOCAB(NC_NAMESPACE_URI, NC, child);
|
||||
DEFINE_RDF_VOCAB(NC_NAMESPACE_URI, NC, BookmarkAddDate);
|
||||
DEFINE_RDF_VOCAB(NC_NAMESPACE_URI, NC, Description);
|
||||
|
@ -55,13 +54,9 @@ DEFINE_RDF_VOCAB(NC_NAMESPACE_URI, NC, Folder);
|
|||
DEFINE_RDF_VOCAB(NC_NAMESPACE_URI, NC, Name);
|
||||
DEFINE_RDF_VOCAB(NC_NAMESPACE_URI, NC, PersonalToolbarFolderCategory);
|
||||
|
||||
|
||||
#define WEB_NAMESPACE_URI "http://home.netscape.com/WEB-rdf#"
|
||||
DEFINE_RDF_VOCAB(WEB_NAMESPACE_URI, WEB, LastVisitDate);
|
||||
DEFINE_RDF_VOCAB(WEB_NAMESPACE_URI, WEB, LastModifiedDate);
|
||||
|
||||
|
||||
#define RDF_NAMESPACE_URI "http://www.w3.org/TR/WD-rdf-syntax#"
|
||||
DEFINE_RDF_VOCAB(RDF_NAMESPACE_URI, RDF, instanceOf);
|
||||
|
||||
static const char kPersonalToolbar[] = "Personal Toolbar";
|
||||
|
|
|
@ -62,7 +62,6 @@ static NS_DEFINE_CID(kRDFInMemoryDataSourceCID, NS_RDFINMEMORYDATASOURCE_CID)
|
|||
|
||||
static const char kURIHistoryRoot[] = "HistoryRoot";
|
||||
|
||||
#define NC_NAMESPACE_URI "http://home.netscape.com/NC-rdf#"
|
||||
DEFINE_RDF_VOCAB(NC_NAMESPACE_URI, NC, child);
|
||||
DEFINE_RDF_VOCAB(NC_NAMESPACE_URI, NC, Name);
|
||||
DEFINE_RDF_VOCAB(NC_NAMESPACE_URI, NC, Folder);
|
||||
|
@ -70,7 +69,6 @@ DEFINE_RDF_VOCAB(NC_NAMESPACE_URI, NC, Column);
|
|||
DEFINE_RDF_VOCAB(NC_NAMESPACE_URI, NC, Columns);
|
||||
DEFINE_RDF_VOCAB(NC_NAMESPACE_URI, NC, Title);
|
||||
|
||||
#define WEB_NAMESPACE_URI "http://home.netscape.com/WEB-rdf#"
|
||||
DEFINE_RDF_VOCAB(WEB_NAMESPACE_URI, WEB, LastVisitDate);
|
||||
DEFINE_RDF_VOCAB(WEB_NAMESPACE_URI, WEB, LastModifiedDate);
|
||||
|
||||
|
|
|
@ -110,7 +110,6 @@ static NS_DEFINE_CID(kRDFInMemoryDataSourceCID, NS_RDFINMEMORYDATASOURCE_CID);
|
|||
|
||||
static const char kURINC_MailRoot[] = "NC:MailRoot";
|
||||
|
||||
#define NC_NAMESPACE_URI "http://home.netscape.com/NC-rdf#"
|
||||
DEFINE_RDF_VOCAB(NC_NAMESPACE_URI, NC, child);
|
||||
DEFINE_RDF_VOCAB(NC_NAMESPACE_URI, NC, subject);
|
||||
DEFINE_RDF_VOCAB(NC_NAMESPACE_URI, NC, from);
|
||||
|
|
|
@ -209,7 +209,7 @@ main(int argc, char** argv)
|
|||
if (NS_FAILED(rv = theRDFService->GetResource("http://home.netscape.com", &theHomePage)))
|
||||
goto done;
|
||||
|
||||
if (NS_FAILED(rv = theRDFService->GetResource("http://home.nescape.com/NC-rdf#title", &NC_title)))
|
||||
if (NS_FAILED(rv = theRDFService->GetResource(NC_NAMESPACE_URI "title", &NC_title)))
|
||||
goto done;
|
||||
|
||||
if (NS_FAILED(rv = theRDFService->GetLiteral(nsAutoString("Netscape's Home Page"), &theTitle)))
|
||||
|
|
Загрузка…
Ссылка в новой задаче