release-0.0.4

This commit is contained in:
Struchkov Mark 2022-01-25 09:44:13 +03:00
parent 5534b18573
commit ea6bc5a175
18 changed files with 549 additions and 209 deletions

165
pom.xml
View File

@ -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>

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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)

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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();
}
}

View File

@ -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 {
}
}

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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
}

View File

@ -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();
}
}
}

View File

@ -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();
}
}
}

View 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;
}

View File

@ -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);
}
}

View File

@ -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;
}