Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Public Attributes | Private Member Functions | Private Attributes | Static Private Attributes | Friends
RDFContainerImpl Class Reference
Inheritance diagram for RDFContainerImpl:
Inheritance graph
[legend]
Collaboration diagram for RDFContainerImpl:
Collaboration graph
[legend]

List of all members.

Public Member Functions

void Init (in nsIRDFDataSource aDataSource, in nsIRDFResource aContainer)
 Initialize the container wrapper to the specified resource using the specified datasource for context.
long GetCount ()
 Return the number of elements in the container.
nsISimpleEnumerator GetElements ()
 Return an enumerator that can be used to enumerate the contents of the container in ascending order.
void AppendElement (in nsIRDFNode aElement)
 Append an element to the container, assigning it the next available ordinal.
void RemoveElement (in nsIRDFNode aElement, in boolean aRenumber)
 Remove the first occurence of the specified element from the container.
void InsertElementAt (in nsIRDFNode aElement, in long aIndex, in boolean aRenumber)
 Insert aElement at the specified index.
nsIRDFNode RemoveElementAt (in long aIndex, in boolean aRenumber)
 Remove the element at the specified index.
long IndexOf (in nsIRDFNode aElement)
 Determine the index of an element in the container.

Public Attributes

readonly attribute nsIRDFDataSource DataSource
readonly attribute nsIRDFResource Resource

Private Member Functions

 RDFContainerImpl ()
virtual ~RDFContainerImpl ()
nsresult Init ()
nsresult Renumber (PRInt32 aStartIndex, PRInt32 aIncrement)
nsresult SetNextValue (PRInt32 aIndex)
nsresult GetNextValue (nsIRDFResource **aResult)

Private Attributes

nsIRDFDataSourcemDataSource
nsIRDFResourcemContainer

Static Private Attributes

static PRInt32 gRefCnt = 0
static nsIRDFServicegRDFService
static nsIRDFContainerUtilsgRDFContainerUtils
static nsIRDFResourcekRDF_nextVal

Friends

nsresult NS_NewRDFContainer (nsIRDFContainer **aResult)

Detailed Description

Definition at line 87 of file nsRDFContainer.cpp.


Constructor & Destructor Documentation

Definition at line 405 of file nsRDFContainer.cpp.

RDFContainerImpl::~RDFContainerImpl ( ) [private, virtual]

Definition at line 438 of file nsRDFContainer.cpp.

{
#ifdef DEBUG_REFS
    --gInstanceCount;
    fprintf(stdout, "%d - RDF: RDFContainerImpl\n", gInstanceCount);
#endif

    NS_IF_RELEASE(mContainer);
    NS_IF_RELEASE(mDataSource);

    if (--gRefCnt == 0) {
        NS_IF_RELEASE(gRDFContainerUtils);
        NS_IF_RELEASE(gRDFService);
        NS_IF_RELEASE(kRDF_nextVal);
    }
}

Here is the call graph for this function:


Member Function Documentation

void nsIRDFContainer::AppendElement ( in nsIRDFNode  aElement) [inherited]

Append an element to the container, assigning it the next available ordinal.

Here is the caller graph for this function:

Return the number of elements in the container.

Note that this may not always be accurate due to aggregation.

Here is the caller graph for this function:

Return an enumerator that can be used to enumerate the contents of the container in ascending order.

Definition at line 688 of file nsRDFContainer.cpp.

