зеркало из https://github.com/mozilla/pjs.git
Move APIs to create 'anonymous' resources into the RDF service. Fix stuff that was using it.
This commit is contained in:
Родитель
943ad089f9
Коммит
52918f3ff4
|
@ -38,6 +38,8 @@ interface nsIRDFService : nsISupports {
|
|||
// be converted to a single-byte representation internally.
|
||||
nsIRDFResource GetUnicodeResource(in wstring aURI);
|
||||
|
||||
nsIRDFResource GetAnonymousResource();
|
||||
|
||||
// Construct an RDF literal from a Unicode string.
|
||||
nsIRDFLiteral GetLiteral(in wstring aValue);
|
||||
|
||||
|
@ -47,6 +49,8 @@ interface nsIRDFService : nsISupports {
|
|||
// Construct an RDF literal from an int.
|
||||
nsIRDFInt GetIntLiteral(in long aValue);
|
||||
|
||||
boolean IsAnonymousResource(in nsIRDFResource aResource);
|
||||
|
||||
// Registers a resource with the RDF system, making it unique w.r.t.
|
||||
// GetResource.
|
||||
//
|
||||
|
|
|
@ -1031,7 +1031,7 @@ RDFContentSinkImpl::GetIdAboutAttribute(const nsIParserNode& aNode,
|
|||
}
|
||||
|
||||
// Otherwise, we couldn't find anything, so just gensym one...
|
||||
rv = rdf_CreateAnonymousResource(nsCAutoString(docURI), aResource);
|
||||
rv = gRDFService->GetAnonymousResource(aResource);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
|
@ -622,6 +622,69 @@ ServiceImpl::GetUnicodeResource(const PRUnichar* aURI, nsIRDFResource** aResourc
|
|||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
ServiceImpl::GetAnonymousResource(nsIRDFResource** aResult)
|
||||
{
|
||||
static PRUint32 gCounter = 0;
|
||||
static char gChars[] = "0123456789abcdef"
|
||||
"ghijklmnopqrstuv"
|
||||
"wxyzABCDEFGHIJKL"
|
||||
"MNOPQRSTUVWXYZ.+";
|
||||
|
||||
static PRInt32 kMask = 0x003f;
|
||||
static PRInt32 kShift = 6;
|
||||
|
||||
if (! gCounter) {
|
||||
// Start it at a semi-unique value, just to minimize the
|
||||
// chance that we get into a situation where
|
||||
//
|
||||
// 1. An anonymous resource gets serialized out in a graph
|
||||
// 2. Reboot
|
||||
// 3. The same anonymous resource gets requested, and refers
|
||||
// to something completely different.
|
||||
// 4. The serialization is read back in.
|
||||
LL_L2UI(gCounter, PR_Now());
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
nsCAutoString s;
|
||||
|
||||
do {
|
||||
// Ugh, this is a really sloppy way to do this; I copied the
|
||||
// implementation from the days when it lived outside the RDF
|
||||
// service. Now that it's a member we can be more cleverer.
|
||||
|
||||
s.Truncate();
|
||||
s.Append("rdf:#$");
|
||||
|
||||
PRUint32 id = ++gCounter;
|
||||
while (id) {
|
||||
char ch = gChars[(id & kMask)];
|
||||
s.Append(ch);
|
||||
id >>= kShift;
|
||||
}
|
||||
|
||||
nsIRDFResource* resource;
|
||||
rv = GetResource((const char*) s, &resource);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// XXX an ugly but effective way to make sure that this
|
||||
// resource is really unique in the world.
|
||||
resource->AddRef();
|
||||
nsrefcnt refcnt = resource->Release();
|
||||
|
||||
if (refcnt == 1) {
|
||||
*aResult = resource;
|
||||
break;
|
||||
}
|
||||
|
||||
NS_RELEASE(resource);
|
||||
} while (1);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
ServiceImpl::GetLiteral(const PRUnichar* aValue, nsIRDFLiteral** aLiteral)
|
||||
{
|
||||
|
@ -679,6 +742,35 @@ ServiceImpl::GetIntLiteral(PRInt32 value, nsIRDFInt** literal)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
ServiceImpl::IsAnonymousResource(nsIRDFResource* aResource, PRBool* _result)
|
||||
{
|
||||
NS_PRECONDITION(aResource != nsnull, "null ptr");
|
||||
if (! aResource)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsresult rv;
|
||||
|
||||
const char* uri;
|
||||
rv = aResource->GetValueConst(&uri);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if ((uri[0] == 'r') &&
|
||||
(uri[1] == 'd') &&
|
||||
(uri[2] == 'f') &&
|
||||
(uri[3] == ':') &&
|
||||
(uri[4] == '#') &&
|
||||
(uri[5] == '$')) {
|
||||
*_result = PR_TRUE;
|
||||
}
|
||||
else {
|
||||
*_result = PR_FALSE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ServiceImpl::RegisterResource(nsIRDFResource* aResource, PRBool replace)
|
||||
{
|
||||
|
|
|
@ -50,100 +50,8 @@ static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
|
|||
#include "prtime.h"
|
||||
#include "rdfutil.h"
|
||||
|
||||
#include "rdf.h"
|
||||
static const char kRDFNameSpaceURI[] = RDF_NAMESPACE_URI;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsresult
|
||||
rdf_CreateAnonymousResource(const nsCString& aContextURI, nsIRDFResource** aResult)
|
||||
{
|
||||
static PRUint32 gCounter = 0;
|
||||
|
||||
if (! gCounter) {
|
||||
// Start it at a semi-unique value, just to minimize the
|
||||
// chance that we get into a situation where
|
||||
//
|
||||
// 1. An anonymous resource gets serialized out in a graph
|
||||
// 2. Reboot
|
||||
// 3. The same anonymous resource gets requested, and refers
|
||||
// to something completely different.
|
||||
// 4. The serialization is read back in.
|
||||
LL_L2UI(gCounter, PR_Now());
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
NS_WITH_SERVICE(nsIRDFService, rdf, kRDFServiceCID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
do {
|
||||
char buf[128];
|
||||
CBufDescriptor desc(buf, PR_TRUE, sizeof(buf));
|
||||
nsCAutoString s(desc);
|
||||
|
||||
s = aContextURI;
|
||||
s.Append("#$");
|
||||
s.Append(++gCounter, 16);
|
||||
|
||||
nsIRDFResource* resource;
|
||||
rv = rdf->GetResource((const char*) s, &resource);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// XXX an ugly but effective way to make sure that this
|
||||
// resource is really unique in the world.
|
||||
resource->AddRef();
|
||||
nsrefcnt refcnt = resource->Release();
|
||||
|
||||
if (refcnt == 1) {
|
||||
*aResult = resource;
|
||||
break;
|
||||
}
|
||||
|
||||
NS_RELEASE(resource);
|
||||
} while (1);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool
|
||||
rdf_IsAnonymousResource(const nsCString& aContextURI, nsIRDFResource* aResource)
|
||||
{
|
||||
nsresult rv;
|
||||
const char* p;
|
||||
rv = aResource->GetValueConst(&p);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get resource URI");
|
||||
if (NS_FAILED(rv))
|
||||
return PR_FALSE;
|
||||
|
||||
{
|
||||
CBufDescriptor desc(NS_CONST_CAST(char*, p), PR_TRUE, -1);
|
||||
nsCAutoString uri(desc);
|
||||
|
||||
if (uri.Find(aContextURI) != 0)
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
{
|
||||
CBufDescriptor desc(NS_CONST_CAST(char*, p + aContextURI.Length()), PR_TRUE, -1);
|
||||
nsCAutoString id(desc);
|
||||
|
||||
if (id.CharAt(0) != '#' || id.CharAt(1) != '$')
|
||||
return PR_FALSE;
|
||||
|
||||
for (PRInt32 i = id.Length() - 1; i >= 1; --i) {
|
||||
if (id.CharAt(i) < '0' || id.CharAt(i) > '9')
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
rdf_MakeRelativeRef(const nsString& aBaseURI, nsString& aURI)
|
||||
{
|
||||
|
|
|
@ -38,25 +38,10 @@
|
|||
|
||||
#include "prtypes.h"
|
||||
|
||||
class nsIRDFResource;
|
||||
class nsCString;
|
||||
class nsString;
|
||||
class nsIURI;
|
||||
|
||||
/**
|
||||
* Construct a new, "anonymous" node; that is, a node with an internal
|
||||
* resource URI.
|
||||
*/
|
||||
nsresult
|
||||
rdf_CreateAnonymousResource(const nsCString& aContextURI, nsIRDFResource** result);
|
||||
|
||||
/**
|
||||
* Determine if a resource is an "anonymous" resource that we've constructed
|
||||
* ourselves.
|
||||
*/
|
||||
PRBool
|
||||
rdf_IsAnonymousResource(const nsCString& aContextURI, nsIRDFResource* aResource);
|
||||
|
||||
nsresult
|
||||
rdf_MakeRelativeRef(const nsString& aBaseURI, nsString& aURI);
|
||||
|
||||
|
|
|
@ -622,7 +622,7 @@ RDFXULBuilderImpl::CreateContents(nsIContent* aElement)
|
|||
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to test contents-generated attribute");
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if ((rv == NS_CONTENT_ATTR_HAS_VALUE) && (attrValue.EqualsIgnoreCase("true")))
|
||||
if ((rv == NS_CONTENT_ATTR_HAS_VALUE) && (attrValue.Equals("true")))
|
||||
return NS_OK;
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
|
@ -902,7 +902,7 @@ RDFXULBuilderImpl::OnAssert(nsIRDFResource* aSource,
|
|||
if (rv == NS_CONTENT_ATTR_NOT_THERE || rv == NS_CONTENT_ATTR_NO_VALUE)
|
||||
continue;
|
||||
|
||||
if (! contentsGenerated.EqualsIgnoreCase("true"))
|
||||
if (! contentsGenerated.Equals("true"))
|
||||
continue;
|
||||
|
||||
// Okay, it's a "live" element, so go ahead and insert the
|
||||
|
@ -1030,7 +1030,7 @@ RDFXULBuilderImpl::OnUnassert(nsIRDFResource* aSource,
|
|||
if (rv == NS_CONTENT_ATTR_NOT_THERE || rv == NS_CONTENT_ATTR_NO_VALUE)
|
||||
continue;
|
||||
|
||||
if (! contentsGenerated.EqualsIgnoreCase("true"))
|
||||
if (! contentsGenerated.Equals("true"))
|
||||
continue;
|
||||
|
||||
// Okay, it's a "live" element, so go ahead and remove the
|
||||
|
@ -1155,7 +1155,7 @@ RDFXULBuilderImpl::OnChange(nsIRDFResource* aSource,
|
|||
if (rv == NS_CONTENT_ATTR_NOT_THERE || rv == NS_CONTENT_ATTR_NO_VALUE)
|
||||
continue;
|
||||
|
||||
if (! contentsGenerated.EqualsIgnoreCase("true"))
|
||||
if (! contentsGenerated.Equals("true"))
|
||||
continue;
|
||||
|
||||
// Okay, it's a "live" element, so go ahead and insert the
|
||||
|
@ -1614,6 +1614,13 @@ RDFXULBuilderImpl::CreateHTMLElement(nsINameSpace* aContainingNameSpace,
|
|||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (aResource) {
|
||||
#ifdef NO_ID_ON_ANONYMOUS_ELEMENTS
|
||||
PRBool isAnonymous;
|
||||
rv = gRDFService->IsAnonymousResource(aResource, &isAnonymous);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (! isAnonymous) {
|
||||
#endif
|
||||
// Set the 'id' attribute
|
||||
nsXPIDLCString uri;
|
||||
rv = aResource->GetValue( getter_Copies(uri) );
|
||||
|
@ -1633,6 +1640,9 @@ RDFXULBuilderImpl::CreateHTMLElement(nsINameSpace* aContainingNameSpace,
|
|||
// got a hacked SetAttribute() method...
|
||||
rv = mDocument->AddElementForResource(aResource, element);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
#ifdef NO_ID_ON_ANONYMOUS_ELEMENTS
|
||||
}
|
||||
#endif
|
||||
|
||||
// Now iterate through all the properties and add them as
|
||||
// attributes on the element. First, create a cursor that'll
|
||||
|
@ -1785,6 +1795,13 @@ RDFXULBuilderImpl::CreateXULElement(nsINameSpace* aContainingNameSpace,
|
|||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (aResource) {
|
||||
#ifdef NO_ID_ON_ANONYMOUS_ELEMENTS
|
||||
PRBool isAnonymous;
|
||||
rv = gRDFService->IsAnonymousResource(aResource, &isAnonymous);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (! isAnonymous) {
|
||||
#endif
|
||||
// Set the element's ID. The XUL document will be listening
|
||||
// for 'id' and 'ref' attribute changes, so we're sure that
|
||||
// this will get properly hashed into the document's
|
||||
|
@ -1805,6 +1822,9 @@ RDFXULBuilderImpl::CreateXULElement(nsINameSpace* aContainingNameSpace,
|
|||
// element to the document's element-to-resource map, so no
|
||||
// need to do it ourselves. N.B. that this is _different_ from
|
||||
// an HTML element...
|
||||
#ifdef NO_ID_ON_ANONYMOUS_ELEMENTS
|
||||
}
|
||||
#endif
|
||||
|
||||
// Now iterate through all the properties and add them as
|
||||
// attributes on the element. First, create a cursor that'll
|
||||
|
|
|
@ -183,6 +183,7 @@ protected:
|
|||
static nsIRDFResource* kRDF_instanceOf;
|
||||
static nsIRDFResource* kXUL_element;
|
||||
static nsIRDFResource* kXUL_tag;
|
||||
static nsIRDFResource* kPosition;
|
||||
|
||||
// Text management
|
||||
nsresult FlushText(PRBool aCreateTextNode=PR_TRUE,
|
||||
|
@ -274,6 +275,7 @@ nsIRDFResource* XULContentSinkImpl::kRDF_child;
|
|||
nsIRDFResource* XULContentSinkImpl::kRDF_instanceOf;
|
||||
nsIRDFResource* XULContentSinkImpl::kXUL_element;
|
||||
nsIRDFResource* XULContentSinkImpl::kXUL_tag;
|
||||
nsIRDFResource* XULContentSinkImpl::kPosition;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -316,6 +318,7 @@ XULContentSinkImpl::XULContentSinkImpl()
|
|||
gRDFService->GetResource(RDF_NAMESPACE_URI "instanceOf", &kRDF_instanceOf);
|
||||
gRDFService->GetResource(XUL_NAMESPACE_URI "#element", &kXUL_element);
|
||||
gRDFService->GetResource(XUL_NAMESPACE_URI "#tag", &kXUL_tag);
|
||||
gRDFService->GetResource("position", &kPosition);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -445,6 +448,7 @@ XULContentSinkImpl::~XULContentSinkImpl()
|
|||
NS_IF_RELEASE(kRDF_instanceOf);
|
||||
NS_IF_RELEASE(kXUL_tag);
|
||||
NS_IF_RELEASE(kXUL_element);
|
||||
NS_IF_RELEASE(kPosition);
|
||||
}
|
||||
|
||||
// Delete all the elements from our overlay array
|
||||
|
@ -1274,7 +1278,7 @@ XULContentSinkImpl::GetXULIDAttribute(const nsIParserNode& aNode,
|
|||
// Otherwise, we couldn't find anything, so just gensym one...
|
||||
nsXPIDLCString url;
|
||||
mDocumentURL->GetSpec(getter_Copies(url));
|
||||
return rdf_CreateAnonymousResource(nsCAutoString(url), aResource);
|
||||
return gRDFService->GetAnonymousResource(aResource);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -1459,14 +1463,8 @@ XULContentSinkImpl::OpenTag(const nsIParserNode& aNode)
|
|||
// Find out if a position is specified. If so, we use that as the arc
|
||||
// label instead of appending the object to the end.
|
||||
// Add the attribute to RDF
|
||||
nsCOMPtr<nsIRDFResource> property;
|
||||
nsAutoString attr("#position");
|
||||
|
||||
rv = gRDFService->GetUnicodeResource(attr.GetUnicode(), getter_AddRefs(property));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCOMPtr<nsIRDFNode> positionValue;
|
||||
rv = mDataSource->GetTarget(rdfResource, property, PR_TRUE, getter_AddRefs(positionValue));
|
||||
rv = mDataSource->GetTarget(rdfResource, kPosition, PR_TRUE, getter_AddRefs(positionValue));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (positionValue) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче