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