Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/koooooo-7/kchain

:nut_and_bolt: A flexible and configurable check chain.
https://github.com/koooooo-7/kchain

chain configurable filter flexible java java8-lambda-expression validator

Last synced: about 2 months ago
JSON representation

:nut_and_bolt: A flexible and configurable check chain.

Awesome Lists containing this project

README

        

# KChain
---





 



 

License

 

jdk8+

**English | [中文](README.zh.md)**

> :nut_and_bolt: *`KChain`, a flexible and configurable chain.*

---

## What is the problem

Sometimes, we will face a situations that we need to check various `properties set` such as `Map` or `Entity` entities ( named it as `properties set`).

Obviously, there will be one or more different verification rules for different properties.

So, it is necessary to have a `chain` structure to solve those problems.

`KChain` is an implementation to solve these problems.

The following two dimensions are usually considered:

**Check Properties**

- For a single `properties set`, such as `Map`

​ It needs to check whether its different properties match one or more rules.

​ For example, the value of the key called`name` in a `Map` can not be empty.

- For batch of `perperties set` , such as `List`

​ It is necessary to check whether they meet certain rules with each other.

​ For example, such as *the same name of `User`* can not exist in the batch of `User` set.

**Rule Strategy**

- Fail fast

When one of the rule conditions is not met, return directly.

- Full check

Running all the verification rules, verify all the rule items for its perperties.

---

## How to solve it

There are some components which play an important role in `KChain`.

- `ChainContext`

The context for the `chain` which can hold the information you wanna use in the whole chain life circle.
Build in the `cache` and `inheritable cache` expired in the current chain test life circle.
Such as some global parameters or special symbol.

- `DataWrapper`

Wrapping the `properties set` and the `Rulecontext` together.

- `RuleContext`

It is used to store the check result and the return flag bit of `Predicate` based on different check strategies.

- `Rule`

It contains some rules for checking.

There are three built-in rules for now:

- `testNotEmpty`,whether the perperty value is empty based on the rule.

- `testInCases`,whether the perperty value is in the given collection (` contains`).

- `testOnCustomized`,the fully customized implementation rule extension.

- `RuleStrategy`

The check strategy.

- `FULL_CHECK`

- `FAIL_FAST `

It is usually used to check a single `perperties set` to quickly know whether the `perperties set` is valid.



- `IChain`

The interface of chain,build-in:

- `Predicate`

`test()`

​ Mainly for the verification of a single `properties set`, the verification rule of each property in the `perperties set` can be configured.

- `Function`

`apply()`

Mainly for the verification of batch of `properties set`, the verification rule of the property between each ` perperties set` can be configured.

Build in the `duplicate rule `.

- `ChainBuiler`
​ Build the chain to use, build in.

---

## How to use it

> All the basic usage you can find in`demo/App.java`.
>
> You can expand as much as you want, no matter the `Rule`, or the implementations of getting property value.

Requests **JDK8+**, the core is using the `@FunctionalInterface`.

**Import**
- Maven
It has been published in `Github Packages`, you can import it directly, more details see the [packages](https://github.com/Koooooo-7?tab=packages&repo_name=KChain).

```xml

com.koy
kchain
${latest.version}

```

### Demo

---

### `Map`

Suppose that we need to verify the `name` and `age` in `map`. The rules are as follows:

**In Single `Map`**

- `name` cannot empty
- `age`can not empty
- `age` should in the cases

**In Map Collections**

- `name` cannot duplicate in collections

- `age` cannot duplicate in collections

#### Build the single properties set chain

- `name` cannot empty
- `age` cannot empty
- `age` should in `[1,2,3,4,5]`

```java
@Override
public Predicate getPredicateChain(ChainContext ctx) {
return Rule.NOT_EMPTY.testNotEmpty("name"
, testEmptyRule("name")
, resultProcessor("name", CheckResultCode.NOT_EMPTY))
.and(Rule.NOT_EMPTY.testNotEmpty("age"
, testEmptyRule("age")
, resultProcessor("age", CheckResultCode.NOT_EMPTY)
))
.and(Rule.IN_CASES.testInCases("age",
CommonTestComponents.testInCasesRule(dataWrapper -> Integer.valueOf(dataWrapper.getString("age"))
, Arrays.asList(1, 2, 3, 4, 5))
, resultProcessor("age", CheckResultCode.IN_CASES)
));

}
```

#### Build the batch properties sets chain

- `name` cannot duplicated in batch of properties sets
- `age`cannot duplicated in batch of properties sets

```java
@Override
public Function, List> getFunction(ChainContext ctx) {
return CommonTestComponents.testDuplicatedInCollection(ctx
, "name"
, dataWrapper -> true, dataWrapper -> dataWrapper.getString("name"))
.andThen(testDuplicatedInCollection(ctx
, "age"
, dataWrapper -> true
, dataWrapper -> dataWrapper.getString("age")));
}
```

#### Usage

```java
public static void demoOnMapBuilder(List> maps) {
// Wrap data to DataWrapper
List mapDataWrappers = Lists.newArrayListWithCapacity(2);
for (HashMap map : maps) {
MapDataWrapper mapDataWrapper = new MapDataWrapper(map, new MapRuleContext(RuleStrategy.FULL_CHECK));
mapDataWrappers.add(mapDataWrapper);
}

// Build the chain with FULL_CHECK strategy
Chain> chain = ChainBuilder.newBuilder()
.setChainContext(new ChainContext(RuleStrategy.FULL_CHECK))
.setChain(new MapPropertiesCheckChain())
.build();

// Verify the property in the map
// There use 6 threads execute it to make it speeder
chain.test(mapDataWrappers);

// Verify the rules between batch properties sets
chain.apply(mapDataWrappers);

// Show the result
for (MapDataWrapper mapDataWrapper : mapDataWrappers) {
System.out.println(mapDataWrapper.getRuleContext().getResult().toString());
}

}
```