if (isResourceElement) { rv = CreateContainerContents(realKid, aChild, PR_FALSE); if (NS_FAILED(rv)) return rv; }
RDFGenericBuilderImpl::BuildContentFromTemplate(nsIContent *aTemplateNode,                                                nsIContent *aRealNode,                                                PRBool aIsUnique,                                                nsIRDFResource* aChild,                                                PRInt32 aNaturalOrderPos,                                                PRBool aNotify){	nsresult rv;#ifdef PR_LOGGING    if (PR_LOG_TEST(gLog, PR_LOG_DEBUG)) {        nsCOMPtr<nsIAtom> tag;        rv = aTemplateNode->GetTag(*getter_AddRefs(tag));        if (NS_FAILED(rv)) return rv;        nsXPIDLCString resourceCStr;        rv = aChild->GetValue(getter_Copies(resourceCStr));        if (NS_FAILED(rv)) return rv;                const PRUnichar *unicodeString;        tag->GetUnicode(&unicodeString);        nsAutoString tagStr(unicodeString);        char* tagCStr = tagStr.ToNewCString();        PR_LOG(gLog, PR_LOG_DEBUG,               ("rdfgeneric build-content-fromt-template %s [%s]",                tagCStr, (const char*) resourceCStr));        nsCRT::free(tagCStr);    }#endif	PRInt32	count;	rv = aTemplateNode->ChildCount(count);    if (NS_FAILED(rv)) return rv;	for (PRInt32 kid = 0; kid < count; kid++) {		nsCOMPtr<nsIContent> tmplKid;		rv = aTemplateNode->ChildAt(kid, *getter_AddRefs(tmplKid));        if (NS_FAILED(rv)) return rv;		PRInt32 nameSpaceID;		rv = tmplKid->GetNameSpaceID(nameSpaceID);        if (NS_FAILED(rv)) return rv;		// check whether this item is the "resource" element		PRBool isResourceElement = PR_FALSE;        {            PRUnichar buf[128];            nsAutoString idValue(CBufDescriptor(buf, PR_TRUE, sizeof(buf) / sizeof(PRUnichar), 0));            rv = tmplKid->GetAttribute(kNameSpaceID_None,                                       kURIAtom,                                       idValue);            if (NS_FAILED(rv)) return rv;            if ((rv == NS_CONTENT_ATTR_HAS_VALUE) &&                (idValue.Equals("...") || idValue.Equals("rdf:*"))) {                isResourceElement = PR_TRUE;                aIsUnique = PR_FALSE;            }        }		nsCOMPtr<nsIAtom> tag;		rv = tmplKid->GetTag(*getter_AddRefs(tag));        if (NS_FAILED(rv)) return rv;        PRBool realKidAlreadyExisted = PR_FALSE;        nsCOMPtr<nsIContent> realKid;        if (aIsUnique) {            // The content is "unique"; that is, we haven't hit the            // "resource" element yet.            rv = EnsureElementHasGenericChild(aRealNode, nameSpaceID, tag, aNotify, getter_AddRefs(realKid));            if (NS_FAILED(rv)) return rv;            if (rv == NS_RDF_ELEMENT_WAS_THERE) {                realKidAlreadyExisted = PR_TRUE;            }            else {                // Mark the element's contents as being generated so                // that any re-entrant calls don't trigger an infinite                // recursion.                nsCOMPtr<nsIXULContent> xulcontent = do_QueryInterface(realKid);                if (xulcontent) {                    rv = xulcontent->SetLazyState(nsIXULContent::eTemplateContentsBuilt);                    if (NS_FAILED(rv)) return rv;                }            }            // Recurse until we get to the resource element.            rv = BuildContentFromTemplate(tmplKid, realKid, PR_TRUE, aChild, -1, aNotify);            if (NS_FAILED(rv)) return rv;        }        else if (isResourceElement) {            // It's the "resource" element            rv = CreateElement(nameSpaceID, tag, aChild, getter_AddRefs(realKid));            if (NS_FAILED(rv)) return rv;            if (IsContainer(tmplKid, aChild)) {                rv = realKid->SetAttribute(kNameSpaceID_None, kContainerAtom, nsAutoString("true"), PR_FALSE);                if (NS_FAILED(rv)) return rv;                // test to see if the container has contents                nsAutoString isEmpty = IsEmpty(tmplKid, aChild) ? (const char *)"true" : (const char *)"false";                rv = realKid->SetAttribute(kNameSpaceID_None, kEmptyAtom, isEmpty, PR_FALSE);                if (NS_FAILED(rv)) return rv;            }                    }        else if ((tag.get() == kTextAtom) && (nameSpaceID == kNameSpaceID_XUL)) {            // <xul:text value="..."> is replaced by text of the            // actual value of the rdf:resource attribute for the given node            PRUnichar attrbuf[128];            nsAutoString attrValue(CBufDescriptor(attrbuf, PR_TRUE, sizeof(attrbuf) / sizeof(PRUnichar), 0));            rv = tmplKid->GetAttribute(kNameSpaceID_None, kValueAtom, attrValue);            if (NS_FAILED(rv)) return rv;            if ((rv == NS_CONTENT_ATTR_HAS_VALUE) && (attrValue.Length() > 0)) {                rv = SubstituteText(aChild, attrValue);                if (NS_FAILED(rv)) return rv;                nsCOMPtr<nsITextContent> content;                rv = nsComponentManager::CreateInstance(kTextNodeCID,                                                        nsnull,                                                        nsITextContent::GetIID(),                                                        getter_AddRefs(content));                if (NS_FAILED(rv)) return rv;                rv = content->SetText(attrValue.GetUnicode(), attrValue.Length(), PR_FALSE);                if (NS_FAILED(rv)) return rv;                rv = aRealNode->AppendChildTo(nsCOMPtr<nsIContent>( do_QueryInterface(content) ), aNotify);                if (NS_FAILED(rv)) return rv;            }        }        else {            // It's just a generic element. Create it!            rv = CreateElement(nameSpaceID, tag, nsnull, getter_AddRefs(realKid));            if (NS_FAILED(rv)) return rv;        }        if (realKid && !realKidAlreadyExisted) {            // save a reference (its ID) to the template node that was used            nsAutoString templateID;            rv = tmplKid->GetAttribute(kNameSpaceID_None, kIdAtom, templateID);            if (NS_FAILED(rv)) return rv;            rv = realKid->SetAttribute(kNameSpaceID_None, kTemplateAtom, templateID, PR_FALSE);            if (NS_FAILED(rv)) return rv;            // set natural order hint            if ((aNaturalOrderPos > 0) && (isResourceElement)) {                nsAutoString	pos, zero("0000");                pos.Append(aNaturalOrderPos, 10);                if (pos.Length() < 4) {                    pos.Insert(zero, 0, 4-pos.Length());                }                realKid->SetAttribute(kNameSpaceID_None, kNaturalOrderPosAtom, pos, PR_FALSE);            }            // copy all attributes from template to new node            PRInt32	numAttribs;            rv = tmplKid->GetAttributeCount(numAttribs);            if (NS_FAILED(rv)) return rv;            for (PRInt32 attr = 0; attr < numAttribs; attr++) {                PRInt32 attribNameSpaceID;                nsCOMPtr<nsIAtom> attribName;                rv = tmplKid->GetAttributeNameAt(attr, attribNameSpaceID, *getter_AddRefs(attribName));                if (NS_FAILED(rv)) return rv;                if (! IsIgnoreableAttribute(attribNameSpaceID, attribName)) {                    // Create a buffer here, because there's a good                    // chance that an attribute in the template is                    // going to be an RDF URI, which is usually                    // longish.                    PRUnichar attrbuf[128];                    nsAutoString attribValue(CBufDescriptor(attrbuf, PR_TRUE, sizeof(attrbuf) / sizeof(PRUnichar), 0));                    rv = tmplKid->GetAttribute(attribNameSpaceID, attribName, attribValue);                    if (NS_FAILED(rv)) return rv;                    if (rv == NS_CONTENT_ATTR_HAS_VALUE) {                        rv = SubstituteText(aChild, attribValue);                        if (NS_FAILED(rv)) return rv;                        rv = realKid->SetAttribute(attribNameSpaceID, attribName, attribValue, PR_FALSE);                        if (NS_FAILED(rv)) return rv;                    }                }            }            // Add any persistent attributes            if (isResourceElement) {                rv = AddPersistentAttributes(tmplKid, aChild, realKid);                if (NS_FAILED(rv)) return rv;            }                        if (nameSpaceID == kNameSpaceID_HTML) {                // If we just built HTML, then we have to recurse "by                // hand" because HTML won't build itself up                // lazily. Note that we _don't_ need to notify: we'll                // add the entire subtree in a single whack.                rv = BuildContentFromTemplate(tmplKid, realKid, aIsUnique, aChild, -1, PR_FALSE);                if (NS_FAILED(rv)) return rv;            }            else {                // Otherwise, just mark the XUL element as requiring                // more work to be done. We'll get around to it when                // somebody asks for it.                nsCOMPtr<nsIXULContent> xulcontent = do_QueryInterface(realKid);                if (! xulcontent)                    return NS_ERROR_UNEXPECTED;                rv = xulcontent->SetLazyState(nsIXULContent::eChildrenMustBeRebuilt);                if (NS_FAILED(rv)) return rv;            }            // We'll _already_ have added the unique elements.            if (! aIsUnique) {                // Add into content model, special casing treeitems.                //                // XXX I've hacked insertion sorting to be OFF for                // now, until I can figure out how to make the                // insertion sort go a bit faster.                if ((nsnull != gXULSortService) && (isResourceElement) && (tag.get() == kTreeItemAtom)) {                    rv = gXULSortService->InsertContainerNode(aRealNode, realKid, aNotify);                    NS_ASSERTION(NS_SUCCEEDED(rv), "unable to insert element via sort service");                }                else {                    rv = aRealNode->AppendChildTo(realKid, aNotify);                    NS_ASSERTION(NS_SUCCEEDED(rv), "unable to insert element");                }            }        }	}	return NS_OK;}