release-0.0.4
This commit is contained in:
parent
5534b18573
commit
ea6bc5a175
165
pom.xml
165
pom.xml
@ -4,14 +4,14 @@
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.sadtech.haiti</groupId>
|
||||
<groupId>dev.struchkov.haiti</groupId>
|
||||
<artifactId>haiti</artifactId>
|
||||
<version>0.0.2-SNAPSHOT</version>
|
||||
<version>0.0.4</version>
|
||||
</parent>
|
||||
|
||||
<groupId>org.sadtech.haiti.filter</groupId>
|
||||
<groupId>dev.struchkov.haiti.filter</groupId>
|
||||
<artifactId>haiti-filter-criteria</artifactId>
|
||||
<version>0.0.3-SNAPSHOT</version>
|
||||
<version>0.0.4</version>
|
||||
|
||||
<name>Haiti Filter Criteria</name>
|
||||
<description>Fast creation of filtering requests using the Criteria Api wrapper.</description>
|
||||
@ -20,57 +20,43 @@
|
||||
<license>
|
||||
<name>Apache License, Version 2.0</name>
|
||||
<url>https://www.apache.org/licenses/LICENSE-2.0</url>
|
||||
<comments>
|
||||
Copyright 2010 the original author or authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
</comments>
|
||||
</license>
|
||||
</licenses>
|
||||
|
||||
<organization>
|
||||
<name>SADTECH</name>
|
||||
<url>https://sadtech.org</url>
|
||||
</organization>
|
||||
|
||||
<scm>
|
||||
<connection>scm:git:https://github.com/haiti-projects/haiti-filter-criteria.git</connection>
|
||||
<url>https://github.com/haiti-projects/haiti-filter-criteria</url>
|
||||
<developerConnection>scm:git:https://github.com/haiti-projects/haiti-filter-criteria.git</developerConnection>
|
||||
</scm>
|
||||
|
||||
<distributionManagement>
|
||||
<snapshotRepository>
|
||||
<id>ossrh</id>
|
||||
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
|
||||
</snapshotRepository>
|
||||
</distributionManagement>
|
||||
|
||||
<issueManagement>
|
||||
<system>GitHub</system>
|
||||
<url>https://github.com/haiti-projects/haiti-framework/issues</url>
|
||||
</issueManagement>
|
||||
|
||||
<properties>
|
||||
<java.version>11</java.version>
|
||||
<maven.compiler.source>${java.version}</maven.compiler.source>
|
||||
<maven.compiler.target>${java.version}</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
|
||||
<haiti.ver>0.0.4</haiti.ver>
|
||||
<google.auto.service.ver>1.0.1</google.auto.service.ver>
|
||||
|
||||
<plugin.maven.compiler.ver>3.9.0</plugin.maven.compiler.ver>
|
||||
<plugin.nexus.staging.ver>1.6.8</plugin.nexus.staging.ver>
|
||||
<plugin.maven.source.ver>3.2.1</plugin.maven.source.ver>
|
||||
<plugin.maven.javadoc.ver>3.3.1</plugin.maven.javadoc.ver>
|
||||
<plugin.maven.gpg.ver>3.0.1</plugin.maven.gpg.ver>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.sadtech.haiti</groupId>
|
||||
<groupId>dev.struchkov.haiti</groupId>
|
||||
<artifactId>haiti-filter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>dev.struchkov.haiti</groupId>
|
||||
<artifactId>haiti-utils</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<groupId>com.google.auto.service</groupId>
|
||||
<artifactId>auto-service</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@ -85,98 +71,35 @@
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-core</artifactId>
|
||||
<version>5.4.29.Final</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>release</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.sonatype.plugins</groupId>
|
||||
<artifactId>nexus-staging-maven-plugin</artifactId>
|
||||
<version>1.6.7</version>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<serverId>ossrh</serverId>
|
||||
<nexusUrl>https://oss.sonatype.org/</nexusUrl>
|
||||
<autoReleaseAfterClose>true</autoReleaseAfterClose>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<version>2.2.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-sources</id>
|
||||
<goals>
|
||||
<goal>jar-no-fork</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>2.9.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-javadocs</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-gpg-plugin</artifactId>
|
||||
<version>1.5</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>sign-artifacts</id>
|
||||
<phase>verify</phase>
|
||||
<goals>
|
||||
<goal>sign</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.0</version>
|
||||
<configuration>
|
||||
<source>8</source>
|
||||
<target>8</target>
|
||||
<annotationProcessorPaths>
|
||||
<annotationProcessorPath>
|
||||
<groupId>com.google.auto.service</groupId>
|
||||
<artifactId>auto-service</artifactId>
|
||||
<version>1.0.1</version>
|
||||
</annotationProcessorPath>
|
||||
</annotationProcessorPaths>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.sonatype.plugins</groupId>
|
||||
<artifactId>nexus-staging-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<developers>
|
||||
<developer>
|
||||
<id>uPagge</id>
|
||||
<name>Struchkov Mark</name>
|
||||
<email>upagge@ya.ru</email>
|
||||
<organization>SADTECH</organization>
|
||||
<organizationUrl>https://sadtech.org</organizationUrl>
|
||||
<url>https://uPagge.sadtech.org</url>
|
||||
<roles>
|
||||
<role>Project lead</role>
|
||||
</roles>
|
||||
<timezone>+3</timezone>
|
||||
</developer>
|
||||
</developers>
|
||||
<scm>
|
||||
<connection>scm:git:https://github.com/haiti-projects/haiti-filter-criteria.git</connection>
|
||||
<url>https://github.com/haiti-projects/haiti-filter-criteria</url>
|
||||
<developerConnection>scm:git:https://github.com/haiti-projects/haiti-filter-criteria.git</developerConnection>
|
||||
</scm>
|
||||
|
||||
</project>
|
@ -1,8 +1,5 @@
|
||||
package org.sadtech.haiti.filter.criteria;
|
||||
package dev.struchkov.haiti.filter.criteria;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
|
||||
import java.util.List;
|
||||
@ -13,9 +10,6 @@ import java.util.UUID;
|
||||
*
|
||||
* @author upagge 09.11.2020
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
public class Container<T> {
|
||||
|
||||
private final String uuid = UUID.randomUUID().toString();
|
||||
@ -31,4 +25,24 @@ public class Container<T> {
|
||||
return new Container<>(joinTables);
|
||||
}
|
||||
|
||||
public List<JoinTable> getJoinTables() {
|
||||
return joinTables;
|
||||
}
|
||||
|
||||
public void setJoinTables(List<JoinTable> joinTables) {
|
||||
this.joinTables = joinTables;
|
||||
}
|
||||
|
||||
public Specification<T> getSpecification() {
|
||||
return specification;
|
||||
}
|
||||
|
||||
public void setSpecification(Specification<T> specification) {
|
||||
this.specification = specification;
|
||||
}
|
||||
|
||||
public String getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
}
|
@ -1,24 +1,25 @@
|
||||
package org.sadtech.haiti.filter.criteria;
|
||||
package dev.struchkov.haiti.filter.criteria;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.sadtech.haiti.filter.Filter;
|
||||
import org.sadtech.haiti.filter.FilterQuery;
|
||||
import dev.struchkov.haiti.filter.Filter;
|
||||
import dev.struchkov.haiti.filter.FilterQuery;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class CriteriaFilter<T> implements Filter {
|
||||
|
||||
private final List<Specification<T>> andSpecifications = new ArrayList<>();
|
||||
private final List<Specification<T>> orSpecifications = new ArrayList<>();
|
||||
private final List<Specification<T>> notSpecifications = new ArrayList<>();
|
||||
|
||||
private CriteriaFilter() {
|
||||
}
|
||||
|
||||
public static <T> Filter create() {
|
||||
return new CriteriaFilter<T>();
|
||||
}
|
||||
@ -29,18 +30,46 @@ public class CriteriaFilter<T> implements Filter {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Filter and(Consumer<FilterQuery> query) {
|
||||
final FilterQuery criteriaQuery = CriteriaQuery.create();
|
||||
query.accept(criteriaQuery);
|
||||
andSpecifications.addAll(getSpecification(criteriaQuery));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Filter or(FilterQuery filterQuery) {
|
||||
orSpecifications.addAll(getSpecification(filterQuery));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Filter or(Consumer<FilterQuery> query) {
|
||||
final FilterQuery criteriaQuery = CriteriaQuery.create();
|
||||
query.accept(criteriaQuery);
|
||||
orSpecifications.addAll(getSpecification(criteriaQuery));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Filter not(FilterQuery filterQuery) {
|
||||
notSpecifications.addAll(
|
||||
getSpecification(filterQuery).stream()
|
||||
.map(Specification::not)
|
||||
.collect(Collectors.toList())
|
||||
.collect(Collectors.toUnmodifiableList())
|
||||
);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Filter not(Consumer<FilterQuery> query) {
|
||||
final FilterQuery criteriaQuery = CriteriaQuery.create();
|
||||
query.accept(criteriaQuery);
|
||||
notSpecifications.addAll(
|
||||
getSpecification(criteriaQuery).stream()
|
||||
.map(Specification::not)
|
||||
.collect(Collectors.toUnmodifiableList())
|
||||
);
|
||||
return this;
|
||||
}
|
@ -1,9 +1,7 @@
|
||||
package org.sadtech.haiti.filter.criteria;
|
||||
package dev.struchkov.haiti.filter.criteria;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.sadtech.haiti.filter.FilterQuery;
|
||||
|
||||
import dev.struchkov.haiti.filter.FilterQuery;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@ -11,14 +9,22 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
import static dev.struchkov.haiti.utils.Assert.Utils.nullPointer;
|
||||
import static dev.struchkov.haiti.utils.Assert.isNotNull;
|
||||
|
||||
public class CriteriaQuery<T> implements FilterQuery {
|
||||
|
||||
private static final CriteriaQuery<?> EMPTY = new CriteriaQuery<>(new ArrayList<>());
|
||||
public static final String FIELD_NAME = "field";
|
||||
|
||||
private final List<Container<T>> containers;
|
||||
private List<JoinTable> joinTables = new ArrayList<>();
|
||||
private final SimpleCriteriaQuery<T> simpleCriteriaQuery = new SimpleCriteriaQuery();
|
||||
|
||||
public CriteriaQuery(List<Container<T>> containers) {
|
||||
this.containers = containers;
|
||||
}
|
||||
|
||||
public static <T> FilterQuery create() {
|
||||
return new CriteriaQuery<T>(new ArrayList<>());
|
||||
}
|
||||
@ -29,20 +35,23 @@ public class CriteriaQuery<T> implements FilterQuery {
|
||||
*
|
||||
* @param fieldName Имя поля сущности, которое отвечает за название таблицы.
|
||||
*/
|
||||
public CriteriaQuery<T> join(@NonNull String... fieldName) {
|
||||
public CriteriaQuery<T> join(String... fieldName) {
|
||||
isNotNull(fieldName, nullPointer("fieldName"));
|
||||
joinTables = Arrays.stream(fieldName)
|
||||
.map(JoinTable::of)
|
||||
.collect(Collectors.toList());
|
||||
return this;
|
||||
}
|
||||
|
||||
public CriteriaQuery<T> join(@NonNull JoinTable... joinTables) {
|
||||
public CriteriaQuery<T> join(JoinTable... joinTables) {
|
||||
isNotNull(joinTables, nullPointer("joinTables"));
|
||||
this.joinTables = Arrays.stream(joinTables).collect(Collectors.toList());
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <Y extends Comparable<? super Y>> FilterQuery between(@NonNull String field, Y from, Y to) {
|
||||
public <Y extends Comparable<? super Y>> FilterQuery between(String field, Y from, Y to) {
|
||||
isNotNull(field, nullPointer(FIELD_NAME));
|
||||
if (from != null && to != null) {
|
||||
containers.add(simpleCriteriaQuery.between(joinTables, field, from, to));
|
||||
}
|
||||
@ -50,7 +59,8 @@ public class CriteriaQuery<T> implements FilterQuery {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <Y extends Comparable<? super Y>> FilterQuery greaterThan(@NonNull String field, Y value) {
|
||||
public <Y extends Comparable<? super Y>> FilterQuery greaterThan(String field, Y value) {
|
||||
isNotNull(field, nullPointer(FIELD_NAME));
|
||||
if (value != null) {
|
||||
containers.add(simpleCriteriaQuery.greaterThan(joinTables, field, value));
|
||||
}
|
||||
@ -58,7 +68,8 @@ public class CriteriaQuery<T> implements FilterQuery {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <Y extends Comparable<? super Y>> FilterQuery lessThan(@NonNull String field, Y value) {
|
||||
public <Y extends Comparable<? super Y>> FilterQuery lessThan(String field, Y value) {
|
||||
isNotNull(field, nullPointer(FIELD_NAME));
|
||||
if (value != null) {
|
||||
containers.add(simpleCriteriaQuery.lessThan(joinTables, field, value));
|
||||
}
|
||||
@ -66,7 +77,8 @@ public class CriteriaQuery<T> implements FilterQuery {
|
||||
}
|
||||
|
||||
@Override
|
||||
public FilterQuery matchPhrase(@NonNull String field, Object value) {
|
||||
public FilterQuery matchPhrase(String field, Object value) {
|
||||
isNotNull(field, nullPointer(FIELD_NAME));
|
||||
if (value != null) {
|
||||
containers.add(simpleCriteriaQuery.matchPhrase(joinTables, field, value));
|
||||
}
|
||||
@ -74,7 +86,8 @@ public class CriteriaQuery<T> implements FilterQuery {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <U> FilterQuery matchPhrase(@NonNull String field, Set<U> values) {
|
||||
public <U> FilterQuery matchPhrase(String field, Set<U> values) {
|
||||
isNotNull(field, nullPointer(FIELD_NAME));
|
||||
if (values != null && !values.isEmpty()) {
|
||||
containers.addAll(
|
||||
values.stream()
|
||||
@ -105,7 +118,8 @@ public class CriteriaQuery<T> implements FilterQuery {
|
||||
}
|
||||
|
||||
@Override
|
||||
public FilterQuery like(@NonNull String field, String value, boolean ignoreCase) {
|
||||
public FilterQuery like(String field, String value, boolean ignoreCase) {
|
||||
isNotNull(field, nullPointer(FIELD_NAME));
|
||||
containers.add(
|
||||
ignoreCase
|
||||
? simpleCriteriaQuery.likeIgnoreCase(joinTables, field, value)
|
||||
@ -115,7 +129,8 @@ public class CriteriaQuery<T> implements FilterQuery {
|
||||
}
|
||||
|
||||
@Override
|
||||
public FilterQuery checkBoolInt(@NonNull String field, Boolean flag) {
|
||||
public FilterQuery checkBoolInt(String field, Boolean flag) {
|
||||
isNotNull(field, nullPointer(FIELD_NAME));
|
||||
if (flag != null) {
|
||||
containers.add(
|
||||
simpleCriteriaQuery.between(joinTables, field, 0, Integer.MAX_VALUE)
|
@ -0,0 +1,37 @@
|
||||
package dev.struchkov.haiti.filter.criteria;
|
||||
|
||||
import dev.struchkov.haiti.utils.Assert;
|
||||
|
||||
import static dev.struchkov.haiti.utils.Assert.Utils.nullPointer;
|
||||
|
||||
/**
|
||||
* @author upagge 15.04.2021
|
||||
*/
|
||||
public class JoinTable {
|
||||
|
||||
private final String tableName;
|
||||
private final JoinTypeOperation joinTypeOperation;
|
||||
|
||||
private JoinTable(String tableName, JoinTypeOperation joinTypeOperation) {
|
||||
this.tableName = tableName;
|
||||
this.joinTypeOperation = joinTypeOperation;
|
||||
}
|
||||
|
||||
public static JoinTable of(String tableName) {
|
||||
Assert.isNotNull(tableName, nullPointer("tableName"));
|
||||
return new JoinTable(tableName, JoinTypeOperation.LEFT);
|
||||
}
|
||||
|
||||
public static JoinTable of(String tableName, JoinTypeOperation joinType) {
|
||||
Assert.isNotNull(tableName, nullPointer("tableName"));
|
||||
return new JoinTable(tableName, joinType);
|
||||
}
|
||||
|
||||
public String getTableName() {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
public JoinTypeOperation getJoinTypeOperation() {
|
||||
return joinTypeOperation;
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package dev.struchkov.haiti.filter.criteria;
|
||||
|
||||
import javax.persistence.criteria.JoinType;
|
||||
|
||||
/**
|
||||
* @author upagge 15.04.2021
|
||||
*/
|
||||
public enum JoinTypeOperation {
|
||||
|
||||
LEFT(JoinType.LEFT),
|
||||
INNER(JoinType.INNER);
|
||||
|
||||
private final JoinType criteriaType;
|
||||
|
||||
JoinTypeOperation(JoinType criteriaType) {
|
||||
this.criteriaType = criteriaType;
|
||||
}
|
||||
|
||||
public JoinType getCriteriaType() {
|
||||
return criteriaType;
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
package org.sadtech.haiti.filter.criteria;
|
||||
package dev.struchkov.haiti.filter.criteria;
|
||||
|
||||
import lombok.NonNull;
|
||||
import dev.struchkov.haiti.utils.Assert;
|
||||
import org.hibernate.query.criteria.internal.path.PluralAttributeJoinSupport;
|
||||
|
||||
import javax.persistence.criteria.From;
|
||||
@ -15,13 +15,20 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static dev.struchkov.haiti.utils.Assert.Utils.nullPointer;
|
||||
|
||||
public class SimpleCriteriaQuery<T> {
|
||||
|
||||
public static final String FIELD = "field";
|
||||
|
||||
private From<Object, Object> lastJoin;
|
||||
private final Set<String> unique = new HashSet<>();
|
||||
private final Map<String, From<Object, Object>> joinMap = new HashMap<>();
|
||||
|
||||
public Container<T> matchPhrase(List<JoinTable> joinTables, @NonNull String field, @NonNull Object value) {
|
||||
public Container<T> matchPhrase(List<JoinTable> joinTables, String field, Object value) {
|
||||
Assert.isNotNull(field, nullPointer(FIELD));
|
||||
Assert.isNotNull(value, nullPointer("value"));
|
||||
|
||||
final Container<T> container = Container.of(joinTables);
|
||||
container.setSpecification((root, query, cb) -> cb.equal(getPath(root, container).get(field), value));
|
||||
return container;
|
||||
@ -38,37 +45,49 @@ public class SimpleCriteriaQuery<T> {
|
||||
return container;
|
||||
}
|
||||
|
||||
public Container<T> exists(List<JoinTable> joinTables, @NonNull String field) {
|
||||
public Container<T> exists(List<JoinTable> joinTables, String field) {
|
||||
Assert.isNotNull(field, nullPointer(FIELD));
|
||||
|
||||
final Container<T> container = Container.of(joinTables);
|
||||
container.setSpecification((root, query, cb) -> cb.isNotNull(getPath(root, container).get(field)));
|
||||
return container;
|
||||
}
|
||||
|
||||
public Container<T> likeIgnoreCase(List<JoinTable> joinTables, @NonNull String field, String value) {
|
||||
public Container<T> likeIgnoreCase(List<JoinTable> joinTables, String field, String value) {
|
||||
Assert.isNotNull(field, nullPointer(FIELD));
|
||||
|
||||
final Container<T> container = Container.of(joinTables);
|
||||
container.setSpecification((root, query, cb) -> cb.like(cb.lower(getPath(root, container).get(field)), value));
|
||||
return container;
|
||||
}
|
||||
|
||||
public Container<T> like(List<JoinTable> joinTables, @NonNull String field, String value) {
|
||||
public Container<T> like(List<JoinTable> joinTables, String field, String value) {
|
||||
Assert.isNotNull(field, nullPointer(FIELD));
|
||||
|
||||
final Container<T> container = Container.of(joinTables);
|
||||
container.setSpecification((root, query, cb) -> cb.like(getPath(root, container).get(field), value));
|
||||
return container;
|
||||
}
|
||||
|
||||
public <Y extends Comparable<? super Y>> Container<T> between(List<JoinTable> joinTables, @NonNull String field, Y from, Y to) {
|
||||
public <Y extends Comparable<? super Y>> Container<T> between(List<JoinTable> joinTables, String field, Y from, Y to) {
|
||||
Assert.isNotNull(field, nullPointer(FIELD));
|
||||
|
||||
final Container<T> container = Container.of(joinTables);
|
||||
container.setSpecification((root, query, cb) -> cb.between(getPath(root, container).get(field), from, to));
|
||||
return container;
|
||||
}
|
||||
|
||||
public <Y extends Comparable<? super Y>> Container<T> greaterThan(List<JoinTable> joinTables, @NonNull String field, Y value) {
|
||||
public <Y extends Comparable<? super Y>> Container<T> greaterThan(List<JoinTable> joinTables, String field, Y value) {
|
||||
Assert.isNotNull(field, nullPointer(FIELD));
|
||||
|
||||
final Container<T> container = Container.of(joinTables);
|
||||
container.setSpecification(((root, query, cb) -> cb.greaterThan(getPath(root, container).get(field), value)));
|
||||
return container;
|
||||
}
|
||||
|
||||
public <Y extends Comparable<? super Y>> Container<T> lessThan(List<JoinTable> joinTables, @NonNull String field, Y value) {
|
||||
public <Y extends Comparable<? super Y>> Container<T> lessThan(List<JoinTable> joinTables, String field, Y value) {
|
||||
Assert.isNotNull(field, nullPointer(FIELD));
|
||||
|
||||
final Container<T> container = Container.of(joinTables);
|
||||
container.setSpecification(((root, query, cb) -> cb.lessThan(getPath(root, container).get(field), value)));
|
||||
return container;
|
@ -0,0 +1,44 @@
|
||||
package dev.struchkov.haiti.filter.criteria.generate;
|
||||
|
||||
import dev.struchkov.haiti.utils.Exceptions;
|
||||
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @author upagge 18.04.2021
|
||||
*/
|
||||
public final class Annotations {
|
||||
|
||||
public static final String TAB = " ";
|
||||
|
||||
private Annotations() {
|
||||
Exceptions.utilityClass();
|
||||
}
|
||||
|
||||
public static boolean isField(Element element) {
|
||||
return element != null && element.getKind().isField();
|
||||
}
|
||||
|
||||
public static String getPackage(TypeMirror typeMirror) {
|
||||
final String[] split = typeMirror.toString().split("\\.");
|
||||
return String.join(".", Arrays.copyOf(split, split.length - 1));
|
||||
}
|
||||
|
||||
public static String getter(int tabCount, String returnType, String name) {
|
||||
return tabs(tabCount) + "public " + returnType + " get" + name + "() " +
|
||||
tabs(tabCount + 1) + "{ " +
|
||||
tabs(tabCount + 2) + "return " + name + ";" +
|
||||
tabs(tabCount + 1) + "}";
|
||||
}
|
||||
|
||||
private static String tabs(int tabCount) {
|
||||
StringBuilder tabs = new StringBuilder(TAB);
|
||||
for (int i = 1; i < tabCount; i++) {
|
||||
tabs.append(TAB);
|
||||
}
|
||||
return tabs.toString();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package dev.struchkov.haiti.filter.criteria.generate.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* @author upagge 18.04.2021
|
||||
*/
|
||||
public @interface FilterField {
|
||||
|
||||
@Target(ElementType.FIELD)
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@interface Exclude {
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package dev.struchkov.haiti.filter.criteria.generate.annotation;
|
||||
|
||||
import dev.struchkov.haiti.filter.criteria.generate.domain.FilterType;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.CLASS)
|
||||
public @interface GenerateFilter {
|
||||
|
||||
String name() default "";
|
||||
|
||||
FilterType[] types() default FilterType.SINGLE;
|
||||
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
package dev.struchkov.haiti.filter.criteria.generate.domain;
|
||||
|
||||
import dev.struchkov.haiti.filter.criteria.generate.annotation.GenerateFilter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* // TODO: 18.04.2021 Добавить описание.
|
||||
*
|
||||
* @author upagge 18.04.2021
|
||||
*/
|
||||
public class FilterDto {
|
||||
|
||||
private String name;
|
||||
private String packageName;
|
||||
private FilterType filterType;
|
||||
private GenerateFilter filterOption;
|
||||
private List<FilterParameter> parameters;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public FilterType getFilterType() {
|
||||
return filterType;
|
||||
}
|
||||
|
||||
public void setFilterType(FilterType filterType) {
|
||||
this.filterType = filterType;
|
||||
}
|
||||
|
||||
public String getPackageName() {
|
||||
return packageName;
|
||||
}
|
||||
|
||||
public void setPackageName(String packageName) {
|
||||
this.packageName = packageName;
|
||||
}
|
||||
|
||||
public GenerateFilter getFilterOption() {
|
||||
return filterOption;
|
||||
}
|
||||
|
||||
public void setFilterOption(GenerateFilter filterOption) {
|
||||
this.filterOption = filterOption;
|
||||
}
|
||||
|
||||
public List<FilterParameter> getParameters() {
|
||||
return parameters;
|
||||
}
|
||||
|
||||
public void setParameters(List<FilterParameter> parameters) {
|
||||
this.parameters = parameters;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package dev.struchkov.haiti.filter.criteria.generate.domain;
|
||||
|
||||
/**
|
||||
* // TODO: 18.04.2021 Добавить описание.
|
||||
*
|
||||
* @author upagge 18.04.2021
|
||||
*/
|
||||
public class FilterParameter {
|
||||
|
||||
private String type;
|
||||
private String name;
|
||||
|
||||
private FilterParameter(String type, String name) {
|
||||
this.type = type;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public static FilterParameter of(String type, String name) {
|
||||
return new FilterParameter(type, name);
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package dev.struchkov.haiti.filter.criteria.generate.domain;
|
||||
|
||||
/**
|
||||
* // TODO: 18.04.2021 Добавить описание.
|
||||
*
|
||||
* @author upagge 18.04.2021
|
||||
*/
|
||||
public enum FilterType {
|
||||
|
||||
SINGLE, AND, OR, NOT
|
||||
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package dev.struchkov.haiti.filter.criteria.generate.processor;
|
||||
|
||||
import dev.struchkov.haiti.filter.criteria.generate.Annotations;
|
||||
import dev.struchkov.haiti.filter.criteria.generate.domain.FilterDto;
|
||||
import dev.struchkov.haiti.filter.criteria.generate.domain.FilterParameter;
|
||||
import dev.struchkov.haiti.utils.Exceptions;
|
||||
|
||||
import javax.annotation.processing.ProcessingEnvironment;
|
||||
import javax.tools.JavaFileObject;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.List;
|
||||
|
||||
public class FilterRecorder {
|
||||
|
||||
private FilterRecorder() {
|
||||
Exceptions.utilityClass();
|
||||
}
|
||||
|
||||
public static void record(FilterDto filter, ProcessingEnvironment environment) {
|
||||
JavaFileObject builderFile = null;
|
||||
try {
|
||||
builderFile = environment.getFiler().createSourceFile(filter.getName());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try (PrintWriter out = new PrintWriter(builderFile.openWriter())) {
|
||||
out.println("package " + filter.getPackageName() + ";");
|
||||
out.println();
|
||||
out.print("public class " + filter.getName() + " {");
|
||||
out.println();
|
||||
out.println();
|
||||
generateName(out, filter);
|
||||
out.println(" public static " + filter.getName() + " empty() {");
|
||||
out.println(" return new " + filter.getName() + "();");
|
||||
out.println(" }");
|
||||
out.println();
|
||||
out.println("}");
|
||||
out.println();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static void generateName(PrintWriter out, FilterDto filter) {
|
||||
final List<FilterParameter> parameters = filter.getParameters();
|
||||
for (FilterParameter parameter : parameters) {
|
||||
out.println(Annotations.getter(1, parameter.getType(), parameter.getName()));
|
||||
out.println();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
package dev.struchkov.haiti.filter.criteria.generate.processor;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import dev.struchkov.haiti.filter.criteria.generate.annotation.FilterField;
|
||||
import dev.struchkov.haiti.filter.criteria.generate.annotation.GenerateFilter;
|
||||
import dev.struchkov.haiti.filter.criteria.generate.domain.FilterDto;
|
||||
import dev.struchkov.haiti.filter.criteria.generate.domain.FilterParameter;
|
||||
import dev.struchkov.haiti.utils.Strings;
|
||||
|
||||
import javax.annotation.processing.AbstractProcessor;
|
||||
import javax.annotation.processing.Processor;
|
||||
import javax.annotation.processing.RoundEnvironment;
|
||||
import javax.annotation.processing.SupportedAnnotationTypes;
|
||||
import javax.annotation.processing.SupportedSourceVersion;
|
||||
import javax.lang.model.SourceVersion;
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
import static dev.struchkov.haiti.filter.criteria.generate.Annotations.getPackage;
|
||||
import static dev.struchkov.haiti.filter.criteria.generate.Annotations.isField;
|
||||
|
||||
/**
|
||||
* @author upagge 17.04.2021
|
||||
*/
|
||||
@SupportedAnnotationTypes("dev.struchkov.haiti.filter.criteria.generate.annotation.GenerateFilter")
|
||||
@SupportedSourceVersion(SourceVersion.RELEASE_8)
|
||||
@AutoService(Processor.class)
|
||||
public class GenerateFilterProcessor extends AbstractProcessor {
|
||||
|
||||
@Override
|
||||
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment env) {
|
||||
for (TypeElement annotation : annotations) {
|
||||
Set<? extends Element> annotatedElements = env.getElementsAnnotatedWith(annotation);
|
||||
for (Element annotatedElement : annotatedElements) {
|
||||
final FilterDto filterDto = createFilter(annotatedElement);
|
||||
FilterRecorder.record(filterDto, processingEnv);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private FilterDto createFilter(Element annotatedElement) {
|
||||
final TypeMirror typeMirror = annotatedElement.asType();
|
||||
final String simpleClassName = annotatedElement.getSimpleName().toString();
|
||||
final GenerateFilter filterOption = annotatedElement.getAnnotation(GenerateFilter.class);
|
||||
|
||||
final FilterDto filterDto = new FilterDto();
|
||||
filterDto.setName(getFilterName(simpleClassName, filterOption));
|
||||
filterDto.setPackageName(getPackage(typeMirror));
|
||||
|
||||
List<FilterParameter> parameters = new ArrayList<>();
|
||||
for (Element element : annotatedElement.getEnclosedElements()) {
|
||||
if (isField(element)) {
|
||||
fieldProcessing(element).ifPresent(parameters::add);
|
||||
}
|
||||
}
|
||||
filterDto.setParameters(parameters);
|
||||
return filterDto;
|
||||
}
|
||||
|
||||
private Optional<FilterParameter> fieldProcessing(Element element) {
|
||||
final FilterField.Exclude exclude = element.getAnnotation(FilterField.Exclude.class);
|
||||
if (exclude == null) {
|
||||
final String simpleName = element.getSimpleName().toString();
|
||||
return Optional.of(FilterParameter.of(element.asType().toString(), simpleName));
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private String getFilterName(String className, GenerateFilter filterOption) {
|
||||
if (Strings.EMPTY.equals(filterOption.name())) {
|
||||
return className + "Filter";
|
||||
} else {
|
||||
return filterOption.name();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
11
src/main/java/module-info.java
Normal file
11
src/main/java/module-info.java
Normal file
@ -0,0 +1,11 @@
|
||||
module haiti.filter.criteria {
|
||||
exports dev.struchkov.haiti.filter.criteria;
|
||||
|
||||
requires java.persistence;
|
||||
requires haiti.utils;
|
||||
requires spring.data.jpa;
|
||||
requires org.hibernate.orm.core;
|
||||
requires haiti.filter;
|
||||
requires java.compiler;
|
||||
requires com.google.auto.service;
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
package org.sadtech.haiti.filter.criteria;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
/**
|
||||
* // TODO: 15.04.2021 Добавить описание.
|
||||
*
|
||||
* @author upagge 15.04.2021
|
||||
*/
|
||||
@Getter
|
||||
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class JoinTable {
|
||||
|
||||
private final String tableName;
|
||||
private final JoinTypeOperation joinTypeOperation;
|
||||
|
||||
public static JoinTable of(@NonNull String tableName) {
|
||||
return new JoinTable(tableName, JoinTypeOperation.LEFT);
|
||||
}
|
||||
|
||||
public static JoinTable of(@NonNull String tableName, JoinTypeOperation joinType) {
|
||||
return new JoinTable(tableName, joinType);
|
||||
}
|
||||
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
package org.sadtech.haiti.filter.criteria;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import javax.persistence.criteria.JoinType;
|
||||
|
||||
/**
|
||||
* // TODO: 15.04.2021 Добавить описание.
|
||||
*
|
||||
* @author upagge 15.04.2021
|
||||
*/
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public enum JoinTypeOperation {
|
||||
|
||||
LEFT(JoinType.LEFT),
|
||||
INNER(JoinType.INNER);
|
||||
|
||||
private final JoinType criteriaType;
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user