From: helge Date: Wed, 22 Dec 2004 07:21:08 +0000 (+0000) Subject: added some NGRule documentation X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b8f9536cc5c70723e7f973cc5c2f26b5b6632e2d;p=sope added some NGRule documentation git-svn-id: http://svn.opengroupware.org/SOPE/trunk@459 e4a50df8-12e2-0310-a44c-efbce7f8a7e3 --- diff --git a/sope-core/NGExtensions/NGExtensions/NGRuleAssignment.h b/sope-core/NGExtensions/NGExtensions/NGRuleAssignment.h index 86d65368..bbfc3196 100644 --- a/sope-core/NGExtensions/NGExtensions/NGRuleAssignment.h +++ b/sope-core/NGExtensions/NGExtensions/NGRuleAssignment.h @@ -1,7 +1,7 @@ /* - Copyright (C) 2000-2003 SKYRIX Software AG + Copyright (C) 2000-2004 SKYRIX Software AG - This file is part of OGo + This file is part of OpenGroupware.org. OGo is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the @@ -18,7 +18,6 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -// $Id$ #ifndef __NGRuleEngine_NGRuleAssignment_H__ #define __NGRuleEngine_NGRuleAssignment_H__ diff --git a/sope-core/NGExtensions/NGExtensions/NGRuleContext.h b/sope-core/NGExtensions/NGExtensions/NGRuleContext.h index 7cc57b6b..23878199 100644 --- a/sope-core/NGExtensions/NGExtensions/NGRuleContext.h +++ b/sope-core/NGExtensions/NGExtensions/NGRuleContext.h @@ -1,7 +1,7 @@ /* - Copyright (C) 2000-2003 SKYRIX Software AG + Copyright (C) 2000-2004 SKYRIX Software AG - This file is part of OGo + This file is part of OpenGroupware.org. OGo is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the @@ -18,7 +18,6 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -// $Id$ #ifndef __NGRuleEngine_NGRuleContext_H__ #define __NGRuleEngine_NGRuleContext_H__ diff --git a/sope-core/NGExtensions/NGExtensions/NGRuleModel.h b/sope-core/NGExtensions/NGExtensions/NGRuleModel.h index f4c7a53d..661aefd6 100644 --- a/sope-core/NGExtensions/NGExtensions/NGRuleModel.h +++ b/sope-core/NGExtensions/NGExtensions/NGRuleModel.h @@ -1,7 +1,7 @@ /* - Copyright (C) 2000-2003 SKYRIX Software AG + Copyright (C) 2000-2004 SKYRIX Software AG - This file is part of OGo + This file is part of OpenGroupware.org. OGo is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the @@ -18,7 +18,6 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -// $Id$ #ifndef __NGRuleEngine_NGRuleModel_H__ #define __NGRuleEngine_NGRuleModel_H__ diff --git a/sope-core/NGExtensions/NGRuleEngine.subproj/NGRule.m b/sope-core/NGExtensions/NGRuleEngine.subproj/NGRule.m index 6c30acb0..3d69ab26 100644 --- a/sope-core/NGExtensions/NGRuleEngine.subproj/NGRule.m +++ b/sope-core/NGExtensions/NGRuleEngine.subproj/NGRule.m @@ -1,7 +1,7 @@ /* - Copyright (C) 2000-2003 SKYRIX Software AG + Copyright (C) 2003-2004 SKYRIX Software AG - This file is part of OGo + This file is part of OpenGroupware.org. OGo is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the @@ -18,7 +18,6 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -// $Id$ #include "NGRule.h" #include "NGRuleAssignment.h" diff --git a/sope-core/NGExtensions/NGRuleEngine.subproj/NGRuleAssignment.m b/sope-core/NGExtensions/NGRuleEngine.subproj/NGRuleAssignment.m index 549d7d79..696ccd8e 100644 --- a/sope-core/NGExtensions/NGRuleEngine.subproj/NGRuleAssignment.m +++ b/sope-core/NGExtensions/NGRuleEngine.subproj/NGRuleAssignment.m @@ -1,7 +1,7 @@ /* - Copyright (C) 2000-2003 SKYRIX Software AG + Copyright (C) 2003-2004 SKYRIX Software AG - This file is part of OGo + This file is part of OpenGroupware.org. OGo is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the @@ -18,7 +18,6 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -// $Id$ #include "NGRuleAssignment.h" #include "common.h" diff --git a/sope-core/NGExtensions/NGRuleEngine.subproj/NGRuleContext.m b/sope-core/NGExtensions/NGRuleEngine.subproj/NGRuleContext.m index d33db7c9..b5980ef5 100644 --- a/sope-core/NGExtensions/NGRuleEngine.subproj/NGRuleContext.m +++ b/sope-core/NGExtensions/NGRuleEngine.subproj/NGRuleContext.m @@ -1,7 +1,7 @@ /* - Copyright (C) 2000-2003 SKYRIX Software AG + Copyright (C) 2003-2004 SKYRIX Software AG - This file is part of OGo + This file is part of OpenGroupware.org. OGo is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the @@ -18,7 +18,6 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -// $Id$ #include "NGRuleContext.h" #include "NGRule.h" @@ -93,7 +92,7 @@ /* processing */ - (id)inferredValueForKey:(NSString *)_key { - NSArray *rules; + NSArray *rules; unsigned i, count; if (self->debugOn) diff --git a/sope-core/NGExtensions/NGRuleEngine.subproj/NGRuleModel.m b/sope-core/NGExtensions/NGRuleEngine.subproj/NGRuleModel.m index 1ab441ed..bf21dc97 100644 --- a/sope-core/NGExtensions/NGRuleEngine.subproj/NGRuleModel.m +++ b/sope-core/NGExtensions/NGRuleEngine.subproj/NGRuleModel.m @@ -1,7 +1,7 @@ /* - Copyright (C) 2000-2003 SKYRIX Software AG + Copyright (C) 2003-2004 SKYRIX Software AG - This file is part of OGo + This file is part of OpenGroupware.org. OGo is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the @@ -18,7 +18,6 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -// $Id$ #include "NGRuleModel.h" #include "NGRule.h" diff --git a/sope-core/NGExtensions/NGRuleEngine.subproj/NGRuleParser.h b/sope-core/NGExtensions/NGRuleEngine.subproj/NGRuleParser.h index bf8d9f5a..1e11f154 100644 --- a/sope-core/NGExtensions/NGRuleEngine.subproj/NGRuleParser.h +++ b/sope-core/NGExtensions/NGRuleEngine.subproj/NGRuleParser.h @@ -1,7 +1,7 @@ /* - Copyright (C) 2000-2003 SKYRIX Software AG + Copyright (C) 2003-2004 SKYRIX Software AG - This file is part of OGo + This file is part of OpenGroupware.org. OGo is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the @@ -18,7 +18,6 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -// $Id$ #ifndef __NGRuleEngine_NGRuleParser_H__ #define __NGRuleEngine_NGRuleParser_H__ diff --git a/sope-core/NGExtensions/NGRuleEngine.subproj/NGRuleParser.m b/sope-core/NGExtensions/NGRuleEngine.subproj/NGRuleParser.m index 21bd4ead..f141c209 100644 --- a/sope-core/NGExtensions/NGRuleEngine.subproj/NGRuleParser.m +++ b/sope-core/NGExtensions/NGRuleEngine.subproj/NGRuleParser.m @@ -1,7 +1,7 @@ /* - Copyright (C) 2000-2003 SKYRIX Software AG + Copyright (C) 2003-2004 SKYRIX Software AG - This file is part of OGo + This file is part of OpenGroupware.org. OGo is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the @@ -18,7 +18,6 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -// $Id$ #include "NGRuleParser.h" #include "NGRule.h" @@ -33,6 +32,7 @@ // TODO: proper reports errors in last-exception ! // TODO: improve performance +// TODO: parse assignment class? (eg "a = b; (BoolAssignment)") #define RULE_PRIORITY_NORMAL 100 diff --git a/sope-core/NGExtensions/NGRuleEngine.subproj/README b/sope-core/NGExtensions/NGRuleEngine.subproj/README index 906bc085..f14b0c15 100644 --- a/sope-core/NGExtensions/NGRuleEngine.subproj/README +++ b/sope-core/NGExtensions/NGRuleEngine.subproj/README @@ -1,10 +1,10 @@ -# $Id$ - NGRuleEngine ============ This is a rule engine inspired by the "BDRuleEngine" available from -bDistributed.com (www.bdistributed.com). +bDistributed.com (www.bdistributed.com) which in turn is inspired by the +direct to web framework which is part of WebObjects. + We have choosen different class names, so that NGExtensions can be used together with the BDRuleEngine framework. @@ -17,6 +17,187 @@ classes: NGRuleContext NSRuleModel + +How does it work? +================= + +The rule engine is an evaluator for a set of rules which map to values. It can +be used to make all kinds of actions configurable without being required to +write code. + +Example Ruleset: + ( + "context.soRequestType='WebDAV' => renderer = 'SoWebDAVRenderer' ; high", + "context.soRequestType='XML-RPC' => renderer = 'SoXmlRpcRenderer' ; high", + "context.soRequestType='SOAP' => renderer = 'SoSOAPRenderer' ; high", + "context.soRequestType='WCAP' => renderer = 'SoWCAPRenderer' ; high", + "*true* => renderer = 'SoDefaultRenderer' ; fallback", + ) + +This is a rule from SOPE which selects the render class for SoObjects. As you +can see a rule has a left hand side, eg: + + context.soRequestType='WebDAV' + +and a right hand side, eg: + + renderer = 'SoWebDAVRenderer' + +further control specifiers like the priority of the rule in the set (high) can +be attached. + +The left hand side is just a regular EOQualifier which is evaluated against +a rule context (an object of the NGRuleContext class). A rule context is the +entry object for all rule processing. + +To configure rule evaluation, you need to set some variables in the context, +those variables are basically the "parameters" of the rule. Eg in the above +case we use: + [self->dispatcherRules reset]; + [self->dispatcherRules takeValue:_rq forKey:@"request"]; + [self->dispatcherRules takeValue:[_rq headers] forKey:@"headers"]; + [self->dispatcherRules takeValue:[_rq method] forKey:@"method"]; + [self->dispatcherRules takeValue:_ctx forKey:@"context"]; + +'dispatcherRules' is the NGRuleContext object. Because we reuse the same +context for each WORequest, we need to 'reset' the context to remove all old +information. + +As you can see the rule context gets set the 'context' variable which is used +in the qualifier - "context.soRequestType='WebDAV'". If this left hand side +(LHS) qualifier evaluates to true, the RHS will be run. + + +So lets get to the right hand side. It is the so called "Assignment" and is +actually someone similiar to a WOAssociation. The actual operation is triggered +by some subclass of NGRuleAssignment in the -fireInContext: method. + +In the above example the RHS is + + renderer = 'SoWebDAVRenderer' + +this says that if the rule context is asked for a value of 'renderer', the +assignment will return the 'SoWebDAVRenderer' string constant. + +Note: the assignment does _not_ set the value in the rule context. +TODO: should it set the value in the context? ;-) + +You can have as many assignment as you like. Assignments are only run if the +user asks for a key which is set by the assignment! + + +Now that we have the basics, how do we use the rule context? Here is a small +example: + + NGRuleModel *model; + NGRuleContext *context; + + /* setup */ + model = [[NGRuleModel alloc] initWithContentsOfFile:@"myrules.plist"]; + context = [NGRuleContext ruleContextWithModel:model]; + + /* fill in parameters */ + [context takeValue:@"10" forKey:@"age"]; + + /* query values that depend on the parameter */ + [context valueForKey:@"color"]; + +A sample myrules.plist: + + ( "age < 5 => color = 'white'", "age > 4 => color = 'green'" ) + +This would return 'green' in the above example (because age = 10 is >4). + +Note that the cool aspect of the rule context is that the rule evaluation is +queried using regular key/value coding methods! This way you can easily bind +values to SOPE templates, eg: + + TableCell: WOGenericContainer { + elementName = "td"; + bgcolor = rules.color; + } + +This assumes that the component returns a rule context in the 'rules' method. +A component setup like this can be easily customized just by changing the rules +avoiding the requirement to hack code. + + +Another neat application for rules is the selection of the "next page", that +is, to control the flow of a web application. +Consider a ruleset like this: + + ( "document.status = 'saved' => pageName = 'MyReviewPage'", + "document.status = 'created' => pageName = 'MyReviewPage'", + "document.status = 'reviewed' => pageName = 'MyPublishPage'" ) + +and code like this: + + - (id)showNextPage { + return [self pageWithName:[rules valueForKey:@"pageName"]]; + } + +This code will automatically determine the correct page to be shown depending +on the rules and the state of an object. Eg if you later decide that the +publish page should also been selected for saved docuents which are green, just +enhance the rule to: + + ( "document.status = 'saved' => pageName = 'MyReviewPage'", + "document.status = 'created' => pageName = 'MyReviewPage'", + "document.status = 'reviewed' => pageName = 'MyPublishPage'", + "document.status = 'saved' AND document.color = 'green' + => pageName = 'MyPublishPage'; priority = high", + ) + +The rule context has a neat shortcut method in case you want to store rules in +the defaults system: + + context = [NGRuleContext ruleContextWithModelInUserDefault:@"MyRules"]; + +Since rules are often used to customize the behaviour of an application, this +is quite useful. + + +Another shortcut method you can use is the evaluation of a ruleset for a set +of objects. Eg if you want to get the color of a set of objects with the 'age' +property, you can run: + + colors = [rules valuesForKeyPath:@"color" + takingSuccessiveValues:ageObjects + forKey:@"document"]; + +This will walk over the 'ageObjects' array and perform a + + [rules takeValue:ageObject forKey:@"document"] + +for each object and add the result of + + [rules valueForKeyPath:@"color"] + +to the result array. + + +Finally remember that assignment results do not need to be base values, they +can also be complex objects, eg: + + [rules takeValue:bossObject forKey:@"boss"]; + [rules takeValue:secretary forKey:@"secretary"]; + + contactEMail = [rules valuesForKeyPath:@"contact.email" + takingSuccessiveValues:mailObjects + forKey:@"mail"]; + +with the ruleset: + + ( "mail.priority = 'high' => contact = boss", + "mail.priority = 'normal' => contact = secretary", + "mail.priority = 'low' => contact = secretary" ) + +Note that another speciality with the above ruleset is that it uses +NGRuleKeyAssignment assignments, that is, it retrieves the value of the +assignment from the rule context (the boss or secretary objects previously +set as parameters). + + Priorities ==========