/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is Mozilla Communicator client code. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1998 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Chris Waterson * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ #ifndef nsTemplateRule_h__ #define nsTemplateRule_h__ #include "nsCOMPtr.h" #include "nsIRDFDataSource.h" #include "nsIRDFResource.h" #include "nsIContent.h" class nsConflictSet; class nsTemplateMatch; class Value; class VariableSet; /** * A rule consists of: * * - Conditions, a set of unbound variables with consistency * constraints that specify the values that each variable can * assume. The conditions must be completely and consistently * "bound" for the rule to be considered "matched". * * - Bindings, a set of unbound variables with consistency constraints * that specify the values that each variable can assume. Unlike the * conditions, the bindings need not be bound for the rule to be * considered matched. * * - Content that should be constructed when the rule is "activated". * * - Priority, which helps to determine which rule should be * considered "active" if several rules "match". * */ class nsTemplateRule { public: nsTemplateRule(nsIRDFDataSource* aDataSource, nsIContent* aContent, PRInt32 aPriority) : mDataSource(aDataSource), mContent(aContent), mContainerVariable(0), mMemberVariable(0), mPriority(aPriority), mCount(0), mCapacity(0), mBindings(nsnull) { MOZ_COUNT_CTOR(nsTemplateRule); } ~nsTemplateRule(); /** * Return the content node that this rule was constructed from. * @param aResult an out parameter, which will contain the content node * that this rule was constructed from * @return NS_OK if no errors occur. */ nsresult GetContent(nsIContent** aResult) const; /** * Set the variable which should be used as the "container * variable" in this rule. The container variable will be bound to * an RDF resource that is the parent of the member resources. * @param aContainerVariable the variable that should be used as the * "container variable" in this rule */ void SetContainerVariable(PRInt32 aContainerVariable) { mContainerVariable = aContainerVariable; } /** * Retrieve the variable that this rule uses as its "container variable". * @return the variable that this rule uses as its "container variable". */ PRInt32 GetContainerVariable() const { return mContainerVariable; } /** * Set the variable which should be used as the "member variable" * in this rule. The member variable will be bound to an RDF * resource that is the child of the container resource. * @param aMemberVariable the variable that should be used as the * "member variable" in this rule. */ void SetMemberVariable(PRInt32 aMemberVariable) { mMemberVariable = aMemberVariable; } /** * Retrieve the variable that this rule uses as its "member variable". * @return the variable that this rule uses as its "member variable" */ PRInt32 GetMemberVariable() const { return mMemberVariable; } /** * Retrieve the "priority" of the rule with respect to the * other rules in the template * @return the rule's priority, lower values mean "use this first". */ PRInt32 GetPriority() const { return mPriority; } /** * Determine if the rule has the specified binding */ PRBool HasBinding(PRInt32 aSourceVariable, nsIRDFResource* aProperty, PRInt32 aTargetVariable) const; /** * Add a binding to the rule. A binding consists of an already-bound * source variable, and the RDF property that should be tested to * generate a target value. The target value is bound to a target * variable. * * @param aSourceVariable the source variable that will be used in * the RDF query. * @param aProperty the RDF property that will be used in the RDF * query. * @param aTargetVariable the variable whose value will be bound * to the RDF node that is returned when querying the binding * @return NS_OK if no errors occur. */ nsresult AddBinding(PRInt32 aSourceVariable, nsIRDFResource* aProperty, PRInt32 aTargetVariable); /** * Initialize a match by adding necessary binding dependencies to * the conflict set. This will allow us to properly update the * match later if a value should change that the match's bindings * depend on. * @param aConflictSet the conflict set * @param aMatch the match we to initialize * @return NS_OK if no errors occur. */ nsresult InitBindings(nsConflictSet& aConflictSet, nsTemplateMatch* aMatch) const; /** * Compute the minimal set of changes to a match's bindings that * must occur which the specified change is made to the RDF graph. * @param aConflictSet the conflict set, which we may need to manipulate * to update the binding dependencies. * @param aMatch the match for which we must recompute the bindings * @param aSource the "source" resource in the RDF graph * @param aProperty the "property" resource in the RDF graph * @param aOldTarget the old "target" node in the RDF graph * @param aNewTarget the new "target" node in the RDF graph. * @param aModifiedVars a VariableSet, into which this routine * will assign each variable whose value has changed. * @return NS_OK if no errors occurred. */ nsresult RecomputeBindings(nsConflictSet& aConflictSet, nsTemplateMatch* aMatch, nsIRDFResource* aSource, nsIRDFResource* aProperty, nsIRDFNode* aOldTarget, nsIRDFNode* aNewTarget, VariableSet& aModifiedVars) const; /** * Compute the value to assign to an arbitrary variable in a * match. This may require us to work out several dependancies, * if there are bindings set up for this rule. * @param aConflictSet the conflict set; if necessary, we may add * a "binding dependency" to the conflict set, which will allow us * to correctly recompute the bindings later if they should change. * @param aMatch the match that provides the "seed" variable assignments, * which we may need to extend using the rule's bindings. * @param aVariable the variable for which we are to compute the * assignment. * @param aValue an out parameter that will receive the value that * was assigned to aVariable, if we could find one. * @return PR_TRUE if an assignment was found for aVariable, PR_FALSE * otherwise. */ PRBool ComputeAssignmentFor(nsConflictSet& aConflictSet, nsTemplateMatch* aMatch, PRInt32 aVariable, Value* aValue) const; /** * Determine if one variable depends on another in the rule's * bindings. * @param aChild the dependent variable, whose value may * depend on the assignment of aParent. * @param aParent the variable whose value aChild is depending on. * @return PR_TRUE if aChild's assignment depends on the assignment * for aParent, PR_FALSE otherwise. */ PRBool DependsOn(PRInt32 aChild, PRInt32 aParent) const; protected: nsCOMPtr mDataSource; nsCOMPtr mContent; PRInt32 mContainerVariable; PRInt32 mMemberVariable; PRInt32 mPriority; PRInt32 mCount; PRInt32 mCapacity; struct Binding { PRInt32 mSourceVariable; nsCOMPtr mProperty; PRInt32 mTargetVariable; Binding* mNext; Binding* mParent; }; Binding* mBindings; }; #endif // nsTemplateRule_h__