diff --git a/pom.xml b/pom.xml
index a391f9a..39cade8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,10 +7,57 @@
org.sadtech.example
create-annotation
0.0.1-SNAPSHOT
+ jar
11
11
+
+
+ com.google.auto.service
+ auto-service
+ 1.0
+ provided
+
+
+ com.google.guava
+ guava
+ 30.1.1-jre
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+
+
+ attach-sources
+
+ jar
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+
+ ${java.home}/bin/javadoc
+
+
+
+ attach-javadocs
+
+ jar
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/org/sadtech/example/annotation/ClassCreator.java b/src/main/java/org/sadtech/example/annotation/ClassCreator.java
new file mode 100644
index 0000000..ba01377
--- /dev/null
+++ b/src/main/java/org/sadtech/example/annotation/ClassCreator.java
@@ -0,0 +1,52 @@
+package org.sadtech.example.annotation;
+
+import org.sadtech.example.annotation.domain.ClassDto;
+import org.sadtech.example.annotation.domain.FieldDto;
+
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.tools.JavaFileObject;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Set;
+
+/**
+ * // TODO: 20.06.2021 Добавить описание.
+ *
+ * @author upagge 20.06.2021
+ */
+public class ClassCreator {
+
+ private ClassCreator() {
+
+ }
+
+ public static void record(ClassDto classDto, ProcessingEnvironment environment) {
+ JavaFileObject builderFile = null;
+ try {
+ builderFile = environment.getFiler().createSourceFile(classDto.getClassName());
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ try (PrintWriter out = new PrintWriter(builderFile.openWriter())) {
+ out.println("package " + classDto.getClassPackage() + ";");
+ out.println();
+ out.print("public class " + classDto.getClassName() + " {");
+ out.println();
+ out.println();
+ generateNames(classDto.getFields(), out);
+ out.println();
+ out.println("}");
+ out.println();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private static void generateNames(Set fields, PrintWriter out) {
+ for (FieldDto field : fields) {
+ out.println(" public static final String " + field.getFieldStringName() + " = \"" + field.getFieldName() + "\";");
+ }
+ }
+
+}
diff --git a/src/main/java/org/sadtech/example/annotation/FieldNames.java b/src/main/java/org/sadtech/example/annotation/FieldNames.java
new file mode 100644
index 0000000..8a2710c
--- /dev/null
+++ b/src/main/java/org/sadtech/example/annotation/FieldNames.java
@@ -0,0 +1,14 @@
+package org.sadtech.example.annotation;
+
+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 FieldNames {
+
+ String postfix() default "Fields";
+
+}
diff --git a/src/main/java/org/sadtech/example/annotation/domain/ClassDto.java b/src/main/java/org/sadtech/example/annotation/domain/ClassDto.java
new file mode 100644
index 0000000..a85d401
--- /dev/null
+++ b/src/main/java/org/sadtech/example/annotation/domain/ClassDto.java
@@ -0,0 +1,35 @@
+package org.sadtech.example.annotation.domain;
+
+import java.util.Set;
+
+public class ClassDto {
+
+ private String className;
+ private Set fields;
+ private String classPackage;
+
+ public String getClassName() {
+ return className;
+ }
+
+ public void setClassName(String className) {
+ this.className = className;
+ }
+
+ public Set getFields() {
+ return fields;
+ }
+
+ public void setFields(Set fields) {
+ this.fields = fields;
+ }
+
+ public String getClassPackage() {
+ return classPackage;
+ }
+
+ public void setClassPackage(String classPackage) {
+ this.classPackage = classPackage;
+ }
+
+}
diff --git a/src/main/java/org/sadtech/example/annotation/domain/FieldDto.java b/src/main/java/org/sadtech/example/annotation/domain/FieldDto.java
new file mode 100644
index 0000000..6d8bfc8
--- /dev/null
+++ b/src/main/java/org/sadtech/example/annotation/domain/FieldDto.java
@@ -0,0 +1,30 @@
+package org.sadtech.example.annotation.domain;
+
+/**
+ * // TODO: 07.06.2021 Добавить описание.
+ *
+ * @author upagge 07.06.2021
+ */
+public class FieldDto {
+
+ private final String fieldStringName;
+ private final String fieldName;
+
+ private FieldDto(String fieldStringName, String fieldName) {
+ this.fieldStringName = fieldStringName;
+ this.fieldName = fieldName;
+ }
+
+ public static FieldDto of(String fieldStringName, String fieldName) {
+ return new FieldDto(fieldStringName, fieldName);
+ }
+
+ public String getFieldStringName() {
+ return fieldStringName;
+ }
+
+ public String getFieldName() {
+ return fieldName;
+ }
+
+}
diff --git a/src/main/java/org/sadtech/example/annotation/processor/FieldNameProcessor.java b/src/main/java/org/sadtech/example/annotation/processor/FieldNameProcessor.java
new file mode 100644
index 0000000..29a1665
--- /dev/null
+++ b/src/main/java/org/sadtech/example/annotation/processor/FieldNameProcessor.java
@@ -0,0 +1,67 @@
+package org.sadtech.example.annotation.processor;
+
+import com.google.auto.service.AutoService;
+import com.google.common.base.CaseFormat;
+import org.sadtech.example.annotation.ClassCreator;
+import org.sadtech.example.annotation.FieldNames;
+import org.sadtech.example.annotation.domain.ClassDto;
+import org.sadtech.example.annotation.domain.FieldDto;
+
+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.Arrays;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+@SupportedAnnotationTypes("org.sadtech.example.annotation.FieldNames")
+@SupportedSourceVersion(SourceVersion.RELEASE_11)
+@AutoService(Processor.class)
+public class FieldNameProcessor extends AbstractProcessor {
+
+ @Override
+ public boolean process(Set extends TypeElement> set, RoundEnvironment roundEnvironment) {
+ for (TypeElement annotation : set) {
+ Set extends Element> annotatedElements = roundEnvironment.getElementsAnnotatedWith(annotation);
+ for (Element annotatedElement : annotatedElements) {
+ final TypeMirror mirror = annotatedElement.asType();
+ final String annotatedElementName = annotatedElement.getSimpleName().toString();
+ final FieldNames settings = annotatedElement.getAnnotation(FieldNames.class);
+ final String newClassName = annotatedElementName + settings.postfix();
+
+ final Set fields = annotatedElement.getEnclosedElements().stream()
+ .filter(this::isField)
+ .map(
+ element -> {
+ final String fieldName = element.getSimpleName().toString();
+ final String fieldStringName = CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, fieldName);
+ return FieldDto.of(fieldStringName, fieldName);
+ }
+ ).collect(Collectors.toSet());
+
+ final ClassDto newClass = new ClassDto();
+ newClass.setClassName(newClassName);
+ newClass.setFields(fields);
+ newClass.setClassPackage(getPackage(mirror));
+ ClassCreator.record(newClass, processingEnv);
+ }
+ }
+ return true;
+ }
+
+ public 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));
+ }
+
+}