1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is mozilla.org code.
16 : *
17 : * The Initial Developer of the Original Code is Neil Deakin
18 : * Portions created by the Initial Developer are Copyright (C) 2005
19 : * the Initial Developer. All Rights Reserved.
20 : *
21 : * Contributor(s):
22 : *
23 : * Alternatively, the contents of this file may be used under the terms of
24 : * either of the GNU General Public License Version 2 or later (the "GPL"),
25 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26 : * in which case the provisions of the GPL or the LGPL are applicable instead
27 : * of those above. If you wish to allow use of your version of this file only
28 : * under the terms of either the GPL or the LGPL, and not to allow others to
29 : * use your version of this file under the terms of the MPL, indicate your
30 : * decision by deleting the provisions above and replace them with the notice
31 : * and other provisions required by the GPL or the LGPL. If you do not delete
32 : * the provisions above, a recipient may use your version of this file under
33 : * the terms of any one of the MPL, the GPL or the LGPL.
34 : *
35 : * ***** END LICENSE BLOCK ***** */
36 :
37 : #include "nsXULTemplateResultRDF.h"
38 : #include "nsXULContentUtils.h"
39 :
40 : // XXXndeakin for some reason, making this class have classinfo breaks trees.
41 : //#include "nsIDOMClassInfo.h"
42 :
43 1464 : NS_IMPL_CYCLE_COLLECTION_1(nsXULTemplateResultRDF, mQuery)
44 :
45 0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXULTemplateResultRDF)
46 0 : NS_INTERFACE_MAP_ENTRY(nsIXULTemplateResult)
47 0 : NS_INTERFACE_MAP_ENTRY(nsISupports)
48 0 : NS_INTERFACE_MAP_END
49 :
50 0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(nsXULTemplateResultRDF)
51 0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(nsXULTemplateResultRDF)
52 :
53 0 : nsXULTemplateResultRDF::nsXULTemplateResultRDF(nsIRDFResource* aNode)
54 : : mQuery(nsnull),
55 0 : mNode(aNode)
56 : {
57 0 : }
58 :
59 0 : nsXULTemplateResultRDF::nsXULTemplateResultRDF(nsRDFQuery* aQuery,
60 : const Instantiation& aInst,
61 : nsIRDFResource *aNode)
62 : : mQuery(aQuery),
63 : mNode(aNode),
64 0 : mInst(aInst)
65 : {
66 0 : }
67 :
68 0 : nsXULTemplateResultRDF::~nsXULTemplateResultRDF()
69 : {
70 0 : }
71 :
72 : NS_IMETHODIMP
73 0 : nsXULTemplateResultRDF::GetIsContainer(bool* aIsContainer)
74 : {
75 0 : *aIsContainer = false;
76 :
77 0 : if (mNode) {
78 0 : nsXULTemplateQueryProcessorRDF* processor = GetProcessor();
79 0 : if (processor)
80 0 : return processor->CheckContainer(mNode, aIsContainer);
81 : }
82 :
83 0 : return NS_OK;
84 : }
85 :
86 : NS_IMETHODIMP
87 0 : nsXULTemplateResultRDF::GetIsEmpty(bool* aIsEmpty)
88 : {
89 0 : *aIsEmpty = true;
90 :
91 0 : if (mNode) {
92 0 : nsXULTemplateQueryProcessorRDF* processor = GetProcessor();
93 0 : if (processor)
94 0 : return processor->CheckEmpty(mNode, aIsEmpty);
95 : }
96 :
97 0 : return NS_OK;
98 : }
99 :
100 : NS_IMETHODIMP
101 0 : nsXULTemplateResultRDF::GetMayProcessChildren(bool* aMayProcessChildren)
102 : {
103 : // RDF always allows recursion
104 0 : *aMayProcessChildren = true;
105 0 : return NS_OK;
106 : }
107 :
108 : NS_IMETHODIMP
109 0 : nsXULTemplateResultRDF::GetId(nsAString& aId)
110 : {
111 0 : if (! mNode)
112 0 : return NS_ERROR_FAILURE;
113 :
114 : const char* uri;
115 0 : mNode->GetValueConst(&uri);
116 :
117 0 : CopyUTF8toUTF16(uri, aId);
118 :
119 0 : return NS_OK;
120 : }
121 :
122 : NS_IMETHODIMP
123 0 : nsXULTemplateResultRDF::GetResource(nsIRDFResource** aResource)
124 : {
125 0 : *aResource = mNode;
126 0 : NS_IF_ADDREF(*aResource);
127 0 : return NS_OK;
128 : }
129 :
130 : NS_IMETHODIMP
131 0 : nsXULTemplateResultRDF::GetType(nsAString& aType)
132 : {
133 0 : aType.Truncate();
134 :
135 0 : nsresult rv = NS_OK;
136 :
137 0 : nsXULTemplateQueryProcessorRDF* processor = GetProcessor();
138 0 : if (processor) {
139 : bool found;
140 0 : rv = processor->CheckIsSeparator(mNode, &found);
141 0 : if (NS_SUCCEEDED(rv) && found)
142 0 : aType.AssignLiteral("separator");
143 : }
144 :
145 0 : return rv;
146 : }
147 :
148 : NS_IMETHODIMP
149 0 : nsXULTemplateResultRDF::GetBindingFor(nsIAtom* aVar, nsAString& aValue)
150 : {
151 0 : nsCOMPtr<nsIRDFNode> val;
152 0 : GetAssignment(aVar, getter_AddRefs(val));
153 :
154 0 : return nsXULContentUtils::GetTextForNode(val, aValue);
155 : }
156 :
157 : NS_IMETHODIMP
158 0 : nsXULTemplateResultRDF::GetBindingObjectFor(nsIAtom* aVar, nsISupports** aValue)
159 : {
160 0 : GetAssignment(aVar, (nsIRDFNode **)aValue);
161 :
162 0 : return NS_OK;
163 : }
164 :
165 : NS_IMETHODIMP
166 0 : nsXULTemplateResultRDF::RuleMatched(nsISupports* aQuery, nsIDOMNode* aRuleNode)
167 : {
168 : // when a rule matches, set the bindings that must be used.
169 0 : nsXULTemplateQueryProcessorRDF* processor = GetProcessor();
170 0 : if (processor) {
171 0 : RDFBindingSet* bindings = processor->GetBindingsForRule(aRuleNode);
172 0 : if (bindings) {
173 0 : nsresult rv = mBindingValues.SetBindingSet(bindings);
174 0 : if (NS_FAILED(rv))
175 0 : return rv;
176 :
177 0 : bindings->AddDependencies(mNode, this);
178 : }
179 : }
180 :
181 0 : return NS_OK;
182 : }
183 :
184 : NS_IMETHODIMP
185 0 : nsXULTemplateResultRDF::HasBeenRemoved()
186 : {
187 : // when a result is no longer used, clean up the dependencies and
188 : // memory elements that refer to it
189 0 : mBindingValues.RemoveDependencies(mNode, this);
190 :
191 0 : nsXULTemplateQueryProcessorRDF* processor = GetProcessor();
192 0 : if (processor)
193 0 : processor->RemoveMemoryElements(mInst, this);
194 :
195 0 : return NS_OK;
196 : }
197 :
198 :
199 : void
200 0 : nsXULTemplateResultRDF::GetAssignment(nsIAtom* aVar, nsIRDFNode** aValue)
201 : {
202 : // look up a variable in the assignments map
203 0 : *aValue = nsnull;
204 0 : mInst.mAssignments.GetAssignmentFor(aVar, aValue);
205 :
206 : // if not found, look up the variable in the bindings
207 0 : if (! *aValue)
208 0 : mBindingValues.GetAssignmentFor(this, aVar, aValue);
209 0 : }
210 :
211 :
212 : bool
213 0 : nsXULTemplateResultRDF::SyncAssignments(nsIRDFResource* aSubject,
214 : nsIRDFResource* aPredicate,
215 : nsIRDFNode* aTarget)
216 : {
217 : // synchronize the bindings when an assertion is added or removed
218 0 : RDFBindingSet* bindingset = mBindingValues.GetBindingSet();
219 0 : if (bindingset) {
220 : return bindingset->SyncAssignments(aSubject, aPredicate, aTarget,
221 0 : (aSubject == mNode) ? mQuery->GetMemberVariable() : nsnull,
222 0 : this, mBindingValues);
223 : }
224 :
225 0 : return false;
226 : }
227 :
228 : bool
229 0 : nsXULTemplateResultRDF::HasMemoryElement(const MemoryElement& aMemoryElement)
230 : {
231 0 : MemoryElementSet::ConstIterator last = mInst.mSupport.Last();
232 0 : for (MemoryElementSet::ConstIterator element = mInst.mSupport.First();
233 : element != last; ++element) {
234 0 : if ((*element).Equals(aMemoryElement))
235 0 : return true;
236 : }
237 :
238 0 : return false;
239 4392 : }
|