Option 1: Add contains to ComparisonOperator
The shortest path to implementing a CONTAINS operator is to add one to the ComparisonOperator enumeration, and do a little bit of hacking to make it so that it validation can be run in the UI to let the user know if they are using the operator appropriately.
Pros & Cons
Easier, lighter weight implementation - no database changes or additional interfaces needed
Version compatibility issues since old client apps could have rules configured on the server with the new operator, but in the client application where the rules actually execute, they would not have the new code
This will only serve as a point solution for what KPME is needing at the moment. We'll have to come back to this in the future if other projects have custom operator needs.
To work around the version compatibility issue, we'd need some additional configuration to allow a way for certain namespaces to "opt-in" for CONTAINS support. That seems pretty hacky.
- Add a
canCompare(Class<?> lhsClass, Class<?> rhsClass)method to
ComparisonOperatorfor validation purposes.
- Add a
ComparisonOperatorthat overrides the
PropositionOpCodeValuesFinderto iterate through the
ComparisonOperatorenum values in order to build the list of
AgendaEditorController.validateSimpleProposition(PropositionBo proposition, String namespace)to use the new
ComparisonOperator.canComparefor UI validation when configuring a proposition.
- Modify the
RuleMaintenance.xmlto make it so that both operands show up when the
CONTAINSoperator is selected.
Option 2: Use custom fuctions to enable new operators
If we try to limit the scope as much as possible by just scanning a certain namespace for custom functions of a certain form, we unfortunately won't be able to provide any validation in the proposition editor to indicate whether the operator is really appropriate for the operands that the user configured. We'd have to rely on the user to know what operands are appropriate, which I feel is an unreasonable expectation. My feeling is that this approach is unacceptable for that reason. Instead, we'll need to add a service interface to allow for validation, and as a bonus we can make the promotion of the custom function to an operator more explicit.
I'm trying to determine how to best configure a custom operator, and the most flexible way I think is using the new type-type relations in KRMS. That would allow you (in this case) to specify that for all contexts with a certain type id, the usage of this custom operator would be allowed. That's basically all that type-type relations are for at the moment: to specify that things with type id X are allowed to use type Y
What I'm thinking is that I'll add another interface for a KRMS type that will specify the custom function ID and provide a validation method for it so the user gets some feedback if the function isn't appropriate for the operands. You'll need to implement that, and add a KRMS type row for it. Then you'll need to add a type-type relation row (https://wiki.kuali.org/x/6BXCEg) between your context type and your new KRMS type implementation.
Pros & Cons
Allows projects that need additional operators to implement themselves
More complex to implement
- Add a new interface for a
CustomOperatorthat has a getter method returning a FunctionDefinition for the custom function that executes to perform the operator evaluation, and a validate method that returns
RemotableAttributeErrors if the argument types are incorrect.
PropositionOpCodeValuesFinderto check the Context for type-type relations (using
CustomOperatorservice impls, and use those in order to build the
AgendaEditorController.validateSimpleProposition(PropositionBo proposition, String namespace)to use the validation method on the
CustomOperatorfor UI validation when saving a proposition.
- Modify the persistence code (probably in
AgendaEditorMaintainable) so that when the agenda is saved, the custom function call is stored properly in the proposition parameters.
- Modify the agenda editor view initialization code to convert custom operators to their special representation on load (probably in
- Modify the
RuleMaintenance.xmlto make it so that the correct number of operands show up for the custom operator that is selected.