nsXULTemplateQueryProcessorRDF.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  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. #ifndef nsXULTemplateQueryProcessorRDF_h__
  6. #define nsXULTemplateQueryProcessorRDF_h__
  7. #include "nsIRDFContainer.h"
  8. #include "nsIRDFContainerUtils.h"
  9. #include "nsIRDFDataSource.h"
  10. #include "nsIRDFObserver.h"
  11. #include "nsIRDFService.h"
  12. #include "nsIXULTemplateBuilder.h"
  13. #include "nsIXULTemplateQueryProcessor.h"
  14. #include "nsCollationCID.h"
  15. #include "nsResourceSet.h"
  16. #include "nsRuleNetwork.h"
  17. #include "nsRDFQuery.h"
  18. #include "nsRDFBinding.h"
  19. #include "nsXULTemplateResultSetRDF.h"
  20. #include "nsCOMArray.h"
  21. #include "nsString.h"
  22. #include "nsClassHashtable.h"
  23. #include "nsRefPtrHashtable.h"
  24. #include "nsCycleCollectionParticipant.h"
  25. #include "mozilla/Attributes.h"
  26. #include "mozilla/Logging.h"
  27. extern mozilla::LazyLogModule gXULTemplateLog;
  28. class nsIContent;
  29. class nsXULTemplateResultRDF;
  30. /**
  31. * An object that generates results from a query on an RDF graph
  32. */
  33. class nsXULTemplateQueryProcessorRDF final : public nsIXULTemplateQueryProcessor,
  34. public nsIRDFObserver
  35. {
  36. public:
  37. typedef nsTArray<RefPtr<nsXULTemplateResultRDF> > ResultArray;
  38. nsXULTemplateQueryProcessorRDF();
  39. nsresult InitGlobals();
  40. // nsISupports interface
  41. NS_DECL_CYCLE_COLLECTING_ISUPPORTS
  42. NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsXULTemplateQueryProcessorRDF,
  43. nsIXULTemplateQueryProcessor)
  44. // nsIXULTemplateQueryProcessor interface
  45. NS_DECL_NSIXULTEMPLATEQUERYPROCESSOR
  46. // nsIRDFObserver interface
  47. NS_DECL_NSIRDFOBSERVER
  48. /*
  49. * Propagate all changes through the rule network when an assertion is
  50. * added to the graph, adding any new results.
  51. */
  52. nsresult
  53. Propagate(nsIRDFResource* aSource,
  54. nsIRDFResource* aProperty,
  55. nsIRDFNode* aTarget);
  56. /*
  57. * Retract all changes through the rule network when an assertion is
  58. * removed from the graph, removing any results that no longer match.
  59. */
  60. nsresult
  61. Retract(nsIRDFResource* aSource,
  62. nsIRDFResource* aProperty,
  63. nsIRDFNode* aTarget);
  64. /*
  65. * Synchronize results when the graph changes, updating their bindings.
  66. */
  67. nsresult
  68. SynchronizeAll(nsIRDFResource* aSource,
  69. nsIRDFResource* aProperty,
  70. nsIRDFNode* aOldTarget,
  71. nsIRDFNode* aNewTarget);
  72. /*
  73. * Return true if a resource is a container
  74. */
  75. nsresult
  76. CheckContainer(nsIRDFResource* aTargetResource,
  77. bool* aIsContainer);
  78. /*
  79. * Check if a resource does not have any children
  80. */
  81. nsresult
  82. CheckEmpty(nsIRDFResource* aTargetResource,
  83. bool* aIsEmpty);
  84. /**
  85. * Check if a resource is a separator
  86. */
  87. nsresult
  88. CheckIsSeparator(nsIRDFResource* aResource, bool* aIsSeparator);
  89. /*
  90. * Compute the containment properties which are additional arcs which
  91. * indicate that a node is a container, in additional to the RDF container
  92. * tests. The computed list is stored in mContainmentProperties
  93. */
  94. nsresult
  95. ComputeContainmentProperties(nsIDOMNode* aRootNode);
  96. /**
  97. * Compile a query that uses the extended template syntax. The last
  98. * compiled node of the query is returned as aLastNode. This node will
  99. * have been added to mAllTests which owns the node.
  100. */
  101. nsresult
  102. CompileExtendedQuery(nsRDFQuery* aQuery,
  103. nsIContent* aConditions,
  104. TestNode** aLastNode);
  105. /**
  106. * Compile a single query child and return the compiled node in aResult.
  107. * This node will have been added to mAllTests which owns the node and
  108. * set as a child of aParentNode.
  109. */
  110. virtual nsresult
  111. CompileQueryChild(nsIAtom* aTag,
  112. nsRDFQuery* aQuery,
  113. nsIContent* aConditions,
  114. TestNode* aParentNode,
  115. TestNode** aResult);
  116. /**
  117. * Parse the value of a property test assertion for a condition or a simple
  118. * rule based on the parseType attribute into the appropriate literal type.
  119. */
  120. nsresult ParseLiteral(const nsString& aParseType,
  121. const nsString& aValue,
  122. nsIRDFNode** aResult);
  123. /**
  124. * Compile a <triple> condition and return the compiled node in aResult.
  125. * This node will have been added to mAllTests which owns the node and
  126. * set as a child of aParentNode.
  127. */
  128. nsresult
  129. CompileTripleCondition(nsRDFQuery* aQuery,
  130. nsIContent* aCondition,
  131. TestNode* aParentNode,
  132. TestNode** aResult);
  133. /**
  134. * Compile a <member> condition and return the compiled node in aResult.
  135. * This node will have been added to mAllTests which owns the node and
  136. * set as a child of aParentNode.
  137. */
  138. nsresult
  139. CompileMemberCondition(nsRDFQuery* aQuery,
  140. nsIContent* aCondition,
  141. TestNode* aParentNode,
  142. TestNode** aResult);
  143. /**
  144. * Add the default rules shared by all simple queries. This creates
  145. * the content start node followed by a member test. The member TestNode
  146. * is returned in aChildNode. Both nodes will have been added to mAllTests
  147. * which owns the nodes.
  148. */
  149. nsresult
  150. AddDefaultSimpleRules(nsRDFQuery* aQuery,
  151. TestNode** aChildNode);
  152. /**
  153. * Compile a query that's specified using the simple template
  154. * syntax. Each TestNode is created in a chain, the last compiled node
  155. * is returned as aLastNode. All nodes will have been added to mAllTests
  156. * which owns the nodes.
  157. */
  158. nsresult
  159. CompileSimpleQuery(nsRDFQuery* aQuery,
  160. nsIContent* aQueryElement,
  161. TestNode** aLastNode);
  162. RDFBindingSet*
  163. GetBindingsForRule(nsIDOMNode* aRule);
  164. /*
  165. * Indicate that a result is dependant on a particular resource. When an
  166. * assertion is added to or removed from the graph involving that
  167. * resource, that result must be recalculated.
  168. */
  169. void
  170. AddBindingDependency(nsXULTemplateResultRDF* aResult,
  171. nsIRDFResource* aResource);
  172. /**
  173. * Remove a dependency a result has on a particular resource.
  174. */
  175. void
  176. RemoveBindingDependency(nsXULTemplateResultRDF* aResult,
  177. nsIRDFResource* aResource);
  178. /**
  179. * A memory element is a hash of an RDF triple. One exists for each triple
  180. * that was involved in generating a result. This function adds this to a
  181. * map, keyed by memory element, when the value is a list of results that
  182. * depend on that memory element. When an RDF triple is removed from the
  183. * datasource, RetractElement is called, and this map is examined to
  184. * determine which results are no longer valid.
  185. */
  186. nsresult
  187. AddMemoryElements(const Instantiation& aInst,
  188. nsXULTemplateResultRDF* aResult);
  189. /**
  190. * Remove the memory elements associated with a result when the result is
  191. * no longer being used.
  192. */
  193. nsresult
  194. RemoveMemoryElements(const Instantiation& aInst,
  195. nsXULTemplateResultRDF* aResult);
  196. /**
  197. * Remove the results associated with a memory element since the
  198. * RDF triple the memory element is a hash of has been removed.
  199. */
  200. void RetractElement(const MemoryElement& aMemoryElement);
  201. /**
  202. * Return the index of a result's resource in its RDF container
  203. */
  204. int32_t
  205. GetContainerIndexOf(nsIXULTemplateResult* aResult);
  206. /**
  207. * Given a result and a predicate to sort on, get the target value of
  208. * the triple to use for sorting. The sort predicate is the predicate
  209. * with '?sort=true' appended.
  210. */
  211. nsresult
  212. GetSortValue(nsIXULTemplateResult* aResult,
  213. nsIRDFResource* aPredicate,
  214. nsIRDFResource* aSortPredicate,
  215. nsISupports** aResultNode);
  216. nsIRDFDataSource* GetDataSource() { return mDB; }
  217. nsIXULTemplateBuilder* GetBuilder() { return mBuilder; }
  218. nsResourceSet& ContainmentProperties() { return mContainmentProperties; }
  219. nsresult
  220. Log(const char* aOperation,
  221. nsIRDFResource* aSource,
  222. nsIRDFResource* aProperty,
  223. nsIRDFNode* aTarget);
  224. #define LOG(_op, _src, _prop, _targ) \
  225. Log(_op, _src, _prop, _targ)
  226. protected:
  227. ~nsXULTemplateQueryProcessorRDF();
  228. // We are an observer of the composite datasource. The cycle is
  229. // broken when the document is destroyed.
  230. nsCOMPtr<nsIRDFDataSource> mDB;
  231. // weak reference to the builder, cleared when the document is destroyed
  232. nsIXULTemplateBuilder* mBuilder;
  233. // true if the query processor has been initialized
  234. bool mQueryProcessorRDFInited;
  235. // true if results have been generated. Once set, bindings can no longer
  236. // be added. If they were, the binding value arrays for results that have
  237. // already been generated would be the wrong size
  238. bool mGenerationStarted;
  239. // nesting level for RDF batch notifications
  240. int32_t mUpdateBatchNest;
  241. // containment properties that are checked to determine if a resource is
  242. // a container
  243. nsResourceSet mContainmentProperties;
  244. // the end node of the default simple node hierarchy
  245. TestNode* mSimpleRuleMemberTest;
  246. // the reference variable
  247. nsCOMPtr<nsIAtom> mRefVariable;
  248. // the last ref that was calculated, used for simple rules
  249. nsCOMPtr<nsIXULTemplateResult> mLastRef;
  250. /**
  251. * A map between nsIRDFNodes that form the left-hand side (the subject) of
  252. * a <binding> and an array of nsIXULTemplateResults. When a new assertion
  253. * is added to the graph involving a particular rdf node, it is looked up
  254. * in this binding map. If it exists, the corresponding results must then
  255. * be synchronized.
  256. */
  257. nsClassHashtable<nsISupportsHashKey, ResultArray> mBindingDependencies;
  258. /**
  259. * A map between memory elements and an array of nsIXULTemplateResults.
  260. * When a triple is unasserted from the graph, the corresponding results
  261. * no longer match so they must be removed.
  262. */
  263. nsClassHashtable<nsUint32HashKey,
  264. nsCOMArray<nsXULTemplateResultRDF> > mMemoryElementToResultMap;
  265. // map of the rules to the bindings for those rules.
  266. // XXXndeakin this might be better just as an array since there is usually
  267. // ten or fewer rules
  268. nsRefPtrHashtable<nsISupportsHashKey, RDFBindingSet> mRuleToBindingsMap;
  269. /**
  270. * The queries
  271. */
  272. nsTArray<nsCOMPtr<nsITemplateRDFQuery> > mQueries;
  273. /**
  274. * All of the RDF tests in the rule network, which are checked when a new
  275. * assertion is added to the graph. This is a subset of mAllTests, which
  276. * also includes non-RDF tests.
  277. */
  278. ReteNodeSet mRDFTests;
  279. /**
  280. * All of the tests in the rule network, owned by this list
  281. */
  282. ReteNodeSet mAllTests;
  283. // pseudo-constants
  284. static nsrefcnt gRefCnt;
  285. public:
  286. static nsIRDFService* gRDFService;
  287. static nsIRDFContainerUtils* gRDFContainerUtils;
  288. static nsIRDFResource* kNC_BookmarkSeparator;
  289. static nsIRDFResource* kRDF_type;
  290. };
  291. #endif // nsXULTemplateQueryProcessorRDF_h__