Bug 470455 - test_database_sync_embed_visits.js leaks, r=sdwilsh
[wine-gecko.git] / content / xul / templates / src / nsXULTemplateQueryProcessorRDF.h
blob10fafba235eb4b60ae76c50ed66626f9b77b3a60
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
13 * License.
15 * The Original Code is Mozilla Communicator client code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
22 * Contributor(s):
23 * Robert Churchill <rjc@netscape.com>
24 * David Hyatt <hyatt@netscape.com>
25 * Chris Waterson <waterson@netscape.com>
26 * Pierre Phaneuf <pp@ludusdesign.com>
27 * Neil Deakin <enndeakin@sympatico.ca>
29 * Alternatively, the contents of this file may be used under the terms of
30 * either of the GNU General Public License Version 2 or later (the "GPL"),
31 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
32 * in which case the provisions of the GPL or the LGPL are applicable instead
33 * of those above. If you wish to allow use of your version of this file only
34 * under the terms of either the GPL or the LGPL, and not to allow others to
35 * use your version of this file under the terms of the MPL, indicate your
36 * decision by deleting the provisions above and replace them with the notice
37 * and other provisions required by the GPL or the LGPL. If you do not delete
38 * the provisions above, a recipient may use your version of this file under
39 * the terms of any one of the MPL, the GPL or the LGPL.
41 * ***** END LICENSE BLOCK ***** */
44 #ifndef nsXULTemplateQueryProcessorRDF_h__
45 #define nsXULTemplateQueryProcessorRDF_h__
47 #include "nsIContent.h"
48 #include "nsIRDFContainer.h"
49 #include "nsIRDFContainerUtils.h"
50 #include "nsIRDFDataSource.h"
51 #include "nsIRDFObserver.h"
52 #include "nsIRDFService.h"
53 #include "nsIXULTemplateBuilder.h"
54 #include "nsIXULTemplateQueryProcessor.h"
55 #include "nsICollation.h"
56 #include "nsCollationCID.h"
58 #include "nsFixedSizeAllocator.h"
59 #include "nsResourceSet.h"
60 #include "nsRuleNetwork.h"
61 #include "nsRDFQuery.h"
62 #include "nsRDFBinding.h"
63 #include "nsXULTemplateResultSetRDF.h"
64 #include "nsVoidArray.h"
65 #include "nsCOMArray.h"
66 #include "nsIArray.h"
67 #include "nsString.h"
68 #include "nsClassHashtable.h"
69 #include "nsRefPtrHashtable.h"
70 #include "nsCycleCollectionParticipant.h"
72 #include "prlog.h"
73 #ifdef PR_LOGGING
74 extern PRLogModuleInfo* gXULTemplateLog;
75 #endif
77 class nsIRDFCompositeDataSource;
78 class nsXULTemplateResultRDF;
80 /**
81 * An object that generates results from a query on an RDF graph
83 class nsXULTemplateQueryProcessorRDF : public nsIXULTemplateQueryProcessor,
84 public nsIRDFObserver
86 public:
88 nsXULTemplateQueryProcessorRDF();
90 ~nsXULTemplateQueryProcessorRDF();
92 nsresult InitGlobals();
94 // nsISupports interface
95 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
96 NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsXULTemplateQueryProcessorRDF,
97 nsIXULTemplateQueryProcessor)
99 // nsIXULTemplateQueryProcessor interface
100 NS_DECL_NSIXULTEMPLATEQUERYPROCESSOR
102 // nsIRDFObserver interface
103 NS_DECL_NSIRDFOBSERVER
106 * Propagate all changes through the rule network when an assertion is
107 * added to the graph, adding any new results.
109 nsresult
110 Propagate(nsIRDFResource* aSource,
111 nsIRDFResource* aProperty,
112 nsIRDFNode* aTarget);
115 * Retract all changes through the rule network when an assertion is
116 * removed from the graph, removing any results that no longer match.
118 nsresult
119 Retract(nsIRDFResource* aSource,
120 nsIRDFResource* aProperty,
121 nsIRDFNode* aTarget);
124 * Synchronize results when the graph changes, updating their bindings.
126 nsresult
127 SynchronizeAll(nsIRDFResource* aSource,
128 nsIRDFResource* aProperty,
129 nsIRDFNode* aOldTarget,
130 nsIRDFNode* aNewTarget);
133 * Return true if a resource is a container
135 nsresult
136 CheckContainer(nsIRDFResource* aTargetResource,
137 PRBool* aIsContainer);
140 * Check if a resource does not have any children
142 nsresult
143 CheckEmpty(nsIRDFResource* aTargetResource,
144 PRBool* aIsEmpty);
147 * Check if a resource is a separator
149 nsresult
150 CheckIsSeparator(nsIRDFResource* aResource, PRBool* aIsSeparator);
153 * Compute the containment properties which are additional arcs which
154 * indicate that a node is a container, in additional to the RDF container
155 * tests. The computed list is stored in mContainmentProperties
157 nsresult
158 ComputeContainmentProperties(nsIDOMNode* aRootNode);
161 * Compile a query that uses the extended template syntax. The last
162 * compiled node of the query is returned as aLastNode. This node will
163 * have been added to mAllTests which owns the node.
165 nsresult
166 CompileExtendedQuery(nsRDFQuery* aQuery,
167 nsIContent* aConditions,
168 TestNode** aLastNode);
171 * Compile a single query child and return the compiled node in aResult.
172 * This node will have been added to mAllTests which owns the node and
173 * set as a child of aParentNode.
175 virtual nsresult
176 CompileQueryChild(nsIAtom* aTag,
177 nsRDFQuery* aQuery,
178 nsIContent* aConditions,
179 TestNode* aParentNode,
180 TestNode** aResult);
183 * Parse the value of a property test assertion for a condition or a simple
184 * rule based on the parseType attribute into the appropriate literal type.
186 nsresult ParseLiteral(const nsString& aParseType,
187 const nsString& aValue,
188 nsIRDFNode** aResult);
191 * Compile a <triple> condition and return the compiled node in aResult.
192 * This node will have been added to mAllTests which owns the node and
193 * set as a child of aParentNode.
195 nsresult
196 CompileTripleCondition(nsRDFQuery* aQuery,
197 nsIContent* aCondition,
198 TestNode* aParentNode,
199 TestNode** aResult);
202 * Compile a <member> condition and return the compiled node in aResult.
203 * This node will have been added to mAllTests which owns the node and
204 * set as a child of aParentNode.
206 nsresult
207 CompileMemberCondition(nsRDFQuery* aQuery,
208 nsIContent* aCondition,
209 TestNode* aParentNode,
210 TestNode** aResult);
213 * Add the default rules shared by all simple queries. This creates
214 * the content start node followed by a member test. The member TestNode
215 * is returned in aChildNode. Both nodes will have been added to mAllTests
216 * which owns the nodes.
218 nsresult
219 AddDefaultSimpleRules(nsRDFQuery* aQuery,
220 TestNode** aChildNode);
223 * Compile a query that's specified using the simple template
224 * syntax. Each TestNode is created in a chain, the last compiled node
225 * is returned as aLastNode. All nodes will have been added to mAllTests
226 * which owns the nodes.
228 nsresult
229 CompileSimpleQuery(nsRDFQuery* aQuery,
230 nsIContent* aQueryElement,
231 TestNode** aLastNode);
233 RDFBindingSet*
234 GetBindingsForRule(nsIDOMNode* aRule);
237 * Indicate that a result is dependant on a particular resource. When an
238 * assertion is added to or removed from the graph involving that
239 * resource, that result must be recalculated.
241 nsresult
242 AddBindingDependency(nsXULTemplateResultRDF* aResult,
243 nsIRDFResource* aResource);
246 * Remove a dependency a result has on a particular resource.
248 nsresult
249 RemoveBindingDependency(nsXULTemplateResultRDF* aResult,
250 nsIRDFResource* aResource);
253 * A memory element is a hash of an RDF triple. One exists for each triple
254 * that was involved in generating a result. This function adds this to a
255 * map, keyed by memory element, when the value is a list of results that
256 * depend on that memory element. When an RDF triple is removed from the
257 * datasource, RetractElement is called, and this map is examined to
258 * determine which results are no longer valid.
260 nsresult
261 AddMemoryElements(const Instantiation& aInst,
262 nsXULTemplateResultRDF* aResult);
265 * Remove the memory elements associated with a result when the result is
266 * no longer being used.
268 nsresult
269 RemoveMemoryElements(const Instantiation& aInst,
270 nsXULTemplateResultRDF* aResult);
273 * Remove the results associated with a memory element since the
274 * RDF triple the memory element is a hash of has been removed.
276 void RetractElement(const MemoryElement& aMemoryElement);
279 * Return the index of a result's resource in its RDF container
281 PRInt32
282 GetContainerIndexOf(nsIXULTemplateResult* aResult);
285 * Given a result and a predicate to sort on, get the target value of
286 * the triple to use for sorting. The sort predicate is the predicate
287 * with '?sort=true' appended.
289 nsresult
290 GetSortValue(nsIXULTemplateResult* aResult,
291 nsIRDFResource* aPredicate,
292 nsIRDFResource* aSortPredicate,
293 nsISupports** aResultNode);
295 nsIRDFDataSource* GetDataSource() { return mDB; }
297 nsIXULTemplateBuilder* GetBuilder() { return mBuilder; }
299 nsResourceSet& ContainmentProperties() { return mContainmentProperties; }
301 #ifdef PR_LOGGING
302 nsresult
303 Log(const char* aOperation,
304 nsIRDFResource* aSource,
305 nsIRDFResource* aProperty,
306 nsIRDFNode* aTarget);
308 #define LOG(_op, _src, _prop, _targ) \
309 Log(_op, _src, _prop, _targ)
311 #else
312 #define LOG(_op, _src, _prop, _targ)
313 #endif
315 protected:
316 // We are an observer of the composite datasource. The cycle is
317 // broken when the document is destroyed.
318 nsCOMPtr<nsIRDFDataSource> mDB;
320 // weak reference to the builder, cleared when the document is destroyed
321 nsIXULTemplateBuilder* mBuilder;
323 // true if the query processor has been initialized
324 PRBool mQueryProcessorRDFInited;
326 // true if results have been generated. Once set, bindings can no longer
327 // be added. If they were, the binding value arrays for results that have
328 // already been generated would be the wrong size
329 PRBool mGenerationStarted;
331 // nesting level for RDF batch notifications
332 PRInt32 mUpdateBatchNest;
334 // containment properties that are checked to determine if a resource is
335 // a container
336 nsResourceSet mContainmentProperties;
338 // the end node of the default simple node hierarchy
339 TestNode* mSimpleRuleMemberTest;
341 // the reference variable
342 nsCOMPtr<nsIAtom> mRefVariable;
344 // the last ref that was calculated, used for simple rules
345 nsCOMPtr<nsIXULTemplateResult> mLastRef;
348 * A map between nsIRDFNodes that form the left-hand side (the subject) of
349 * a <binding> and an array of nsIXULTemplateResults. When a new assertion
350 * is added to the graph involving a particular rdf node, it is looked up
351 * in this binding map. If it exists, the corresponding results must then
352 * be synchronized.
354 nsClassHashtable<nsISupportsHashKey,
355 nsCOMArray<nsXULTemplateResultRDF> > mBindingDependencies;
358 * A map between memory elements and an array of nsIXULTemplateResults.
359 * When a triple is unasserted from the graph, the corresponding results
360 * no longer match so they must be removed.
362 nsClassHashtable<nsUint32HashKey,
363 nsCOMArray<nsXULTemplateResultRDF> > mMemoryElementToResultMap;
365 // map of the rules to the bindings for those rules.
366 // XXXndeakin this might be better just as an array since there is usually
367 // ten or fewer rules
368 nsRefPtrHashtable<nsISupportsHashKey, RDFBindingSet> mRuleToBindingsMap;
371 * The queries
373 nsCOMArray<nsITemplateRDFQuery> mQueries;
376 * All of the RDF tests in the rule network, which are checked when a new
377 * assertion is added to the graph. This is a subset of mAllTests, which
378 * also includes non-RDF tests.
380 ReteNodeSet mRDFTests;
383 * All of the tests in the rule network, owned by this list
385 ReteNodeSet mAllTests;
387 // pseudo-constants
388 static nsrefcnt gRefCnt;
390 public:
391 static nsIRDFService* gRDFService;
392 static nsIRDFContainerUtils* gRDFContainerUtils;
393 static nsIRDFResource* kNC_BookmarkSeparator;
394 static nsIRDFResource* kRDF_type;
397 #endif // nsXULTemplateQueryProcessorRDF_h__