From ea6bc5a175017959c2840c1186c182a289bdaebc Mon Sep 17 00:00:00 2001 From: Struchkov Mark Date: Tue, 25 Jan 2022 09:44:13 +0300 Subject: [PATCH] release-0.0.4 --- pom.xml | 165 +++++------------- .../haiti/filter/criteria/Container.java | 28 ++- .../haiti/filter/criteria/CriteriaFilter.java | 43 ++++- .../haiti/filter/criteria/CriteriaQuery.java | 45 +++-- .../haiti/filter/criteria/JoinTable.java | 37 ++++ .../filter/criteria/JoinTypeOperation.java | 22 +++ .../filter/criteria/SimpleCriteriaQuery.java | 37 +++- .../filter/criteria/generate/Annotations.java | 44 +++++ .../generate/annotation/FilterField.java | 19 ++ .../generate/annotation/GenerateFilter.java | 18 ++ .../criteria/generate/domain/FilterDto.java | 60 +++++++ .../generate/domain/FilterParameter.java | 30 ++++ .../criteria/generate/domain/FilterType.java | 12 ++ .../generate/processor/FilterRecorder.java | 54 ++++++ .../processor/GenerateFilterProcessor.java | 83 +++++++++ src/main/java/module-info.java | 11 ++ .../haiti/filter/criteria/JoinTable.java | 28 --- .../filter/criteria/JoinTypeOperation.java | 22 --- 18 files changed, 549 insertions(+), 209 deletions(-) rename src/main/java/{org/sadtech => dev/struchkov}/haiti/filter/criteria/Container.java (54%) rename src/main/java/{org/sadtech => dev/struchkov}/haiti/filter/criteria/CriteriaFilter.java (72%) rename src/main/java/{org/sadtech => dev/struchkov}/haiti/filter/criteria/CriteriaQuery.java (74%) create mode 100644 src/main/java/dev/struchkov/haiti/filter/criteria/JoinTable.java create mode 100644 src/main/java/dev/struchkov/haiti/filter/criteria/JoinTypeOperation.java rename src/main/java/{org/sadtech => dev/struchkov}/haiti/filter/criteria/SimpleCriteriaQuery.java (81%) create mode 100644 src/main/java/dev/struchkov/haiti/filter/criteria/generate/Annotations.java create mode 100644 src/main/java/dev/struchkov/haiti/filter/criteria/generate/annotation/FilterField.java create mode 100644 src/main/java/dev/struchkov/haiti/filter/criteria/generate/annotation/GenerateFilter.java create mode 100644 src/main/java/dev/struchkov/haiti/filter/criteria/generate/domain/FilterDto.java create mode 100644 src/main/java/dev/struchkov/haiti/filter/criteria/generate/domain/FilterParameter.java create mode 100644 src/main/java/dev/struchkov/haiti/filter/criteria/generate/domain/FilterType.java create mode 100644 src/main/java/dev/struchkov/haiti/filter/criteria/generate/processor/FilterRecorder.java create mode 100644 src/main/java/dev/struchkov/haiti/filter/criteria/generate/processor/GenerateFilterProcessor.java create mode 100644 src/main/java/module-info.java delete mode 100644 src/main/java/org/sadtech/haiti/filter/criteria/JoinTable.java delete mode 100644 src/main/java/org/sadtech/haiti/filter/criteria/JoinTypeOperation.java diff --git a/pom.xml b/pom.xml index ca0f0d0..90a3020 100644 --- a/pom.xml +++ b/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"> 4.0.0 - org.sadtech.haiti + dev.struchkov.haiti haiti - 0.0.2-SNAPSHOT + 0.0.4 - org.sadtech.haiti.filter + dev.struchkov.haiti.filter haiti-filter-criteria - 0.0.3-SNAPSHOT + 0.0.4 Haiti Filter Criteria Fast creation of filtering requests using the Criteria Api wrapper. @@ -20,57 +20,43 @@ Apache License, Version 2.0 https://www.apache.org/licenses/LICENSE-2.0 - - 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. - - - - SADTECH - https://sadtech.org - - - - scm:git:https://github.com/haiti-projects/haiti-filter-criteria.git - https://github.com/haiti-projects/haiti-filter-criteria - scm:git:https://github.com/haiti-projects/haiti-filter-criteria.git - - - - - ossrh - https://oss.sonatype.org/content/repositories/snapshots - - - GitHub https://github.com/haiti-projects/haiti-framework/issues + + 11 + ${java.version} + ${java.version} + UTF-8 + UTF-8 + + 0.0.4 + 1.0.1 + + 3.9.0 + 1.6.8 + 3.2.1 + 3.3.1 + 3.0.1 + + - org.sadtech.haiti + dev.struchkov.haiti haiti-filter + + dev.struchkov.haiti + haiti-utils + - org.projectlombok - lombok + com.google.auto.service + auto-service @@ -85,98 +71,35 @@ org.hibernate hibernate-core - 5.4.29.Final - - - release - - - - org.sonatype.plugins - nexus-staging-maven-plugin - 1.6.7 - true - - ossrh - https://oss.sonatype.org/ - true - - - - org.apache.maven.plugins - maven-source-plugin - 2.2.1 - - - attach-sources - - jar-no-fork - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 2.9.1 - - - attach-javadocs - - jar - - - - - - org.apache.maven.plugins - maven-gpg-plugin - 1.5 - - - sign-artifacts - verify - - sign - - - - - - - - - org.apache.maven.plugins maven-compiler-plugin - 3.8.0 - 8 - 8 + + + com.google.auto.service + auto-service + 1.0.1 + + + + org.sonatype.plugins + nexus-staging-maven-plugin + - - - uPagge - Struchkov Mark - upagge@ya.ru - SADTECH - https://sadtech.org - https://uPagge.sadtech.org - - Project lead - - +3 - - + + scm:git:https://github.com/haiti-projects/haiti-filter-criteria.git + https://github.com/haiti-projects/haiti-filter-criteria + scm:git:https://github.com/haiti-projects/haiti-filter-criteria.git + \ No newline at end of file diff --git a/src/main/java/org/sadtech/haiti/filter/criteria/Container.java b/src/main/java/dev/struchkov/haiti/filter/criteria/Container.java similarity index 54% rename from src/main/java/org/sadtech/haiti/filter/criteria/Container.java rename to src/main/java/dev/struchkov/haiti/filter/criteria/Container.java index 5733632..a86fa47 100644 --- a/src/main/java/org/sadtech/haiti/filter/criteria/Container.java +++ b/src/main/java/dev/struchkov/haiti/filter/criteria/Container.java @@ -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 { private final String uuid = UUID.randomUUID().toString(); @@ -31,4 +25,24 @@ public class Container { return new Container<>(joinTables); } + public List getJoinTables() { + return joinTables; + } + + public void setJoinTables(List joinTables) { + this.joinTables = joinTables; + } + + public Specification getSpecification() { + return specification; + } + + public void setSpecification(Specification specification) { + this.specification = specification; + } + + public String getUuid() { + return uuid; + } + } diff --git a/src/main/java/org/sadtech/haiti/filter/criteria/CriteriaFilter.java b/src/main/java/dev/struchkov/haiti/filter/criteria/CriteriaFilter.java similarity index 72% rename from src/main/java/org/sadtech/haiti/filter/criteria/CriteriaFilter.java rename to src/main/java/dev/struchkov/haiti/filter/criteria/CriteriaFilter.java index c4d61e3..82c16be 100644 --- a/src/main/java/org/sadtech/haiti/filter/criteria/CriteriaFilter.java +++ b/src/main/java/dev/struchkov/haiti/filter/criteria/CriteriaFilter.java @@ -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 implements Filter { private final List> andSpecifications = new ArrayList<>(); private final List> orSpecifications = new ArrayList<>(); private final List> notSpecifications = new ArrayList<>(); + private CriteriaFilter() { + } + public static Filter create() { return new CriteriaFilter(); } @@ -29,18 +30,46 @@ public class CriteriaFilter implements Filter { return this; } + @Override + public Filter and(Consumer 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 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 query) { + final FilterQuery criteriaQuery = CriteriaQuery.create(); + query.accept(criteriaQuery); + notSpecifications.addAll( + getSpecification(criteriaQuery).stream() + .map(Specification::not) + .collect(Collectors.toUnmodifiableList()) ); return this; } diff --git a/src/main/java/org/sadtech/haiti/filter/criteria/CriteriaQuery.java b/src/main/java/dev/struchkov/haiti/filter/criteria/CriteriaQuery.java similarity index 74% rename from src/main/java/org/sadtech/haiti/filter/criteria/CriteriaQuery.java rename to src/main/java/dev/struchkov/haiti/filter/criteria/CriteriaQuery.java index acc025a..10b0e9a 100644 --- a/src/main/java/org/sadtech/haiti/filter/criteria/CriteriaQuery.java +++ b/src/main/java/dev/struchkov/haiti/filter/criteria/CriteriaQuery.java @@ -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 implements FilterQuery { private static final CriteriaQuery EMPTY = new CriteriaQuery<>(new ArrayList<>()); + public static final String FIELD_NAME = "field"; + private final List> containers; private List joinTables = new ArrayList<>(); private final SimpleCriteriaQuery simpleCriteriaQuery = new SimpleCriteriaQuery(); + public CriteriaQuery(List> containers) { + this.containers = containers; + } + public static FilterQuery create() { return new CriteriaQuery(new ArrayList<>()); } @@ -29,20 +35,23 @@ public class CriteriaQuery implements FilterQuery { * * @param fieldName Имя поля сущности, которое отвечает за название таблицы. */ - public CriteriaQuery join(@NonNull String... fieldName) { + public CriteriaQuery join(String... fieldName) { + isNotNull(fieldName, nullPointer("fieldName")); joinTables = Arrays.stream(fieldName) .map(JoinTable::of) .collect(Collectors.toList()); return this; } - public CriteriaQuery join(@NonNull JoinTable... joinTables) { + public CriteriaQuery join(JoinTable... joinTables) { + isNotNull(joinTables, nullPointer("joinTables")); this.joinTables = Arrays.stream(joinTables).collect(Collectors.toList()); return this; } @Override - public > FilterQuery between(@NonNull String field, Y from, Y to) { + public > 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 implements FilterQuery { } @Override - public > FilterQuery greaterThan(@NonNull String field, Y value) { + public > 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 implements FilterQuery { } @Override - public > FilterQuery lessThan(@NonNull String field, Y value) { + public > 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 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 implements FilterQuery { } @Override - public FilterQuery matchPhrase(@NonNull String field, Set values) { + public FilterQuery matchPhrase(String field, Set values) { + isNotNull(field, nullPointer(FIELD_NAME)); if (values != null && !values.isEmpty()) { containers.addAll( values.stream() @@ -105,7 +118,8 @@ public class CriteriaQuery 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 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) diff --git a/src/main/java/dev/struchkov/haiti/filter/criteria/JoinTable.java b/src/main/java/dev/struchkov/haiti/filter/criteria/JoinTable.java new file mode 100644 index 0000000..3bef8df --- /dev/null +++ b/src/main/java/dev/struchkov/haiti/filter/criteria/JoinTable.java @@ -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; + } +} diff --git a/src/main/java/dev/struchkov/haiti/filter/criteria/JoinTypeOperation.java b/src/main/java/dev/struchkov/haiti/filter/criteria/JoinTypeOperation.java new file mode 100644 index 0000000..a6e1f85 --- /dev/null +++ b/src/main/java/dev/struchkov/haiti/filter/criteria/JoinTypeOperation.java @@ -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; + } +} diff --git a/src/main/java/org/sadtech/haiti/filter/criteria/SimpleCriteriaQuery.java b/src/main/java/dev/struchkov/haiti/filter/criteria/SimpleCriteriaQuery.java similarity index 81% rename from src/main/java/org/sadtech/haiti/filter/criteria/SimpleCriteriaQuery.java rename to src/main/java/dev/struchkov/haiti/filter/criteria/SimpleCriteriaQuery.java index d090e4a..3ea1294 100644 --- a/src/main/java/org/sadtech/haiti/filter/criteria/SimpleCriteriaQuery.java +++ b/src/main/java/dev/struchkov/haiti/filter/criteria/SimpleCriteriaQuery.java @@ -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 { + public static final String FIELD = "field"; + private From lastJoin; private final Set unique = new HashSet<>(); private final Map> joinMap = new HashMap<>(); - public Container matchPhrase(List joinTables, @NonNull String field, @NonNull Object value) { + public Container matchPhrase(List joinTables, String field, Object value) { + Assert.isNotNull(field, nullPointer(FIELD)); + Assert.isNotNull(value, nullPointer("value")); + final Container 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 { return container; } - public Container exists(List joinTables, @NonNull String field) { + public Container exists(List joinTables, String field) { + Assert.isNotNull(field, nullPointer(FIELD)); + final Container container = Container.of(joinTables); container.setSpecification((root, query, cb) -> cb.isNotNull(getPath(root, container).get(field))); return container; } - public Container likeIgnoreCase(List joinTables, @NonNull String field, String value) { + public Container likeIgnoreCase(List joinTables, String field, String value) { + Assert.isNotNull(field, nullPointer(FIELD)); + final Container container = Container.of(joinTables); container.setSpecification((root, query, cb) -> cb.like(cb.lower(getPath(root, container).get(field)), value)); return container; } - public Container like(List joinTables, @NonNull String field, String value) { + public Container like(List joinTables, String field, String value) { + Assert.isNotNull(field, nullPointer(FIELD)); + final Container container = Container.of(joinTables); container.setSpecification((root, query, cb) -> cb.like(getPath(root, container).get(field), value)); return container; } - public > Container between(List joinTables, @NonNull String field, Y from, Y to) { + public > Container between(List joinTables, String field, Y from, Y to) { + Assert.isNotNull(field, nullPointer(FIELD)); + final Container container = Container.of(joinTables); container.setSpecification((root, query, cb) -> cb.between(getPath(root, container).get(field), from, to)); return container; } - public > Container greaterThan(List joinTables, @NonNull String field, Y value) { + public > Container greaterThan(List joinTables, String field, Y value) { + Assert.isNotNull(field, nullPointer(FIELD)); + final Container container = Container.of(joinTables); container.setSpecification(((root, query, cb) -> cb.greaterThan(getPath(root, container).get(field), value))); return container; } - public > Container lessThan(List joinTables, @NonNull String field, Y value) { + public > Container lessThan(List joinTables, String field, Y value) { + Assert.isNotNull(field, nullPointer(FIELD)); + final Container container = Container.of(joinTables); container.setSpecification(((root, query, cb) -> cb.lessThan(getPath(root, container).get(field), value))); return container; diff --git a/src/main/java/dev/struchkov/haiti/filter/criteria/generate/Annotations.java b/src/main/java/dev/struchkov/haiti/filter/criteria/generate/Annotations.java new file mode 100644 index 0000000..9f4277f --- /dev/null +++ b/src/main/java/dev/struchkov/haiti/filter/criteria/generate/Annotations.java @@ -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(); + } + +} diff --git a/src/main/java/dev/struchkov/haiti/filter/criteria/generate/annotation/FilterField.java b/src/main/java/dev/struchkov/haiti/filter/criteria/generate/annotation/FilterField.java new file mode 100644 index 0000000..cf55ec8 --- /dev/null +++ b/src/main/java/dev/struchkov/haiti/filter/criteria/generate/annotation/FilterField.java @@ -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 { + + } + +} diff --git a/src/main/java/dev/struchkov/haiti/filter/criteria/generate/annotation/GenerateFilter.java b/src/main/java/dev/struchkov/haiti/filter/criteria/generate/annotation/GenerateFilter.java new file mode 100644 index 0000000..4dac29b --- /dev/null +++ b/src/main/java/dev/struchkov/haiti/filter/criteria/generate/annotation/GenerateFilter.java @@ -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; + +} diff --git a/src/main/java/dev/struchkov/haiti/filter/criteria/generate/domain/FilterDto.java b/src/main/java/dev/struchkov/haiti/filter/criteria/generate/domain/FilterDto.java new file mode 100644 index 0000000..0931ade --- /dev/null +++ b/src/main/java/dev/struchkov/haiti/filter/criteria/generate/domain/FilterDto.java @@ -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 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 getParameters() { + return parameters; + } + + public void setParameters(List parameters) { + this.parameters = parameters; + } + +} diff --git a/src/main/java/dev/struchkov/haiti/filter/criteria/generate/domain/FilterParameter.java b/src/main/java/dev/struchkov/haiti/filter/criteria/generate/domain/FilterParameter.java new file mode 100644 index 0000000..248a75f --- /dev/null +++ b/src/main/java/dev/struchkov/haiti/filter/criteria/generate/domain/FilterParameter.java @@ -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; + } + +} diff --git a/src/main/java/dev/struchkov/haiti/filter/criteria/generate/domain/FilterType.java b/src/main/java/dev/struchkov/haiti/filter/criteria/generate/domain/FilterType.java new file mode 100644 index 0000000..a0b8700 --- /dev/null +++ b/src/main/java/dev/struchkov/haiti/filter/criteria/generate/domain/FilterType.java @@ -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 + +} diff --git a/src/main/java/dev/struchkov/haiti/filter/criteria/generate/processor/FilterRecorder.java b/src/main/java/dev/struchkov/haiti/filter/criteria/generate/processor/FilterRecorder.java new file mode 100644 index 0000000..3526e19 --- /dev/null +++ b/src/main/java/dev/struchkov/haiti/filter/criteria/generate/processor/FilterRecorder.java @@ -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 parameters = filter.getParameters(); + for (FilterParameter parameter : parameters) { + out.println(Annotations.getter(1, parameter.getType(), parameter.getName())); + out.println(); + } + } + +} diff --git a/src/main/java/dev/struchkov/haiti/filter/criteria/generate/processor/GenerateFilterProcessor.java b/src/main/java/dev/struchkov/haiti/filter/criteria/generate/processor/GenerateFilterProcessor.java new file mode 100644 index 0000000..48f4d0c --- /dev/null +++ b/src/main/java/dev/struchkov/haiti/filter/criteria/generate/processor/GenerateFilterProcessor.java @@ -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 annotations, RoundEnvironment env) { + for (TypeElement annotation : annotations) { + Set 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 parameters = new ArrayList<>(); + for (Element element : annotatedElement.getEnclosedElements()) { + if (isField(element)) { + fieldProcessing(element).ifPresent(parameters::add); + } + } + filterDto.setParameters(parameters); + return filterDto; + } + + private Optional 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(); + } + } + +} diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java new file mode 100644 index 0000000..2a278fc --- /dev/null +++ b/src/main/java/module-info.java @@ -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; +} \ No newline at end of file diff --git a/src/main/java/org/sadtech/haiti/filter/criteria/JoinTable.java b/src/main/java/org/sadtech/haiti/filter/criteria/JoinTable.java deleted file mode 100644 index 736229c..0000000 --- a/src/main/java/org/sadtech/haiti/filter/criteria/JoinTable.java +++ /dev/null @@ -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); - } - -} diff --git a/src/main/java/org/sadtech/haiti/filter/criteria/JoinTypeOperation.java b/src/main/java/org/sadtech/haiti/filter/criteria/JoinTypeOperation.java deleted file mode 100644 index dd8f3a5..0000000 --- a/src/main/java/org/sadtech/haiti/filter/criteria/JoinTypeOperation.java +++ /dev/null @@ -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; - -}