{
    if (!mDataSource || !mContainer)
        return NS_ERROR_NOT_INITIALIZED;

    nsresult rv;

    // Get the next value, which hangs off of the bag via the
    // RDF:nextVal property.
    nsCOMPtr<nsIRDFNode> nextValNode;
    rv = mDataSource->GetTarget(mContainer, kRDF_nextVal, PR_TRUE, getter_AddRefs(nextValNode));
    if (NS_FAILED(rv)) return rv;

    if (rv == NS_RDF_NO_VALUE)
        return NS_ERROR_UNEXPECTED;

    nsCOMPtr<nsIRDFLiteral> nextValLiteral;
    rv = nextValNode->QueryInterface(NS_GET_IID(nsIRDFLiteral), getter_AddRefs(nextValLiteral));
    if (NS_FAILED(rv)) return rv;

    const PRUnichar* s;
    rv = nextValLiteral->GetValueConst(&s);
    if (NS_FAILED(rv)) return rv;

    PRInt32 nextVal = 0;
    {
        for (const PRUnichar* p = s; *p != 0; ++p) {
            NS_ASSERTION(*p >= '0' && *p <= '9', "not a digit");
            if (*p < '0' || *p > '9')
                break;

            nextVal *= 10;
            nextVal += *p - '0';
        }
    }

    char buf[sizeof(kRDFNameSpaceURI) + 16];
    nsFixedCString nextValStr(buf, sizeof(buf), 0);
    nextValStr = kRDFNameSpaceURI;
    nextValStr.Append("_");
    nextValStr.AppendInt(nextVal, 10);

    rv = gRDFService->GetResource(nextValStr, aResult);
    if (NS_FAILED(rv)) return rv;

    // Now increment the RDF:nextVal property.
    rv = mDataSource->Unassert(mContainer, kRDF_nextVal, nextValLiteral);
    if (NS_FAILED(rv)) return rv;

    ++nextVal;
    nextValStr.Truncate();
    nextValStr.AppendInt(nextVal, 10);

    rv = gRDFService->GetLiteral(NS_ConvertASCIItoUCS2(nextValStr).get(), getter_AddRefs(nextValLiteral));
    if (NS_FAILED(rv)) return rv;

    rv = mDataSource->Assert(mContainer, kRDF_nextVal, nextValLiteral, PR_TRUE);
    if (NS_FAILED(rv)) return rv;

    if (RDF_SEQ_LIST_LIMIT == nextVal)
    {
        // focal point for RDF container mutation;
        // basically, provide a hint to allow for fast access
        nsCOMPtr<nsIRDFInMemoryDataSource> inMem = do_QueryInterface(mDataSource);
        if (inMem)
        {
            // ignore error; failure just means slower access
            (void)inMem->EnsureFastContainment(mContainer);
        }
    }

    return NS_OK;
}

Here is the call graph for this function:

long nsIRDFContainer::IndexOf ( in nsIRDFNode  aElement) [inherited]

Determine the index of an element in the container.

Returns:
The index of the specified element in the container. If the element is not contained in the container, this function returns '-1'.
void nsIRDFContainer::Init ( in nsIRDFDataSource  aDataSource,
in nsIRDFResource  aContainer 
) [inherited]

Initialize the container wrapper to the specified resource using the specified datasource for context.

Definition at line 154 of file nsRDFContainer.cpp.

