mirror of
https://github.com/JHUAPL/Jackfruit.git
synced 2026-01-06 21:13:54 -05:00
1 publish to maven central (#2)
* pom updates * update artifactId, add gpg plugin * use oss.sonatype.org * update groupId in README * update plugins * use nexus-staging-maven-plugin * add javadoc * javadoc cleanup * update versioning * javadoc cleanup * Update demo --------- Co-authored-by: Hari Nair <hari@alumni.caltech.edu>
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1 +1,2 @@
|
||||
.idea
|
||||
/target
|
||||
|
||||
@@ -10,14 +10,14 @@ Include Jackfruit in your project with the following POM:
|
||||
|
||||
```
|
||||
<dependency>
|
||||
<groupId>edu.jhuapl.ses.srn</groupId>
|
||||
<groupId>edu.jhuapl.ses</groupId>
|
||||
<artifactId>jackfruit</artifactId>
|
||||
<version>$VERSION</version>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
Find the latest version at [Surfshop](http://surfshop:8082/ui/repos/tree/General/libs-snapshot-local/edu/jhuapl/ses/srn/jackfruit/).
|
||||
Find the latest version at [Maven Central](https://central.sonatype.com/).
|
||||
|
||||
The annotation processor runs on any interface or abstract class annotated with `@Jackfruit`
|
||||
```
|
||||
|
||||
@@ -3,9 +3,10 @@
|
||||
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">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<artifactId>jackfruit-parent</artifactId>
|
||||
<groupId>edu.jhuapl.ses.srn</groupId>
|
||||
<groupId>edu.jhuapl.ses</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
@@ -29,7 +30,7 @@
|
||||
<version>1.9.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>edu.jhuapl.ses.srn</groupId>
|
||||
<groupId>edu.jhuapl.ses</groupId>
|
||||
<artifactId>jackfruit</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
|
||||
@@ -9,9 +9,9 @@ package crucible.crust.logging;
|
||||
* 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.
|
||||
@@ -37,16 +37,16 @@ import org.apache.logging.log4j.core.layout.PatternLayout;
|
||||
|
||||
/**
|
||||
* A simple configuration class.
|
||||
* <p>
|
||||
* Default settings:
|
||||
* <ul>
|
||||
* <li>Pattern is "%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%c{1}:%L] %msg%n%throwable"<br>
|
||||
* (e.g. 2021-11-09 19:32:37.119 INFO [LoggingTest:25] Level INFO)</li>
|
||||
* <li>Log level is {@link Level#INFO}</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author nairah1
|
||||
*
|
||||
* <p>Default settings:
|
||||
*
|
||||
* <ul>
|
||||
* <li>Pattern is "%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%c{1}:%L] %msg%n%throwable"<br>
|
||||
* (e.g. 2021-11-09 19:32:37.119 INFO [LoggingTest:25] Level INFO)
|
||||
* <li>Log level is {@link Level#INFO}
|
||||
* </ul>
|
||||
*
|
||||
* @author Hari.Nair@jhuapl.edu
|
||||
*/
|
||||
public class Log4j2Configurator {
|
||||
|
||||
@@ -56,10 +56,9 @@ public class Log4j2Configurator {
|
||||
private static Log4j2Configurator instance = null;
|
||||
|
||||
/**
|
||||
*
|
||||
* @return an instance of this singleton class.
|
||||
*/
|
||||
synchronized public static Log4j2Configurator getInstance() {
|
||||
public static synchronized Log4j2Configurator getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new Log4j2Configurator();
|
||||
}
|
||||
@@ -69,15 +68,17 @@ public class Log4j2Configurator {
|
||||
private Log4j2Configurator() {
|
||||
final LoggerContext loggerContext = LoggerContext.getContext(false);
|
||||
final Configuration config = loggerContext.getConfiguration();
|
||||
layout = PatternLayout.newBuilder().withPattern(DefaultConfiguration.DEFAULT_PATTERN)
|
||||
.withConfiguration(config).build();
|
||||
layout =
|
||||
PatternLayout.newBuilder()
|
||||
.withPattern(DefaultConfiguration.DEFAULT_PATTERN)
|
||||
.withConfiguration(config)
|
||||
.build();
|
||||
fileAppenders = new HashMap<>();
|
||||
setPattern("%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%c{1}:%L] %msg%n%throwable");
|
||||
setLevel(Level.INFO);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return a map of logger names to {@link LoggerConfig}
|
||||
*/
|
||||
private Map<String, LoggerConfig> getLoggerMap() {
|
||||
@@ -85,22 +86,25 @@ public class Log4j2Configurator {
|
||||
final Configuration config = loggerContext.getConfiguration();
|
||||
|
||||
Map<String, LoggerConfig> loggerMap = new HashMap<>(config.getLoggers());
|
||||
loggerMap.put(LogManager.getRootLogger().getName(),
|
||||
loggerMap.put(
|
||||
LogManager.getRootLogger().getName(),
|
||||
config.getLoggerConfig(LogManager.getRootLogger().getName()));
|
||||
return Collections.unmodifiableMap(loggerMap);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param filename Append log to named file, or create it if it doesn't exist.
|
||||
*/
|
||||
public void addFile(String filename) {
|
||||
final LoggerContext loggerContext = LoggerContext.getContext(false);
|
||||
Map<String, LoggerConfig> loggerMap = getLoggerMap();
|
||||
|
||||
FileAppender appender = FileAppender.newBuilder().setName(filename).withFileName(filename)
|
||||
.setLayout(layout).build();
|
||||
FileAppender appender =
|
||||
FileAppender.newBuilder()
|
||||
.setName(filename)
|
||||
.withFileName(filename)
|
||||
.setLayout(layout)
|
||||
.build();
|
||||
appender.start();
|
||||
|
||||
for (String loggerName : loggerMap.keySet()) {
|
||||
@@ -112,8 +116,6 @@ public class Log4j2Configurator {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param filename Stop logging to named file.
|
||||
*/
|
||||
public void removeFile(String filename) {
|
||||
@@ -132,7 +134,6 @@ public class Log4j2Configurator {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param pattern layout pattern for all {@link ConsoleAppender} and {@link FileAppender} objects.
|
||||
*/
|
||||
public void setPattern(String pattern) {
|
||||
@@ -152,11 +153,20 @@ public class Log4j2Configurator {
|
||||
// there should be a better way to do this - a toBuilder() method on the appender would be
|
||||
// really useful
|
||||
if (oldAppender instanceof ConsoleAppender) {
|
||||
newAppender = ConsoleAppender.newBuilder().setName(appenderName).setConfiguration(config)
|
||||
.setLayout(layout).build();
|
||||
newAppender =
|
||||
ConsoleAppender.newBuilder()
|
||||
.setName(appenderName)
|
||||
.setConfiguration(config)
|
||||
.setLayout(layout)
|
||||
.build();
|
||||
} else if (oldAppender instanceof FileAppender) {
|
||||
newAppender = FileAppender.newBuilder().setName(appenderName).setConfiguration(config)
|
||||
.withFileName(((FileAppender) oldAppender).getFileName()).setLayout(layout).build();
|
||||
newAppender =
|
||||
FileAppender.newBuilder()
|
||||
.setName(appenderName)
|
||||
.setConfiguration(config)
|
||||
.withFileName(((FileAppender) oldAppender).getFileName())
|
||||
.setLayout(layout)
|
||||
.build();
|
||||
}
|
||||
if (newAppender != null) {
|
||||
newAppender.start();
|
||||
@@ -169,15 +179,15 @@ public class Log4j2Configurator {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the levels of <code>parentLogger</code> and all 'child' loggers to the given
|
||||
* <code>level</code>. This is simply a call to
|
||||
*
|
||||
* Sets the levels of <code>parentLogger</code> and all 'child' loggers to the given <code>level
|
||||
* </code>. This is simply a call to
|
||||
*
|
||||
* <pre>
|
||||
* Configurator.setAllLevels(parentLogger, level)
|
||||
* </pre>
|
||||
*
|
||||
* @param parentLogger
|
||||
* @param level
|
||||
*
|
||||
* @param parentLogger name of parent logger
|
||||
* @param level logging level
|
||||
*/
|
||||
public void setLevel(String parentLogger, Level level) {
|
||||
Configurator.setAllLevels(parentLogger, level);
|
||||
@@ -185,15 +195,14 @@ public class Log4j2Configurator {
|
||||
|
||||
/**
|
||||
* Set all logger levels. This is simply a call to
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
* setLevel(LogManager.getRootLogger().getName(), level)
|
||||
* </pre>
|
||||
*
|
||||
* @param level
|
||||
*
|
||||
* @param level logging level
|
||||
*/
|
||||
public void setLevel(Level level) {
|
||||
setLevel(LogManager.getRootLogger().getName(), level);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,9 +9,9 @@ package jackfruit.demo;
|
||||
* 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,43 +20,42 @@ package jackfruit.demo;
|
||||
* #L%
|
||||
*/
|
||||
|
||||
import java.util.List;
|
||||
import jackfruit.annotations.Comment;
|
||||
import jackfruit.annotations.DefaultValue;
|
||||
import jackfruit.annotations.Jackfruit;
|
||||
import jackfruit.annotations.ParserClass;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Jackfruit on abstract class
|
||||
* <ul>
|
||||
* <li>prefix is optional</li>
|
||||
* </ul>
|
||||
* Method annotations:
|
||||
* <ul>
|
||||
* <li>@Key
|
||||
* <ul>
|
||||
* <li>If omitted value is method name</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li>@Comment
|
||||
* <ul>
|
||||
* <li>Optional</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li>@DefaultValue
|
||||
* <ul>
|
||||
* <li>Required, String value</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li>@Parser
|
||||
* <ul>
|
||||
* <li>Optional, name of class to create object from String using its fromString() method</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* Inspired by <a href="http://owner.aeonbits.org/">owner</a>.
|
||||
*
|
||||
* @author nairah1
|
||||
*
|
||||
* <ul>
|
||||
* <li>prefix is optional
|
||||
* </ul>
|
||||
*
|
||||
* Method annotations:
|
||||
*
|
||||
* <ul>
|
||||
* <li>@Key
|
||||
* <ul>
|
||||
* <li>If omitted value is method name
|
||||
* </ul>
|
||||
* <li>@Comment
|
||||
* <ul>
|
||||
* <li>Optional
|
||||
* </ul>
|
||||
* <li>@DefaultValue
|
||||
* <ul>
|
||||
* <li>Required, String value
|
||||
* </ul>
|
||||
* <li>@Parser
|
||||
* <ul>
|
||||
* <li>Optional, name of class to create object from String using its fromString() method
|
||||
* </ul>
|
||||
* <p>Inspired by <a href="http://owner.aeonbits.org/">owner</a>.
|
||||
* </ul>
|
||||
*
|
||||
* @author Hari.Nair@jhuapl.edu
|
||||
*/
|
||||
@Jackfruit(prefix = "prefix")
|
||||
public abstract class DemoClass extends DemoSuperClass {
|
||||
@@ -66,11 +65,13 @@ public abstract class DemoClass extends DemoSuperClass {
|
||||
@Override
|
||||
public abstract int intMethod();
|
||||
|
||||
@Comment("This is a very long comment line that really should be wrapped into more than one line but that's really up to you.")
|
||||
@Comment(
|
||||
"This is a very long comment line that really should be wrapped into more than one line but that's really up to you.")
|
||||
@DefaultValue("0.")
|
||||
public abstract Double doubleMethod();
|
||||
|
||||
@Comment("""
|
||||
@Comment(
|
||||
"""
|
||||
This is a multiline
|
||||
java text block.
|
||||
|
||||
@@ -100,5 +101,4 @@ public abstract class DemoClass extends DemoSuperClass {
|
||||
public void noAnnotationsOnThisMethod() {
|
||||
System.out.println("This method was not processed since it has no DefaultValue annotation");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,9 +9,9 @@ package jackfruit.demo;
|
||||
* 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,46 +20,44 @@ package jackfruit.demo;
|
||||
* #L%
|
||||
*/
|
||||
|
||||
import java.util.List;
|
||||
import jackfruit.annotations.Comment;
|
||||
import jackfruit.annotations.DefaultValue;
|
||||
import jackfruit.annotations.Jackfruit;
|
||||
import jackfruit.annotations.Key;
|
||||
import jackfruit.annotations.ParserClass;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Jackfruit on interface
|
||||
* <ul>
|
||||
* <li>prefix is optional</li>
|
||||
* </ul>
|
||||
* Method annotations:
|
||||
* <ul>
|
||||
* <li>@Key
|
||||
* <ul>
|
||||
* <li>If omitted value is method name</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li>@Comment
|
||||
* <ul>
|
||||
* <li>Optional</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li>@DefaultValue
|
||||
* <ul>
|
||||
* <li>Required, String value</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li>@Parser
|
||||
* <ul>
|
||||
* <li>Optional, name of class to create object from String using its fromString() method</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* Inspired by <a href="http://owner.aeonbits.org/">owner</a>.
|
||||
*
|
||||
* @author nairah1
|
||||
*
|
||||
* <ul>
|
||||
* <li>prefix is optional
|
||||
* </ul>
|
||||
*
|
||||
* Method annotations:
|
||||
*
|
||||
* <ul>
|
||||
* <li>@Key
|
||||
* <ul>
|
||||
* <li>If omitted value is method name
|
||||
* </ul>
|
||||
* <li>@Comment
|
||||
* <ul>
|
||||
* <li>Optional
|
||||
* </ul>
|
||||
* <li>@DefaultValue
|
||||
* <ul>
|
||||
* <li>Required, String value
|
||||
* </ul>
|
||||
* <li>@Parser
|
||||
* <ul>
|
||||
* <li>Optional, name of class to create object from String using its fromString() method
|
||||
* </ul>
|
||||
* <p>Inspired by <a href="http://owner.aeonbits.org/">owner</a>.
|
||||
* </ul>
|
||||
*
|
||||
* @author Hari.Nair@jhuapl.edu
|
||||
*/
|
||||
|
||||
@Jackfruit(prefix = "prefix")
|
||||
public interface DemoInterface {
|
||||
|
||||
@@ -69,11 +67,13 @@ public interface DemoInterface {
|
||||
@DefaultValue("1")
|
||||
int intMethod();
|
||||
|
||||
@Comment("This is a very long comment line that really should be wrapped into more than one line but that's really up to you.")
|
||||
@Comment(
|
||||
"This is a very long comment line that really should be wrapped into more than one line but that's really up to you.")
|
||||
@DefaultValue("0.")
|
||||
Double doubleMethod();
|
||||
|
||||
@Comment("""
|
||||
@Comment(
|
||||
"""
|
||||
This is a multiline
|
||||
java text block.
|
||||
|
||||
@@ -82,7 +82,8 @@ public interface DemoInterface {
|
||||
@DefaultValue("Default String")
|
||||
String StringMethod();
|
||||
|
||||
@Comment("This string is serialized into an object\n\tThis comment contains a newline character, and this line starts with a tab.")
|
||||
@Comment(
|
||||
"This string is serialized into an object\n\tThis comment contains a newline character, and this line starts with a tab.")
|
||||
@DefaultValue("serialized string")
|
||||
@ParserClass(SomeRandomClassParser.class)
|
||||
SomeRandomClass randomClass();
|
||||
@@ -95,10 +96,9 @@ public interface DemoInterface {
|
||||
@DefaultValue("""
|
||||
obj1
|
||||
obj2
|
||||
|
||||
|
||||
obj3 obj4
|
||||
""")
|
||||
@ParserClass(SomeRandomClassParser.class)
|
||||
List<SomeRandomClass> randoms();
|
||||
|
||||
}
|
||||
|
||||
@@ -9,9 +9,9 @@ package jackfruit.demo;
|
||||
* 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.
|
||||
@@ -38,8 +38,9 @@ public abstract class DemoSuperClass extends DemoSuperSuperClass {
|
||||
@DefaultValue("2")
|
||||
@Override
|
||||
public abstract int intMethod();
|
||||
|
||||
@Comment("This string is serialized into an object\n\tThis comment contains a newline character, and this line starts with a tab.")
|
||||
|
||||
@Comment(
|
||||
"This string is serialized into an object\n\tThis comment contains a newline character, and this line starts with a tab.")
|
||||
@DefaultValue("serialized string")
|
||||
@ParserClass(SomeRandomClassParser.class)
|
||||
public abstract SomeRandomClass randomClass();
|
||||
|
||||
@@ -9,9 +9,9 @@ package jackfruit.demo;
|
||||
* 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.
|
||||
@@ -31,7 +31,7 @@ public abstract class DemoSuperSuperClass {
|
||||
@Comment("from DemoSuperSuperClass")
|
||||
@DefaultValue("-3")
|
||||
public abstract int inherited2();
|
||||
|
||||
|
||||
@Comment("from DemoSuperSuperClass")
|
||||
@DefaultValue("-2")
|
||||
public abstract int inherited();
|
||||
|
||||
@@ -9,9 +9,9 @@ package jackfruit.demo;
|
||||
* 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.
|
||||
@@ -23,6 +23,7 @@ package jackfruit.demo;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.apache.commons.configuration2.PropertiesConfiguration;
|
||||
import org.apache.commons.configuration2.PropertiesConfigurationLayout;
|
||||
@@ -89,14 +90,21 @@ public class JackfruitDemo {
|
||||
System.out.println("random.toUpperCase() = " + random.toUpperCase());
|
||||
|
||||
// create a new factory with a different prefix, but same parameters
|
||||
System.out.println();
|
||||
System.out.println(
|
||||
"Create a config with anotherPrefix and retrieve randoms. This will throw an exception.");
|
||||
factory = new DemoClassFactory("anotherPrefix");
|
||||
template = factory.fromConfig(config);
|
||||
|
||||
// this will not find anything, since template was created from the original config, which
|
||||
// uses the original prefix.
|
||||
randoms = template.randoms();
|
||||
// this will throw an exception since anotherPrefix.randoms is not one of the keys in the
|
||||
// configuration.
|
||||
try {
|
||||
randoms = template.randoms();
|
||||
} catch (Exception e) {
|
||||
System.out.println("Caught expected RuntimeException:\n" + e.getLocalizedMessage());
|
||||
randoms = new ArrayList<>();
|
||||
}
|
||||
for (SomeRandomClass random : randoms)
|
||||
System.out.println("random.toUpperCase() = " + random.toUpperCase());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,9 +9,9 @@ package jackfruit.demo;
|
||||
* 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.
|
||||
@@ -35,5 +35,4 @@ public class SomeRandomClass {
|
||||
public String toUpperCase() {
|
||||
return internalString.toUpperCase();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -39,9 +39,8 @@ import org.junit.Test;
|
||||
/**
|
||||
* From <a href=
|
||||
* "https://stackoverflow.com/questions/21427301/debugging-annotation-processors-in-eclipse">https://stackoverflow.com/questions/21427301/debugging-annotation-processors-in-eclipse</a>
|
||||
*
|
||||
* @author nairah1
|
||||
*
|
||||
* @author Hari.Nair@jhuapl.edu
|
||||
*/
|
||||
public class TestProcessor {
|
||||
|
||||
|
||||
@@ -3,16 +3,16 @@
|
||||
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">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<artifactId>jackfruit-parent</artifactId>
|
||||
<groupId>edu.jhuapl.ses.srn</groupId>
|
||||
<groupId>edu.jhuapl.ses</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>jackfruit</artifactId>
|
||||
|
||||
<name>jackfruit</name>
|
||||
<description>Java Annotations Configuration library</description>
|
||||
|
||||
<!-- Specifies organization -->
|
||||
<organization>
|
||||
@@ -26,7 +26,7 @@
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
|
||||
<auto-service.version>1.1.0</auto-service.version>
|
||||
<auto-service.version>1.1.1</auto-service.version>
|
||||
<commons-configuration2.version>2.9.0</commons-configuration2.version>
|
||||
<log4j-version>2.20.0</log4j-version>
|
||||
<immutables.version>2.9.3</immutables.version>
|
||||
@@ -84,6 +84,9 @@
|
||||
</goals>
|
||||
<configuration>
|
||||
<executable>${project.basedir}/src/main/bash/createVersionFile.bash</executable>
|
||||
<arguments>
|
||||
<argument>${project.version}</argument>
|
||||
</arguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
|
||||
@@ -7,22 +7,10 @@ srcFile="../java/jackfruit/JackfruitVersion.java"
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
version=$1
|
||||
|
||||
date=$(date -u +"%y.%m.%d")
|
||||
|
||||
rev=$(git rev-parse --verify --short=8 HEAD)
|
||||
if [ $? -gt 0 ]; then
|
||||
lastCommit=$(date -u +"%y.%m.%d")
|
||||
rev="UNVERSIONED"
|
||||
else
|
||||
lastCommit=$(git log -1 --format=%cd --date=format:%y.%m.%d)
|
||||
|
||||
if [[ $(git diff --stat) != '' ]]; then
|
||||
if [[ $(git status -s | grep -v pom.xml | grep -v pom.bak | grep -v .m2 | grep -v $srcFile) != '' ]]; then
|
||||
rev=${rev}M
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
mkdir -p "$(dirname "$srcFile")"
|
||||
|
||||
touch $srcFile
|
||||
@@ -32,9 +20,7 @@ cat <<EOF > $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";
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
* <p>
|
||||
* For example: <br>
|
||||
* @Jackfruit(prefix = "myPrefix")
|
||||
* <p>
|
||||
* Inspired by <a href="http://owner.aeonbits.org/">owner</a>.
|
||||
*
|
||||
* @author nairah1
|
||||
*
|
||||
* <p>For example: <br>
|
||||
* @Jackfruit(prefix = "myPrefix")
|
||||
*
|
||||
* <p>Inspired by <a href="http://owner.aeonbits.org/">owner</a>.
|
||||
*
|
||||
* @author Hari.Nair@jhuapl.edu
|
||||
*/
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@Target(ElementType.TYPE)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 <T>
|
||||
* @author Hari.Nair@jhuapl.edu
|
||||
* @param <T> Type to be serialized/deserialized
|
||||
*/
|
||||
public interface Parser<T> {
|
||||
T fromString(String s);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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<TypeMirror> parserClass();
|
||||
}
|
||||
|
||||
@@ -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 <T>
|
||||
* @author Hari.Nair@jhuapl.edu
|
||||
* @param <T> configuration class with annotations
|
||||
*/
|
||||
public interface ConfigFactory<T> {
|
||||
|
||||
|
||||
@@ -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:
|
||||
* <ul>
|
||||
* <li><a href=
|
||||
* "https://www.javacodegeeks.com/2015/09/java-annotation-processors.html">https://www.javacodegeeks.com/2015/09/java-annotation-processors.html</a></li>
|
||||
* <li><a href=
|
||||
* "https://hannesdorfmann.com/annotation-processing/annotationprocessing101/">https://hannesdorfmann.com/annotation-processing/annotationprocessing101/</a></li>
|
||||
* <li><a href=
|
||||
* "http://www.javatronic.fr/articles/2014/08/31/how_to_make_sure_javac_is_using_a_specific_annotation_processor.html">http://www.javatronic.fr/articles/2014/08/31/how_to_make_sure_javac_is_using_a_specific_annotation_processor.html</a></li>
|
||||
* </ul>
|
||||
*
|
||||
* @author nairah1
|
||||
*
|
||||
* <ul>
|
||||
* <li><a href=
|
||||
* "https://www.javacodegeeks.com/2015/09/java-annotation-processors.html">https://www.javacodegeeks.com/2015/09/java-annotation-processors.html</a>
|
||||
* <li><a href=
|
||||
* "https://hannesdorfmann.com/annotation-processing/annotationprocessing101/">https://hannesdorfmann.com/annotation-processing/annotationprocessing101/</a>
|
||||
* <li><a href=
|
||||
* "http://www.javatronic.fr/articles/2014/08/31/how_to_make_sure_javac_is_using_a_specific_annotation_processor.html">http://www.javatronic.fr/articles/2014/08/31/how_to_make_sure_javac_is_using_a_specific_annotation_processor.html</a>
|
||||
* </ul>
|
||||
*
|
||||
* @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<Element> 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<Element> 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<ConfigTemplate>)
|
||||
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<MethodSpec> 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<Annotation> 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<ExecutableElement, AnnotationBundle> annotationsMap, String prefixMemberName) {
|
||||
private MethodSpec buildToConfig(
|
||||
TypeVariableName tvn,
|
||||
Method m,
|
||||
Map<ExecutableElement, AnnotationBundle> 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<ExecutableElement, AnnotationBundle> annotationsMap) {
|
||||
private MethodSpec buildGetTemplate(
|
||||
TypeVariableName tvn, Method m, Map<ExecutableElement, AnnotationBundle> 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<ExecutableElement, AnnotationBundle> annotationsMap, String prefix) {
|
||||
private MethodSpec buildFromConfig(
|
||||
TypeVariableName tvn,
|
||||
Method m,
|
||||
Map<ExecutableElement, AnnotationBundle> 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<MethodSpec> buildWithMethods(TypeVariableName tvn,
|
||||
Map<ExecutableElement, AnnotationBundle> annotationsMap, String prefixMemberName) {
|
||||
private List<MethodSpec> buildWithMethods(
|
||||
TypeVariableName tvn,
|
||||
Map<ExecutableElement, AnnotationBundle> annotationsMap,
|
||||
String prefixMemberName) {
|
||||
|
||||
List<MethodSpec> 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
105
pom.xml
105
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">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>edu.jhuapl.ses.srn</groupId>
|
||||
|
||||
<groupId>edu.jhuapl.ses</groupId>
|
||||
<artifactId>jackfruit-parent</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<name>jackfruit-parent</name>
|
||||
<description>Jackfruit processes annotations on Java interfaces and abstract classes to generate code that can read and write Apache Configuration files.</description>
|
||||
<url>https://github.com/JHUAPL/Jackfruit</url>
|
||||
|
||||
<inceptionYear>2023</inceptionYear>
|
||||
<organization>
|
||||
<name>Johns Hopkins University Applied Physics Laboratory</name>
|
||||
<url>http://jhuapl.edu</url>
|
||||
<url>https://www.jhuapl.edu/</url>
|
||||
</organization>
|
||||
|
||||
<licenses>
|
||||
@@ -22,14 +26,31 @@
|
||||
</license>
|
||||
</licenses>
|
||||
|
||||
<!-- publish to surfshop -->
|
||||
<developers>
|
||||
<developer>
|
||||
<id>HariNairJHUAPL</id>
|
||||
<name>Hari Nair</name>
|
||||
<email>Hari.Nair@jhuapl.edu</email>
|
||||
<organization>JHUAPL</organization>
|
||||
<organizationUrl>https://www.jhuapl.edu/</organizationUrl>
|
||||
</developer>
|
||||
</developers>
|
||||
|
||||
<scm>
|
||||
<connection>scm:git:https://github.com/JHUAPL/Jackfruit.git</connection>
|
||||
<url>https://github.com/JHUAPL/Jackfruit.git</url>
|
||||
<developerConnection>scm:git:https://github.com/JHUAPL/Jackfruit.git</developerConnection>
|
||||
<tag>HEAD</tag>
|
||||
</scm>
|
||||
|
||||
<!-- publish to maven central -->
|
||||
<distributionManagement>
|
||||
<repository>
|
||||
<id>central</id>
|
||||
<name>surfshop-snapshots</name>
|
||||
<url>http://surfshop.jhuapl.edu:8081/artifactory/libs-snapshot-local</url>
|
||||
</repository>
|
||||
<snapshotRepository>
|
||||
<id>ossrh</id>
|
||||
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
|
||||
</snapshotRepository>
|
||||
</distributionManagement>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
@@ -45,8 +66,8 @@
|
||||
<version>4.13.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
<pluginManagement>
|
||||
@@ -56,7 +77,7 @@
|
||||
https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
|
||||
<plugin>
|
||||
<artifactId>maven-clean-plugin</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.1</version>
|
||||
</plugin>
|
||||
<!-- default lifecycle, jar packaging: see
|
||||
https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
|
||||
@@ -73,7 +94,7 @@
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<version>3.1.2</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
@@ -85,14 +106,28 @@
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<version>2.8.2</version>
|
||||
<version>3.1.1</version>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>3.5.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-javadocs</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<!-- site lifecycle, see
|
||||
https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
|
||||
<plugin>
|
||||
<artifactId>maven-site-plugin</artifactId>
|
||||
<version>4.0.0-M8</version>
|
||||
<version>4.0.0-M9</version>
|
||||
<configuration>
|
||||
<skip>${maven-site-plugin.skip}</skip>
|
||||
</configuration>
|
||||
@@ -100,13 +135,13 @@
|
||||
|
||||
<plugin>
|
||||
<artifactId>maven-project-info-reports-plugin</artifactId>
|
||||
<version>3.4.4</version>
|
||||
<version>3.4.5</version>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>license-maven-plugin</artifactId>
|
||||
<version>2.0.1</version>
|
||||
<version>2.2.0</version>
|
||||
<configuration>
|
||||
<licenseName>apache_v2</licenseName>
|
||||
</configuration>
|
||||
@@ -139,10 +174,15 @@
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-enforcer-plugin</artifactId>
|
||||
<version>3.3.0</version>
|
||||
<version>3.4.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>enforce-maven</id>
|
||||
@@ -160,6 +200,39 @@
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-gpg-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>sign-artifacts</id>
|
||||
<phase>verify</phase>
|
||||
<goals>
|
||||
<goal>sign</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<gpgArguments>
|
||||
<arg>--pinentry-mode</arg>
|
||||
<arg>loopback</arg>
|
||||
</gpgArguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.sonatype.plugins</groupId>
|
||||
<artifactId>nexus-staging-maven-plugin</artifactId>
|
||||
<version>1.6.13</version>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<serverId>ossrh</serverId>
|
||||
<nexusUrl>https://oss.sonatype.org/</nexusUrl>
|
||||
<autoReleaseAfterClose>true</autoReleaseAfterClose>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
|
||||
</build>
|
||||
|
||||
Reference in New Issue
Block a user