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
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/
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
15 * The Original Code is mozilla.org code.
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.
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.
35 * ***** END LICENSE BLOCK ***** */
37 #include "nsXULTemplateQueryProcessorRDF.h"
38 #include "nsXULTemplateResultRDF.h"
39 #include "nsRDFBinding.h"
42 #include "nsXULContentUtils.h"
45 RDFBindingSet::~RDFBindingSet()
48 RDFBinding
* doomed
= mFirst
;
49 mFirst
= mFirst
->mNext
;
53 MOZ_COUNT_DTOR(RDFBindingSet
);
57 RDFBindingSet::AddBinding(nsIAtom
* aVar
, nsIAtom
* aRef
, nsIRDFResource
* aPredicate
)
59 RDFBinding
* newbinding
= new RDFBinding(aRef
, aPredicate
, aVar
);
61 return NS_ERROR_OUT_OF_MEMORY
;
64 RDFBinding
* binding
= mFirst
;
67 // the binding is dependant on the calculation of a previous binding
68 if (binding
->mSubjectVariable
== aVar
)
69 newbinding
->mHasDependency
= PR_TRUE
;
71 // if the target variable is already used in a binding, ignore it
72 // since it won't be useful for anything
73 if (binding
->mTargetVariable
== aVar
) {
78 // add the binding at the end of the list
79 if (! binding
->mNext
) {
80 binding
->mNext
= newbinding
;
84 binding
= binding
->mNext
;
97 RDFBindingSet::SyncAssignments(nsIRDFResource
* aSubject
,
98 nsIRDFResource
* aPredicate
,
100 nsIAtom
* aMemberVariable
,
101 nsXULTemplateResultRDF
* aResult
,
102 nsBindingValues
& aBindingValues
)
104 NS_ASSERTION(aBindingValues
.GetBindingSet() == this,
105 "nsBindingValues not for this RDFBindingSet");
106 NS_PRECONDITION(aResult
, "Must have result");
108 PRBool needSync
= PR_FALSE
;
109 nsCOMPtr
<nsIRDFNode
>* valuesArray
= aBindingValues
.ValuesArray();
113 RDFBinding
* binding
= mFirst
;
116 // QI for proper comparisons just to be safe
117 nsCOMPtr
<nsIRDFNode
> subjectnode
= do_QueryInterface(aSubject
);
119 // iterate through the bindings looking for ones that would match the RDF
120 // nodes that were involved in a change
121 nsCOMPtr
<nsIRDFNode
> value
;
123 if (aPredicate
== binding
->mPredicate
) {
124 // if the source of the binding is the member variable, optimize
125 if (binding
->mSubjectVariable
== aMemberVariable
) {
126 valuesArray
[count
] = aTarget
;
130 aResult
->GetAssignment(binding
->mSubjectVariable
, getter_AddRefs(value
));
131 if (value
== subjectnode
) {
132 valuesArray
[count
] = aTarget
;
138 binding
= binding
->mNext
;
146 RDFBindingSet::AddDependencies(nsIRDFResource
* aSubject
,
147 nsXULTemplateResultRDF
* aResult
)
149 NS_PRECONDITION(aResult
, "Must have result");
151 // iterate through the bindings and add binding dependencies to the
154 nsXULTemplateQueryProcessorRDF
* processor
= aResult
->GetProcessor();
158 nsCOMPtr
<nsIRDFNode
> value
;
160 RDFBinding
* binding
= mFirst
;
162 aResult
->GetAssignment(binding
->mSubjectVariable
, getter_AddRefs(value
));
164 nsCOMPtr
<nsIRDFResource
> valueres
= do_QueryInterface(value
);
166 processor
->AddBindingDependency(aResult
, valueres
);
168 binding
= binding
->mNext
;
173 RDFBindingSet::RemoveDependencies(nsIRDFResource
* aSubject
,
174 nsXULTemplateResultRDF
* aResult
)
176 NS_PRECONDITION(aResult
, "Must have result");
178 // iterate through the bindings and remove binding dependencies from the
181 nsXULTemplateQueryProcessorRDF
* processor
= aResult
->GetProcessor();
185 nsCOMPtr
<nsIRDFNode
> value
;
187 RDFBinding
* binding
= mFirst
;
189 aResult
->GetAssignment(binding
->mSubjectVariable
, getter_AddRefs(value
));
191 nsCOMPtr
<nsIRDFResource
> valueres
= do_QueryInterface(value
);
193 processor
->RemoveBindingDependency(aResult
, valueres
);
195 binding
= binding
->mNext
;
200 RDFBindingSet::LookupTargetIndex(nsIAtom
* aTargetVariable
, RDFBinding
** aBinding
)
203 RDFBinding
* binding
= mFirst
;
206 if (binding
->mTargetVariable
== aTargetVariable
) {
211 binding
= binding
->mNext
;
217 nsBindingValues::~nsBindingValues()
220 MOZ_COUNT_DTOR(nsBindingValues
);
224 nsBindingValues::ClearBindingSet()
226 if (mBindings
&& mValues
) {
235 nsBindingValues::SetBindingSet(RDFBindingSet
* aBindings
)
239 PRInt32 count
= aBindings
->Count();
241 mValues
= new nsCOMPtr
<nsIRDFNode
>[count
];
243 return NS_ERROR_OUT_OF_MEMORY
;
245 mBindings
= aBindings
;
255 nsBindingValues::GetAssignmentFor(nsXULTemplateResultRDF
* aResult
,
261 // assignments are calculated lazily when asked for. The only issue is
262 // when a binding has no value in the RDF graph, it will be checked again
265 if (mBindings
&& mValues
) {
267 PRInt32 idx
= mBindings
->LookupTargetIndex(aVar
, &binding
);
269 *aValue
= mValues
[idx
];
274 nsXULTemplateQueryProcessorRDF
* processor
= aResult
->GetProcessor();
278 nsIRDFDataSource
* ds
= processor
->GetDataSource();
282 nsCOMPtr
<nsIRDFNode
> subjectValue
;
283 aResult
->GetAssignment(binding
->mSubjectVariable
,
284 getter_AddRefs(subjectValue
));
286 NS_ASSERTION(subjectValue
, "Value of subject is not set");
289 nsCOMPtr
<nsIRDFResource
> subject
= do_QueryInterface(subjectValue
);
291 ds
->GetTarget(subject
, binding
->mPredicate
, PR_TRUE
, aValue
);
293 mValues
[idx
] = *aValue
;
301 nsBindingValues::RemoveDependencies(nsIRDFResource
* aSubject
,
302 nsXULTemplateResultRDF
* aResult
)
305 mBindings
->RemoveDependencies(aSubject
, aResult
);