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 : #ifndef nsRDFBinding_h__
38 : #define nsRDFBinding_h__
39 :
40 : #include "nsAutoPtr.h"
41 : #include "nsIAtom.h"
42 : #include "nsIRDFResource.h"
43 : #include "nsISupportsImpl.h"
44 :
45 : class nsXULTemplateResultRDF;
46 : class nsBindingValues;
47 :
48 : /*
49 : * Classes related to storing bindings for RDF handling.
50 : */
51 :
52 : /*
53 : * a <binding> descriptors
54 : */
55 : class RDFBinding {
56 :
57 : public:
58 :
59 : nsCOMPtr<nsIAtom> mSubjectVariable;
60 : nsCOMPtr<nsIRDFResource> mPredicate;
61 : nsCOMPtr<nsIAtom> mTargetVariable;
62 :
63 : // indicates whether a binding is dependant on the result from a
64 : // previous binding
65 : bool mHasDependency;
66 :
67 : RDFBinding* mNext;
68 :
69 : private:
70 :
71 : friend class RDFBindingSet;
72 :
73 0 : RDFBinding(nsIAtom* aSubjectVariable,
74 : nsIRDFResource* aPredicate,
75 : nsIAtom* aTargetVariable)
76 : : mSubjectVariable(aSubjectVariable),
77 : mPredicate(aPredicate),
78 : mTargetVariable(aTargetVariable),
79 : mHasDependency(false),
80 0 : mNext(nsnull)
81 : {
82 0 : MOZ_COUNT_CTOR(RDFBinding);
83 0 : }
84 :
85 0 : ~RDFBinding()
86 0 : {
87 0 : MOZ_COUNT_DTOR(RDFBinding);
88 0 : }
89 : };
90 :
91 : /*
92 : * a collection of <binding> descriptors. This object is refcounted by
93 : * nsBindingValues objects and the query processor.
94 : */
95 : class RDFBindingSet
96 : {
97 : protected:
98 :
99 : // the number of bindings
100 : PRInt32 mCount;
101 :
102 : // pointer to the first binding in a linked list
103 : RDFBinding* mFirst;
104 :
105 : public:
106 :
107 0 : RDFBindingSet()
108 : : mCount(0),
109 0 : mFirst(nsnull)
110 : {
111 0 : MOZ_COUNT_CTOR(RDFBindingSet);
112 0 : }
113 :
114 : ~RDFBindingSet();
115 :
116 0 : NS_INLINE_DECL_REFCOUNTING(RDFBindingSet)
117 :
118 0 : PRInt32 Count() const { return mCount; }
119 :
120 : /*
121 : * Add a binding (aRef -> aPredicate -> aVar) to the set
122 : */
123 : nsresult
124 : AddBinding(nsIAtom* aVar, nsIAtom* aRef, nsIRDFResource* aPredicate);
125 :
126 : /*
127 : * Return true if the binding set contains a binding which would cause
128 : * the result to need resynchronizing for an RDF triple. The member
129 : * variable may be supplied as an optimization since bindings most
130 : * commonly use the member variable as the subject. If aMemberVariable
131 : * is set, aSubject must be the value of the member variable for the
132 : * result. The supplied binding values aBindingValues must be values
133 : * using this binding set (that is aBindingValues->GetBindingSet() == this)
134 : *
135 : * @param aSubject subject of the RDF triple
136 : * @param aPredicate predicate of the RDF triple
137 : * @param aTarget target of the RDF triple
138 : * @param aMemberVariable member variable for the query for the binding
139 : * @param aResult result to synchronize
140 : * @param aBindingValues the values for the bindings for the result
141 : */
142 : bool
143 : SyncAssignments(nsIRDFResource* aSubject,
144 : nsIRDFResource* aPredicate,
145 : nsIRDFNode* aTarget,
146 : nsIAtom* aMemberVariable,
147 : nsXULTemplateResultRDF* aResult,
148 : nsBindingValues& aBindingValues);
149 :
150 : /*
151 : * The query processor maintains a map of subjects to an array of results.
152 : * This is used such that when a new assertion is added to the RDF graph,
153 : * the results associated with the subject of that triple may be checked
154 : * to see if their bindings have changed. The AddDependencies method adds
155 : * these subject dependencies to the map.
156 : */
157 : void
158 : AddDependencies(nsIRDFResource* aSubject,
159 : nsXULTemplateResultRDF* aResult);
160 :
161 : /*
162 : * Remove the results from the dependencies map when results are deleted.
163 : */
164 : void
165 : RemoveDependencies(nsIRDFResource* aSubject,
166 : nsXULTemplateResultRDF* aResult);
167 :
168 : /*
169 : * The nsBindingValues classes stores an array of values, one for each
170 : * target symbol that could be set by the bindings in the set.
171 : * LookupTargetIndex determines the index into the array for a given
172 : * target symbol.
173 : */
174 : PRInt32
175 : LookupTargetIndex(nsIAtom* aTargetVariable, RDFBinding** aBinding);
176 : };
177 :
178 : /*
179 : * A set of values of bindings. This object is used once per result.
180 : * This stores a reference to the binding set and an array of node values.
181 : * Since the binding set is used once per query and the values are
182 : * used once per result, we reduce size by only storing the value array's
183 : * length in the binding set. This is possible since the array is always
184 : * a fixed length for a particular binding set.
185 : *
186 : * XXX ndeakin We may want to revisit this later since it makes the code
187 : * more complicated.
188 : */
189 : class nsBindingValues
190 : {
191 : protected:
192 :
193 : // the binding set
194 : nsRefPtr<RDFBindingSet> mBindings;
195 :
196 : /*
197 : * A set of values for variable bindings. To look up a binding value,
198 : * scan through the binding set in mBindings for the right target atom.
199 : * Its index will correspond to the index in this array. The size of this
200 : * array is determined by the RDFBindingSet's Count().
201 : */
202 : nsCOMPtr<nsIRDFNode>* mValues;
203 :
204 : public:
205 :
206 0 : nsBindingValues()
207 : : mBindings(nsnull),
208 0 : mValues(nsnull)
209 : {
210 0 : MOZ_COUNT_CTOR(nsBindingValues);
211 0 : }
212 :
213 : ~nsBindingValues();
214 :
215 :
216 : /**
217 : * Clear the binding set, to be called when the nsBindingValues is deleted
218 : * or a new binding set is being set.
219 : */
220 : void ClearBindingSet();
221 :
222 0 : RDFBindingSet* GetBindingSet() { return mBindings; }
223 :
224 : /**
225 : * Set the binding set to use. This needs to be called once a rule matches
226 : * since it is then known which bindings will apply.
227 : */
228 : nsresult SetBindingSet(RDFBindingSet* aBindings);
229 :
230 0 : nsCOMPtr<nsIRDFNode>* ValuesArray() { return mValues; }
231 :
232 : /*
233 : * Retrieve the assignment for a particular variable
234 : */
235 : void
236 : GetAssignmentFor(nsXULTemplateResultRDF* aResult,
237 : nsIAtom* aVar,
238 : nsIRDFNode** aValue);
239 :
240 : /*
241 : * Remove depenedencies the bindings have on particular resources
242 : */
243 : void
244 : RemoveDependencies(nsIRDFResource* aSubject,
245 : nsXULTemplateResultRDF* aResult);
246 : };
247 :
248 : #endif // nsRDFBinding_h__
|