Hi Wyclif,
This is an interesting question, and I'm not sure what the right approach
is.
I don't think your options are phrased quite right--I think it should be:
Option A: implement one single LogicCalculationProvider which is capable of
fetching all logic rules.
If we went this route, I'd suggest:
- calculation's TokenRegistration.ruleName would be the classname of the
logic RuleProvider
- calculation's TokenRegistration.configuration would be directly the
configuration string for the logic RuleProvider
- we would completely ignore tokens registered in the logic module. It
would be perfectly fine for the same underlying rule to be exposed as the
calculation token "Chica A12", whereas it might be "A12" in logic, or not
even have a token registered in logic.
An alternate single provider approach would be to only expose as
Calculations, rules that have tokens registered in logic. E.g. the
calculation's TokenRegistration with ruleName="WEIGHT (KG)" and
configuration=null would ultimately end up calling LogicService's
eval("WEIGHT (KG)"). Personally I like this approach less, but I haven't
thought it through much.
Option B: one CalculationProvider per RuleProvider in logic. If we're doing
this:
- expose *all* the logic RuleProviders (including the data source ones)
as CalculationProviders
- but you don't need to care about how the data sources work. Just get
all of them, and delegate to their getRule(String config) method.
And actually, having written this email, I now favor Option A (my first
variant).
Off the top of my head the code would look something like this:
class LogicCalculationProvider implements CalculationProvider {
public Calculation getCalculation(String calculationName, String
configuration) {
// treat calculationName as the fully-qualified classname of the logic
RuleProvider
RuleProvider p =
TokenRegistrationService.getRuleProvider(calculationName); // need to write
this method
if (p == null) throw new Exception();
// pass configuration straight through to the logic RuleProvider
Rule rule = p.getRule(configuration);
return new RuleAsCalculationWrapper(rule);
}
}
The bulk of the code would actually be around converting logic's results to
calculation's results.
Also, looking at this, I think we should add a *checked* exception to
CalculationProvider.getCalculation, like
InvalidCalculationConfigurationException or something. Given that we're
counting on two String being interpreted correctly, I'd much rather have a
compile-time exception than a runtime one.
-Darius
On Wed, Mar 14, 2012 at 2:20 PM, Wyclif Luyima <[email protected]> wrote:
> Hello,
>
> In the effort of refactoring logic to expose itself in a way based on the
> calculation module i'm trying to figure out how to handle the
> LogicCalculationProvider(s) and i need your views on this. The current
> logic module has 2 main rule providers, the ClassRuleProvider and
> RuleDefinitionRuleProvider(I'm trying to ignore the DataSourceRuleProvider
> since i'm not yet sure how this is going to be incorporated). 2 questions
> come to my mind,
>
> 1. Should we have 2 separate LogicCalculationProviders equivalents for
> these?
> 2. If yes, RuleDefinitionRuleProvider looks up Rules stored as tokens
> in the database which is the equivalent of TokenRegistrations in the
> calculation module, does it mean that the CalculationProvider equivalent
> for it should instead go through the TokenRegistrationService and the
> equivalent for ClassRuleProvider goes through the
> ClasspathCalculationProvider?
> 3. If no, What are your suggestions?
>
>
> Wyclif
>
>
>
> ------------------------------
> Click here to
> unsubscribe<[email protected]?body=SIGNOFF%20openmrs-devel-l>from
> OpenMRS Developers' mailing list
_________________________________________
To unsubscribe from OpenMRS Developers' mailing list, send an e-mail to
[email protected] with "SIGNOFF openmrs-devel-l" in the body (not
the subject) of your e-mail.
[mailto:[email protected]?body=SIGNOFF%20openmrs-devel-l]