|
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 #include "nsInstantiationNode.h" |
|
7 #include "nsTemplateRule.h" |
|
8 #include "nsXULTemplateQueryProcessorRDF.h" |
|
9 |
|
10 #include "prlog.h" |
|
11 #ifdef PR_LOGGING |
|
12 extern PRLogModuleInfo* gXULTemplateLog; |
|
13 #endif |
|
14 |
|
15 nsInstantiationNode::nsInstantiationNode(nsXULTemplateQueryProcessorRDF* aProcessor, |
|
16 nsRDFQuery* aQuery) |
|
17 : mProcessor(aProcessor), |
|
18 mQuery(aQuery) |
|
19 { |
|
20 #ifdef PR_LOGGING |
|
21 PR_LOG(gXULTemplateLog, PR_LOG_DEBUG, |
|
22 ("nsInstantiationNode[%p] query=%p", this, aQuery)); |
|
23 #endif |
|
24 |
|
25 MOZ_COUNT_CTOR(nsInstantiationNode); |
|
26 } |
|
27 |
|
28 |
|
29 nsInstantiationNode::~nsInstantiationNode() |
|
30 { |
|
31 MOZ_COUNT_DTOR(nsInstantiationNode); |
|
32 } |
|
33 |
|
34 nsresult |
|
35 nsInstantiationNode::Propagate(InstantiationSet& aInstantiations, |
|
36 bool aIsUpdate, bool& aTakenInstantiations) |
|
37 { |
|
38 // In update mode, iterate through the results and call the template |
|
39 // builder to update them. In non-update mode, cache them in the processor |
|
40 // to be used during processing. The results are cached in the processor |
|
41 // so that the simple rules are only computed once. In this situation, all |
|
42 // data for all queries are calculated at once. |
|
43 nsresult rv = NS_OK; |
|
44 |
|
45 aTakenInstantiations = false; |
|
46 |
|
47 if (aIsUpdate) { |
|
48 // Iterate through newly added keys to determine which rules fired. |
|
49 // |
|
50 // XXXwaterson Unfortunately, this could also lead to retractions; |
|
51 // e.g., (container ?a ^empty false) could become "unmatched". How |
|
52 // to track those? |
|
53 nsCOMPtr<nsIDOMNode> querynode; |
|
54 mQuery->GetQueryNode(getter_AddRefs(querynode)); |
|
55 |
|
56 InstantiationSet::ConstIterator last = aInstantiations.Last(); |
|
57 for (InstantiationSet::ConstIterator inst = aInstantiations.First(); inst != last; ++inst) { |
|
58 nsAssignmentSet assignments = inst->mAssignments; |
|
59 |
|
60 nsCOMPtr<nsIRDFNode> node; |
|
61 assignments.GetAssignmentFor(mQuery->mMemberVariable, |
|
62 getter_AddRefs(node)); |
|
63 if (node) { |
|
64 nsCOMPtr<nsIRDFResource> resource = do_QueryInterface(node); |
|
65 if (resource) { |
|
66 nsRefPtr<nsXULTemplateResultRDF> nextresult = |
|
67 new nsXULTemplateResultRDF(mQuery, *inst, resource); |
|
68 if (! nextresult) |
|
69 return NS_ERROR_OUT_OF_MEMORY; |
|
70 |
|
71 rv = mProcessor->AddMemoryElements(*inst, nextresult); |
|
72 if (NS_FAILED(rv)) |
|
73 return rv; |
|
74 |
|
75 mProcessor->GetBuilder()->AddResult(nextresult, querynode); |
|
76 } |
|
77 } |
|
78 } |
|
79 } |
|
80 else { |
|
81 nsresult rv = mQuery->SetCachedResults(mProcessor, aInstantiations); |
|
82 if (NS_SUCCEEDED(rv)) |
|
83 aTakenInstantiations = true; |
|
84 } |
|
85 |
|
86 return rv; |
|
87 } |