Conditional values

Conditional values simplify conditional logic and get rid of if-statements in the code

License

License

GroupId

GroupId

ru.d-shap
ArtifactId

ArtifactId

conditional-values
Last Version

Last Version

1.2
Release Date

Release Date

Type

Type

jar
Description

Description

Conditional values
Conditional values simplify conditional logic and get rid of if-statements in the code
Project URL

Project URL

https://github.com/d-shap/conditional-values
Source Code Management

Source Code Management

https://github.com/d-shap/conditional-values

Download conditional-values

How to add to project

<!-- https://jarcasting.com/artifacts/ru.d-shap/conditional-values/ -->
<dependency>
    <groupId>ru.d-shap</groupId>
    <artifactId>conditional-values</artifactId>
    <version>1.2</version>
</dependency>
// https://jarcasting.com/artifacts/ru.d-shap/conditional-values/
implementation 'ru.d-shap:conditional-values:1.2'
// https://jarcasting.com/artifacts/ru.d-shap/conditional-values/
implementation ("ru.d-shap:conditional-values:1.2")
'ru.d-shap:conditional-values:jar:1.2'
<dependency org="ru.d-shap" name="conditional-values" rev="1.2">
  <artifact name="conditional-values" type="jar" />
</dependency>
@Grapes(
@Grab(group='ru.d-shap', module='conditional-values', version='1.2')
)
libraryDependencies += "ru.d-shap" % "conditional-values" % "1.2"
[ru.d-shap/conditional-values "1.2"]

Dependencies

test (2)

Group / Artifact Type Version
junit : junit jar 4.12
ru.d-shap : assertions jar 2.0

Project Modules

There are no modules declared in this project.

Conditional values

Conditional values simplify conditional logic and get rid of if-statements in the code.

The main purpose is to find the best result from many predefined conditions.

For example, we should edit form fields based on some conditions. This conditions could be:

  • form type with many different values (contract, order, incoming document, etc.)
  • form state with many different values (draft, approval, active, etc.)
  • user role (viewer, editor, administrator, etc.)
  • some other conditions

And based on this conditions there are different editable fields (title, subject, due date, etc.).

First we create a ValueSet object for each distinct condition and store this objects in a single ConditionalValues object:

ConditionalValuesBuilder<String> conditionalValuesBuilder = ConditionalValuesBuilder.newInstance();
ValueSetBuilder<String> valueSetBuilder = ValueSetBuilder.newInstance();

valueSetBuilder.addCondition("type", "contract");
valueSetBuilder.addCondition("state", "draft");
valueSetBuilder.addCondition("role", "viewer");
valueSetBuilder.addValues("title", "subject");
conditionalValuesBuilder.addValueSet(valueSetBuilder.build());

valueSetBuilder.addCondition("type", "contract");
valueSetBuilder.addCondition("state", "approval")
               .addCondition("state", "active");
valueSetBuilder.addCondition("role", "viewer");
valueSetBuilder.addValues("subject", "due date");
conditionalValuesBuilder.addValueSet(valueSetBuilder.build());

valueSetBuilder.addCondition("type", "contract");
valueSetBuilder.addCondition("state", "approval")
               .addCondition("state", "active");
valueSetBuilder.addCondition("role", "editor");
valueSetBuilder.addValues("title", "due date");
conditionalValuesBuilder.addValueSet(valueSetBuilder.build());

ConditionalValues<String> conditionalValues = conditionalValuesBuilder.build();

This ConditionalValues object could be created during design-time, for example in the class static initializer.

In runtime now we can define editable fields based on current condition (current form type, current form state, current user role, etc). To perform this we create a ConditionSet object:

ConditionSetBuilder conditionSetBuilder = ConditionSetBuilder.newInstance();

conditionSetBuilder.addCondition("type", "contract");
conditionSetBuilder.addCondition("state", "approval");
conditionSetBuilder.addCondition("role", "editor");

ConditionSet conditionSet = conditionSetBuilder.build();

And perform lookup for the best matching ValueSet objects from ConditionalValues object:

Values<String> values = conditionalValues.lookup(conditionSet);

Now we can use Values to get all editable fields.

The lookup algorithm for the best matching ValueSet objects is the following. First, all matching ValueSet objects are defined. A ValueSet object matches if all the object's conditions match a ConditionSet object. Then less specific ValueSet objects are removed. The ValueSet object is less specific than another one if another object has all of the conditions this object has, and some more additional conditions. And, according to the previous step, both objects match a ConditionSet object. Then values of remaining ValueSet objects are joined and returned as a lookup result.

For example, there are predefined conditions:

Value Set 1

  • type: contract
  • isViewer: true

Value Set 2

  • type: contract
  • isEditor: true

Value Set 3

  • type: contract
  • state: draft
  • isViewer: true

Then if we have runtime conditions (type = contract, state = draft, isViewer = true), then the best matching value set is Value Set 3 (the only one matching value set).

If we have runtime conditions (type = contract, state = approval, isViewer = true), then the best matching value set is Value Set 1 (the only one matching value set).

If we have runtime conditions (type = contract, isViewer = true, isEditor = true), then the best matching value sets are Value Set 1 and Value Set 2 (Values object contains values from both ValueSet objects).

If we have runtime conditions (type = contract, state = draft, isViewer = true, isEditor = true), then the best matching value sets are Value Set 2 and Value Set 3 (Value Set 1 also matches, but Value Set 3 is more specific then Value Set 1).

If we have runtime conditions (type = contract, isViewer = true), then the best matching value set is Value Set 1 (the only one matching value set).

If we have runtime conditions (isViewer = true, isEditor = true), then there are no matching value sets (Values object is empty).

To select conditions the following should be considered. Form in the example above could be only in one state at any given moment of time. So the condition with the name state and values draft, approval, active is good enough. If the user in the examample above could have only one role, then condition with the name role and values viewer, editor, administrator is also good enough. But if the user can have several roles simultaneously, then this condition would not work. In this case several conditions should be used: condition with the name isViewer and values true and false, condition with the name isEditor and values true and false, condition with the name isAdministrator and values true and false. Then if the user has several roles, then this user could edit form fields available for each role.

Latest release

Conditional values:

  • <groupId>: ru.d-shap
  • <artifactId>: conditional-values
  • <version>: 1.2

Donation

If you find my code useful, you can bye me a coffee

Versions

Version
1.2
1.1
1.0