1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/content/xul/templates/src/nsRDFBinding.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,217 @@ 1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#ifndef nsRDFBinding_h__ 1.10 +#define nsRDFBinding_h__ 1.11 + 1.12 +#include "nsAutoPtr.h" 1.13 +#include "nsIAtom.h" 1.14 +#include "nsIRDFResource.h" 1.15 +#include "nsISupportsImpl.h" 1.16 + 1.17 +class nsXULTemplateResultRDF; 1.18 +class nsBindingValues; 1.19 + 1.20 +/* 1.21 + * Classes related to storing bindings for RDF handling. 1.22 + */ 1.23 + 1.24 +/* 1.25 + * a <binding> descriptors 1.26 + */ 1.27 +class RDFBinding { 1.28 + 1.29 +public: 1.30 + 1.31 + nsCOMPtr<nsIAtom> mSubjectVariable; 1.32 + nsCOMPtr<nsIRDFResource> mPredicate; 1.33 + nsCOMPtr<nsIAtom> mTargetVariable; 1.34 + 1.35 + // indicates whether a binding is dependant on the result from a 1.36 + // previous binding 1.37 + bool mHasDependency; 1.38 + 1.39 + RDFBinding* mNext; 1.40 + 1.41 +private: 1.42 + 1.43 + friend class RDFBindingSet; 1.44 + 1.45 + RDFBinding(nsIAtom* aSubjectVariable, 1.46 + nsIRDFResource* aPredicate, 1.47 + nsIAtom* aTargetVariable) 1.48 + : mSubjectVariable(aSubjectVariable), 1.49 + mPredicate(aPredicate), 1.50 + mTargetVariable(aTargetVariable), 1.51 + mHasDependency(false), 1.52 + mNext(nullptr) 1.53 + { 1.54 + MOZ_COUNT_CTOR(RDFBinding); 1.55 + } 1.56 + 1.57 + ~RDFBinding() 1.58 + { 1.59 + MOZ_COUNT_DTOR(RDFBinding); 1.60 + } 1.61 +}; 1.62 + 1.63 +/* 1.64 + * a collection of <binding> descriptors. This object is refcounted by 1.65 + * nsBindingValues objects and the query processor. 1.66 + */ 1.67 +class RDFBindingSet MOZ_FINAL 1.68 +{ 1.69 +private: 1.70 + // Private destructor, to discourage deletion outside of Release(): 1.71 + ~RDFBindingSet(); 1.72 + 1.73 + // the number of bindings 1.74 + int32_t mCount; 1.75 + 1.76 + // pointer to the first binding in a linked list 1.77 + RDFBinding* mFirst; 1.78 + 1.79 +public: 1.80 + 1.81 + RDFBindingSet() 1.82 + : mCount(0), 1.83 + mFirst(nullptr) 1.84 + { 1.85 + MOZ_COUNT_CTOR(RDFBindingSet); 1.86 + } 1.87 + 1.88 + NS_INLINE_DECL_REFCOUNTING(RDFBindingSet) 1.89 + 1.90 + int32_t Count() const { return mCount; } 1.91 + 1.92 + /* 1.93 + * Add a binding (aRef -> aPredicate -> aVar) to the set 1.94 + */ 1.95 + nsresult 1.96 + AddBinding(nsIAtom* aVar, nsIAtom* aRef, nsIRDFResource* aPredicate); 1.97 + 1.98 + /* 1.99 + * Return true if the binding set contains a binding which would cause 1.100 + * the result to need resynchronizing for an RDF triple. The member 1.101 + * variable may be supplied as an optimization since bindings most 1.102 + * commonly use the member variable as the subject. If aMemberVariable 1.103 + * is set, aSubject must be the value of the member variable for the 1.104 + * result. The supplied binding values aBindingValues must be values 1.105 + * using this binding set (that is aBindingValues->GetBindingSet() == this) 1.106 + * 1.107 + * @param aSubject subject of the RDF triple 1.108 + * @param aPredicate predicate of the RDF triple 1.109 + * @param aTarget target of the RDF triple 1.110 + * @param aMemberVariable member variable for the query for the binding 1.111 + * @param aResult result to synchronize 1.112 + * @param aBindingValues the values for the bindings for the result 1.113 + */ 1.114 + bool 1.115 + SyncAssignments(nsIRDFResource* aSubject, 1.116 + nsIRDFResource* aPredicate, 1.117 + nsIRDFNode* aTarget, 1.118 + nsIAtom* aMemberVariable, 1.119 + nsXULTemplateResultRDF* aResult, 1.120 + nsBindingValues& aBindingValues); 1.121 + 1.122 + /* 1.123 + * The query processor maintains a map of subjects to an array of results. 1.124 + * This is used such that when a new assertion is added to the RDF graph, 1.125 + * the results associated with the subject of that triple may be checked 1.126 + * to see if their bindings have changed. The AddDependencies method adds 1.127 + * these subject dependencies to the map. 1.128 + */ 1.129 + void 1.130 + AddDependencies(nsIRDFResource* aSubject, 1.131 + nsXULTemplateResultRDF* aResult); 1.132 + 1.133 + /* 1.134 + * Remove the results from the dependencies map when results are deleted. 1.135 + */ 1.136 + void 1.137 + RemoveDependencies(nsIRDFResource* aSubject, 1.138 + nsXULTemplateResultRDF* aResult); 1.139 + 1.140 + /* 1.141 + * The nsBindingValues classes stores an array of values, one for each 1.142 + * target symbol that could be set by the bindings in the set. 1.143 + * LookupTargetIndex determines the index into the array for a given 1.144 + * target symbol. 1.145 + */ 1.146 + int32_t 1.147 + LookupTargetIndex(nsIAtom* aTargetVariable, RDFBinding** aBinding); 1.148 +}; 1.149 + 1.150 +/* 1.151 + * A set of values of bindings. This object is used once per result. 1.152 + * This stores a reference to the binding set and an array of node values. 1.153 + * Since the binding set is used once per query and the values are 1.154 + * used once per result, we reduce size by only storing the value array's 1.155 + * length in the binding set. This is possible since the array is always 1.156 + * a fixed length for a particular binding set. 1.157 + * 1.158 + * XXX ndeakin We may want to revisit this later since it makes the code 1.159 + * more complicated. 1.160 + */ 1.161 +class nsBindingValues 1.162 +{ 1.163 +protected: 1.164 + 1.165 + // the binding set 1.166 + nsRefPtr<RDFBindingSet> mBindings; 1.167 + 1.168 + /* 1.169 + * A set of values for variable bindings. To look up a binding value, 1.170 + * scan through the binding set in mBindings for the right target atom. 1.171 + * Its index will correspond to the index in this array. The size of this 1.172 + * array is determined by the RDFBindingSet's Count(). 1.173 + */ 1.174 + nsCOMPtr<nsIRDFNode>* mValues; 1.175 + 1.176 +public: 1.177 + 1.178 + nsBindingValues() 1.179 + : mBindings(nullptr), 1.180 + mValues(nullptr) 1.181 + { 1.182 + MOZ_COUNT_CTOR(nsBindingValues); 1.183 + } 1.184 + 1.185 + ~nsBindingValues(); 1.186 + 1.187 + 1.188 + /** 1.189 + * Clear the binding set, to be called when the nsBindingValues is deleted 1.190 + * or a new binding set is being set. 1.191 + */ 1.192 + void ClearBindingSet(); 1.193 + 1.194 + RDFBindingSet* GetBindingSet() { return mBindings; } 1.195 + 1.196 + /** 1.197 + * Set the binding set to use. This needs to be called once a rule matches 1.198 + * since it is then known which bindings will apply. 1.199 + */ 1.200 + nsresult SetBindingSet(RDFBindingSet* aBindings); 1.201 + 1.202 + nsCOMPtr<nsIRDFNode>* ValuesArray() { return mValues; } 1.203 + 1.204 + /* 1.205 + * Retrieve the assignment for a particular variable 1.206 + */ 1.207 + void 1.208 + GetAssignmentFor(nsXULTemplateResultRDF* aResult, 1.209 + nsIAtom* aVar, 1.210 + nsIRDFNode** aValue); 1.211 + 1.212 + /* 1.213 + * Remove depenedencies the bindings have on particular resources 1.214 + */ 1.215 + void 1.216 + RemoveDependencies(nsIRDFResource* aSubject, 1.217 + nsXULTemplateResultRDF* aResult); 1.218 +}; 1.219 + 1.220 +#endif // nsRDFBinding_h__