$srcFile
package jackfruit;
public class JackfruitVersion {
- public final static String lastCommit = "$lastCommit";
- // an M at the end of gitRevision means this was built from a "dirty" git repository
- public final static String rev = "$rev";
+ public final static String version = "$version";
public final static String packageName = "$package";
public final static String dateString = "$date";
}
diff --git a/jackfruit/src/main/java/jackfruit/JackfruitVersion.java b/jackfruit/src/main/java/jackfruit/JackfruitVersion.java
index 8ad0d61..d5dc6d8 100644
--- a/jackfruit/src/main/java/jackfruit/JackfruitVersion.java
+++ b/jackfruit/src/main/java/jackfruit/JackfruitVersion.java
@@ -2,10 +2,8 @@
package jackfruit;
public class JackfruitVersion {
- public final static String lastCommit = "23.06.04";
- // an M at the end of gitRevision means this was built from a "dirty" git repository
- public final static String rev = "72908621";
+ public final static String version = "1.0-SNAPSHOT";
public final static String packageName = "jackfruit";
- public final static String dateString = "23.06.04";
+ public final static String dateString = "23.09.02";
}
diff --git a/jackfruit/src/main/java/jackfruit/annotations/Comment.java b/jackfruit/src/main/java/jackfruit/annotations/Comment.java
index 84acb13..9c8a485 100644
--- a/jackfruit/src/main/java/jackfruit/annotations/Comment.java
+++ b/jackfruit/src/main/java/jackfruit/annotations/Comment.java
@@ -28,8 +28,8 @@ import java.lang.annotation.Target;
/**
* The Comment annotation specifies the comment that appears in the configuration file above the
* parameter itself.
- *
- * @author nairah1
+ *
+ * @author Hari.Nair@jhuapl.edu
*
*/
@Retention(RetentionPolicy.SOURCE)
diff --git a/jackfruit/src/main/java/jackfruit/annotations/DefaultValue.java b/jackfruit/src/main/java/jackfruit/annotations/DefaultValue.java
index bf3a80f..956fd7f 100644
--- a/jackfruit/src/main/java/jackfruit/annotations/DefaultValue.java
+++ b/jackfruit/src/main/java/jackfruit/annotations/DefaultValue.java
@@ -32,8 +32,8 @@ import java.lang.annotation.Target;
* Strings and primitives (and their corresponding wrapper types) are read natively. Other objects
* will need to use the {@link ParserClass} annotation to specify a class which implements the
* {@link Parser} interface to convert the object to and from a String.
- *
- * @author nairah1
+ *
+ * @author Hari.Nair@jhuapl.edu
*
*/
@Retention(RetentionPolicy.SOURCE)
diff --git a/jackfruit/src/main/java/jackfruit/annotations/Jackfruit.java b/jackfruit/src/main/java/jackfruit/annotations/Jackfruit.java
index 06ced97..dfe10c5 100644
--- a/jackfruit/src/main/java/jackfruit/annotations/Jackfruit.java
+++ b/jackfruit/src/main/java/jackfruit/annotations/Jackfruit.java
@@ -9,9 +9,9 @@ package jackfruit.annotations;
* 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
- *
+ *
* http://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.
@@ -27,16 +27,15 @@ import java.lang.annotation.Target;
/**
* Use this annotation to signify that it should be run through the annotation processor. There is
- * an optional "prefix" argument that can be used to add a prefix to all of the configuration keys
+ * an optional "prefix" argument that can be used to add a prefix to all the configuration keys
* created by the processor.
- *
- * For example:
- * @Jackfruit(prefix = "myPrefix")
- *
- * Inspired by owner.
- *
- * @author nairah1
*
+ *
For example:
+ * @Jackfruit(prefix = "myPrefix")
+ *
+ *
Inspired by owner.
+ *
+ * @author Hari.Nair@jhuapl.edu
*/
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE)
diff --git a/jackfruit/src/main/java/jackfruit/annotations/Key.java b/jackfruit/src/main/java/jackfruit/annotations/Key.java
index 05e7453..30e88cc 100644
--- a/jackfruit/src/main/java/jackfruit/annotations/Key.java
+++ b/jackfruit/src/main/java/jackfruit/annotations/Key.java
@@ -9,9 +9,9 @@ package jackfruit.annotations;
* 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
- *
+ *
* http://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.
@@ -28,9 +28,8 @@ import java.lang.annotation.Target;
/**
* The Key annotation can be used to specify the name for the configuration key. The default is to
* use the name of the method.
- *
- * @author nairah1
*
+ * @author Hari.Nair@jhuapl.edu
*/
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.METHOD)
diff --git a/jackfruit/src/main/java/jackfruit/annotations/Parser.java b/jackfruit/src/main/java/jackfruit/annotations/Parser.java
index f3b1588..69d8df4 100644
--- a/jackfruit/src/main/java/jackfruit/annotations/Parser.java
+++ b/jackfruit/src/main/java/jackfruit/annotations/Parser.java
@@ -9,9 +9,9 @@ package jackfruit.annotations;
* 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
- *
+ *
* http://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.
@@ -22,10 +22,9 @@ package jackfruit.annotations;
/**
* Interface to serialize/deserialize a string to a custom class.
- *
- * @author nairah1
*
- * @param
+ * @author Hari.Nair@jhuapl.edu
+ * @param Type to be serialized/deserialized
*/
public interface Parser {
T fromString(String s);
diff --git a/jackfruit/src/main/java/jackfruit/annotations/ParserClass.java b/jackfruit/src/main/java/jackfruit/annotations/ParserClass.java
index 8159e76..df7e5b4 100644
--- a/jackfruit/src/main/java/jackfruit/annotations/ParserClass.java
+++ b/jackfruit/src/main/java/jackfruit/annotations/ParserClass.java
@@ -9,9 +9,9 @@ package jackfruit.annotations;
* 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
- *
+ *
* http://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.
@@ -28,9 +28,8 @@ import java.lang.annotation.Target;
/**
* The ParserClass annotation specifies a class which implements the {@link Parser} interface to
* convert an object to and from a String.
- *
- * @author nairah1
*
+ * @author Hari.Nair@jhuapl.edu
*/
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.METHOD)
diff --git a/jackfruit/src/main/java/jackfruit/processor/AnnotationBundle.java b/jackfruit/src/main/java/jackfruit/processor/AnnotationBundle.java
index 86558b8..195adf5 100644
--- a/jackfruit/src/main/java/jackfruit/processor/AnnotationBundle.java
+++ b/jackfruit/src/main/java/jackfruit/processor/AnnotationBundle.java
@@ -9,9 +9,9 @@ package jackfruit.processor;
* 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
- *
+ *
* http://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.
@@ -29,7 +29,7 @@ import org.immutables.value.Value;
/**
* Holds annotation information and other metadata about an annotated method.
*
- * @author nairah1
+ * @author Hari.Nair@jhuapl.edu
*/
@Value.Immutable
public abstract class AnnotationBundle {
@@ -65,7 +65,7 @@ public abstract class AnnotationBundle {
/**
* @return If this configuration parameter is not a string or primitive/boxed type, this class
* will convert the string to the proper object and vice versa. This class must implement
- * {@link Parser}.
+ * {@link jackfruit.annotations.Parser}.
*/
public abstract Optional parserClass();
}
diff --git a/jackfruit/src/main/java/jackfruit/processor/ConfigFactory.java b/jackfruit/src/main/java/jackfruit/processor/ConfigFactory.java
index 3acbc25..6bc67e0 100644
--- a/jackfruit/src/main/java/jackfruit/processor/ConfigFactory.java
+++ b/jackfruit/src/main/java/jackfruit/processor/ConfigFactory.java
@@ -9,9 +9,9 @@ package jackfruit.processor;
* 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
- *
+ *
* http://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.
@@ -28,8 +28,8 @@ import org.apache.commons.configuration2.PropertiesConfigurationLayout;
* This interface converts instances of annotated interfaces of type T to Apache Commons
* Configuration files and vice versa.
*
- * @author nairah1
- * @param
+ * @author Hari.Nair@jhuapl.edu
+ * @param configuration class with annotations
*/
public interface ConfigFactory {
diff --git a/jackfruit/src/main/java/jackfruit/processor/ConfigProcessor.java b/jackfruit/src/main/java/jackfruit/processor/ConfigProcessor.java
index 4da059c..0f1512d 100644
--- a/jackfruit/src/main/java/jackfruit/processor/ConfigProcessor.java
+++ b/jackfruit/src/main/java/jackfruit/processor/ConfigProcessor.java
@@ -9,9 +9,9 @@ package jackfruit.processor;
* 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
- *
+ *
* http://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.
@@ -20,6 +20,22 @@ package jackfruit.processor;
* #L%
*/
+import com.google.auto.service.AutoService;
+import com.squareup.javapoet.AnnotationSpec;
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.JavaFile;
+import com.squareup.javapoet.MethodSpec;
+import com.squareup.javapoet.ParameterSpec;
+import com.squareup.javapoet.ParameterizedTypeName;
+import com.squareup.javapoet.TypeName;
+import com.squareup.javapoet.TypeSpec;
+import com.squareup.javapoet.TypeVariableName;
+import jackfruit.JackfruitVersion;
+import jackfruit.annotations.Comment;
+import jackfruit.annotations.DefaultValue;
+import jackfruit.annotations.Jackfruit;
+import jackfruit.annotations.Key;
+import jackfruit.annotations.ParserClass;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.annotation.Annotation;
@@ -56,36 +72,20 @@ import javax.lang.model.util.Types;
import javax.tools.Diagnostic;
import javax.tools.JavaFileObject;
import org.apache.commons.configuration2.Configuration;
-import com.google.auto.service.AutoService;
-import com.squareup.javapoet.AnnotationSpec;
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.JavaFile;
-import com.squareup.javapoet.MethodSpec;
-import com.squareup.javapoet.ParameterSpec;
-import com.squareup.javapoet.ParameterizedTypeName;
-import com.squareup.javapoet.TypeName;
-import com.squareup.javapoet.TypeSpec;
-import com.squareup.javapoet.TypeVariableName;
-import jackfruit.JackfruitVersion;
-import jackfruit.annotations.Comment;
-import jackfruit.annotations.DefaultValue;
-import jackfruit.annotations.Jackfruit;
-import jackfruit.annotations.Key;
-import jackfruit.annotations.ParserClass;
/**
* Useful references for writing an annotation processor:
- *
- *
- * @author nairah1
*
+ *
+ *
+ * @author Hari.Nair@jhuapl.edu
*/
@SupportedSourceVersion(SourceVersion.RELEASE_17)
@SupportedAnnotationTypes("jackfruit.annotations.Jackfruit")
@@ -107,10 +107,14 @@ public class ConfigProcessor extends AbstractProcessor {
messager = processingEnv.getMessager();
// find interfaces or abstract classes with the Jackfruit annotation
- List annotatedElements = roundEnv.getElementsAnnotatedWith(Jackfruit.class).stream()
- .filter(e -> e.getKind() == ElementKind.INTERFACE
- || (e.getKind() == ElementKind.CLASS && e.getModifiers().contains(Modifier.ABSTRACT)))
- .collect(Collectors.toList());
+ List annotatedElements =
+ roundEnv.getElementsAnnotatedWith(Jackfruit.class).stream()
+ .filter(
+ e ->
+ e.getKind() == ElementKind.INTERFACE
+ || (e.getKind() == ElementKind.CLASS
+ && e.getModifiers().contains(Modifier.ABSTRACT)))
+ .collect(Collectors.toList());
for (Element element : annotatedElements) {
@@ -119,16 +123,16 @@ public class ConfigProcessor extends AbstractProcessor {
Jackfruit configParams = annotatedType.getAnnotation(Jackfruit.class);
String prefix = configParams.prefix().strip();
- if (prefix.length() > 0 && !prefix.endsWith("."))
- prefix += ".";
+ if (!prefix.isEmpty() && !prefix.endsWith(".")) prefix += ".";
// This is the templatized class with annotations to be processed (e.g.
// ConfigTemplate)
TypeVariableName tvn = TypeVariableName.get(annotatedType.getSimpleName().toString());
// This is the generic class (e.g. ConfigFactory)
- ParameterizedTypeName ptn = ParameterizedTypeName
- .get(ClassName.get(jackfruit.processor.ConfigFactory.class), tvn);
+ ParameterizedTypeName ptn =
+ ParameterizedTypeName.get(
+ ClassName.get(jackfruit.processor.ConfigFactory.class), tvn);
// This is the name of the class to create (e.g. ConfigTemplateFactory)
String factoryName = String.format("%sFactory", annotatedType.getSimpleName());
@@ -136,16 +140,21 @@ public class ConfigProcessor extends AbstractProcessor {
OffsetDateTime now = OffsetDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
- AnnotationSpec generated = AnnotationSpec.builder(Generated.class)
- .addMember("value", String.format("\"%s\"", JackfruitVersion.packageName))
- .addMember("date", String.format("\"%s\"", formatter.format(now)))
- .addMember("comments", String.format("\"version %s-%s\"", JackfruitVersion.dateString,
- JackfruitVersion.rev))
- .build();
+ AnnotationSpec generated =
+ AnnotationSpec.builder(Generated.class)
+ .addMember("value", String.format("\"%s\"", JackfruitVersion.packageName))
+ .addMember("date", String.format("\"%s\"", formatter.format(now)))
+ .addMember(
+ "comments",
+ String.format(
+ "\"version %s built %s\"", JackfruitVersion.version, JackfruitVersion.dateString))
+ .build();
TypeSpec.Builder classBuilder =
- TypeSpec.classBuilder(factoryName).addModifiers(Modifier.PUBLIC, Modifier.FINAL)
- .addSuperinterface(ptn).addAnnotation(generated);
+ TypeSpec.classBuilder(factoryName)
+ .addModifiers(Modifier.PUBLIC, Modifier.FINAL)
+ .addSuperinterface(ptn)
+ .addAnnotation(generated);
/*-
// logger for the generated class
FieldSpec loggerField = FieldSpec.builder(org.apache.logging.log4j.Logger.class, "logger")
@@ -185,8 +194,8 @@ public class ConfigProcessor extends AbstractProcessor {
&& e instanceof ExecutableElement ex) {
enclosedMethods.put(ex.getSimpleName(), ex);
AnnotationBundle defaultValues = defaultAnnotationsMap.get(ex.getSimpleName());
- defaultAnnotationsMap.put(ex.getSimpleName(),
- buildAnnotationBundle(ex, defaultValues));
+ defaultAnnotationsMap.put(
+ ex.getSimpleName(), buildAnnotationBundle(ex, defaultValues));
}
}
}
@@ -201,28 +210,33 @@ public class ConfigProcessor extends AbstractProcessor {
// default constructor; initialize prefix
String prefixMemberName = "prefix";
classBuilder.addField(String.class, prefixMemberName, Modifier.PRIVATE, Modifier.FINAL);
- MethodSpec constructor = MethodSpec.constructorBuilder().addModifiers(Modifier.PUBLIC)
- .addStatement("this.$N = $S", prefixMemberName, prefix).build();
+ MethodSpec constructor =
+ MethodSpec.constructorBuilder()
+ .addModifiers(Modifier.PUBLIC)
+ .addStatement("this.$N = $S", prefixMemberName, prefix)
+ .build();
classBuilder.addMethod(constructor);
// add a constructor where caller can set prefix
constructor =
- MethodSpec.constructorBuilder().addModifiers(Modifier.PUBLIC)
+ MethodSpec.constructorBuilder()
+ .addModifiers(Modifier.PUBLIC)
.addParameter(String.class, prefixMemberName)
.beginControlFlow("if ($N == null)", prefixMemberName)
- .addStatement("$N = \"\"", prefixMemberName).endControlFlow()
+ .addStatement("$N = \"\"", prefixMemberName)
+ .endControlFlow()
.addStatement("$N = $N.strip()", prefixMemberName, prefixMemberName)
- .addStatement("if (!$N.endsWith(\".\")) $N += $S", prefixMemberName,
- prefixMemberName, ".")
- .addStatement("this.$N = $N", prefixMemberName, prefixMemberName).build();
+ .addStatement(
+ "if (!$N.endsWith(\".\")) $N += $S", prefixMemberName, prefixMemberName, ".")
+ .addStatement("this.$N = $N", prefixMemberName, prefixMemberName)
+ .build();
classBuilder.addMethod(constructor);
// generate the methods from the interface
List methods = new ArrayList<>();
for (Method m : ConfigFactory.class.getMethods()) {
- if (m.isDefault())
- continue;
+ if (m.isDefault()) continue;
if (m.getName().equals("toConfig")) {
MethodSpec toConfig = buildToConfig(tvn, m, annotationsMap, prefixMemberName);
@@ -238,7 +252,6 @@ public class ConfigProcessor extends AbstractProcessor {
MethodSpec fromConfig = buildFromConfig(tvn, m, annotationsMap, prefixMemberName);
methods.add(fromConfig);
}
-
}
methods.addAll(buildWithMethods(tvn, annotationsMap, prefixMemberName));
@@ -254,8 +267,8 @@ public class ConfigProcessor extends AbstractProcessor {
try (PrintWriter pw = new PrintWriter(jfo.openWriter())) {
javaFile.writeTo(pw);
}
- messager.printMessage(Diagnostic.Kind.NOTE,
- String.format("wrote %s", javaFile.toJavaFileObject().toUri()));
+ messager.printMessage(
+ Diagnostic.Kind.NOTE, String.format("wrote %s", javaFile.toJavaFileObject().toUri()));
}
} catch (IOException e1) {
messager.printMessage(Diagnostic.Kind.ERROR, e1.getLocalizedMessage());
@@ -263,17 +276,15 @@ public class ConfigProcessor extends AbstractProcessor {
}
}
return true;
-
}
/**
- *
* @param e annotated method
* @param defaultValues default values for annotations - could be from a parent class
* @return annotation values
*/
- private AnnotationBundle buildAnnotationBundle(ExecutableElement e,
- AnnotationBundle defaultValues) {
+ private AnnotationBundle buildAnnotationBundle(
+ ExecutableElement e, AnnotationBundle defaultValues) {
ImmutableAnnotationBundle.Builder builder = ImmutableAnnotationBundle.builder();
builder.key(e.getSimpleName().toString());
@@ -300,19 +311,22 @@ public class ConfigProcessor extends AbstractProcessor {
} else if (erasure.getKind().isPrimitive()) {
// no type arguments here
} else {
- processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, String.format(
- "Unsupported kind %s for type %s!", erasure.getKind().toString(), erasure.toString()));
+ processingEnv
+ .getMessager()
+ .printMessage(
+ Diagnostic.Kind.ERROR,
+ String.format(
+ "Unsupported kind %s for type %s!",
+ erasure.getKind().toString(), erasure));
}
builder.addAllTypeArgs(typeArgs);
List methodAnnotations = new ArrayList<>();
- for (var a : supportedMethodAnnotations)
- methodAnnotations.add(e.getAnnotation(a));
+ for (var a : supportedMethodAnnotations) methodAnnotations.add(e.getAnnotation(a));
for (Annotation annotation : methodAnnotations) {
- if (annotation == null)
- continue;
+ if (annotation == null) continue;
if (annotation instanceof Key) {
builder.key(((Key) annotation).value());
@@ -340,34 +354,45 @@ public class ConfigProcessor extends AbstractProcessor {
AnnotationBundle bundle = builder.build();
if (ConfigProcessorUtils.isList(bundle.erasure(), processingEnv)
- && bundle.typeArgs().size() == 0)
- messager.printMessage(Diagnostic.Kind.ERROR,
+ && bundle.typeArgs().isEmpty())
+ messager.printMessage(
+ Diagnostic.Kind.ERROR,
String.format("No parameter type for List on method %s!", e.getSimpleName()));
return bundle;
}
/**
* Build the method to generate an Apache Commons {@link Configuration} from an object
- *
+ *
* @param tvn
* @param m
* @param annotationsMap
* @param prefixMemberName
* @return
*/
- private MethodSpec buildToConfig(TypeVariableName tvn, Method m,
- Map annotationsMap, String prefixMemberName) {
+ private MethodSpec buildToConfig(
+ TypeVariableName tvn,
+ Method m,
+ Map annotationsMap,
+ String prefixMemberName) {
ParameterSpec ps = ParameterSpec.builder(tvn, "t").build();
- ParameterSpec layout = ParameterSpec.builder(TypeVariableName.get(
- org.apache.commons.configuration2.PropertiesConfigurationLayout.class.getCanonicalName()),
- "layout").build();
+ ParameterSpec layout =
+ ParameterSpec.builder(
+ TypeVariableName.get(
+ org.apache.commons.configuration2.PropertiesConfigurationLayout.class
+ .getCanonicalName()),
+ "layout")
+ .build();
MethodSpec.Builder methodBuilder =
- MethodSpec.methodBuilder(m.getName()).addAnnotation(Override.class)
- .addModifiers(Modifier.PUBLIC).returns(m.getGenericReturnType());
+ MethodSpec.methodBuilder(m.getName())
+ .addAnnotation(Override.class)
+ .addModifiers(Modifier.PUBLIC)
+ .returns(m.getGenericReturnType());
methodBuilder.addParameter(ps);
methodBuilder.addParameter(layout);
- methodBuilder.addStatement("$T config = new $T()",
+ methodBuilder.addStatement(
+ "$T config = new $T()",
org.apache.commons.configuration2.PropertiesConfiguration.class,
org.apache.commons.configuration2.PropertiesConfiguration.class);
methodBuilder.addStatement("config.setLayout($N)", layout);
@@ -377,8 +402,8 @@ public class ConfigProcessor extends AbstractProcessor {
AnnotationBundle ab = annotationsMap.get(method);
String key = ab.key();
if (needBlank) {
- methodBuilder.addStatement("$N.setBlankLinesBefore($N + $S, 1)", layout, prefixMemberName,
- key);
+ methodBuilder.addStatement(
+ "$N.setBlankLinesBefore($N + $S, 1)", layout, prefixMemberName, key);
needBlank = false;
}
@@ -405,49 +430,54 @@ public class ConfigProcessor extends AbstractProcessor {
} else {
TypeMirror typeArg = ab.typeArgs().get(0);
if (ConfigProcessorUtils.isByte(typeArg, processingEnv))
- methodBuilder.addStatement("$L.add($T.toString(element))", listName,
- java.lang.Byte.class);
+ methodBuilder.addStatement(
+ "$L.add($T.toString(element))", listName, java.lang.Byte.class);
if (ConfigProcessorUtils.isBoolean(typeArg, processingEnv))
- methodBuilder.addStatement("$L.add($T.toString(element))", listName,
- java.lang.Boolean.class);
+ methodBuilder.addStatement(
+ "$L.add($T.toString(element))", listName, java.lang.Boolean.class);
if (ConfigProcessorUtils.isDouble(typeArg, processingEnv))
- methodBuilder.addStatement("$L.add($T.toString(element))", listName,
- java.lang.Double.class);
+ methodBuilder.addStatement(
+ "$L.add($T.toString(element))", listName, java.lang.Double.class);
if (ConfigProcessorUtils.isFloat(typeArg, processingEnv))
- methodBuilder.addStatement("$L.add($T.toString(element))", listName,
- java.lang.Float.class);
+ methodBuilder.addStatement(
+ "$L.add($T.toString(element))", listName, java.lang.Float.class);
if (ConfigProcessorUtils.isInteger(typeArg, processingEnv))
- methodBuilder.addStatement("$L.add($T.toString(element))", listName,
- java.lang.Integer.class);
+ methodBuilder.addStatement(
+ "$L.add($T.toString(element))", listName, java.lang.Integer.class);
if (ConfigProcessorUtils.isLong(typeArg, processingEnv))
- methodBuilder.addStatement("$L.add($T.toString(element))", listName,
- java.lang.Long.class);
+ methodBuilder.addStatement(
+ "$L.add($T.toString(element))", listName, java.lang.Long.class);
if (ConfigProcessorUtils.isShort(typeArg, processingEnv))
- methodBuilder.addStatement("$L.add($T.toString(element))", listName,
- java.lang.Short.class);
+ methodBuilder.addStatement(
+ "$L.add($T.toString(element))", listName, java.lang.Short.class);
if (ConfigProcessorUtils.isString(typeArg, processingEnv))
methodBuilder.addStatement("$L.add(element)", listName);
}
methodBuilder.endControlFlow();
- methodBuilder.addStatement("config.setProperty($N + $S, $L)", prefixMemberName, key,
- listName);
+ methodBuilder.addStatement(
+ "config.setProperty($N + $S, $L)", prefixMemberName, key, listName);
} else {
if (ab.parserClass().isPresent()) {
// store the serialized string as the property
- methodBuilder.addStatement("config.setProperty($N + $S, $L.toString($N.$L()))",
- prefixMemberName, key, parserName, ps, method.getSimpleName());
- } else {
- methodBuilder.addStatement("config.setProperty($N + $S, t.$L())", prefixMemberName, key,
+ methodBuilder.addStatement(
+ "config.setProperty($N + $S, $L.toString($N.$L()))",
+ prefixMemberName,
+ key,
+ parserName,
+ ps,
method.getSimpleName());
+ } else {
+ methodBuilder.addStatement(
+ "config.setProperty($N + $S, t.$L())", prefixMemberName, key, method.getSimpleName());
}
}
// add the comment
- if (ab.comment().length() > 0) {
+ if (!ab.comment().isEmpty()) {
String commentName = String.format("%sComment", method.getSimpleName());
methodBuilder.addStatement("$T $L = $S", String.class, commentName, ab.comment());
- methodBuilder.addStatement("$N.setComment($N + $S, $L)", layout, prefixMemberName, key,
- commentName);
+ methodBuilder.addStatement(
+ "$N.setComment($N + $S, $L)", layout, prefixMemberName, key, commentName);
}
}
@@ -458,27 +488,33 @@ public class ConfigProcessor extends AbstractProcessor {
/**
* Create a method that returns a template object, populated by the default values
- *
+ *
* @param tvn
* @param m
* @param annotationsMap
* @return
*/
- private MethodSpec buildGetTemplate(TypeVariableName tvn, Method m,
- Map annotationsMap) {
+ private MethodSpec buildGetTemplate(
+ TypeVariableName tvn, Method m, Map annotationsMap) {
// this builds the getTemplate() method
- MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder(m.getName())
- .addAnnotation(Override.class).addModifiers(Modifier.PUBLIC).returns(tvn);
+ MethodSpec.Builder methodBuilder =
+ MethodSpec.methodBuilder(m.getName())
+ .addAnnotation(Override.class)
+ .addModifiers(Modifier.PUBLIC)
+ .returns(tvn);
TypeSpec.Builder typeBuilder = TypeSpec.anonymousClassBuilder("").addSuperinterface(tvn);
for (ExecutableElement method : annotationsMap.keySet()) {
AnnotationBundle bundle = annotationsMap.get(method);
// this builds the method on the anonymous class
- MethodSpec.Builder builder = MethodSpec.methodBuilder(method.getSimpleName().toString())
- .addModifiers(Modifier.PUBLIC).addAnnotation(Override.class)
- .returns(TypeName.get(method.getReturnType())).addJavadoc(bundle.comment());
+ MethodSpec.Builder builder =
+ MethodSpec.methodBuilder(method.getSimpleName().toString())
+ .addModifiers(Modifier.PUBLIC)
+ .addAnnotation(Override.class)
+ .returns(TypeName.get(method.getReturnType()))
+ .addJavadoc(bundle.comment());
TypeMirror parser = null;
String parserName = null;
@@ -498,8 +534,8 @@ public class ConfigProcessor extends AbstractProcessor {
String listName = method.getSimpleName() + "List";
builder.addStatement("$T " + listName + " = new $T()", listType, arrayListType);
- builder.addStatement("String [] parts = ($S).split($S)", bundle.defaultValue(),
- "[\\n\\r\\s]+");
+ builder.addStatement(
+ "String [] parts = ($S).split($S)", bundle.defaultValue(), "[\\n\\r\\s]+");
builder.beginControlFlow("for (String part : parts)");
builder.beginControlFlow("if (part.trim().length() > 0)");
if (bundle.parserClass().isPresent()) {
@@ -534,9 +570,13 @@ public class ConfigProcessor extends AbstractProcessor {
if (ConfigProcessorUtils.isString(bundle.erasure(), processingEnv)) {
builder.addStatement("return $S", bundle.defaultValue());
} else {
- if (bundle.defaultValue().trim().length() == 0) {
- processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,
- String.format("Default value on method %s is blank!", method.getSimpleName()));
+ if (bundle.defaultValue().trim().isEmpty()) {
+ processingEnv
+ .getMessager()
+ .printMessage(
+ Diagnostic.Kind.ERROR,
+ String.format(
+ "Default value on method %s is blank!", method.getSimpleName()));
}
builder.addStatement("return $L", bundle.defaultValue());
}
@@ -551,31 +591,40 @@ public class ConfigProcessor extends AbstractProcessor {
/**
* Create a method to create a configuration from the object
- *
+ *
* @param tvn
* @param m
* @param annotationsMap
* @param prefix
* @return
*/
- private MethodSpec buildFromConfig(TypeVariableName tvn, Method m,
- Map annotationsMap, String prefix) {
+ private MethodSpec buildFromConfig(
+ TypeVariableName tvn,
+ Method m,
+ Map annotationsMap,
+ String prefix) {
- MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder(m.getName())
- .addAnnotation(Override.class).addModifiers(Modifier.PUBLIC).returns(tvn)
- .addParameter(org.apache.commons.configuration2.Configuration.class, "config");
+ MethodSpec.Builder methodBuilder =
+ MethodSpec.methodBuilder(m.getName())
+ .addAnnotation(Override.class)
+ .addModifiers(Modifier.PUBLIC)
+ .returns(tvn)
+ .addParameter(org.apache.commons.configuration2.Configuration.class, "config");
TypeSpec.Builder typeBuilder = TypeSpec.anonymousClassBuilder("").addSuperinterface(tvn);
for (ExecutableElement method : annotationsMap.keySet()) {
AnnotationBundle bundle = annotationsMap.get(method);
- MethodSpec.Builder builder = MethodSpec.methodBuilder(method.getSimpleName().toString())
- .addModifiers(Modifier.PUBLIC).addAnnotation(Override.class)
- .returns(TypeName.get(method.getReturnType())).addJavadoc(bundle.comment());
+ MethodSpec.Builder builder =
+ MethodSpec.methodBuilder(method.getSimpleName().toString())
+ .addModifiers(Modifier.PUBLIC)
+ .addAnnotation(Override.class)
+ .returns(TypeName.get(method.getReturnType()))
+ .addJavadoc(bundle.comment());
builder.addStatement("String key = $N + $S", prefix, bundle.key());
builder
.beginControlFlow("if (!config.containsKey(key))")
- .addStatement("throw new $T($S + key)", RuntimeException.class, "No such key")
+ .addStatement("throw new $T($S + key)", RuntimeException.class, "No such key ")
.endControlFlow();
TypeMirror parser = null;
@@ -642,8 +691,11 @@ public class ConfigProcessor extends AbstractProcessor {
} else if (ConfigProcessorUtils.isString(bundle.erasure(), processingEnv)) {
builder.addStatement("return config.getString(key)");
} else {
- processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,
- "Can't handle return type " + m.getReturnType().getCanonicalName());
+ processingEnv
+ .getMessager()
+ .printMessage(
+ Diagnostic.Kind.ERROR,
+ "Can't handle return type " + m.getReturnType().getCanonicalName());
}
}
}
@@ -656,14 +708,16 @@ public class ConfigProcessor extends AbstractProcessor {
/**
* Create a method for each member that allows it to be replaced.
- *
+ *
* @param tvn
* @param annotationsMap
* @param prefixMemberName
* @return
*/
- private List buildWithMethods(TypeVariableName tvn,
- Map annotationsMap, String prefixMemberName) {
+ private List buildWithMethods(
+ TypeVariableName tvn,
+ Map annotationsMap,
+ String prefixMemberName) {
List withMethods = new ArrayList<>();
@@ -671,14 +725,17 @@ public class ConfigProcessor extends AbstractProcessor {
for (ExecutableElement method : annotationsMap.keySet()) {
String methodName = method.getSimpleName().toString();
- String camelCase = String.format("with%s%s", methodName.substring(0, 1).toUpperCase(),
- methodName.substring(1));
+ String camelCase =
+ String.format(
+ "with%s%s", methodName.substring(0, 1).toUpperCase(), methodName.substring(1));
TypeName propertiesConfigurationClass =
TypeName.get(org.apache.commons.configuration2.PropertiesConfiguration.class);
// method with object passed in as an argument
- MethodSpec.Builder builder = MethodSpec.methodBuilder(camelCase).addModifiers(Modifier.PUBLIC)
- .returns(propertiesConfigurationClass);
+ MethodSpec.Builder builder =
+ MethodSpec.methodBuilder(camelCase)
+ .addModifiers(Modifier.PUBLIC)
+ .returns(propertiesConfigurationClass);
builder.addJavadoc("Replace the value of " + methodName);
builder.addParameter(ps);
builder.addParameter(
@@ -688,8 +745,10 @@ public class ConfigProcessor extends AbstractProcessor {
withMethods.add(builder.build());
// method with PropertiesConfiguration passed in as an argument
- builder = MethodSpec.methodBuilder(camelCase).addModifiers(Modifier.PUBLIC)
- .returns(propertiesConfigurationClass);
+ builder =
+ MethodSpec.methodBuilder(camelCase)
+ .addModifiers(Modifier.PUBLIC)
+ .returns(propertiesConfigurationClass);
builder.addJavadoc("Replace the value of " + methodName);
builder.addParameter(ParameterSpec.builder(propertiesConfigurationClass, "config").build());
builder.addParameter(
@@ -742,8 +801,11 @@ public class ConfigProcessor extends AbstractProcessor {
} else {
if (ab.parserClass().isPresent()) {
// store the serialized string as the property
- builder.addStatement("config.setProperty($N + $S, $L.toString(replaceValue))",
- prefixMemberName, key, parserName);
+ builder.addStatement(
+ "config.setProperty($N + $S, $L.toString(replaceValue))",
+ prefixMemberName,
+ key,
+ parserName);
} else {
builder.addStatement("config.setProperty($N + $S, replaceValue)", prefixMemberName, key);
}
@@ -756,5 +818,4 @@ public class ConfigProcessor extends AbstractProcessor {
return withMethods;
}
-
}
diff --git a/jackfruit/src/main/java/jackfruit/processor/ConfigProcessorUtils.java b/jackfruit/src/main/java/jackfruit/processor/ConfigProcessorUtils.java
index 2f91d39..bc54d32 100644
--- a/jackfruit/src/main/java/jackfruit/processor/ConfigProcessorUtils.java
+++ b/jackfruit/src/main/java/jackfruit/processor/ConfigProcessorUtils.java
@@ -9,9 +9,9 @@ package jackfruit.processor;
* 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
- *
+ *
* http://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.
@@ -30,7 +30,11 @@ import javax.tools.Diagnostic;
public class ConfigProcessorUtils {
/**
- * @param processingEnv
+ *
+ * @param typeMirror the return type without any parameters (e.g. List rather than
+ * * List<String>)
+ * @param processingEnv Processing environment providing by the tool framework, from {@link
+ * javax.annotation.processing.AbstractProcessor}
* @return true if this annotated member returns a {@link List}
*/
public static boolean isList(TypeMirror typeMirror, ProcessingEnvironment processingEnv) {
@@ -38,9 +42,10 @@ public class ConfigProcessorUtils {
}
/**
- * @param typeMirror either {@link AnnotationBundle#erasure()} for the return value, or an element of {@link
- * AnnotationBundle#typeArgs()} for a parameterized type
- * @param processingEnv
+ * @param typeMirror either {@link AnnotationBundle#erasure()} for the return value, or an element
+ * of {@link AnnotationBundle#typeArgs()} for a parameterized type
+ * @param processingEnv Processing environment providing by the tool framework, from {@link
+ * javax.annotation.processing.AbstractProcessor}
* @return true if this annotated member returns a {@link Boolean} or primitive boolean
*/
public static boolean isBoolean(TypeMirror typeMirror, ProcessingEnvironment processingEnv) {
@@ -49,9 +54,10 @@ public class ConfigProcessorUtils {
}
/**
- * @param typeMirror either {@link AnnotationBundle#erasure()} for the return value, or an element of {@link
- * AnnotationBundle#typeArgs()} for a parameterized type
- * @param processingEnv
+ * @param typeMirror either {@link AnnotationBundle#erasure()} for the return value, or an element
+ * of {@link AnnotationBundle#typeArgs()} for a parameterized type
+ * @param processingEnv Processing environment providing by the tool framework, from {@link
+ * javax.annotation.processing.AbstractProcessor}
* @return true if this annotated member returns a {@link Byte} or primitive byte
*/
public static boolean isByte(TypeMirror typeMirror, ProcessingEnvironment processingEnv) {
@@ -60,9 +66,10 @@ public class ConfigProcessorUtils {
}
/**
- * @param typeMirror either {@link AnnotationBundle#erasure()} for the return value, or an element of {@link
- * AnnotationBundle#typeArgs()} for a parameterized type
- * @param processingEnv
+ * @param typeMirror either {@link AnnotationBundle#erasure()} for the return value, or an element
+ * of {@link AnnotationBundle#typeArgs()} for a parameterized type
+ * @param processingEnv Processing environment providing by the tool framework, from {@link
+ * javax.annotation.processing.AbstractProcessor}
* @return true if this annotated member returns a {@link Double} or primitive double
*/
public static boolean isDouble(TypeMirror typeMirror, ProcessingEnvironment processingEnv) {
@@ -71,9 +78,10 @@ public class ConfigProcessorUtils {
}
/**
- * @param typeMirror either {@link AnnotationBundle#erasure()} for the return value, or an element of {@link
- * AnnotationBundle#typeArgs()} for a parameterized type
- * @param processingEnv
+ * @param typeMirror either {@link AnnotationBundle#erasure()} for the return value, or an element
+ * of {@link AnnotationBundle#typeArgs()} for a parameterized type
+ * @param processingEnv Processing environment providing by the tool framework, from {@link
+ * javax.annotation.processing.AbstractProcessor}
* @return true if this annotated member returns a {@link Float} or primitive float
*/
public static boolean isFloat(TypeMirror typeMirror, ProcessingEnvironment processingEnv) {
@@ -82,9 +90,10 @@ public class ConfigProcessorUtils {
}
/**
- * @param typeMirror either {@link AnnotationBundle#erasure()} for the return value, or an element of {@link
- * AnnotationBundle#typeArgs()} for a parameterized type
- * @param processingEnv
+ * @param typeMirror either {@link AnnotationBundle#erasure()} for the return value, or an element
+ * of {@link AnnotationBundle#typeArgs()} for a parameterized type
+ * @param processingEnv Processing environment providing by the tool framework, from {@link
+ * javax.annotation.processing.AbstractProcessor}
* @return true if this annotated member returns a {@link Integer} or primitive int
*/
public static boolean isInteger(TypeMirror typeMirror, ProcessingEnvironment processingEnv) {
@@ -93,9 +102,10 @@ public class ConfigProcessorUtils {
}
/**
- * @param typeMirror either {@link AnnotationBundle#erasure()} for the return value, or an element of {@link
- * AnnotationBundle#typeArgs()} for a parameterized type
- * @param processingEnv
+ * @param typeMirror either {@link AnnotationBundle#erasure()} for the return value, or an element
+ * of {@link AnnotationBundle#typeArgs()} for a parameterized type
+ * @param processingEnv Processing environment providing by the tool framework, from {@link
+ * javax.annotation.processing.AbstractProcessor}
* @return true if this annotated member returns a {@link Long} or primitive long
*/
public static boolean isLong(TypeMirror typeMirror, ProcessingEnvironment processingEnv) {
@@ -104,9 +114,10 @@ public class ConfigProcessorUtils {
}
/**
- * @param typeMirror either {@link AnnotationBundle#erasure()} for the return value, or an element of {@link
- * AnnotationBundle#typeArgs()} for a parameterized type
- * @param processingEnv
+ * @param typeMirror either {@link AnnotationBundle#erasure()} for the return value, or an element
+ * of {@link AnnotationBundle#typeArgs()} for a parameterized type
+ * @param processingEnv Processing environment providing by the tool framework, from {@link
+ * javax.annotation.processing.AbstractProcessor}
* @return true if this annotated member returns a {@link Short} or primitive float
*/
public static boolean isShort(TypeMirror typeMirror, ProcessingEnvironment processingEnv) {
@@ -115,9 +126,10 @@ public class ConfigProcessorUtils {
}
/**
- * @param typeMirror either {@link AnnotationBundle#erasure()} for the return value, or an element of {@link
- * AnnotationBundle#typeArgs()} for a parameterized type
- * @param processingEnv
+ * @param typeMirror either {@link AnnotationBundle#erasure()} for the return value, or an element
+ * of {@link AnnotationBundle#typeArgs()} for a parameterized type
+ * @param processingEnv Processing environment providing by the tool framework, from {@link
+ * javax.annotation.processing.AbstractProcessor}
* @return true if this annotated member returns a {@link String}
*/
public static boolean isString(TypeMirror typeMirror, ProcessingEnvironment processingEnv) {
diff --git a/pom.xml b/pom.xml
index 2ebd086..4610438 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,16 +3,20 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
- edu.jhuapl.ses.srn
+
+ edu.jhuapl.ses
jackfruit-parent
1.0-SNAPSHOT
pom
+
jackfruit-parent
+ Jackfruit processes annotations on Java interfaces and abstract classes to generate code that can read and write Apache Configuration files.
+ https://github.com/JHUAPL/Jackfruit
2023
Johns Hopkins University Applied Physics Laboratory
- http://jhuapl.edu
+ https://www.jhuapl.edu/
@@ -22,14 +26,31 @@
-
+
+
+ HariNairJHUAPL
+ Hari Nair
+ Hari.Nair@jhuapl.edu
+ JHUAPL
+ https://www.jhuapl.edu/
+
+
+
+
+ scm:git:https://github.com/JHUAPL/Jackfruit.git
+ https://github.com/JHUAPL/Jackfruit.git
+ scm:git:https://github.com/JHUAPL/Jackfruit.git
+ HEAD
+
+
+
-
- central
- surfshop-snapshots
- http://surfshop.jhuapl.edu:8081/artifactory/libs-snapshot-local
-
+
+ ossrh
+ https://oss.sonatype.org/content/repositories/snapshots
+
+
UTF-8
17
@@ -45,8 +66,8 @@
4.13.2
test
-
+
@@ -56,7 +77,7 @@
https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
maven-clean-plugin
- 3.2.0
+ 3.3.1
@@ -73,7 +94,7 @@
maven-surefire-plugin
- 3.1.0
+ 3.1.2
maven-jar-plugin
@@ -85,14 +106,28 @@
maven-deploy-plugin
- 2.8.2
+ 3.1.1
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 3.5.0
+
+
+ attach-javadocs
+
+ jar
+
+
+
+
+
maven-site-plugin
- 4.0.0-M8
+ 4.0.0-M9
${maven-site-plugin.skip}
@@ -100,13 +135,13 @@
maven-project-info-reports-plugin
- 3.4.4
+ 3.4.5
org.codehaus.mojo
license-maven-plugin
- 2.0.1
+ 2.2.0
apache_v2
@@ -139,10 +174,15 @@
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+
+
org.apache.maven.plugins
maven-enforcer-plugin
- 3.3.0
+ 3.4.0
enforce-maven
@@ -160,6 +200,39 @@
+
+ org.apache.maven.plugins
+ maven-gpg-plugin
+ 3.1.0
+
+
+ sign-artifacts
+ verify
+
+ sign
+
+
+
+ --pinentry-mode
+ loopback
+
+
+
+
+
+
+
+ org.sonatype.plugins
+ nexus-staging-maven-plugin
+ 1.6.13
+ true
+
+ ossrh
+ https://oss.sonatype.org/
+ true
+
+
+