1999-01-19 02:42:30 +00:00
|
|
|
/* -*- 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 "NPL"); you may not use this file except in
|
|
|
|
* compliance with the NPL. You may obtain a copy of the NPL at
|
|
|
|
* http://www.mozilla.org/NPL/
|
|
|
|
*
|
|
|
|
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
|
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
|
|
|
* for the specific language governing rights and limitations under the
|
|
|
|
* NPL.
|
|
|
|
*
|
|
|
|
* The Initial Developer of this code under the NPL is Netscape
|
|
|
|
* Communications Corporation. Portions created by Netscape are
|
|
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
|
|
|
* Reserved.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
A data source that can read itself from and write itself to an
|
|
|
|
RDF/XML stream.
|
|
|
|
|
1999-06-09 08:29:51 +00:00
|
|
|
For more information on the RDF/XML syntax,
|
|
|
|
see http://www.w3.org/TR/REC-rdf-syntax/.
|
|
|
|
|
|
|
|
This code is based on the final W3C Recommendation,
|
|
|
|
http://www.w3.org/TR/1999/REC-rdf-syntax-19990222.
|
|
|
|
|
|
|
|
|
1999-01-19 02:42:30 +00:00
|
|
|
TO DO
|
|
|
|
-----
|
|
|
|
|
1999-01-21 22:24:32 +00:00
|
|
|
1) Right now, the only kind of stream data sources that are _really_
|
1999-06-20 00:19:23 +00:00
|
|
|
writable are "file:" URIs. (In fact, _all_ "file:" URIs are
|
|
|
|
writable, modulo flie system permissions; this may lead to some
|
|
|
|
surprising behavior.) Eventually, it'd be great if we could open
|
|
|
|
an arbitrary nsIOutputStream on *any* URL, and Netlib could just
|
|
|
|
do the magic.
|
1999-01-21 22:24:32 +00:00
|
|
|
|
1999-01-22 06:48:25 +00:00
|
|
|
2) Implement a more terse output for "typed" nodes; that is, instead
|
1999-04-21 00:09:41 +00:00
|
|
|
of "RDF:Description type='ns:foo'", just output "ns:foo".
|
1999-01-19 02:42:30 +00:00
|
|
|
|
1999-06-09 08:29:51 +00:00
|
|
|
3) When re-serializing, we "cheat" for Descriptions that talk about
|
|
|
|
inline resources (i.e.., using the `ID' attribute specified in
|
|
|
|
[6.21]). Instead of writing an `ID="foo"' for the first instance,
|
|
|
|
and then `about="#foo"' for each subsequent instance, we just
|
|
|
|
_always_ write `about="#foo"'.
|
1999-01-26 01:24:34 +00:00
|
|
|
|
1999-06-20 00:19:23 +00:00
|
|
|
We do this so that we can handle the case where an RDF container
|
|
|
|
has been assigned arbitrary properties: the spec says we can't
|
|
|
|
dangle the attributes directly off the container, so we need to
|
|
|
|
refer to it. Of course, with a little cleverness, we could fix
|
|
|
|
this. But who cares?
|
|
|
|
|
|
|
|
4) When re-serializing containers. We have to cheat on some
|
|
|
|
containers, and use an illegal "about=" construct. We do this to
|
|
|
|
handle containers that have been assigned URIs outside of the
|
|
|
|
local document.
|
1999-06-16 05:11:05 +00:00
|
|
|
|
1999-01-19 02:42:30 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "nsFileSpec.h"
|
|
|
|
#include "nsFileStream.h"
|
|
|
|
#include "nsIDTD.h"
|
1999-05-05 03:09:12 +00:00
|
|
|
#include "nsIRDFPurgeableDataSource.h"
|
1999-01-19 02:42:30 +00:00
|
|
|
#include "nsIInputStream.h"
|
|
|
|
#include "nsINameSpaceManager.h"
|
|
|
|
#include "nsIOutputStream.h"
|
|
|
|
#include "nsIParser.h"
|
1999-04-27 05:54:18 +00:00
|
|
|
#include "nsIRDFContainerUtils.h"
|
1999-01-19 02:42:30 +00:00
|
|
|
#include "nsIRDFContentSink.h"
|
|
|
|
#include "nsIRDFNode.h"
|
1999-06-24 00:22:58 +00:00
|
|
|
#include "nsIRDFRemoteDataSource.h"
|
1999-01-19 02:42:30 +00:00
|
|
|
#include "nsIRDFService.h"
|
1999-06-24 00:22:58 +00:00
|
|
|
#include "nsIRDFXMLSink.h"
|
1999-01-19 02:42:30 +00:00
|
|
|
#include "nsIRDFXMLSource.h"
|
|
|
|
#include "nsIServiceManager.h"
|
|
|
|
#include "nsIStreamListener.h"
|
|
|
|
#include "nsIURL.h"
|
1999-06-18 17:34:08 +00:00
|
|
|
#ifdef NECKO
|
1999-06-26 06:36:26 +00:00
|
|
|
#include "nsNeckoUtil.h"
|
1999-07-02 06:15:00 +00:00
|
|
|
#include "nsIChannel.h"
|
1999-06-18 17:34:08 +00:00
|
|
|
#endif // NECKO
|
1999-01-19 02:42:30 +00:00
|
|
|
#include "nsLayoutCID.h" // for NS_NAMESPACEMANAGER_CID.
|
|
|
|
#include "nsParserCIID.h"
|
|
|
|
#include "nsRDFCID.h"
|
1999-06-24 00:22:58 +00:00
|
|
|
#include "nsRDFBaseDataSources.h"
|
1999-01-19 02:42:30 +00:00
|
|
|
#include "nsVoidArray.h"
|
1999-03-29 19:52:54 +00:00
|
|
|
#include "nsXPIDLString.h"
|
1999-01-19 02:42:30 +00:00
|
|
|
#include "plstr.h"
|
|
|
|
#include "prio.h"
|
|
|
|
#include "prthread.h"
|
1999-04-22 03:16:55 +00:00
|
|
|
#include "rdf.h"
|
1999-01-21 22:24:32 +00:00
|
|
|
#include "rdfutil.h"
|
1999-03-09 09:44:27 +00:00
|
|
|
#include "prlog.h"
|
1999-01-19 02:42:30 +00:00
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
static NS_DEFINE_IID(kIDTDIID, NS_IDTD_IID);
|
|
|
|
static NS_DEFINE_IID(kIInputStreamIID, NS_IINPUTSTREAM_IID);
|
|
|
|
static NS_DEFINE_IID(kINameSpaceManagerIID, NS_INAMESPACEMANAGER_IID);
|
|
|
|
static NS_DEFINE_IID(kIParserIID, NS_IPARSER_IID);
|
|
|
|
static NS_DEFINE_IID(kIStreamListenerIID, NS_ISTREAMLISTENER_IID);
|
|
|
|
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
|
|
|
|
|
|
|
static NS_DEFINE_CID(kNameSpaceManagerCID, NS_NAMESPACEMANAGER_CID);
|
|
|
|
static NS_DEFINE_CID(kParserCID, NS_PARSER_IID); // XXX
|
|
|
|
static NS_DEFINE_CID(kRDFInMemoryDataSourceCID, NS_RDFINMEMORYDATASOURCE_CID);
|
1999-04-27 05:54:18 +00:00
|
|
|
static NS_DEFINE_CID(kRDFContainerUtilsCID, NS_RDFCONTAINERUTILS_CID);
|
1999-01-19 02:42:30 +00:00
|
|
|
static NS_DEFINE_CID(kRDFContentSinkCID, NS_RDFCONTENTSINK_CID);
|
|
|
|
static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
|
|
|
|
static NS_DEFINE_CID(kWellFormedDTDCID, NS_WELLFORMEDDTD_CID);
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
class ProxyStream : public nsIInputStream
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
const char* mBuffer;
|
|
|
|
PRUint32 mSize;
|
|
|
|
PRUint32 mIndex;
|
|
|
|
|
|
|
|
public:
|
|
|
|
ProxyStream(void) : mBuffer(nsnull)
|
|
|
|
{
|
|
|
|
NS_INIT_REFCNT();
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual ~ProxyStream(void) {
|
|
|
|
}
|
|
|
|
|
|
|
|
// nsISupports
|
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
|
|
|
|
// nsIBaseStream
|
|
|
|
NS_IMETHOD Close(void) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// nsIInputStream
|
|
|
|
NS_IMETHOD GetLength(PRUint32 *aLength) {
|
|
|
|
*aLength = mSize - mIndex;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-05-05 03:09:12 +00:00
|
|
|
|
1999-03-05 22:53:56 +00:00
|
|
|
NS_IMETHOD Read(char* aBuf, PRUint32 aCount, PRUint32 *aReadCount) {
|
1999-01-19 02:42:30 +00:00
|
|
|
PRUint32 readCount = 0;
|
|
|
|
while (mIndex < mSize && aCount > 0) {
|
|
|
|
*aBuf = mBuffer[mIndex];
|
|
|
|
aBuf++;
|
|
|
|
mIndex++;
|
|
|
|
readCount++;
|
|
|
|
aCount--;
|
|
|
|
}
|
|
|
|
*aReadCount = readCount;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Implementation
|
|
|
|
void SetBuffer(const char* aBuffer, PRUint32 aSize) {
|
|
|
|
mBuffer = aBuffer;
|
|
|
|
mSize = aSize;
|
|
|
|
mIndex = 0;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
NS_IMPL_ISUPPORTS(ProxyStream, kIInputStreamIID);
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
// RDFXMLDataSourceImpl
|
|
|
|
|
1999-06-24 00:22:58 +00:00
|
|
|
class RDFXMLDataSourceImpl : public nsIRDFDataSource,
|
|
|
|
public nsIRDFRemoteDataSource,
|
|
|
|
public nsIRDFXMLSink,
|
1999-01-19 02:42:30 +00:00
|
|
|
public nsIRDFXMLSource
|
|
|
|
{
|
|
|
|
protected:
|
1999-01-21 22:24:32 +00:00
|
|
|
struct NameSpaceMap {
|
|
|
|
nsString URI;
|
|
|
|
nsIAtom* Prefix;
|
|
|
|
NameSpaceMap* Next;
|
|
|
|
};
|
|
|
|
|
1999-05-05 03:09:12 +00:00
|
|
|
nsIRDFDataSource* mInner; // OWNER
|
1999-01-20 19:56:34 +00:00
|
|
|
PRBool mIsWritable; // true if the document can be written back
|
1999-01-20 01:42:13 +00:00
|
|
|
PRBool mIsDirty; // true if the document should be written back
|
1999-05-05 03:09:12 +00:00
|
|
|
nsVoidArray mObservers; // WEAK REFERENCES
|
|
|
|
PRBool mIsLoading; // true while the document is loading
|
1999-01-21 22:24:32 +00:00
|
|
|
NameSpaceMap* mNameSpaces;
|
1999-06-23 03:29:44 +00:00
|
|
|
nsCOMPtr<nsIURI> mURL;
|
1999-06-24 00:22:58 +00:00
|
|
|
char* mURLSpec;
|
1999-01-19 02:42:30 +00:00
|
|
|
|
1999-04-22 03:16:55 +00:00
|
|
|
// pseudo-constants
|
|
|
|
static PRInt32 gRefCnt;
|
1999-06-09 08:29:51 +00:00
|
|
|
static nsIRDFContainerUtils* gRDFC;
|
1999-08-06 20:24:29 +00:00
|
|
|
static nsIRDFService* gRDFService;
|
1999-04-22 03:16:55 +00:00
|
|
|
static nsIRDFResource* kRDF_instanceOf;
|
|
|
|
static nsIRDFResource* kRDF_nextVal;
|
1999-04-27 05:54:18 +00:00
|
|
|
static nsIRDFResource* kRDF_Bag;
|
|
|
|
static nsIRDFResource* kRDF_Seq;
|
|
|
|
static nsIRDFResource* kRDF_Alt;
|
1999-04-22 03:16:55 +00:00
|
|
|
|
1999-06-09 08:29:51 +00:00
|
|
|
nsresult Init();
|
1999-01-19 02:42:30 +00:00
|
|
|
RDFXMLDataSourceImpl(void);
|
|
|
|
virtual ~RDFXMLDataSourceImpl(void);
|
|
|
|
|
1999-06-09 08:29:51 +00:00
|
|
|
friend nsresult
|
1999-06-24 00:22:58 +00:00
|
|
|
NS_NewRDFXMLDataSource(nsIRDFDataSource** aResult);
|
1999-06-09 08:29:51 +00:00
|
|
|
|
|
|
|
public:
|
1999-01-19 02:42:30 +00:00
|
|
|
// nsISupports
|
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
|
|
|
|
// nsIRDFDataSource
|
1999-06-24 00:22:58 +00:00
|
|
|
NS_IMETHOD GetURI(char* *uri);
|
1999-01-19 02:42:30 +00:00
|
|
|
|
|
|
|
NS_IMETHOD GetSource(nsIRDFResource* property,
|
|
|
|
nsIRDFNode* target,
|
|
|
|
PRBool tv,
|
|
|
|
nsIRDFResource** source) {
|
|
|
|
return mInner->GetSource(property, target, tv, source);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHOD GetSources(nsIRDFResource* property,
|
|
|
|
nsIRDFNode* target,
|
|
|
|
PRBool tv,
|
1999-04-24 02:41:02 +00:00
|
|
|
nsISimpleEnumerator** sources) {
|
1999-01-19 02:42:30 +00:00
|
|
|
return mInner->GetSources(property, target, tv, sources);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHOD GetTarget(nsIRDFResource* source,
|
|
|
|
nsIRDFResource* property,
|
|
|
|
PRBool tv,
|
|
|
|
nsIRDFNode** target) {
|
|
|
|
return mInner->GetTarget(source, property, tv, target);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHOD GetTargets(nsIRDFResource* source,
|
|
|
|
nsIRDFResource* property,
|
|
|
|
PRBool tv,
|
1999-04-24 02:41:02 +00:00
|
|
|
nsISimpleEnumerator** targets) {
|
1999-01-19 02:42:30 +00:00
|
|
|
return mInner->GetTargets(source, property, tv, targets);
|
|
|
|
}
|
|
|
|
|
1999-05-05 03:09:12 +00:00
|
|
|
NS_IMETHOD Assert(nsIRDFResource* aSource,
|
|
|
|
nsIRDFResource* aProperty,
|
|
|
|
nsIRDFNode* aTarget,
|
1999-01-19 02:42:30 +00:00
|
|
|
PRBool tv);
|
|
|
|
|
|
|
|
NS_IMETHOD Unassert(nsIRDFResource* source,
|
|
|
|
nsIRDFResource* property,
|
|
|
|
nsIRDFNode* target);
|
|
|
|
|
1999-06-24 00:22:58 +00:00
|
|
|
NS_IMETHOD Change(nsIRDFResource* aSource,
|
|
|
|
nsIRDFResource* aProperty,
|
|
|
|
nsIRDFNode* aOldTarget,
|
|
|
|
nsIRDFNode* aNewTarget);
|
|
|
|
|
|
|
|
NS_IMETHOD Move(nsIRDFResource* aOldSource,
|
|
|
|
nsIRDFResource* aNewSource,
|
|
|
|
nsIRDFResource* aProperty,
|
|
|
|
nsIRDFNode* aTarget);
|
|
|
|
|
1999-01-19 02:42:30 +00:00
|
|
|
NS_IMETHOD HasAssertion(nsIRDFResource* source,
|
|
|
|
nsIRDFResource* property,
|
|
|
|
nsIRDFNode* target,
|
|
|
|
PRBool tv,
|
|
|
|
PRBool* hasAssertion) {
|
|
|
|
return mInner->HasAssertion(source, property, target, tv, hasAssertion);
|
|
|
|
}
|
|
|
|
|
1999-07-06 23:36:44 +00:00
|
|
|
NS_IMETHOD AddObserver(nsIRDFObserver* aObserver) {
|
|
|
|
return mInner->AddObserver(aObserver);
|
1999-01-19 02:42:30 +00:00
|
|
|
}
|
|
|
|
|
1999-07-06 23:36:44 +00:00
|
|
|
NS_IMETHOD RemoveObserver(nsIRDFObserver* aObserver) {
|
|
|
|
return mInner->RemoveObserver(aObserver);
|
1999-01-19 02:42:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHOD ArcLabelsIn(nsIRDFNode* node,
|
1999-04-24 02:41:02 +00:00
|
|
|
nsISimpleEnumerator** labels) {
|
1999-01-19 02:42:30 +00:00
|
|
|
return mInner->ArcLabelsIn(node, labels);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHOD ArcLabelsOut(nsIRDFResource* source,
|
1999-04-24 02:41:02 +00:00
|
|
|
nsISimpleEnumerator** labels) {
|
1999-01-19 02:42:30 +00:00
|
|
|
return mInner->ArcLabelsOut(source, labels);
|
|
|
|
}
|
|
|
|
|
1999-04-24 02:41:02 +00:00
|
|
|
NS_IMETHOD GetAllResources(nsISimpleEnumerator** aResult) {
|
|
|
|
return mInner->GetAllResources(aResult);
|
1999-01-21 22:24:32 +00:00
|
|
|
}
|
|
|
|
|
1999-03-12 21:28:34 +00:00
|
|
|
NS_IMETHOD GetAllCommands(nsIRDFResource* source,
|
|
|
|
nsIEnumerator/*<nsIRDFResource>*/** commands) {
|
|
|
|
return mInner->GetAllCommands(source, commands);
|
1999-01-19 02:42:30 +00:00
|
|
|
}
|
|
|
|
|
1999-06-26 01:09:02 +00:00
|
|
|
NS_IMETHOD GetAllCmds(nsIRDFResource* source,
|
|
|
|
nsISimpleEnumerator/*<nsIRDFResource>*/** commands) {
|
|
|
|
return mInner->GetAllCmds(source, commands);
|
|
|
|
}
|
|
|
|
|
1999-03-12 21:28:34 +00:00
|
|
|
NS_IMETHOD IsCommandEnabled(nsISupportsArray/*<nsIRDFResource>*/* aSources,
|
|
|
|
nsIRDFResource* aCommand,
|
1999-03-29 19:52:54 +00:00
|
|
|
nsISupportsArray/*<nsIRDFResource>*/* aArguments,
|
|
|
|
PRBool* aResult) {
|
|
|
|
return mInner->IsCommandEnabled(aSources, aCommand, aArguments, aResult);
|
1999-03-12 21:28:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHOD DoCommand(nsISupportsArray/*<nsIRDFResource>*/* aSources,
|
1999-03-11 10:01:25 +00:00
|
|
|
nsIRDFResource* aCommand,
|
1999-03-12 21:28:34 +00:00
|
|
|
nsISupportsArray/*<nsIRDFResource>*/* aArguments) {
|
1999-01-19 02:42:30 +00:00
|
|
|
// XXX Uh oh, this could cause problems wrt. the "dirty" flag
|
|
|
|
// if it changes the in-memory store's internal state.
|
1999-03-11 10:01:25 +00:00
|
|
|
return mInner->DoCommand(aSources, aCommand, aArguments);
|
1999-01-19 02:42:30 +00:00
|
|
|
}
|
|
|
|
|
1999-06-24 00:22:58 +00:00
|
|
|
// nsIRDFRemoteDataSource interface
|
1999-08-24 09:11:48 +00:00
|
|
|
NS_DECL_NSIRDFREMOTEDATASOURCE
|
1999-06-24 00:22:58 +00:00
|
|
|
|
|
|
|
// nsIRDFXMLSink interface
|
1999-08-24 09:11:48 +00:00
|
|
|
NS_DECL_NSIRDFXMLSINK
|
1999-01-19 02:42:30 +00:00
|
|
|
|
|
|
|
// nsIRDFXMLSource interface
|
1999-08-24 09:11:48 +00:00
|
|
|
NS_DECL_NSIRDFXMLSOURCE
|
1999-01-19 02:42:30 +00:00
|
|
|
|
|
|
|
// Implementation methods
|
1999-01-21 22:24:32 +00:00
|
|
|
PRBool
|
|
|
|
MakeQName(nsIRDFResource* aResource,
|
|
|
|
nsString& property,
|
|
|
|
nsString& nameSpacePrefix,
|
|
|
|
nsString& nameSpaceURI);
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
SerializeAssertion(nsIOutputStream* aStream,
|
|
|
|
nsIRDFResource* aResource,
|
|
|
|
nsIRDFResource* aProperty,
|
|
|
|
nsIRDFNode* aValue);
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
SerializeProperty(nsIOutputStream* aStream,
|
|
|
|
nsIRDFResource* aResource,
|
|
|
|
nsIRDFResource* aProperty);
|
|
|
|
|
1999-06-09 08:29:51 +00:00
|
|
|
PRBool
|
|
|
|
IsContainerProperty(nsIRDFResource* aProperty);
|
|
|
|
|
1999-01-21 22:24:32 +00:00
|
|
|
nsresult
|
|
|
|
SerializeDescription(nsIOutputStream* aStream,
|
|
|
|
nsIRDFResource* aResource);
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
SerializeMember(nsIOutputStream* aStream,
|
|
|
|
nsIRDFResource* aContainer,
|
1999-06-09 08:29:51 +00:00
|
|
|
nsIRDFNode* aMember);
|
1999-01-21 22:24:32 +00:00
|
|
|
|
|
|
|
nsresult
|
|
|
|
SerializeContainer(nsIOutputStream* aStream,
|
|
|
|
nsIRDFResource* aContainer);
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
SerializePrologue(nsIOutputStream* aStream);
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
SerializeEpilogue(nsIOutputStream* aStream);
|
1999-01-19 02:42:30 +00:00
|
|
|
};
|
|
|
|
|
1999-04-22 03:16:55 +00:00
|
|
|
PRInt32 RDFXMLDataSourceImpl::gRefCnt = 0;
|
1999-08-06 20:24:29 +00:00
|
|
|
nsIRDFService* RDFXMLDataSourceImpl::gRDFService;
|
1999-06-09 08:29:51 +00:00
|
|
|
nsIRDFContainerUtils* RDFXMLDataSourceImpl::gRDFC;
|
1999-04-22 03:16:55 +00:00
|
|
|
nsIRDFResource* RDFXMLDataSourceImpl::kRDF_instanceOf;
|
|
|
|
nsIRDFResource* RDFXMLDataSourceImpl::kRDF_nextVal;
|
1999-04-27 05:54:18 +00:00
|
|
|
nsIRDFResource* RDFXMLDataSourceImpl::kRDF_Bag;
|
|
|
|
nsIRDFResource* RDFXMLDataSourceImpl::kRDF_Seq;
|
|
|
|
nsIRDFResource* RDFXMLDataSourceImpl::kRDF_Alt;
|
1999-01-19 02:42:30 +00:00
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
nsresult
|
1999-06-24 00:22:58 +00:00
|
|
|
NS_NewRDFXMLDataSource(nsIRDFDataSource** aResult)
|
1999-01-19 02:42:30 +00:00
|
|
|
{
|
1999-06-09 08:29:51 +00:00
|
|
|
NS_PRECONDITION(aResult != nsnull, "null ptr");
|
|
|
|
if (! aResult)
|
1999-01-19 02:42:30 +00:00
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
1999-06-09 08:29:51 +00:00
|
|
|
RDFXMLDataSourceImpl* datasource = new RDFXMLDataSourceImpl();
|
|
|
|
if (! datasource)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
nsresult rv;
|
|
|
|
rv = datasource->Init();
|
|
|
|
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
delete datasource;
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_ADDREF(datasource);
|
|
|
|
*aResult = datasource;
|
1999-01-19 02:42:30 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
RDFXMLDataSourceImpl::RDFXMLDataSourceImpl(void)
|
1999-02-02 07:06:56 +00:00
|
|
|
: mInner(nsnull),
|
1999-01-20 19:56:34 +00:00
|
|
|
mIsWritable(PR_TRUE),
|
1999-01-20 01:42:13 +00:00
|
|
|
mIsDirty(PR_FALSE),
|
1999-01-21 22:24:32 +00:00
|
|
|
mIsLoading(PR_FALSE),
|
1999-06-24 00:22:58 +00:00
|
|
|
mNameSpaces(nsnull),
|
|
|
|
mURLSpec(nsnull)
|
1999-01-19 02:42:30 +00:00
|
|
|
{
|
1999-04-22 03:16:55 +00:00
|
|
|
NS_INIT_REFCNT();
|
1999-06-09 08:29:51 +00:00
|
|
|
}
|
|
|
|
|
1999-04-22 03:16:55 +00:00
|
|
|
|
1999-06-09 08:29:51 +00:00
|
|
|
nsresult
|
|
|
|
RDFXMLDataSourceImpl::Init()
|
|
|
|
{
|
1999-01-19 02:42:30 +00:00
|
|
|
nsresult rv;
|
1999-06-09 08:29:51 +00:00
|
|
|
rv = nsComponentManager::CreateInstance(kRDFInMemoryDataSourceCID,
|
|
|
|
nsnull,
|
1999-06-24 00:22:58 +00:00
|
|
|
nsIRDFDataSource::GetIID(),
|
1999-06-09 08:29:51 +00:00
|
|
|
(void**) &mInner);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-01-19 02:42:30 +00:00
|
|
|
|
1999-01-21 22:24:32 +00:00
|
|
|
// 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.
|
1999-01-22 06:48:25 +00:00
|
|
|
//
|
|
|
|
// 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);
|
1999-04-22 03:16:55 +00:00
|
|
|
|
|
|
|
if (gRefCnt++ == 0) {
|
1999-08-06 20:24:29 +00:00
|
|
|
rv = nsServiceManager::GetService(kRDFServiceCID,
|
|
|
|
nsCOMTypeInfo<nsIRDFService>::GetIID(),
|
|
|
|
NS_REINTERPRET_CAST(nsISupports**, &gRDFService));
|
|
|
|
|
1999-04-22 03:16:55 +00:00
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get RDF service");
|
1999-06-09 08:29:51 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-04-22 03:16:55 +00:00
|
|
|
|
1999-08-06 20:24:29 +00:00
|
|
|
rv = gRDFService->GetResource(RDF_NAMESPACE_URI "instanceOf", &kRDF_instanceOf);
|
|
|
|
rv = gRDFService->GetResource(RDF_NAMESPACE_URI "nextVal", &kRDF_nextVal);
|
|
|
|
rv = gRDFService->GetResource(RDF_NAMESPACE_URI "Bag", &kRDF_Bag);
|
|
|
|
rv = gRDFService->GetResource(RDF_NAMESPACE_URI "Seq", &kRDF_Seq);
|
|
|
|
rv = gRDFService->GetResource(RDF_NAMESPACE_URI "Alt", &kRDF_Alt);
|
1999-06-09 08:29:51 +00:00
|
|
|
|
|
|
|
rv = nsServiceManager::GetService(kRDFContainerUtilsCID,
|
|
|
|
nsIRDFContainerUtils::GetIID(),
|
|
|
|
(nsISupports**) &gRDFC);
|
|
|
|
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get container utils");
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-04-22 03:16:55 +00:00
|
|
|
}
|
1999-06-09 08:29:51 +00:00
|
|
|
|
|
|
|
return NS_OK;
|
1999-01-19 02:42:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
RDFXMLDataSourceImpl::~RDFXMLDataSourceImpl(void)
|
|
|
|
{
|
1999-05-13 20:53:07 +00:00
|
|
|
nsresult rv;
|
1999-01-19 02:42:30 +00:00
|
|
|
|
1999-08-06 20:24:29 +00:00
|
|
|
// Unregister first so that nobody else tries to get us.
|
|
|
|
rv = gRDFService->UnregisterDataSource(this);
|
1999-01-19 02:42:30 +00:00
|
|
|
|
1999-08-06 20:24:29 +00:00
|
|
|
// Now flush contents
|
|
|
|
rv = Flush();
|
|
|
|
|
|
|
|
if (mURLSpec)
|
|
|
|
PL_strfree(mURLSpec);
|
1999-07-03 04:26:04 +00:00
|
|
|
|
1999-01-21 22:24:32 +00:00
|
|
|
while (mNameSpaces) {
|
|
|
|
NameSpaceMap* doomed = mNameSpaces;
|
|
|
|
mNameSpaces = mNameSpaces->Next;
|
|
|
|
|
1999-03-26 04:42:29 +00:00
|
|
|
NS_IF_RELEASE(doomed->Prefix);
|
1999-01-21 22:24:32 +00:00
|
|
|
delete doomed;
|
|
|
|
}
|
1999-02-02 07:06:56 +00:00
|
|
|
|
|
|
|
NS_RELEASE(mInner);
|
1999-04-22 03:16:55 +00:00
|
|
|
|
|
|
|
if (--gRefCnt == 0) {
|
1999-06-09 08:29:51 +00:00
|
|
|
NS_IF_RELEASE(kRDF_Bag);
|
|
|
|
NS_IF_RELEASE(kRDF_Seq);
|
|
|
|
NS_IF_RELEASE(kRDF_Alt);
|
1999-04-22 03:16:55 +00:00
|
|
|
NS_IF_RELEASE(kRDF_instanceOf);
|
|
|
|
NS_IF_RELEASE(kRDF_nextVal);
|
1999-08-06 20:24:29 +00:00
|
|
|
|
|
|
|
if (gRDFC) {
|
|
|
|
nsServiceManager::ReleaseService(kRDFContainerUtilsCID, gRDFC);
|
|
|
|
gRDFC = nsnull;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (gRDFService) {
|
|
|
|
nsServiceManager::ReleaseService(kRDFServiceCID, gRDFService);
|
|
|
|
gRDFService = nsnull;
|
|
|
|
}
|
1999-04-22 03:16:55 +00:00
|
|
|
}
|
1999-01-19 02:42:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMPL_ADDREF(RDFXMLDataSourceImpl);
|
|
|
|
NS_IMPL_RELEASE(RDFXMLDataSourceImpl);
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-06-24 00:22:58 +00:00
|
|
|
RDFXMLDataSourceImpl::QueryInterface(REFNSIID aIID, void** aResult)
|
1999-01-19 02:42:30 +00:00
|
|
|
{
|
1999-06-24 00:22:58 +00:00
|
|
|
NS_PRECONDITION(aResult != nsnull, "null ptr");
|
|
|
|
if (! aResult)
|
1999-01-19 02:42:30 +00:00
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
1999-06-24 00:22:58 +00:00
|
|
|
if (aIID.Equals(kISupportsIID) ||
|
|
|
|
aIID.Equals(nsIRDFDataSource::GetIID())) {
|
|
|
|
*aResult = NS_STATIC_CAST(nsIRDFDataSource*, this);
|
1999-01-19 02:42:30 +00:00
|
|
|
}
|
1999-06-24 00:22:58 +00:00
|
|
|
else if (aIID.Equals(nsIRDFRemoteDataSource::GetIID())) {
|
|
|
|
*aResult = NS_STATIC_CAST(nsIRDFRemoteDataSource*, this);
|
|
|
|
}
|
|
|
|
else if (aIID.Equals(nsIRDFXMLSink::GetIID())) {
|
|
|
|
*aResult = NS_STATIC_CAST(nsIRDFXMLSink*, this);
|
|
|
|
}
|
|
|
|
else if (aIID.Equals(nsIRDFXMLSource::GetIID())) {
|
|
|
|
*aResult = NS_STATIC_CAST(nsIRDFXMLSource*, this);
|
1999-01-19 02:42:30 +00:00
|
|
|
}
|
|
|
|
else {
|
1999-06-24 00:22:58 +00:00
|
|
|
*aResult = nsnull;
|
1999-01-19 02:42:30 +00:00
|
|
|
return NS_NOINTERFACE;
|
|
|
|
}
|
1999-06-24 00:22:58 +00:00
|
|
|
|
|
|
|
NS_ADDREF(this);
|
|
|
|
return NS_OK;
|
1999-01-19 02:42:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static nsresult
|
1999-06-23 03:29:44 +00:00
|
|
|
rdf_BlockingParse(nsIURI* aURL, nsIStreamListener* aConsumer)
|
1999-01-19 02:42:30 +00:00
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
|
1999-01-20 01:42:13 +00:00
|
|
|
// XXX I really hate the way that we're spoon-feeding this stuff
|
|
|
|
// to the parser: it seems like this is something that netlib
|
|
|
|
// should be able to do by itself.
|
|
|
|
|
1999-06-26 06:36:26 +00:00
|
|
|
#ifdef NECKO
|
1999-07-02 06:15:00 +00:00
|
|
|
nsCOMPtr<nsIChannel> channel;
|
1999-08-26 22:45:55 +00:00
|
|
|
// Null LoadGroup ?
|
|
|
|
rv = NS_OpenURI(getter_AddRefs(channel), aURL, nsnull);
|
1999-07-02 06:15:00 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
{
|
|
|
|
NS_ERROR("unable to open channel");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
nsIInputStream* in;
|
|
|
|
PRUint32 sourceOffset = 0;
|
|
|
|
rv = channel->OpenInputStream(0, -1, &in);
|
1999-06-26 06:36:26 +00:00
|
|
|
#else
|
1999-07-02 06:15:00 +00:00
|
|
|
nsIInputStream* in;
|
|
|
|
rv = NS_OpenURL(aURL, &in, nsnull /* XXX aConsumer */);
|
1999-06-26 06:36:26 +00:00
|
|
|
#endif
|
1999-07-02 06:15:00 +00:00
|
|
|
if (NS_FAILED(rv))
|
1999-06-26 06:36:26 +00:00
|
|
|
{
|
1999-08-03 21:59:40 +00:00
|
|
|
// file doesn't exist -- just exit
|
|
|
|
// NS_ERROR("unable to open blocking stream");
|
1999-01-19 02:42:30 +00:00
|
|
|
return rv;
|
1999-03-26 04:42:29 +00:00
|
|
|
}
|
1999-01-19 02:42:30 +00:00
|
|
|
|
1999-03-27 00:28:08 +00:00
|
|
|
NS_ASSERTION(in != nsnull, "no input stream");
|
|
|
|
if (! in) return NS_ERROR_FAILURE;
|
|
|
|
|
1999-01-19 02:42:30 +00:00
|
|
|
rv = NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
ProxyStream* proxy = new ProxyStream();
|
|
|
|
if (! proxy)
|
|
|
|
goto done;
|
|
|
|
|
1999-07-02 06:15:00 +00:00
|
|
|
#ifdef NECKO
|
1999-07-07 08:08:40 +00:00
|
|
|
aConsumer->OnStartRequest(channel, nsnull);
|
1999-07-02 06:15:00 +00:00
|
|
|
#else
|
1999-01-19 02:42:30 +00:00
|
|
|
// XXX shouldn't netlib be doing this???
|
1999-07-01 19:30:20 +00:00
|
|
|
aConsumer->OnStartRequest(aURL, "text/rdf");
|
1999-06-26 06:36:26 +00:00
|
|
|
#endif
|
1999-01-19 02:42:30 +00:00
|
|
|
while (PR_TRUE) {
|
|
|
|
char buf[1024];
|
|
|
|
PRUint32 readCount;
|
|
|
|
|
1999-03-05 22:53:56 +00:00
|
|
|
if (NS_FAILED(rv = in->Read(buf, sizeof(buf), &readCount)))
|
1999-01-19 02:42:30 +00:00
|
|
|
break; // error or eof
|
|
|
|
|
|
|
|
if (readCount == 0)
|
|
|
|
break; // eof
|
|
|
|
|
|
|
|
proxy->SetBuffer(buf, readCount);
|
1999-05-05 03:09:12 +00:00
|
|
|
|
1999-07-02 06:15:00 +00:00
|
|
|
#ifdef NECKO
|
1999-07-07 08:08:40 +00:00
|
|
|
rv = aConsumer->OnDataAvailable(channel, nsnull, proxy, sourceOffset, readCount);
|
1999-07-02 06:15:00 +00:00
|
|
|
sourceOffset += readCount;
|
|
|
|
#else
|
1999-01-19 02:42:30 +00:00
|
|
|
// XXX shouldn't netlib be doing this???
|
1999-06-26 06:36:26 +00:00
|
|
|
rv = aConsumer->OnDataAvailable(aURL, proxy, readCount);
|
|
|
|
#endif
|
|
|
|
if (NS_FAILED(rv))
|
1999-01-19 02:42:30 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (rv == NS_BASE_STREAM_EOF) {
|
|
|
|
rv = NS_OK;
|
|
|
|
}
|
1999-07-02 06:15:00 +00:00
|
|
|
#ifdef NECKO
|
1999-07-07 08:08:40 +00:00
|
|
|
aConsumer->OnStopRequest(channel, nsnull, NS_OK, nsnull);
|
1999-07-02 06:15:00 +00:00
|
|
|
#else
|
1999-01-19 02:42:30 +00:00
|
|
|
// XXX shouldn't netlib be doing this???
|
1999-07-01 19:30:20 +00:00
|
|
|
aConsumer->OnStopRequest(aURL, 0, nsnull);
|
1999-06-26 06:36:26 +00:00
|
|
|
#endif
|
1999-01-19 02:42:30 +00:00
|
|
|
|
1999-08-05 20:10:08 +00:00
|
|
|
// don't leak proxy!
|
|
|
|
proxy->Close();
|
|
|
|
delete proxy;
|
|
|
|
proxy = nsnull;
|
|
|
|
|
1999-01-19 02:42:30 +00:00
|
|
|
done:
|
|
|
|
NS_RELEASE(in);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
RDFXMLDataSourceImpl::Init(const char* uri)
|
|
|
|
{
|
|
|
|
static const char kFileURIPrefix[] = "file:";
|
|
|
|
static const char kResourceURIPrefix[] = "resource:";
|
|
|
|
|
|
|
|
NS_PRECONDITION(mInner != nsnull, "not initialized");
|
|
|
|
if (! mInner)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
nsresult rv;
|
|
|
|
|
1999-06-18 17:34:08 +00:00
|
|
|
#ifndef NECKO
|
1999-05-05 03:09:12 +00:00
|
|
|
rv = NS_NewURL(getter_AddRefs(mURL), uri);
|
1999-06-18 17:34:08 +00:00
|
|
|
#else
|
1999-06-26 06:36:26 +00:00
|
|
|
rv = NS_NewURI(getter_AddRefs(mURL), uri);
|
1999-06-18 17:34:08 +00:00
|
|
|
#endif // NECKO
|
1999-05-05 03:09:12 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-01-19 02:42:30 +00:00
|
|
|
|
1999-04-10 08:18:20 +00:00
|
|
|
// XXX this is a hack: any "file:" URI is considered writable. All
|
|
|
|
// others are considered read-only.
|
1999-06-26 06:36:26 +00:00
|
|
|
#ifdef NECKO
|
|
|
|
char* realURL;
|
|
|
|
#else
|
1999-05-05 03:09:12 +00:00
|
|
|
const char* realURL;
|
1999-06-26 06:36:26 +00:00
|
|
|
#endif
|
1999-05-05 03:09:12 +00:00
|
|
|
mURL->GetSpec(&realURL);
|
1999-04-10 08:18:20 +00:00
|
|
|
if ((PL_strncmp(realURL, kFileURIPrefix, sizeof(kFileURIPrefix) - 1) != 0) &&
|
|
|
|
(PL_strncmp(realURL, kResourceURIPrefix, sizeof(kResourceURIPrefix) - 1) != 0)) {
|
|
|
|
mIsWritable = PR_FALSE;
|
|
|
|
}
|
|
|
|
|
1999-06-24 00:22:58 +00:00
|
|
|
// XXX Keep a 'cached' copy of the URL; opening it may cause the
|
|
|
|
// spec to be re-written.
|
|
|
|
if (mURLSpec)
|
|
|
|
PL_strfree(mURLSpec);
|
|
|
|
|
|
|
|
mURLSpec = PL_strdup(realURL);
|
1999-06-26 06:36:26 +00:00
|
|
|
#ifdef NECKO
|
|
|
|
nsCRT::free(realURL);
|
|
|
|
#endif
|
1999-01-19 02:42:30 +00:00
|
|
|
|
1999-08-06 20:24:29 +00:00
|
|
|
rv = gRDFService->RegisterDataSource(this, PR_FALSE);
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "somebody already registered this");
|
1999-05-05 03:09:12 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-01-19 02:42:30 +00:00
|
|
|
|
1999-05-05 03:09:12 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-01-19 02:42:30 +00:00
|
|
|
|
|
|
|
|
1999-06-24 00:22:58 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
RDFXMLDataSourceImpl::GetURI(char* *aURI)
|
|
|
|
{
|
|
|
|
*aURI = nsnull;
|
|
|
|
if (mURLSpec) {
|
|
|
|
// XXX We don't use the mURL, because it might get re-written
|
|
|
|
// when it's actually opened.
|
|
|
|
*aURI = nsXPIDLCString::Copy(mURLSpec);
|
|
|
|
if (! *aURI)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-05-05 03:09:12 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
RDFXMLDataSourceImpl::Assert(nsIRDFResource* aSource,
|
|
|
|
nsIRDFResource* aProperty,
|
|
|
|
nsIRDFNode* aTarget,
|
|
|
|
PRBool aTruthValue)
|
|
|
|
{
|
|
|
|
// We don't accept assertions unless we're writable (except in the
|
|
|
|
// case that we're actually _reading_ the datasource in).
|
|
|
|
nsresult rv;
|
1999-01-19 02:42:30 +00:00
|
|
|
|
1999-05-05 03:09:12 +00:00
|
|
|
if (mIsLoading) {
|
|
|
|
PRBool hasAssertion = PR_FALSE;
|
1999-01-19 02:42:30 +00:00
|
|
|
|
1999-05-05 03:09:12 +00:00
|
|
|
nsCOMPtr<nsIRDFPurgeableDataSource> gcable = do_QueryInterface(mInner);
|
|
|
|
if (gcable) {
|
|
|
|
rv = gcable->Mark(aSource, aProperty, aTarget, aTruthValue, &hasAssertion);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
1999-01-19 02:42:30 +00:00
|
|
|
|
1999-05-05 03:09:12 +00:00
|
|
|
rv = NS_RDF_ASSERTION_ACCEPTED;
|
1999-04-27 21:33:36 +00:00
|
|
|
|
1999-05-05 03:09:12 +00:00
|
|
|
if (! hasAssertion) {
|
|
|
|
rv = mInner->Assert(aSource, aProperty, aTarget, aTruthValue);
|
1999-01-19 02:42:30 +00:00
|
|
|
|
1999-05-05 03:09:12 +00:00
|
|
|
if (NS_SUCCEEDED(rv) && gcable) {
|
|
|
|
// Now mark the new assertion, so it doesn't get
|
|
|
|
// removed when we sweep. Ignore rv, because we want
|
|
|
|
// to return what mInner->Assert() gave us.
|
|
|
|
PRBool didMark;
|
|
|
|
(void) gcable->Mark(aSource, aProperty, aTarget, aTruthValue, &didMark);
|
|
|
|
}
|
1999-01-19 02:42:30 +00:00
|
|
|
|
1999-05-05 03:09:12 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
1999-01-19 02:42:30 +00:00
|
|
|
|
1999-05-05 03:09:12 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
else if (mIsWritable) {
|
|
|
|
rv = mInner->Assert(aSource, aProperty, aTarget, aTruthValue);
|
1999-01-19 02:42:30 +00:00
|
|
|
|
1999-05-05 03:09:12 +00:00
|
|
|
if (rv == NS_RDF_ASSERTION_ACCEPTED)
|
|
|
|
mIsDirty = PR_TRUE;
|
1999-01-19 02:42:30 +00:00
|
|
|
|
1999-05-05 03:09:12 +00:00
|
|
|
return rv;
|
1999-01-19 02:42:30 +00:00
|
|
|
}
|
|
|
|
else {
|
1999-04-07 06:29:41 +00:00
|
|
|
return NS_RDF_ASSERTION_REJECTED;
|
1999-01-19 02:42:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-05-05 03:09:12 +00:00
|
|
|
RDFXMLDataSourceImpl::Unassert(nsIRDFResource* source,
|
|
|
|
nsIRDFResource* property,
|
1999-01-19 02:42:30 +00:00
|
|
|
nsIRDFNode* target)
|
|
|
|
{
|
1999-04-07 06:29:41 +00:00
|
|
|
// We don't accept assertions unless we're writable (except in the
|
|
|
|
// case that we're actually _reading_ the datasource in).
|
1999-01-20 19:56:34 +00:00
|
|
|
if (!mIsLoading && !mIsWritable)
|
1999-04-07 06:29:41 +00:00
|
|
|
return NS_RDF_ASSERTION_REJECTED;
|
1999-01-19 02:42:30 +00:00
|
|
|
|
|
|
|
nsresult rv;
|
|
|
|
if (NS_SUCCEEDED(rv = mInner->Unassert(source, property, target))) {
|
|
|
|
if (!mIsLoading)
|
|
|
|
mIsDirty = PR_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1999-06-24 00:22:58 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
RDFXMLDataSourceImpl::Change(nsIRDFResource* aSource,
|
|
|
|
nsIRDFResource* aProperty,
|
|
|
|
nsIRDFNode* aOldTarget,
|
|
|
|
nsIRDFNode* aNewTarget)
|
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
if (mIsLoading) {
|
|
|
|
NS_NOTYETIMPLEMENTED("hmm, why is this being called?");
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
else if (mIsWritable) {
|
|
|
|
rv = mInner->Change(aSource, aProperty, aOldTarget, aNewTarget);
|
|
|
|
|
|
|
|
if (rv == NS_RDF_ASSERTION_ACCEPTED)
|
|
|
|
mIsDirty = PR_TRUE;
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return NS_RDF_ASSERTION_REJECTED;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
RDFXMLDataSourceImpl::Move(nsIRDFResource* aOldSource,
|
|
|
|
nsIRDFResource* aNewSource,
|
|
|
|
nsIRDFResource* aProperty,
|
|
|
|
nsIRDFNode* aTarget)
|
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
if (mIsLoading) {
|
|
|
|
NS_NOTYETIMPLEMENTED("hmm, why is this being called?");
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
else if (mIsWritable) {
|
|
|
|
rv = mInner->Move(aOldSource, aNewSource, aProperty, aTarget);
|
|
|
|
if (rv == NS_RDF_ASSERTION_ACCEPTED)
|
|
|
|
mIsDirty = PR_TRUE;
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return NS_RDF_ASSERTION_REJECTED;
|
|
|
|
}
|
|
|
|
}
|
1999-01-19 02:42:30 +00:00
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
RDFXMLDataSourceImpl::Flush(void)
|
|
|
|
{
|
1999-01-20 19:56:34 +00:00
|
|
|
if (!mIsWritable || !mIsDirty)
|
1999-01-19 02:42:30 +00:00
|
|
|
return NS_OK;
|
|
|
|
|
1999-07-03 03:19:28 +00:00
|
|
|
NS_PRECONDITION(mURLSpec != nsnull, "not initialized");
|
|
|
|
if (! mURLSpec)
|
|
|
|
return NS_ERROR_NOT_INITIALIZED;
|
1999-01-19 02:42:30 +00:00
|
|
|
|
1999-07-03 03:19:28 +00:00
|
|
|
nsresult rv;
|
1999-01-19 02:42:30 +00:00
|
|
|
|
1999-07-03 03:19:28 +00:00
|
|
|
// XXX Replace this with channels someday soon...
|
|
|
|
nsFileURL url(mURLSpec);
|
1999-02-25 20:58:10 +00:00
|
|
|
nsFileSpec path(url);
|
1999-01-19 02:42:30 +00:00
|
|
|
|
1999-02-25 20:58:10 +00:00
|
|
|
nsOutputFileStream out(path);
|
|
|
|
if (! out.is_open())
|
|
|
|
return NS_ERROR_FAILURE;
|
1999-01-22 22:04:04 +00:00
|
|
|
|
1999-02-25 20:58:10 +00:00
|
|
|
nsCOMPtr<nsIOutputStream> outIStream = out.GetIStream();
|
|
|
|
if (NS_FAILED(rv = Serialize(outIStream)))
|
1999-01-19 02:42:30 +00:00
|
|
|
goto done;
|
|
|
|
|
|
|
|
mIsDirty = PR_FALSE;
|
|
|
|
|
|
|
|
done:
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
// nsIRDFXMLDataSource methods
|
|
|
|
|
1999-01-20 01:42:13 +00:00
|
|
|
NS_IMETHODIMP
|
1999-05-05 03:09:12 +00:00
|
|
|
RDFXMLDataSourceImpl::GetReadOnly(PRBool* aIsReadOnly)
|
1999-01-20 01:42:13 +00:00
|
|
|
{
|
1999-05-05 03:09:12 +00:00
|
|
|
*aIsReadOnly = !mIsWritable;
|
1999-01-20 01:42:13 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-05-05 03:09:12 +00:00
|
|
|
|
1999-01-20 01:42:13 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
RDFXMLDataSourceImpl::SetReadOnly(PRBool aIsReadOnly)
|
|
|
|
{
|
1999-01-20 19:56:34 +00:00
|
|
|
if (mIsWritable && aIsReadOnly)
|
|
|
|
mIsWritable = PR_FALSE;
|
|
|
|
|
1999-01-20 01:42:13 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-05-05 03:09:12 +00:00
|
|
|
NS_IMETHODIMP
|
1999-06-24 00:22:58 +00:00
|
|
|
RDFXMLDataSourceImpl::Refresh(PRBool aBlocking)
|
1999-05-05 03:09:12 +00:00
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsINameSpaceManager> nsmgr;
|
|
|
|
rv = nsComponentManager::CreateInstance(kNameSpaceManagerCID,
|
|
|
|
nsnull,
|
|
|
|
kINameSpaceManagerIID,
|
|
|
|
getter_AddRefs(nsmgr));
|
|
|
|
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIRDFContentSink> sink;
|
|
|
|
rv = nsComponentManager::CreateInstance(kRDFContentSinkCID,
|
|
|
|
nsnull,
|
1999-06-24 00:22:58 +00:00
|
|
|
nsIRDFContentSink::GetIID(),
|
1999-05-05 03:09:12 +00:00
|
|
|
getter_AddRefs(sink));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
rv = sink->Init(mURL, nsmgr);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
// We set the content sink's data source directly to our in-memory
|
|
|
|
// store. This allows the initial content to be generated "directly".
|
|
|
|
rv = sink->SetDataSource(this);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIParser> parser;
|
|
|
|
rv = nsComponentManager::CreateInstance(kParserCID,
|
|
|
|
nsnull,
|
|
|
|
kIParserIID,
|
|
|
|
getter_AddRefs(parser));
|
1999-08-10 05:35:09 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-05-05 03:09:12 +00:00
|
|
|
|
|
|
|
nsAutoString utf8("UTF-8");
|
|
|
|
parser->SetDocumentCharset(utf8, kCharsetFromDocTypeDefault);
|
|
|
|
|
|
|
|
parser->SetContentSink(sink);
|
|
|
|
|
|
|
|
// XXX this should eventually be kRDFDTDCID (oh boy, that's a
|
|
|
|
// pretty identifier). The RDF DTD will be a much more
|
|
|
|
// RDF-resilient parser.
|
|
|
|
nsCOMPtr<nsIDTD> dtd;
|
|
|
|
rv = nsComponentManager::CreateInstance(kWellFormedDTDCID,
|
|
|
|
nsnull,
|
|
|
|
kIDTDIID,
|
|
|
|
getter_AddRefs(dtd));
|
|
|
|
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
parser->RegisterDTD(dtd);
|
|
|
|
|
|
|
|
|
|
|
|
nsCOMPtr<nsIStreamListener> lsnr;
|
|
|
|
rv = parser->QueryInterface(kIStreamListenerIID, getter_AddRefs(lsnr));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
rv = parser->Parse(mURL);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
if (aBlocking) {
|
|
|
|
rv = rdf_BlockingParse(mURL, lsnr);
|
|
|
|
}
|
|
|
|
else {
|
1999-06-26 06:36:26 +00:00
|
|
|
#ifdef NECKO
|
1999-08-26 22:45:55 +00:00
|
|
|
// Null LoadGroup ?
|
|
|
|
rv = NS_OpenURI(lsnr, nsnull, mURL, nsnull);
|
1999-06-26 06:36:26 +00:00
|
|
|
#else
|
1999-05-05 03:09:12 +00:00
|
|
|
rv = NS_OpenURL(mURL, lsnr);
|
1999-06-26 06:36:26 +00:00
|
|
|
#endif
|
1999-05-05 03:09:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1999-01-19 02:42:30 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
RDFXMLDataSourceImpl::BeginLoad(void)
|
|
|
|
{
|
|
|
|
mIsLoading = PR_TRUE;
|
|
|
|
for (PRInt32 i = mObservers.Count() - 1; i >= 0; --i) {
|
1999-06-24 00:22:58 +00:00
|
|
|
nsIRDFXMLSinkObserver* obs = (nsIRDFXMLSinkObserver*) mObservers[i];
|
1999-01-19 02:42:30 +00:00
|
|
|
obs->OnBeginLoad(this);
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
RDFXMLDataSourceImpl::Interrupt(void)
|
|
|
|
{
|
|
|
|
for (PRInt32 i = mObservers.Count() - 1; i >= 0; --i) {
|
1999-06-24 00:22:58 +00:00
|
|
|
nsIRDFXMLSinkObserver* obs = (nsIRDFXMLSinkObserver*) mObservers[i];
|
1999-01-19 02:42:30 +00:00
|
|
|
obs->OnInterrupt(this);
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
RDFXMLDataSourceImpl::Resume(void)
|
|
|
|
{
|
|
|
|
for (PRInt32 i = mObservers.Count() - 1; i >= 0; --i) {
|
1999-06-24 00:22:58 +00:00
|
|
|
nsIRDFXMLSinkObserver* obs = (nsIRDFXMLSinkObserver*) mObservers[i];
|
1999-01-19 02:42:30 +00:00
|
|
|
obs->OnResume(this);
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
RDFXMLDataSourceImpl::EndLoad(void)
|
|
|
|
{
|
1999-01-20 01:42:13 +00:00
|
|
|
mIsLoading = PR_FALSE;
|
1999-05-05 03:09:12 +00:00
|
|
|
nsCOMPtr<nsIRDFPurgeableDataSource> gcable = do_QueryInterface(mInner);
|
|
|
|
if (gcable) {
|
|
|
|
gcable->Sweep();
|
1999-01-19 02:42:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for (PRInt32 i = mObservers.Count() - 1; i >= 0; --i) {
|
1999-06-24 00:22:58 +00:00
|
|
|
nsIRDFXMLSinkObserver* obs = (nsIRDFXMLSinkObserver*) mObservers[i];
|
1999-05-05 03:09:12 +00:00
|
|
|
obs->OnEndLoad(this);
|
1999-01-19 02:42:30 +00:00
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-01-21 22:24:32 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
RDFXMLDataSourceImpl::AddNameSpace(nsIAtom* aPrefix, const nsString& aURI)
|
|
|
|
{
|
|
|
|
NameSpaceMap* entry;
|
|
|
|
|
|
|
|
// ensure that URIs are unique
|
|
|
|
for (entry = mNameSpaces; entry != nsnull; entry = entry->Next) {
|
|
|
|
if (aURI.Equals(entry->URI))
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// okay, it's a new one: let's add it.
|
|
|
|
entry = new NameSpaceMap;
|
|
|
|
if (! entry)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
1999-03-26 04:42:29 +00:00
|
|
|
NS_IF_ADDREF(aPrefix);
|
1999-01-21 22:24:32 +00:00
|
|
|
entry->Prefix = aPrefix;
|
|
|
|
entry->URI = aURI;
|
|
|
|
entry->Next = mNameSpaces;
|
|
|
|
mNameSpaces = entry;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-01-19 02:42:30 +00:00
|
|
|
|
|
|
|
|
1999-02-01 22:34:51 +00:00
|
|
|
NS_IMETHODIMP
|
1999-06-24 00:22:58 +00:00
|
|
|
RDFXMLDataSourceImpl::AddXMLSinkObserver(nsIRDFXMLSinkObserver* aObserver)
|
1999-02-01 22:34:51 +00:00
|
|
|
{
|
|
|
|
mObservers.AppendElement(aObserver);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-06-24 00:22:58 +00:00
|
|
|
RDFXMLDataSourceImpl::RemoveXMLSinkObserver(nsIRDFXMLSinkObserver* aObserver)
|
1999-02-01 22:34:51 +00:00
|
|
|
{
|
|
|
|
mObservers.RemoveElement(aObserver);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
1999-01-19 02:42:30 +00:00
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
// nsIRDFXMLSource methods
|
|
|
|
|
1999-01-21 22:24:32 +00:00
|
|
|
static nsresult
|
|
|
|
rdf_BlockingWrite(nsIOutputStream* stream, const char* buf, PRUint32 size)
|
|
|
|
{
|
|
|
|
PRUint32 written = 0;
|
|
|
|
PRUint32 remaining = size;
|
|
|
|
while (remaining > 0) {
|
|
|
|
nsresult rv;
|
|
|
|
PRUint32 cb;
|
|
|
|
|
1999-03-05 22:53:56 +00:00
|
|
|
if (NS_FAILED(rv = stream->Write(buf + written, remaining, &cb)))
|
1999-01-21 22:24:32 +00:00
|
|
|
return rv;
|
|
|
|
|
|
|
|
written += cb;
|
|
|
|
remaining -= cb;
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static nsresult
|
|
|
|
rdf_BlockingWrite(nsIOutputStream* stream, const nsString& s)
|
|
|
|
{
|
|
|
|
char buf[256];
|
|
|
|
char* p = buf;
|
|
|
|
|
1999-06-24 00:22:58 +00:00
|
|
|
if (s.Length() >= PRInt32(sizeof buf))
|
1999-01-21 22:24:32 +00:00
|
|
|
p = new char[s.Length() + 1];
|
|
|
|
|
|
|
|
nsresult rv = rdf_BlockingWrite(stream, s.ToCString(p, s.Length() + 1), s.Length());
|
|
|
|
|
|
|
|
if (p != buf)
|
|
|
|
delete[](p);
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// This converts a property resource (like
|
|
|
|
// "http://www.w3.org/TR/WD-rdf-syntax#Description") into a property
|
|
|
|
// ("Description"), a namespace prefix ("RDF"), and a namespace URI
|
|
|
|
// ("http://www.w3.org/TR/WD-rdf-syntax#").
|
|
|
|
|
|
|
|
PRBool
|
|
|
|
RDFXMLDataSourceImpl::MakeQName(nsIRDFResource* resource,
|
|
|
|
nsString& property,
|
|
|
|
nsString& nameSpacePrefix,
|
|
|
|
nsString& nameSpaceURI)
|
|
|
|
{
|
1999-03-29 19:52:54 +00:00
|
|
|
nsXPIDLCString s;
|
|
|
|
resource->GetValue(getter_Copies(s));
|
|
|
|
nsAutoString uri((const char*) s);
|
1999-01-21 22:24:32 +00:00
|
|
|
|
|
|
|
for (NameSpaceMap* entry = mNameSpaces; entry != nsnull; entry = entry->Next) {
|
|
|
|
if (uri.Find(entry->URI) == 0) {
|
|
|
|
nameSpaceURI = entry->URI;
|
1999-03-26 04:42:29 +00:00
|
|
|
if (entry->Prefix) {
|
|
|
|
entry->Prefix->ToString(nameSpacePrefix);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
nameSpacePrefix.Truncate();
|
|
|
|
}
|
1999-01-21 22:24:32 +00:00
|
|
|
uri.Right(property, uri.Length() - nameSpaceURI.Length());
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Okay, so we don't have it in our map. Try to make one up.
|
1999-07-19 03:29:56 +00:00
|
|
|
PRInt32 i = uri.RFindChar('#'); // first try a '#'
|
1999-06-24 00:22:58 +00:00
|
|
|
if (i == -1) {
|
1999-07-19 03:29:56 +00:00
|
|
|
i = uri.RFindChar('/');
|
1999-06-24 00:22:58 +00:00
|
|
|
if (i == -1) {
|
1999-01-21 22:24:32 +00:00
|
|
|
// Okay, just punt and assume there is _no_ namespace on
|
|
|
|
// this thing...
|
1999-04-16 08:36:56 +00:00
|
|
|
//NS_ASSERTION(PR_FALSE, "couldn't find reasonable namespace prefix");
|
1999-01-21 22:24:32 +00:00
|
|
|
nameSpaceURI.Truncate();
|
|
|
|
nameSpacePrefix.Truncate();
|
|
|
|
property = uri;
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Take whatever is to the right of the '#' and call it the
|
|
|
|
// property.
|
|
|
|
property.Truncate();
|
1999-07-06 23:36:44 +00:00
|
|
|
uri.Right(property, uri.Length() - (i + 1));
|
1999-01-21 22:24:32 +00:00
|
|
|
|
|
|
|
// Truncate the namespace URI down to the string up to and
|
|
|
|
// including the '#'.
|
|
|
|
nameSpaceURI = uri;
|
1999-06-24 00:22:58 +00:00
|
|
|
nameSpaceURI.Truncate(i + 1);
|
1999-01-21 22:24:32 +00:00
|
|
|
|
|
|
|
// Just generate a random prefix
|
|
|
|
static PRInt32 gPrefixID = 0;
|
|
|
|
nameSpacePrefix = "NS";
|
|
|
|
nameSpacePrefix.Append(++gPrefixID, 10);
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
|
1999-06-09 08:29:51 +00:00
|
|
|
|
|
|
|
PRBool
|
|
|
|
RDFXMLDataSourceImpl::IsContainerProperty(nsIRDFResource* aProperty)
|
|
|
|
{
|
|
|
|
// Return `true' if the property is an internal property related
|
|
|
|
// to being a container.
|
|
|
|
if (aProperty == kRDF_instanceOf)
|
|
|
|
return PR_TRUE;
|
|
|
|
|
|
|
|
if (aProperty == kRDF_nextVal)
|
|
|
|
return PR_TRUE;
|
|
|
|
|
|
|
|
PRBool isOrdinal = PR_FALSE;
|
|
|
|
gRDFC->IsOrdinalProperty(aProperty, &isOrdinal);
|
|
|
|
if (isOrdinal)
|
|
|
|
return PR_TRUE;
|
|
|
|
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-01-21 22:24:32 +00:00
|
|
|
// convert '<' and '>' into '<' and '>', respectively.
|
|
|
|
static void
|
|
|
|
rdf_EscapeAngleBrackets(nsString& s)
|
|
|
|
{
|
1999-06-24 00:22:58 +00:00
|
|
|
PRInt32 i;
|
1999-07-26 00:47:36 +00:00
|
|
|
while ((i = s.FindChar('<')) != -1) {
|
1999-06-24 00:22:58 +00:00
|
|
|
s.SetCharAt('&', i);
|
|
|
|
s.Insert(nsAutoString("lt;"), i + 1);
|
1999-01-21 22:24:32 +00:00
|
|
|
}
|
|
|
|
|
1999-07-26 00:47:36 +00:00
|
|
|
while ((i = s.FindChar('>')) != -1) {
|
1999-06-24 00:22:58 +00:00
|
|
|
s.SetCharAt('&', i);
|
|
|
|
s.Insert(nsAutoString("gt;"), i + 1);
|
1999-01-21 22:24:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
rdf_EscapeAmpersands(nsString& s)
|
|
|
|
{
|
1999-06-24 00:22:58 +00:00
|
|
|
PRInt32 i = 0;
|
1999-07-26 00:47:36 +00:00
|
|
|
while ((i = s.FindChar('&', PR_FALSE,i)) != -1) {
|
1999-06-24 00:22:58 +00:00
|
|
|
s.SetCharAt('&', i);
|
|
|
|
s.Insert(nsAutoString("amp;"), i + 1);
|
|
|
|
i += 4;
|
1999-01-21 22:24:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
RDFXMLDataSourceImpl::SerializeAssertion(nsIOutputStream* aStream,
|
|
|
|
nsIRDFResource* aResource,
|
|
|
|
nsIRDFResource* aProperty,
|
|
|
|
nsIRDFNode* aValue)
|
|
|
|
{
|
|
|
|
nsAutoString property, nameSpacePrefix, nameSpaceURI;
|
|
|
|
nsAutoString tag;
|
|
|
|
|
|
|
|
PRBool wasDefinedAtGlobalScope =
|
|
|
|
MakeQName(aProperty, property, nameSpacePrefix, nameSpaceURI);
|
|
|
|
|
|
|
|
if (nameSpacePrefix.Length()) {
|
|
|
|
tag.Append(nameSpacePrefix);
|
|
|
|
tag.Append(':');
|
|
|
|
}
|
|
|
|
tag.Append(property);
|
|
|
|
|
|
|
|
rdf_BlockingWrite(aStream, " <", 5);
|
|
|
|
rdf_BlockingWrite(aStream, tag);
|
|
|
|
|
|
|
|
if (!wasDefinedAtGlobalScope && nameSpacePrefix.Length()) {
|
|
|
|
rdf_BlockingWrite(aStream, " xmlns:", 7);
|
|
|
|
rdf_BlockingWrite(aStream, nameSpacePrefix);
|
|
|
|
rdf_BlockingWrite(aStream, "=\"", 2);
|
|
|
|
rdf_BlockingWrite(aStream, nameSpaceURI);
|
|
|
|
rdf_BlockingWrite(aStream, "\"", 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
nsIRDFResource* resource;
|
|
|
|
nsIRDFLiteral* literal;
|
|
|
|
|
1999-06-24 00:22:58 +00:00
|
|
|
if (NS_SUCCEEDED(aValue->QueryInterface(nsIRDFResource::GetIID(), (void**) &resource))) {
|
1999-03-29 19:52:54 +00:00
|
|
|
nsXPIDLCString s;
|
|
|
|
resource->GetValue(getter_Copies(s));
|
1999-01-21 22:24:32 +00:00
|
|
|
|
1999-03-29 19:52:54 +00:00
|
|
|
nsXPIDLCString docURI;
|
1999-01-22 06:48:25 +00:00
|
|
|
|
1999-01-26 01:24:34 +00:00
|
|
|
nsAutoString uri(s);
|
1999-07-06 23:36:44 +00:00
|
|
|
rdf_MakeRelativeRef(mURLSpec, uri);
|
1999-01-26 01:24:34 +00:00
|
|
|
rdf_EscapeAmpersands(uri);
|
|
|
|
|
1999-04-21 00:09:41 +00:00
|
|
|
static const char kRDFResource1[] = " resource=\"";
|
1999-01-26 01:24:34 +00:00
|
|
|
static const char kRDFResource2[] = "\"/>\n";
|
|
|
|
rdf_BlockingWrite(aStream, kRDFResource1, sizeof(kRDFResource1) - 1);
|
|
|
|
rdf_BlockingWrite(aStream, uri);
|
|
|
|
rdf_BlockingWrite(aStream, kRDFResource2, sizeof(kRDFResource2) - 1);
|
1999-01-22 06:48:25 +00:00
|
|
|
|
1999-01-21 22:24:32 +00:00
|
|
|
NS_RELEASE(resource);
|
|
|
|
}
|
1999-06-24 00:22:58 +00:00
|
|
|
else if (NS_SUCCEEDED(aValue->QueryInterface(nsIRDFLiteral::GetIID(), (void**) &literal))) {
|
1999-03-29 19:52:54 +00:00
|
|
|
nsXPIDLString value;
|
|
|
|
literal->GetValue(getter_Copies(value));
|
|
|
|
nsAutoString s((const PRUnichar*) value);
|
1999-01-21 22:24:32 +00:00
|
|
|
|
|
|
|
rdf_EscapeAmpersands(s); // do these first!
|
|
|
|
rdf_EscapeAngleBrackets(s);
|
|
|
|
|
1999-01-22 06:48:25 +00:00
|
|
|
rdf_BlockingWrite(aStream, ">", 1);
|
1999-01-21 22:24:32 +00:00
|
|
|
rdf_BlockingWrite(aStream, s);
|
1999-01-22 06:48:25 +00:00
|
|
|
rdf_BlockingWrite(aStream, "</", 2);
|
|
|
|
rdf_BlockingWrite(aStream, tag);
|
|
|
|
rdf_BlockingWrite(aStream, ">\n", 2);
|
1999-01-21 22:24:32 +00:00
|
|
|
|
|
|
|
NS_RELEASE(literal);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// XXX it doesn't support nsIRDFResource _or_ nsIRDFLiteral???
|
|
|
|
NS_ASSERTION(PR_FALSE, "huh?");
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
RDFXMLDataSourceImpl::SerializeProperty(nsIOutputStream* aStream,
|
|
|
|
nsIRDFResource* aResource,
|
|
|
|
nsIRDFResource* aProperty)
|
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
|
1999-04-24 02:41:02 +00:00
|
|
|
nsCOMPtr<nsISimpleEnumerator> assertions;
|
1999-03-30 02:30:16 +00:00
|
|
|
if (NS_FAILED(rv = mInner->GetTargets(aResource, aProperty, PR_TRUE, getter_AddRefs(assertions))))
|
1999-01-21 22:24:32 +00:00
|
|
|
return rv;
|
|
|
|
|
1999-03-30 02:30:16 +00:00
|
|
|
while (1) {
|
1999-04-24 02:41:02 +00:00
|
|
|
PRBool hasMore;
|
|
|
|
rv = assertions->HasMoreElements(&hasMore);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-03-30 02:30:16 +00:00
|
|
|
|
1999-04-24 02:41:02 +00:00
|
|
|
if (! hasMore)
|
1999-03-30 02:30:16 +00:00
|
|
|
break;
|
|
|
|
|
1999-01-21 22:24:32 +00:00
|
|
|
nsIRDFNode* value;
|
1999-04-24 02:41:02 +00:00
|
|
|
rv = assertions->GetNext((nsISupports**) &value);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-01-21 22:24:32 +00:00
|
|
|
|
|
|
|
rv = SerializeAssertion(aStream, aResource, aProperty, value);
|
|
|
|
NS_RELEASE(value);
|
|
|
|
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
1999-03-30 02:30:16 +00:00
|
|
|
return NS_OK;
|
1999-01-21 22:24:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
RDFXMLDataSourceImpl::SerializeDescription(nsIOutputStream* aStream,
|
|
|
|
nsIRDFResource* aResource)
|
|
|
|
{
|
1999-04-21 00:09:41 +00:00
|
|
|
static const char kRDFDescription1[] = " <RDF:Description about=\"";
|
1999-01-21 22:24:32 +00:00
|
|
|
static const char kRDFDescription2[] = "\">\n";
|
|
|
|
static const char kRDFDescription3[] = " </RDF:Description>\n";
|
|
|
|
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
// XXX Look for an "RDF:type" property: if one exists, then output
|
|
|
|
// as a "typed node" instead of the more verbose "RDF:Description
|
1999-04-21 00:09:41 +00:00
|
|
|
// type='...'".
|
1999-01-21 22:24:32 +00:00
|
|
|
|
1999-03-29 19:52:54 +00:00
|
|
|
nsXPIDLCString s;
|
|
|
|
rv = aResource->GetValue(getter_Copies(s));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-01-21 22:24:32 +00:00
|
|
|
|
1999-01-26 01:24:34 +00:00
|
|
|
nsAutoString uri(s);
|
1999-07-06 23:36:44 +00:00
|
|
|
rdf_MakeRelativeRef(mURLSpec, uri);
|
1999-01-26 01:24:34 +00:00
|
|
|
rdf_EscapeAmpersands(uri);
|
1999-01-21 22:24:32 +00:00
|
|
|
|
|
|
|
rdf_BlockingWrite(aStream, kRDFDescription1, sizeof(kRDFDescription1) - 1);
|
1999-01-26 01:24:34 +00:00
|
|
|
rdf_BlockingWrite(aStream, uri);
|
1999-01-21 22:24:32 +00:00
|
|
|
rdf_BlockingWrite(aStream, kRDFDescription2, sizeof(kRDFDescription2) - 1);
|
|
|
|
|
1999-04-24 02:41:02 +00:00
|
|
|
nsCOMPtr<nsISimpleEnumerator> arcs;
|
|
|
|
rv = mInner->ArcLabelsOut(aResource, getter_AddRefs(arcs));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-01-21 22:24:32 +00:00
|
|
|
|
1999-03-30 02:30:16 +00:00
|
|
|
while (1) {
|
1999-04-24 02:41:02 +00:00
|
|
|
PRBool hasMore;
|
|
|
|
rv = arcs->HasMoreElements(&hasMore);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-03-30 02:30:16 +00:00
|
|
|
|
1999-04-24 02:41:02 +00:00
|
|
|
if (! hasMore)
|
1999-03-30 02:30:16 +00:00
|
|
|
break;
|
|
|
|
|
1999-01-21 22:24:32 +00:00
|
|
|
nsIRDFResource* property;
|
1999-04-24 02:41:02 +00:00
|
|
|
rv = arcs->GetNext((nsISupports**) &property);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-01-21 22:24:32 +00:00
|
|
|
|
1999-06-09 08:29:51 +00:00
|
|
|
if (! IsContainerProperty(property)) {
|
|
|
|
// Ignore properties that pertain to containers; we may be
|
|
|
|
// called from SerializeContainer() if the container
|
|
|
|
// resource has been assigned non-container properties.
|
|
|
|
rv = SerializeProperty(aStream, aResource, property);
|
|
|
|
}
|
|
|
|
|
1999-01-21 22:24:32 +00:00
|
|
|
NS_RELEASE(property);
|
|
|
|
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
rdf_BlockingWrite(aStream, kRDFDescription3, sizeof(kRDFDescription3) - 1);
|
1999-03-30 02:30:16 +00:00
|
|
|
return NS_OK;
|
1999-01-21 22:24:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
RDFXMLDataSourceImpl::SerializeMember(nsIOutputStream* aStream,
|
|
|
|
nsIRDFResource* aContainer,
|
1999-06-09 08:29:51 +00:00
|
|
|
nsIRDFNode* aMember)
|
1999-01-21 22:24:32 +00:00
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
|
1999-06-09 08:29:51 +00:00
|
|
|
// If it's a resource, then output a "<RDF:li resource=... />"
|
|
|
|
// tag, because we'll be dumping the resource separately. (We
|
|
|
|
// iterate thru all the resources in the datasource,
|
|
|
|
// remember?) Otherwise, output the literal value.
|
1999-03-30 02:30:16 +00:00
|
|
|
|
1999-06-09 08:29:51 +00:00
|
|
|
nsIRDFResource* resource = nsnull;
|
|
|
|
nsIRDFLiteral* literal = nsnull;
|
1999-03-30 02:30:16 +00:00
|
|
|
|
1999-06-24 00:22:58 +00:00
|
|
|
if (NS_SUCCEEDED(rv = aMember->QueryInterface(nsIRDFResource::GetIID(), (void**) &resource))) {
|
1999-06-09 08:29:51 +00:00
|
|
|
nsXPIDLCString s;
|
|
|
|
if (NS_SUCCEEDED(rv = resource->GetValue( getter_Copies(s) ))) {
|
1999-04-21 00:09:41 +00:00
|
|
|
static const char kRDFLIResource1[] = " <RDF:li resource=\"";
|
1999-01-26 01:24:34 +00:00
|
|
|
static const char kRDFLIResource2[] = "\"/>\n";
|
|
|
|
|
1999-06-09 08:29:51 +00:00
|
|
|
nsAutoString uri(s);
|
1999-07-06 23:36:44 +00:00
|
|
|
rdf_MakeRelativeRef(mURLSpec, uri);
|
1999-06-09 08:29:51 +00:00
|
|
|
rdf_EscapeAmpersands(uri);
|
1999-01-26 01:24:34 +00:00
|
|
|
|
1999-06-09 08:29:51 +00:00
|
|
|
rdf_BlockingWrite(aStream, kRDFLIResource1, sizeof(kRDFLIResource1) - 1);
|
|
|
|
rdf_BlockingWrite(aStream, uri);
|
|
|
|
rdf_BlockingWrite(aStream, kRDFLIResource2, sizeof(kRDFLIResource2) - 1);
|
1999-01-21 22:24:32 +00:00
|
|
|
}
|
1999-06-09 08:29:51 +00:00
|
|
|
NS_RELEASE(resource);
|
|
|
|
}
|
1999-06-24 00:22:58 +00:00
|
|
|
else if (NS_SUCCEEDED(rv = aMember->QueryInterface(nsIRDFLiteral::GetIID(), (void**) &literal))) {
|
1999-06-09 08:29:51 +00:00
|
|
|
nsXPIDLString value;
|
|
|
|
if (NS_SUCCEEDED(rv = literal->GetValue( getter_Copies(value) ))) {
|
1999-01-26 01:24:34 +00:00
|
|
|
static const char kRDFLILiteral1[] = " <RDF:li>";
|
|
|
|
static const char kRDFLILiteral2[] = "</RDF:li>\n";
|
1999-01-21 22:24:32 +00:00
|
|
|
|
1999-06-09 08:29:51 +00:00
|
|
|
rdf_BlockingWrite(aStream, kRDFLILiteral1, sizeof(kRDFLILiteral1) - 1);
|
|
|
|
rdf_BlockingWrite(aStream, (const PRUnichar*) value);
|
|
|
|
rdf_BlockingWrite(aStream, kRDFLILiteral2, sizeof(kRDFLILiteral2) - 1);
|
|
|
|
}
|
|
|
|
NS_RELEASE(literal);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
NS_ASSERTION(PR_FALSE, "uhh -- it's not a literal or a resource?");
|
1999-01-21 22:24:32 +00:00
|
|
|
}
|
1999-03-30 02:30:16 +00:00
|
|
|
return NS_OK;
|
1999-01-21 22:24:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
RDFXMLDataSourceImpl::SerializeContainer(nsIOutputStream* aStream,
|
|
|
|
nsIRDFResource* aContainer)
|
|
|
|
{
|
1999-01-22 06:48:25 +00:00
|
|
|
static const char kRDFBag[] = "RDF:Bag";
|
|
|
|
static const char kRDFSeq[] = "RDF:Seq";
|
|
|
|
static const char kRDFAlt[] = "RDF:Alt";
|
1999-01-21 22:24:32 +00:00
|
|
|
|
|
|
|
nsresult rv;
|
1999-01-22 06:48:25 +00:00
|
|
|
const char* tag;
|
|
|
|
|
|
|
|
// Decide if it's a sequence, bag, or alternation, and print the
|
|
|
|
// appropriate tag-open sequence
|
|
|
|
|
1999-04-27 05:54:18 +00:00
|
|
|
if (rdf_IsA(mInner, aContainer, kRDF_Bag)) {
|
1999-01-22 06:48:25 +00:00
|
|
|
tag = kRDFBag;
|
|
|
|
}
|
1999-04-27 05:54:18 +00:00
|
|
|
else if (rdf_IsA(mInner, aContainer, kRDF_Seq)) {
|
1999-01-22 06:48:25 +00:00
|
|
|
tag = kRDFSeq;
|
|
|
|
}
|
1999-04-27 05:54:18 +00:00
|
|
|
else if (rdf_IsA(mInner, aContainer, kRDF_Alt)) {
|
1999-01-22 06:48:25 +00:00
|
|
|
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);
|
1999-01-21 22:24:32 +00:00
|
|
|
|
|
|
|
|
1999-01-22 06:48:25 +00:00
|
|
|
// 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...
|
|
|
|
|
1999-03-29 19:52:54 +00:00
|
|
|
nsXPIDLCString s;
|
|
|
|
if (NS_SUCCEEDED(aContainer->GetValue( getter_Copies(s) ))) {
|
1999-01-22 06:48:25 +00:00
|
|
|
nsAutoString uri(s);
|
1999-07-06 23:36:44 +00:00
|
|
|
rdf_MakeRelativeRef(mURLSpec, uri);
|
1999-06-20 00:19:23 +00:00
|
|
|
|
1999-01-26 01:24:34 +00:00
|
|
|
rdf_EscapeAmpersands(uri);
|
1999-06-20 00:19:23 +00:00
|
|
|
|
|
|
|
if (uri.First() == PRUnichar('#')) {
|
|
|
|
// Okay, it's actually identified as an element in the
|
|
|
|
// current document, not trying to decorate some absolute
|
|
|
|
// URI. We can use the 'ID=' attribute...
|
|
|
|
static const char kIDEquals[] = " ID=\"";
|
|
|
|
|
|
|
|
uri.Cut(0, 1); // chop the '#'
|
|
|
|
rdf_BlockingWrite(aStream, kIDEquals, sizeof(kIDEquals) - 1);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// We need to cheat and spit out an illegal 'about=' on
|
|
|
|
// the sequence.
|
|
|
|
static const char kAboutEquals[] = " about=\"";
|
|
|
|
rdf_BlockingWrite(aStream, kAboutEquals, sizeof(kAboutEquals) - 1);
|
|
|
|
}
|
|
|
|
|
1999-01-22 06:48:25 +00:00
|
|
|
rdf_BlockingWrite(aStream, uri);
|
|
|
|
rdf_BlockingWrite(aStream, "\"", 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
rdf_BlockingWrite(aStream, ">\n", 2);
|
|
|
|
|
1999-06-09 08:29:51 +00:00
|
|
|
// First iterate through each of the ordinal elements (the RDF/XML
|
|
|
|
// syntax doesn't allow us to place properties on RDF container
|
|
|
|
// elements).
|
|
|
|
nsCOMPtr<nsISimpleEnumerator> elements;
|
|
|
|
rv = NS_NewContainerEnumerator(mInner, aContainer, getter_AddRefs(elements));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
PRBool hasMore;
|
|
|
|
rv = elements->HasMoreElements(&hasMore);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
if (! hasMore)
|
|
|
|
break;
|
|
|
|
|
|
|
|
nsCOMPtr<nsISupports> isupports;
|
|
|
|
rv = elements->GetNext(getter_AddRefs(isupports));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIRDFNode> element = do_QueryInterface(isupports);
|
|
|
|
NS_ASSERTION(element != nsnull, "not an nsIRDFNode");
|
|
|
|
if (! element)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
rv = SerializeMember(aStream, aContainer, element);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// close the container tag
|
|
|
|
rdf_BlockingWrite(aStream, " </", 4);
|
|
|
|
rdf_BlockingWrite(aStream, tag);
|
|
|
|
rdf_BlockingWrite(aStream, ">\n", 2);
|
1999-01-21 22:24:32 +00:00
|
|
|
|
1999-01-22 06:48:25 +00:00
|
|
|
|
1999-06-09 08:29:51 +00:00
|
|
|
// Now, we iterate through _all_ of the arcs, in case someone has
|
|
|
|
// applied properties to the bag itself. These'll be placed in a
|
|
|
|
// separate RDF:Description element.
|
1999-04-24 02:41:02 +00:00
|
|
|
nsCOMPtr<nsISimpleEnumerator> arcs;
|
|
|
|
rv = mInner->ArcLabelsOut(aContainer, getter_AddRefs(arcs));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-01-21 22:24:32 +00:00
|
|
|
|
1999-06-09 08:29:51 +00:00
|
|
|
PRBool wroteDescription = PR_FALSE;
|
|
|
|
while (! wroteDescription) {
|
1999-04-24 02:41:02 +00:00
|
|
|
PRBool hasMore;
|
|
|
|
rv = arcs->HasMoreElements(&hasMore);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-03-30 02:30:16 +00:00
|
|
|
|
1999-04-24 02:41:02 +00:00
|
|
|
if (! hasMore)
|
1999-03-30 02:30:16 +00:00
|
|
|
break;
|
|
|
|
|
1999-01-21 22:24:32 +00:00
|
|
|
nsIRDFResource* property;
|
1999-04-24 02:41:02 +00:00
|
|
|
rv = arcs->GetNext((nsISupports**) &property);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-01-21 22:24:32 +00:00
|
|
|
|
|
|
|
// If it's a membership property, then output a "LI"
|
|
|
|
// tag. Otherwise, output a property.
|
1999-06-09 08:29:51 +00:00
|
|
|
if (! IsContainerProperty(property)) {
|
|
|
|
rv = SerializeDescription(aStream, aContainer);
|
|
|
|
wroteDescription = PR_TRUE;
|
1999-01-22 06:48:25 +00:00
|
|
|
}
|
1999-01-21 22:24:32 +00:00
|
|
|
|
|
|
|
NS_RELEASE(property);
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
1999-03-30 02:30:16 +00:00
|
|
|
return NS_OK;
|
1999-01-21 22:24:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
RDFXMLDataSourceImpl::SerializePrologue(nsIOutputStream* aStream)
|
|
|
|
{
|
|
|
|
static const char kXMLVersion[] = "<?xml version=\"1.0\"?>\n";
|
|
|
|
static const char kOpenRDF[] = "<RDF:RDF";
|
1999-04-01 05:17:05 +00:00
|
|
|
static const char kXMLNS[] = "\n xmlns";
|
1999-01-21 22:24:32 +00:00
|
|
|
|
|
|
|
rdf_BlockingWrite(aStream, kXMLVersion, sizeof(kXMLVersion) - 1);
|
|
|
|
|
|
|
|
// global name space declarations
|
|
|
|
rdf_BlockingWrite(aStream, kOpenRDF, sizeof(kOpenRDF) - 1);
|
|
|
|
for (NameSpaceMap* entry = mNameSpaces; entry != nsnull; entry = entry->Next) {
|
|
|
|
rdf_BlockingWrite(aStream, kXMLNS, sizeof(kXMLNS) - 1);
|
|
|
|
|
1999-04-01 05:17:05 +00:00
|
|
|
if (entry->Prefix) {
|
|
|
|
rdf_BlockingWrite(aStream, ":", 1);
|
|
|
|
nsAutoString prefix;
|
|
|
|
entry->Prefix->ToString(prefix);
|
|
|
|
rdf_BlockingWrite(aStream, prefix);
|
|
|
|
}
|
1999-01-21 22:24:32 +00:00
|
|
|
|
|
|
|
rdf_BlockingWrite(aStream, "=\"", 2);
|
|
|
|
rdf_BlockingWrite(aStream, entry->URI);
|
|
|
|
rdf_BlockingWrite(aStream, "\"", 1);
|
|
|
|
}
|
|
|
|
rdf_BlockingWrite(aStream, ">\n", 2);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
RDFXMLDataSourceImpl::SerializeEpilogue(nsIOutputStream* aStream)
|
|
|
|
{
|
|
|
|
static const char kCloseRDF[] = "</RDF:RDF>\n";
|
|
|
|
|
|
|
|
rdf_BlockingWrite(aStream, kCloseRDF);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-01-19 02:42:30 +00:00
|
|
|
NS_IMETHODIMP
|
1999-01-21 22:24:32 +00:00
|
|
|
RDFXMLDataSourceImpl::Serialize(nsIOutputStream* aStream)
|
1999-01-19 02:42:30 +00:00
|
|
|
{
|
|
|
|
nsresult rv;
|
1999-04-24 02:41:02 +00:00
|
|
|
nsCOMPtr<nsISimpleEnumerator> resources;
|
1999-01-21 22:24:32 +00:00
|
|
|
|
1999-03-30 02:30:16 +00:00
|
|
|
rv = mInner->GetAllResources(getter_AddRefs(resources));
|
1999-04-24 02:41:02 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-01-21 22:24:32 +00:00
|
|
|
|
1999-03-30 02:30:16 +00:00
|
|
|
rv = SerializePrologue(aStream);
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
while (1) {
|
1999-04-24 02:41:02 +00:00
|
|
|
PRBool hasMore;
|
|
|
|
rv = resources->HasMoreElements(&hasMore);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-03-30 02:30:16 +00:00
|
|
|
|
1999-04-24 02:41:02 +00:00
|
|
|
if (! hasMore)
|
1999-03-30 02:30:16 +00:00
|
|
|
break;
|
1999-01-21 22:24:32 +00:00
|
|
|
|
|
|
|
nsIRDFResource* resource;
|
1999-04-24 02:41:02 +00:00
|
|
|
rv = resources->GetNext((nsISupports**) &resource);
|
|
|
|
if (NS_FAILED(rv))
|
1999-01-21 22:24:32 +00:00
|
|
|
break;
|
|
|
|
|
1999-04-27 05:54:18 +00:00
|
|
|
if (rdf_IsA(mInner, resource, kRDF_Bag) ||
|
|
|
|
rdf_IsA(mInner, resource, kRDF_Seq) ||
|
|
|
|
rdf_IsA(mInner, resource, kRDF_Alt)) {
|
1999-01-21 22:24:32 +00:00
|
|
|
rv = SerializeContainer(aStream, resource);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
rv = SerializeDescription(aStream, resource);
|
|
|
|
}
|
|
|
|
NS_RELEASE(resource);
|
|
|
|
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
break;
|
1999-01-19 02:42:30 +00:00
|
|
|
}
|
1999-01-21 22:24:32 +00:00
|
|
|
|
|
|
|
rv = SerializeEpilogue(aStream);
|
1999-01-19 02:42:30 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1999-01-21 22:24:32 +00:00
|
|
|
|