{
    NS_PRECONDITION(aDataSource != nsnull, "null ptr");
    if (! aDataSource)
        return NS_ERROR_NULL_POINTER;

    NS_PRECONDITION(aContainer != nsnull, "null ptr");
    if (! aContainer)
        return NS_ERROR_NULL_POINTER;

    nsresult rv;
    PRBool isContainer;
    rv = gRDFContainerUtils->IsContainer(aDataSource, aContainer, &isContainer);
    if (NS_FAILED(rv)) return rv;

    // ``throw'' if we can't create a container on the specified
    // datasource/resource combination.
    if (! isContainer)
        return NS_ERROR_FAILURE;

    NS_IF_RELEASE(mDataSource);
    mDataSource = aDataSource;
    NS_ADDREF(mDataSource);

    NS_IF_RELEASE(mContainer);
    mContainer = aContainer;
    NS_ADDREF(mContainer);

    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsIRDFContainer::InsertElementAt ( in nsIRDFNode  aElement,
in long  aIndex,
in boolean  aRenumber 
) [inherited]

Insert aElement at the specified index.

If aRenumber is 'true', then the underlying RDF graph will be 're-numbered' to accomodate the new element.

Here is the caller graph for this function:

void nsIRDFContainer::RemoveElement ( in nsIRDFNode  aElement,
in boolean  aRenumber 
) [inherited]

Remove the first occurence of the specified element from the container.

If aRenumber is 'true', then the underlying RDF graph will be 're-numbered' to account for the removal.

Here is the caller graph for this function:

nsIRDFNode nsIRDFContainer::RemoveElementAt ( in long  aIndex,
in boolean  aRenumber 
) [inherited]

Remove the element at the specified index.

If aRenumber is 'true', then the underlying RDF graph will be 're-numbered' to account for the removal.

Returns:
the element that was removed.
nsresult RDFContainerImpl::Renumber ( PRInt32  aStartIndex,
PRInt32  aIncrement 
) [private]

Definition at line 494 of file nsRDFContainer.cpp.

{
    if (!mDataSource || !mContainer)
        return NS_ERROR_NOT_INITIALIZED;

    // Renumber the elements in the container starting with
    // aStartIndex, updating each element's index by aIncrement. For
    // example,
    //
    //   (1:a 2:b 3:c)
    //   Renumber(2, +1);
    //   (1:a 3:b 4:c)
    //   Renumber(3, -1);
    //   (1:a 2:b 3:c)
    //
    nsresult rv;

    if (! aIncrement)
        return NS_OK;

    PRInt32 count;
    rv = GetCount(&count);
    if (NS_FAILED(rv)) return rv;

    if (aIncrement > 0) {
        // Update the container's nextVal to reflect the
        // renumbering. We do this now if aIncrement > 0 because we'll
        // want to be able to acknowledge that new elements are in the
        // container.
        rv = SetNextValue(count + aIncrement + 1);
        if (NS_FAILED(rv)) return rv;
    }

    PRInt32 i;
    if (aIncrement < 0) {
        i = aStartIndex;
    }
    else {
        i = count; // we're one-indexed.
    }

    // Note: once we disable notifications, don't exit this method until
    // enabling notifications
    nsCOMPtr<nsIRDFPropagatableDataSource> propagatable =
        do_QueryInterface(mDataSource);
    if (propagatable) {
        propagatable->SetPropagateChanges(PR_FALSE);
    }

    PRBool  err = PR_FALSE;
    while ((err == PR_FALSE) && ((aIncrement < 0) ? (i <= count) : (i >= aStartIndex)))
    {
        nsCOMPtr<nsIRDFResource> oldOrdinal;
        rv = gRDFContainerUtils->IndexToOrdinalResource(i, getter_AddRefs(oldOrdinal));
        if (NS_FAILED(rv))
        {
            err = PR_TRUE;
            continue;
        }

        nsCOMPtr<nsIRDFResource> newOrdinal;
        rv = gRDFContainerUtils->IndexToOrdinalResource(i + aIncrement, getter_AddRefs(newOrdinal));
        if (NS_FAILED(rv))
        {
            err = PR_TRUE;
            continue;
        }

        // Because of aggregation, we need to be paranoid about the
        // possibility that >1 element may be present per ordinal. If
        // there _is_ in fact more than one element, they'll all get
        // assigned to the same new ordinal; i.e., we don't make any
        // attempt to "clean up" the duplicate numbering. (Doing so
        // would require two passes.)
        nsCOMPtr<nsISimpleEnumerator> targets;
        rv = mDataSource->GetTargets(mContainer, oldOrdinal, PR_TRUE, getter_AddRefs(targets));
        if (NS_FAILED(rv))
        {
            err = PR_TRUE;
            continue;
        }

        while (1) {
            PRBool hasMore;
            rv = targets->HasMoreElements(&hasMore);
            if (NS_FAILED(rv))
            {
                err = PR_TRUE;
                break;
            }

            if (! hasMore)
                break;

            nsCOMPtr<nsISupports> isupports;
            rv = targets->GetNext(getter_AddRefs(isupports));
            if (NS_FAILED(rv))
            {
                err = PR_TRUE;
                break;
            }

            nsCOMPtr<nsIRDFNode> element( do_QueryInterface(isupports) );
            NS_ASSERTION(element != nsnull, "something funky in the enumerator");
            if (! element)
            {
                err = PR_TRUE;
                rv = NS_ERROR_UNEXPECTED;
                break;
            }

            rv = mDataSource->Unassert(mContainer, oldOrdinal, element);
            if (NS_FAILED(rv))
            {
                err = PR_TRUE;
                break;
            }

            rv = mDataSource->Assert(mContainer, newOrdinal, element, PR_TRUE);
            if (NS_FAILED(rv))
            {
                err = PR_TRUE;
                break;
            }
        }

        i -= aIncrement;
    }

    if ((err == PR_FALSE) && (aIncrement < 0))
    {
        // Update the container's nextVal to reflect the
        // renumbering. We do this now if aIncrement < 0 because, up
        // until this point, we'll want people to be able to find
        // things that are still "at the end".
        rv = SetNextValue(count + aIncrement + 1);
        if (NS_FAILED(rv))
        {
            err = PR_TRUE;
        }
    }

    // Note: MUST enable notifications before exiting this method
    if (propagatable) {
        propagatable->SetPropagateChanges(PR_TRUE);
    }

    if (err == PR_TRUE) return(rv);

    return NS_OK;
}

Here is the call graph for this function:

Definition at line 649 of file nsRDFContainer.cpp.

{
    if (!mDataSource || !mContainer)
        return NS_ERROR_NOT_INITIALIZED;

    nsresult rv;

    // Remove the current value of nextVal, if there is one.
    nsCOMPtr<nsIRDFNode> nextValNode;
    if (NS_SUCCEEDED(rv = mDataSource->GetTarget(mContainer,
                                                 kRDF_nextVal,
                                                 PR_TRUE,
                                                 getter_AddRefs(nextValNode)))) {
        if (NS_FAILED(rv = mDataSource->Unassert(mContainer, kRDF_nextVal, nextValNode))) {
            NS_ERROR("unable to update nextVal");
            return rv;
        }
    }

    nsAutoString s;
    s.AppendInt(aIndex, 10);

    nsCOMPtr<nsIRDFLiteral> nextVal;
    if (NS_FAILED(rv = gRDFService->GetLiteral(s.get(), getter_AddRefs(nextVal)))) {
        NS_ERROR("unable to get nextVal literal");
        return rv;
    }

    rv = mDataSource->Assert(mContainer, kRDF_nextVal, nextVal, PR_TRUE);
    if (rv != NS_RDF_ASSERTION_ACCEPTED) {
        NS_ERROR("unable to update nextVal");
        return NS_ERROR_FAILURE;
    }

    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Friends And Related Function Documentation

nsresult NS_NewRDFContainer ( nsIRDFContainer **  aResult) [friend]

Definition at line 457 of file nsRDFContainer.cpp.

{
    RDFContainerImpl* result = new RDFContainerImpl();
    if (! result)
        return NS_ERROR_OUT_OF_MEMORY;

    nsresult rv;
    rv = result->Init();
    if (NS_FAILED(rv)) {
        delete result;
        return rv;
    }

    NS_ADDREF(result);
    *aResult = result;
    return NS_OK;
}

Member Data Documentation

Definition at line 47 of file nsIRDFContainer.idl.

Definition at line 115 of file nsRDFContainer.cpp.

Definition at line 114 of file nsRDFContainer.cpp.

PRInt32 RDFContainerImpl::gRefCnt = 0 [static, private]

Definition at line 113 of file nsRDFContainer.cpp.

Definition at line 116 of file nsRDFContainer.cpp.

Definition at line 110 of file nsRDFContainer.cpp.

Definition at line 109 of file nsRDFContainer.cpp.

Definition at line 48 of file nsIRDFContainer.idl.


The documentation for this class was generated from the following file: