123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350 |
- /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
- /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- #ifndef nsXULTemplateQueryProcessorRDF_h__
- #define nsXULTemplateQueryProcessorRDF_h__
- #include "nsIRDFContainer.h"
- #include "nsIRDFContainerUtils.h"
- #include "nsIRDFDataSource.h"
- #include "nsIRDFObserver.h"
- #include "nsIRDFService.h"
- #include "nsIXULTemplateBuilder.h"
- #include "nsIXULTemplateQueryProcessor.h"
- #include "nsCollationCID.h"
- #include "nsResourceSet.h"
- #include "nsRuleNetwork.h"
- #include "nsRDFQuery.h"
- #include "nsRDFBinding.h"
- #include "nsXULTemplateResultSetRDF.h"
- #include "nsCOMArray.h"
- #include "nsString.h"
- #include "nsClassHashtable.h"
- #include "nsRefPtrHashtable.h"
- #include "nsCycleCollectionParticipant.h"
- #include "mozilla/Attributes.h"
- #include "mozilla/Logging.h"
- extern mozilla::LazyLogModule gXULTemplateLog;
- class nsIContent;
- class nsXULTemplateResultRDF;
- /**
- * An object that generates results from a query on an RDF graph
- */
- class nsXULTemplateQueryProcessorRDF final : public nsIXULTemplateQueryProcessor,
- public nsIRDFObserver
- {
- public:
- typedef nsTArray<RefPtr<nsXULTemplateResultRDF> > ResultArray;
- nsXULTemplateQueryProcessorRDF();
- nsresult InitGlobals();
- // nsISupports interface
- NS_DECL_CYCLE_COLLECTING_ISUPPORTS
- NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsXULTemplateQueryProcessorRDF,
- nsIXULTemplateQueryProcessor)
- // nsIXULTemplateQueryProcessor interface
- NS_DECL_NSIXULTEMPLATEQUERYPROCESSOR
-
- // nsIRDFObserver interface
- NS_DECL_NSIRDFOBSERVER
- /*
- * Propagate all changes through the rule network when an assertion is
- * added to the graph, adding any new results.
- */
- nsresult
- Propagate(nsIRDFResource* aSource,
- nsIRDFResource* aProperty,
- nsIRDFNode* aTarget);
- /*
- * Retract all changes through the rule network when an assertion is
- * removed from the graph, removing any results that no longer match.
- */
- nsresult
- Retract(nsIRDFResource* aSource,
- nsIRDFResource* aProperty,
- nsIRDFNode* aTarget);
- /*
- * Synchronize results when the graph changes, updating their bindings.
- */
- nsresult
- SynchronizeAll(nsIRDFResource* aSource,
- nsIRDFResource* aProperty,
- nsIRDFNode* aOldTarget,
- nsIRDFNode* aNewTarget);
- /*
- * Return true if a resource is a container
- */
- nsresult
- CheckContainer(nsIRDFResource* aTargetResource,
- bool* aIsContainer);
- /*
- * Check if a resource does not have any children
- */
- nsresult
- CheckEmpty(nsIRDFResource* aTargetResource,
- bool* aIsEmpty);
- /**
- * Check if a resource is a separator
- */
- nsresult
- CheckIsSeparator(nsIRDFResource* aResource, bool* aIsSeparator);
- /*
- * Compute the containment properties which are additional arcs which
- * indicate that a node is a container, in additional to the RDF container
- * tests. The computed list is stored in mContainmentProperties
- */
- nsresult
- ComputeContainmentProperties(nsIDOMNode* aRootNode);
- /**
- * Compile a query that uses the extended template syntax. The last
- * compiled node of the query is returned as aLastNode. This node will
- * have been added to mAllTests which owns the node.
- */
- nsresult
- CompileExtendedQuery(nsRDFQuery* aQuery,
- nsIContent* aConditions,
- TestNode** aLastNode);
- /**
- * Compile a single query child and return the compiled node in aResult.
- * This node will have been added to mAllTests which owns the node and
- * set as a child of aParentNode.
- */
- virtual nsresult
- CompileQueryChild(nsIAtom* aTag,
- nsRDFQuery* aQuery,
- nsIContent* aConditions,
- TestNode* aParentNode,
- TestNode** aResult);
- /**
- * Parse the value of a property test assertion for a condition or a simple
- * rule based on the parseType attribute into the appropriate literal type.
- */
- nsresult ParseLiteral(const nsString& aParseType,
- const nsString& aValue,
- nsIRDFNode** aResult);
- /**
- * Compile a <triple> condition and return the compiled node in aResult.
- * This node will have been added to mAllTests which owns the node and
- * set as a child of aParentNode.
- */
- nsresult
- CompileTripleCondition(nsRDFQuery* aQuery,
- nsIContent* aCondition,
- TestNode* aParentNode,
- TestNode** aResult);
- /**
- * Compile a <member> condition and return the compiled node in aResult.
- * This node will have been added to mAllTests which owns the node and
- * set as a child of aParentNode.
- */
- nsresult
- CompileMemberCondition(nsRDFQuery* aQuery,
- nsIContent* aCondition,
- TestNode* aParentNode,
- TestNode** aResult);
- /**
- * Add the default rules shared by all simple queries. This creates
- * the content start node followed by a member test. The member TestNode
- * is returned in aChildNode. Both nodes will have been added to mAllTests
- * which owns the nodes.
- */
- nsresult
- AddDefaultSimpleRules(nsRDFQuery* aQuery,
- TestNode** aChildNode);
- /**
- * Compile a query that's specified using the simple template
- * syntax. Each TestNode is created in a chain, the last compiled node
- * is returned as aLastNode. All nodes will have been added to mAllTests
- * which owns the nodes.
- */
- nsresult
- CompileSimpleQuery(nsRDFQuery* aQuery,
- nsIContent* aQueryElement,
- TestNode** aLastNode);
- RDFBindingSet*
- GetBindingsForRule(nsIDOMNode* aRule);
- /*
- * Indicate that a result is dependant on a particular resource. When an
- * assertion is added to or removed from the graph involving that
- * resource, that result must be recalculated.
- */
- void
- AddBindingDependency(nsXULTemplateResultRDF* aResult,
- nsIRDFResource* aResource);
- /**
- * Remove a dependency a result has on a particular resource.
- */
- void
- RemoveBindingDependency(nsXULTemplateResultRDF* aResult,
- nsIRDFResource* aResource);
- /**
- * A memory element is a hash of an RDF triple. One exists for each triple
- * that was involved in generating a result. This function adds this to a
- * map, keyed by memory element, when the value is a list of results that
- * depend on that memory element. When an RDF triple is removed from the
- * datasource, RetractElement is called, and this map is examined to
- * determine which results are no longer valid.
- */
- nsresult
- AddMemoryElements(const Instantiation& aInst,
- nsXULTemplateResultRDF* aResult);
- /**
- * Remove the memory elements associated with a result when the result is
- * no longer being used.
- */
- nsresult
- RemoveMemoryElements(const Instantiation& aInst,
- nsXULTemplateResultRDF* aResult);
- /**
- * Remove the results associated with a memory element since the
- * RDF triple the memory element is a hash of has been removed.
- */
- void RetractElement(const MemoryElement& aMemoryElement);
- /**
- * Return the index of a result's resource in its RDF container
- */
- int32_t
- GetContainerIndexOf(nsIXULTemplateResult* aResult);
- /**
- * Given a result and a predicate to sort on, get the target value of
- * the triple to use for sorting. The sort predicate is the predicate
- * with '?sort=true' appended.
- */
- nsresult
- GetSortValue(nsIXULTemplateResult* aResult,
- nsIRDFResource* aPredicate,
- nsIRDFResource* aSortPredicate,
- nsISupports** aResultNode);
- nsIRDFDataSource* GetDataSource() { return mDB; }
- nsIXULTemplateBuilder* GetBuilder() { return mBuilder; }
- nsResourceSet& ContainmentProperties() { return mContainmentProperties; }
- nsresult
- Log(const char* aOperation,
- nsIRDFResource* aSource,
- nsIRDFResource* aProperty,
- nsIRDFNode* aTarget);
- #define LOG(_op, _src, _prop, _targ) \
- Log(_op, _src, _prop, _targ)
- protected:
- ~nsXULTemplateQueryProcessorRDF();
- // We are an observer of the composite datasource. The cycle is
- // broken when the document is destroyed.
- nsCOMPtr<nsIRDFDataSource> mDB;
- // weak reference to the builder, cleared when the document is destroyed
- nsIXULTemplateBuilder* mBuilder;
- // true if the query processor has been initialized
- bool mQueryProcessorRDFInited;
- // true if results have been generated. Once set, bindings can no longer
- // be added. If they were, the binding value arrays for results that have
- // already been generated would be the wrong size
- bool mGenerationStarted;
- // nesting level for RDF batch notifications
- int32_t mUpdateBatchNest;
- // containment properties that are checked to determine if a resource is
- // a container
- nsResourceSet mContainmentProperties;
- // the end node of the default simple node hierarchy
- TestNode* mSimpleRuleMemberTest;
- // the reference variable
- nsCOMPtr<nsIAtom> mRefVariable;
- // the last ref that was calculated, used for simple rules
- nsCOMPtr<nsIXULTemplateResult> mLastRef;
- /**
- * A map between nsIRDFNodes that form the left-hand side (the subject) of
- * a <binding> and an array of nsIXULTemplateResults. When a new assertion
- * is added to the graph involving a particular rdf node, it is looked up
- * in this binding map. If it exists, the corresponding results must then
- * be synchronized.
- */
- nsClassHashtable<nsISupportsHashKey, ResultArray> mBindingDependencies;
- /**
- * A map between memory elements and an array of nsIXULTemplateResults.
- * When a triple is unasserted from the graph, the corresponding results
- * no longer match so they must be removed.
- */
- nsClassHashtable<nsUint32HashKey,
- nsCOMArray<nsXULTemplateResultRDF> > mMemoryElementToResultMap;
- // map of the rules to the bindings for those rules.
- // XXXndeakin this might be better just as an array since there is usually
- // ten or fewer rules
- nsRefPtrHashtable<nsISupportsHashKey, RDFBindingSet> mRuleToBindingsMap;
- /**
- * The queries
- */
- nsTArray<nsCOMPtr<nsITemplateRDFQuery> > mQueries;
- /**
- * All of the RDF tests in the rule network, which are checked when a new
- * assertion is added to the graph. This is a subset of mAllTests, which
- * also includes non-RDF tests.
- */
- ReteNodeSet mRDFTests;
- /**
- * All of the tests in the rule network, owned by this list
- */
- ReteNodeSet mAllTests;
- // pseudo-constants
- static nsrefcnt gRefCnt;
- public:
- static nsIRDFService* gRDFService;
- static nsIRDFContainerUtils* gRDFContainerUtils;
- static nsIRDFResource* kNC_BookmarkSeparator;
- static nsIRDFResource* kRDF_type;
- };
- #endif // nsXULTemplateQueryProcessorRDF_h__
|