README
The
REFCODES.ORG
codes represent a group of artifacts consolidating parts of my work in the past years. Several topics are covered which I consider useful for you, programmers, developers and software engineers.
What is this repository for?
This artifact allows the construction of Criteria
instances for selecting, filtering or identifying (such as the selection of entries from a database). This implies the creation of query statements from Criteria
instances which can be applied to data sinks; such as databases (SQL like statements). In turn, this also implies parsing (construction) of criteria trees from a query statement.
How do I get set up?
To get up and running, include the following dependency (without the three dots “…”) in your pom.xml
:
1
2
3
4
5
6
7
8
9
<dependencies>
...
<dependency>
<artifactId>refcodes-criteria</artifactId>
<groupId>org.refcodes</groupId>
<version>3.3.8</version>
</dependency>
...
</dependencies>
The artifact is hosted directly at Maven Central. Jump straight to the source codes at Bitbucket. Read the artifact’s javadoc at javadoc.io.
Overview
This toolkit allows the creation of query statements from Criteria
instances as well as parsing (construction) of criteria trees from query statements. Such a parsable query statement might look as follows:
( ( ( City = 'Berlin' ) OR ( City = 'Munich' ) ) AND ( Surname = 'Miller' ) )
A dedicated
QueryFactory
implementation is provided for parsing the above query statement into aCriteria
hierarchy (ExpressionQueryFactory
) and a dedicatedCriteriaFactory
implementation is provided for producing a query expression (as above) from aCriteria
hierarchy (ExpressionCriteriaFactory
).
A Criteria
represents an atomic query or atomic logical operator with which complex queries can be constructed in an object oriented manner by combining the Criteria
instances in a hierarchical tree structure. From this tree structure, query statements can be generated. In turn, query statements provided as logical operators can be parsed for the construction of Criteria
trees. This means that a query is constructed from a Criteria
tree with CriteriaNode
node instances and CriteriaLeaf
leaf instances. A node may contain other node instances and/or other leaf instances, all of which being the node’s children.
CriteriaNode
A CriteriaNode
tree node may represent a logical AND
, a logical OR
or a logical NOT
applied on the node’s children Criteria
(CriteriaNode
instances and CriteriaLeaf
instances).
CriteriaLeaf
A CriteriaLeaf
tree leaf is an expression usually relating to a key (for example identifying a table’s column in a database) and a value, both of which consolidating an expression (for example “City = 'Munich'
”).
Criteria
The Criteria
itself is the base definition of functionality which the CriteriaNode
and CriteriaLeaf
implementations are to support. Mainly, a Criteria
is to have an alias (for example “AND
”, “OR
”, “LESS_THAN
” and so on).
CriteriaSugar
The CriteriaSugar
syntactic sugar is a handy class which may be statically imported in order to allow declarative definitions of Criteria
trees. In the Java code this may look as follows (simplified):
1
2
3
4
import static org.refcodes.criteria.CriteriaSugar.*;
...
Criteria theCriteria = and( or( equalWith( "City", "Berlin" ), equalWith( "City", "Munich" ) ), equalWith( "Surname", "Miller" ) );
...
CriteriaFactory
The CriteriaFactory
constructs a Criteria
tree from a provided query. The syntax of the query is implementation specific and may look as follows:
( ( ( City = 'Berlin' ) OR ( City = 'Munich' ) ) AND ( Surname = 'Miller' ) )
CAUTION: The syntax supported for the query statement is implementation depended!
The ExpressionCriteriaFactory
implements a CriteriaFactory
being capable of parsing the above query.
QueryFactory
The QueryFactory
generates a query from the provided Criteria
tree. The resulting query may be targeted at a database and therefore be SQL like.
CAUTION: The syntax supported for the query statement is implementation depended!
This enables the creation of query statements from the a Criteria
tree which can be applied to data sinks; such as databases (SQL like statements), e.g:
( ( ( City = 'Berlin' ) OR ( City = 'Munich' ) ) AND ( Surname = 'Miller' ) )
The ExpressionQueryFactory
implements a QueryFactory
being capable of producing the above query.
Snippets of interest
Below find some code snippets which demonstrate the various aspects of using the refcodes-criteria
artifact (and , if applicable, its offsprings). See also the example source codes of this artifact for further information on the usage of this artifact.
Creating queries from criteria
The code snippet below uses an ExpressionQueryFactory
and constructs a query equivalent to NOT ( NOT ( ( City != 'Berlin' ) AND ( ZIP < 30000 ) ) NOT ( AGE > 65 ) )
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import static org.refcodes.criteria.CriteriaSugar.*;
import org.refcodes.criteria.*;
...
Criteria theCriteria = not(
and(
not(
and(
notEqualWith( "City", "Berlin" ), lessThan( "ZIP", 30000 )
)
),
greaterThan( "AGE", 65 )
)
);
ExpressionQueryFactory theQueryFactory = new ExpressionQueryFactory();
String theQuery = theQueryFactory.fromCriteria( theCriteria );
System.out.println( "Query = " + theQuery );
...
Note that we combine NotCriteria
and AndCriteria
instances with NotEqualsWithCriteria
, LessThanCriteria
and GreaterThanCriteria
instances (further nesting is possible, only limited by your ideas).
The code snippet below uses an ExpressionQueryFactory
and constructs a query equivalent to NOT ( ( City = 'Berlin' ) NOT ( ZIP = 10337 ) ) OR ( Age >= 18 )
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import static org.refcodes.criteria.CriteriaSugar.*;
import org.refcodes.criteria.*;
...
Criteria theCriteria = not(
and(
not(
and(
notEqualWith( "City", "Berlin" ), lessThan( "ZIP", 30000 )
)
),
greaterThan( "AGE", 65 )
)
);
ExpressionQueryFactory theQueryFactory = new ExpressionQueryFactory();
String theQuery = theQueryFactory.fromCriteria( theCriteria );
System.out.println( "Query = " + theQuery );
...
Note that we combine OrCriteria
and AndCriteria
instances with EqualsWithCriteria
and GreaterOrEqualThanCriteria
instances (further nesting is possible, only limited by your ideas). Finally the ExpressionQueryFactory
instance (line 15) produces the according expression:
Creating criteria from queries
The code snippet below uses an ExpressionCriteriaFactory
and parses the query NOT ( NOT ( ( City != 'Berlin' ) NOT ( ZIP < 30000 ) ) NOT ( AGE > 65 ) )
:
1
2
3
4
5
6
7
8
import static org.refcodes.criteria.CriteriaSugar.*;
import org.refcodes.criteria.*;
...
ExpressionCriteriaFactory theExpressionFactory = new ExpressionCriteriaFactory();
String theQuery = "NOT ( NOT ( ( City != 'Berlin' ) NOT ( ZIP < 30000 ) ) NOT ( AGE > 65 ) )";
Criteria theCriteria = theExpressionFactory.fromQuery( theQuery );
System.out.println( theCriteria.toSchema() );
...
Feeding the expression NOT ( NOT ( ( City != 'Berlin' ) NOT ( ZIP < 30000 ) ) NOT ( AGE > 65 ) )
into the ExpressionCriteriaFactory
instance (line 6) produces the according Criteria
and finally the CriteriaSchema
representation (line 7) is produced:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
NotCriteria: {
ALIAS: "NOT",
DESCRIPTION: "Logical NOT expression.",
TYPE: "org.refcodes.criteria.NotCriteria",
AndCriteria: {
ALIAS: "AND",
DESCRIPTION: "Logical AND expression.",
TYPE: "org.refcodes.criteria.AndCriteria",
NotCriteria: {
ALIAS: "NOT",
DESCRIPTION: "Logical NOT expression.",
TYPE: "org.refcodes.criteria.NotCriteria",
AndCriteria: {
ALIAS: "AND",
DESCRIPTION: "Logical AND expression.",
TYPE: "org.refcodes.criteria.AndCriteria",
NotEqualWithCriteria: {
ALIAS: "UNEQUAL",
DESCRIPTION: "Logical UNEQUAL (!=) expression.",
KEY: "City",
TYPE: "org.refcodes.criteria.NotEqualWithCriteria",
VALUE: "Berlin"
},
LessThanCriteria: {
ALIAS: "LESS_OR_EQUAL_THAN",
DESCRIPTION: "Logical LESS (<) expression.",
KEY: "ZIP",
TYPE: "org.refcodes.criteria.LessThanCriteria",
VALUE: 30000
}
}
},
GreaterThanCriteria: {
ALIAS: "GREATER_THAN",
DESCRIPTION: "Logical GREATER (>) expression.",
KEY: "AGE",
TYPE: "org.refcodes.criteria.GreaterThanCriteria",
VALUE: 65
}
}
}
The
CriteriaSchema
is aJSON
alike representation of your expression and helps to further process, analyze, debug or document your expressions.
Examples
See the example source codes of this artifact for further information on the usage of this artifact.
Contribution guidelines
- Report issues
- Finding bugs
- Helping fixing bugs
- Making code and documentation better
- Enhance the code
Who do I talk to?
- Siegfried Steiner (steiner@refcodes.org)
Terms and conditions
The REFCODES.ORG
group of artifacts is published under some open source licenses; covered by the refcodes-licensing
(org.refcodes
group) artifact - evident in each artifact in question as of the pom.xml
dependency included in such artifact.