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