HHH-16217 Use only rendered Javadocs for collecting configuration properties
This commit is contained in:
parent
977a6cd987
commit
844a89a74c
|
@ -17,7 +17,6 @@ apply from: rootProject.file( 'gradle/releasable.gradle' )
|
|||
|
||||
apply plugin: 'org.hibernate.matrix-test'
|
||||
apply plugin: 'org.hibernate.orm.build.reports'
|
||||
apply plugin: 'org.hibernate.orm.build.properties'
|
||||
|
||||
tasks.build.dependsOn 'buildDocs'
|
||||
defaultTasks 'buildDocs'
|
||||
|
@ -106,24 +105,6 @@ asciidoctorj {
|
|||
options logDocuments: true
|
||||
}
|
||||
|
||||
// Collect config properties ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
task collectConfigProperties { task ->
|
||||
group 'Documentation'
|
||||
description 'Collect config properties'
|
||||
|
||||
// make sure that the javadocs are generated prior to collecting properties.
|
||||
dependsOn ':hibernate-core:javadoc'
|
||||
dependsOn ':hibernate-envers:javadoc'
|
||||
dependsOn ':hibernate-jcache:javadoc'
|
||||
|
||||
dependsOn tasks.generateConfigPropertiesMap
|
||||
dependsOn tasks.writeConfigPropertiesMap
|
||||
|
||||
tasks.buildDocs.dependsOn task
|
||||
tasks.buildDocsForPublishing.dependsOn task
|
||||
|
||||
}
|
||||
|
||||
// Topical Guides ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
task renderTopicalGuides(type: AsciidoctorTask, group: 'Documentation') {task->
|
||||
|
@ -178,7 +159,9 @@ task renderUserGuide(type: AsciidoctorTask, group: 'Documentation') {task->
|
|||
tasks.buildDocs.dependsOn task
|
||||
tasks.buildDocsForPublishing.dependsOn task
|
||||
|
||||
dependsOn tasks.collectConfigProperties
|
||||
dependsOn ':hibernate-core:collectConfigProperties'
|
||||
dependsOn ':hibernate-envers:collectConfigProperties'
|
||||
dependsOn ':hibernate-jcache:collectConfigProperties'
|
||||
|
||||
sourceDir = file( 'src/main/asciidoc/userguide' )
|
||||
sources {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
== List of all available configuration properties
|
||||
|
||||
include::../../../../target/configs.asciidoc[opts=optional]
|
||||
include::../../../../target/config-properties/hibernate-core.asciidoc[opts=optional]
|
||||
include::../../../../target/config-properties/hibernate-envers.asciidoc[opts=optional]
|
||||
include::../../../../target/config-properties/hibernate-jcache.asciidoc[opts=optional]
|
|
@ -15,7 +15,7 @@ description = 'Hibernate\'s core ORM functionality'
|
|||
apply from: rootProject.file( 'gradle/published-java-module.gradle' )
|
||||
apply plugin: 'org.hibernate.orm.antlr'
|
||||
apply plugin: 'org.hibernate.matrix-test'
|
||||
|
||||
apply plugin: 'org.hibernate.orm.build.properties'
|
||||
|
||||
configurations {
|
||||
tests {
|
||||
|
@ -308,3 +308,11 @@ javadoc {
|
|||
stylesheetFile = new File(projectDir, 'src/main/javadoc/stylesheet.css')
|
||||
}
|
||||
}
|
||||
|
||||
task collectConfigProperties { task ->
|
||||
description 'Collect config properties'
|
||||
|
||||
tasks.generateConfigsProperties.javadocsBaseLink = 'https://docs.jboss.org/hibernate/orm/' + rootProject.ormVersion.family + '/javadocs/'
|
||||
|
||||
dependsOn tasks.generateConfigsProperties
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ description = 'Hibernate\'s entity version (audit/history) support'
|
|||
|
||||
apply from: rootProject.file( 'gradle/published-java-module.gradle' )
|
||||
apply plugin: 'org.hibernate.matrix-test'
|
||||
apply plugin: 'org.hibernate.orm.build.properties'
|
||||
|
||||
dependencies {
|
||||
api project( ':hibernate-core' )
|
||||
|
@ -69,3 +70,11 @@ tasks."matrix_mariadb" {
|
|||
println "Starting test: " + descriptor
|
||||
}
|
||||
}
|
||||
|
||||
task collectConfigProperties { task ->
|
||||
description 'Collect config properties'
|
||||
|
||||
tasks.generateConfigsProperties.javadocsBaseLink = 'https://docs.jboss.org/hibernate/orm/' + rootProject.ormVersion.family + '/javadocs/'
|
||||
|
||||
dependsOn tasks.generateConfigsProperties
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
description = 'Integration for javax.cache into Hibernate as a second-level caching service'
|
||||
|
||||
apply from: rootProject.file( 'gradle/published-java-module.gradle' )
|
||||
|
||||
apply plugin: 'org.hibernate.orm.build.properties'
|
||||
|
||||
dependencies {
|
||||
api project( ':hibernate-core' )
|
||||
|
@ -15,3 +15,11 @@ dependencies {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
task collectConfigProperties { task ->
|
||||
description 'Collect config properties'
|
||||
|
||||
tasks.generateConfigsProperties.javadocsBaseLink = 'https://docs.jboss.org/hibernate/orm/' + rootProject.ormVersion.family + '/javadocs/'
|
||||
|
||||
dependsOn tasks.generateConfigsProperties
|
||||
}
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.orm.properties;
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
public class AsciiDocWriter implements BiConsumer<Set<ConfigurationProperty>, Writer> {
|
||||
|
||||
private final String anchor;
|
||||
private final String title;
|
||||
|
||||
public AsciiDocWriter(String anchor, String title) {
|
||||
this.anchor = anchor;
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(Set<ConfigurationProperty> properties, Writer writer) {
|
||||
try {
|
||||
tryToWriteLine( writer, "[[configuration-properties-aggregated-", anchor, "]]" );
|
||||
tryToWriteLine( writer, "=== ", title );
|
||||
writer.write( '\n' );
|
||||
for ( ConfigurationProperty el : properties ) {
|
||||
String key = el.key();
|
||||
writer.write( "[[" );
|
||||
writer.write( "configuration-properties-aggregated-" );
|
||||
writer.write( el.anchorPrefix() );
|
||||
writer.write( key.replaceAll( "[^\\w-.]", "-" ) );
|
||||
writer.write( "]] " );
|
||||
|
||||
writer.write( '`' );
|
||||
writer.write( key );
|
||||
writer.write( '`' );
|
||||
writer.write( "::\n" );
|
||||
|
||||
// using inline passthrough for javadocs to not render HTML.
|
||||
writer.write( "+++ " );
|
||||
writer.write( el.javadoc() );
|
||||
writer.write( " +++ " );
|
||||
|
||||
writer.write( '\n' );
|
||||
}
|
||||
writer.write( '\n' );
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException( "Unable to create asciidoc output", e );
|
||||
}
|
||||
}
|
||||
|
||||
private void tryToWriteLine(Writer writer, String prefix, String value, String... other) {
|
||||
try {
|
||||
writer.write( prefix );
|
||||
writer.write( value );
|
||||
for ( String s : other ) {
|
||||
writer.write( s );
|
||||
}
|
||||
writer.write( "\n" );
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException( "Unable to create asciidoc output", e );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,8 +6,6 @@
|
|||
*/
|
||||
package org.hibernate.orm.properties;
|
||||
|
||||
import org.hibernate.orm.properties.processor.ConfigPropertyHolder;
|
||||
|
||||
import org.gradle.api.Plugin;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.Task;
|
||||
|
@ -20,20 +18,15 @@ public class ConfigPropertyCollectorPlugin implements Plugin<Project> {
|
|||
final Task groupingTask = project.getTasks().maybeCreate( "generateHibernateConfigProperties" );
|
||||
groupingTask.setGroup( TASK_GROUP_NAME );
|
||||
|
||||
ConfigPropertyHolder propertyHolder = new ConfigPropertyHolder();
|
||||
final ConfigPropertyCollectorTask configPropertyCollectorTask = project.getTasks().create(
|
||||
"generateConfigPropertiesMap",
|
||||
ConfigPropertyCollectorTask.class,
|
||||
propertyHolder
|
||||
);
|
||||
groupingTask.dependsOn( configPropertyCollectorTask );
|
||||
Task javadoc = project.getTasks().maybeCreate( "javadoc" );
|
||||
groupingTask.dependsOn( javadoc );
|
||||
|
||||
final ConfigPropertyWriterTask configPropertyWriterTask = project.getTasks().create(
|
||||
"writeConfigPropertiesMap",
|
||||
ConfigPropertyWriterTask.class,
|
||||
propertyHolder
|
||||
|
||||
final ConfigPropertyCollectorTask configPropertyCollectorTask = project.getTasks().create(
|
||||
"generateConfigsProperties",
|
||||
ConfigPropertyCollectorTask.class
|
||||
);
|
||||
groupingTask.dependsOn( configPropertyWriterTask );
|
||||
configPropertyWriterTask.dependsOn( configPropertyCollectorTask );
|
||||
configPropertyCollectorTask.dependsOn( javadoc );
|
||||
groupingTask.dependsOn( configPropertyCollectorTask );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,178 +1,68 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html.
|
||||
*/
|
||||
package org.hibernate.orm.properties;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.FileVisitResult;
|
||||
import java.io.Writer;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.SimpleFileVisitor;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import javax.inject.Inject;
|
||||
import javax.tools.JavaCompiler;
|
||||
import javax.tools.JavaFileObject;
|
||||
import javax.tools.StandardJavaFileManager;
|
||||
import javax.tools.StandardLocation;
|
||||
import javax.tools.ToolProvider;
|
||||
|
||||
import org.hibernate.orm.properties.processor.ConfigPropertyHolder;
|
||||
import org.hibernate.orm.properties.processor.Configuration;
|
||||
import org.hibernate.orm.properties.processor.ConfigurationPropertyProcessor;
|
||||
|
||||
import org.gradle.api.DefaultTask;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.UnknownDomainObjectException;
|
||||
import org.gradle.api.tasks.SourceSetContainer;
|
||||
import org.gradle.api.provider.Property;
|
||||
import org.gradle.api.tasks.Internal;
|
||||
import org.gradle.api.tasks.TaskAction;
|
||||
|
||||
/**
|
||||
* Task that goes to the root project and then sends all the sources from children projects trough annotation processing
|
||||
* collecting all the config properties into a map. See {@link ConfigurationPropertyProcessor}
|
||||
*/
|
||||
public class ConfigPropertyCollectorTask extends DefaultTask {
|
||||
|
||||
private final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
|
||||
private final Project project;
|
||||
private final ConfigPropertyHolder properties;
|
||||
private final Path target;
|
||||
private final Path javadocsLocation;
|
||||
private final Property<String> javadocsBaseLink;
|
||||
private final String anchor;
|
||||
private final String moduleName;
|
||||
private final ConfigPropertyHolder propertyHolder = new ConfigPropertyHolder();
|
||||
|
||||
private final Path output;
|
||||
private final String fileName;
|
||||
|
||||
|
||||
@Inject
|
||||
public ConfigPropertyCollectorTask(ConfigPropertyHolder properties, Project project) {
|
||||
this.project = project;
|
||||
this.properties = properties;
|
||||
this.target = project.getBuildDir().toPath();
|
||||
public ConfigPropertyCollectorTask(Project project) {
|
||||
this.javadocsLocation = project.getBuildDir().toPath().resolve( "docs/javadoc" );
|
||||
this.javadocsBaseLink = project.getObjects().property( String.class );
|
||||
this.anchor = project.getName() + "-";
|
||||
this.moduleName = project.getDescription();
|
||||
this.output = project.getRootProject().project( ":documentation" ).getBuildDir().toPath()
|
||||
.resolve( "config-properties" );
|
||||
this.fileName = project.getName() + ".asciidoc";
|
||||
}
|
||||
|
||||
@Internal
|
||||
public Property<String> getJavadocsBaseLink() {
|
||||
return javadocsBaseLink;
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
public void collectProperties() {
|
||||
for ( Map.Entry<String, Project> projectEntry : project.getRootProject().getChildProjects().entrySet() ) {
|
||||
try {
|
||||
// we don't need to look at testing projects as these aren't for public configurations.
|
||||
if ( projectEntry.getKey().contains( "test" ) ) {
|
||||
continue;
|
||||
}
|
||||
SourceSetContainer sources = projectEntry.getValue().getExtensions().getByType(
|
||||
SourceSetContainer.class );
|
||||
|
||||
sources.all( s -> {
|
||||
// no need to compile/process test sources:
|
||||
if ( !"test".equals( s.getName() ) ) {
|
||||
compile(
|
||||
projectEntry.getValue(),
|
||||
s.getAllJava().getSourceDirectories().getFiles(),
|
||||
s.getCompileClasspath().getFiles()
|
||||
);
|
||||
}
|
||||
} );
|
||||
}
|
||||
catch (UnknownDomainObjectException e) {
|
||||
getLogger().info( "Ignoring " + projectEntry.getKey() + " because of " + e.getMessage(), e );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean compile(Project project, Collection<File> sources, Collection<File> classpath) {
|
||||
List<File> classes = new ArrayList<>();
|
||||
for ( File sourceFile : sources ) {
|
||||
try {
|
||||
// need to find all java files to be later converted to compilation units:
|
||||
Files.walkFileTree( sourceFile.toPath(), new SimpleFileVisitor<>() {
|
||||
@Override
|
||||
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
|
||||
if ( file.getFileName().toString().endsWith( ".java" ) ) {
|
||||
classes.add( file.toFile() );
|
||||
}
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
} );
|
||||
}
|
||||
catch (IOException e) {
|
||||
getLogger().debug( "Failed to process " + sourceFile.getAbsolutePath(), e );
|
||||
}
|
||||
}
|
||||
|
||||
if ( classes.isEmpty() ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
StandardJavaFileManager fileManager = compiler.getStandardFileManager( null, null, null );
|
||||
Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjects(
|
||||
classes.stream().toArray( File[]::new ) );
|
||||
|
||||
try {
|
||||
// we don't really need the compiled classes, so we just dump them somewhere to not mess with the rest of the
|
||||
// classes:
|
||||
fileManager.setLocation(
|
||||
StandardLocation.CLASS_OUTPUT,
|
||||
Arrays.asList(
|
||||
Files.createDirectories( target.resolve( "config-property-collector-compiled-classes" ) )
|
||||
.toFile() )
|
||||
);
|
||||
fileManager.setLocation(
|
||||
StandardLocation.CLASS_PATH,
|
||||
classpath
|
||||
);
|
||||
public void generateConfigProperties() {
|
||||
new ConfigurationPropertyCollector(
|
||||
propertyHolder, getLogger(), javadocsLocation, javadocsBaseLink.get(), anchor, moduleName
|
||||
).processClasses();
|
||||
try{
|
||||
Files.createDirectories( output );
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException( e );
|
||||
throw new RuntimeException( "Unable to prepare output directory structure", e );
|
||||
}
|
||||
try ( Writer writer = new FileWriter( output.resolve( fileName ).toFile() ) ) {
|
||||
propertyHolder.write( new AsciiDocWriter( anchor, moduleName ), writer );
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException( "Failed to produce asciidoc output for collected properties", e );
|
||||
}
|
||||
|
||||
List<String> options = new ArrayList<>();
|
||||
options.add( "-proc:only" );
|
||||
options.add(
|
||||
String.format(
|
||||
Locale.ROOT,
|
||||
"-A%s=%s",
|
||||
Configuration.MODULE_TITLE,
|
||||
project.getDescription()
|
||||
)
|
||||
);
|
||||
options.add(
|
||||
String.format(
|
||||
Locale.ROOT,
|
||||
"-A%s=%s",
|
||||
Configuration.MODULE_LINK_ANCHOR,
|
||||
project.getName() + "-"
|
||||
)
|
||||
);
|
||||
// todo: this should come from some plugin/task config rather than be hardcoded:
|
||||
options.add(
|
||||
String.format(
|
||||
Locale.ROOT,
|
||||
"-A%s=%s",
|
||||
Configuration.JAVADOC_LINK,
|
||||
"https://docs.jboss.org/hibernate/orm/6.2/javadocs/"
|
||||
)
|
||||
);
|
||||
|
||||
JavaCompiler.CompilationTask task = compiler.getTask(
|
||||
null,
|
||||
fileManager,
|
||||
null,
|
||||
options,
|
||||
null,
|
||||
compilationUnits
|
||||
);
|
||||
|
||||
task.setProcessors( Arrays.asList( new ConfigurationPropertyProcessor(
|
||||
project.getBuildDir().toPath().resolve( "docs/javadoc" ),
|
||||
properties
|
||||
) ) );
|
||||
|
||||
return task.call();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -4,36 +4,36 @@
|
|||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.orm.properties.processor;
|
||||
package org.hibernate.orm.properties;
|
||||
|
||||
import java.io.Writer;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class ConfigPropertyHolder {
|
||||
|
||||
private final Map<String, ConfigurationProperty> properties = new TreeMap<>();
|
||||
private final Set<ConfigurationProperty> properties = new TreeSet<>();
|
||||
|
||||
|
||||
public boolean isEmpty() {
|
||||
return properties.isEmpty();
|
||||
}
|
||||
|
||||
public void write(BiConsumer<Map<String, ConfigurationProperty>, Writer> transformer, Writer writer) {
|
||||
public void write(BiConsumer<Set<ConfigurationProperty>, Writer> transformer, Writer writer) {
|
||||
transformer.accept( this.properties, writer );
|
||||
}
|
||||
|
||||
public void put(String key, ConfigurationProperty property) {
|
||||
properties.put( key, property );
|
||||
public void add(ConfigurationProperty property) {
|
||||
properties.add( property );
|
||||
}
|
||||
|
||||
public boolean hasProperties() {
|
||||
return !properties.isEmpty();
|
||||
}
|
||||
|
||||
public boolean hasProperties(Predicate<Map.Entry<String, ConfigurationProperty>> filter) {
|
||||
return properties.entrySet().stream().anyMatch( filter );
|
||||
public boolean hasProperties(Predicate<ConfigurationProperty> filter) {
|
||||
return properties.stream().anyMatch( filter );
|
||||
}
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.orm.properties;
|
||||
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.hibernate.orm.properties.processor.AsciiDocWriter;
|
||||
import org.hibernate.orm.properties.processor.ConfigPropertyHolder;
|
||||
import org.hibernate.orm.properties.processor.ConfigurationProperty;
|
||||
|
||||
import org.gradle.api.DefaultTask;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.tasks.TaskAction;
|
||||
|
||||
/**
|
||||
* Task that writes two asciidoc files from the collected config properties. One is for public configurations, another - for SPI.
|
||||
*/
|
||||
public class ConfigPropertyWriterTask extends DefaultTask {
|
||||
|
||||
private final Project project;
|
||||
private final ConfigPropertyHolder properties;
|
||||
private final String fileName = "configs";
|
||||
|
||||
@Inject
|
||||
public ConfigPropertyWriterTask(Project project, ConfigPropertyHolder properties) {
|
||||
this.project = project;
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
public void writeProperties() {
|
||||
if ( properties.hasProperties() ) {
|
||||
writeProperties(
|
||||
fileName + ".asciidoc",
|
||||
new AsciiDocWriter()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeProperties(String fileName, BiConsumer<Map<String, ConfigurationProperty>, Writer> transformer) {
|
||||
try ( Writer writer = new FileWriter( project.getBuildDir().toPath().resolve( fileName ).toFile() )
|
||||
) {
|
||||
properties.write( transformer, writer );
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException( e );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -4,29 +4,26 @@
|
|||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.orm.properties.processor;
|
||||
package org.hibernate.orm.properties;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class ConfigurationProperty implements Comparable<ConfigurationProperty> {
|
||||
|
||||
private static final Comparator<ConfigurationProperty> CONFIGURATION_PROPERTY_COMPARATOR = Comparator.comparing(
|
||||
c -> c.key().key );
|
||||
private Key key;
|
||||
ConfigurationProperty::key );
|
||||
private String key;
|
||||
private String javadoc;
|
||||
private String sourceClass;
|
||||
private String anchorPrefix;
|
||||
private String moduleName;
|
||||
|
||||
public Key key() {
|
||||
public String key() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public ConfigurationProperty key(Key key) {
|
||||
public ConfigurationProperty key(String key) {
|
||||
this.key = key;
|
||||
return this;
|
||||
}
|
||||
|
@ -53,7 +50,7 @@ public class ConfigurationProperty implements Comparable<ConfigurationProperty>
|
|||
return anchorPrefix;
|
||||
}
|
||||
|
||||
public ConfigurationProperty withAnchorPrefix(String anchorPrefix) {
|
||||
public ConfigurationProperty anchorPrefix(String anchorPrefix) {
|
||||
this.anchorPrefix = anchorPrefix.replaceAll( "[^\\w-.]", "_" );
|
||||
return this;
|
||||
}
|
||||
|
@ -62,7 +59,7 @@ public class ConfigurationProperty implements Comparable<ConfigurationProperty>
|
|||
return moduleName;
|
||||
}
|
||||
|
||||
public ConfigurationProperty withModuleName(String moduleName) {
|
||||
public ConfigurationProperty moduleName(String moduleName) {
|
||||
this.moduleName = moduleName;
|
||||
return this;
|
||||
}
|
||||
|
@ -103,25 +100,4 @@ public class ConfigurationProperty implements Comparable<ConfigurationProperty>
|
|||
public int hashCode() {
|
||||
return Objects.hash( key, javadoc, sourceClass, anchorPrefix, moduleName );
|
||||
}
|
||||
|
||||
public static class Key {
|
||||
private final String key;
|
||||
|
||||
public Key(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public boolean matches(Pattern pattern) {
|
||||
return pattern.matcher( key ).matches();
|
||||
}
|
||||
|
||||
public List<String> resolvedKeys() {
|
||||
return Collections.singletonList( key );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.orm.properties;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.gradle.api.logging.Logger;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
|
||||
public class ConfigurationPropertyCollector {
|
||||
|
||||
private final ConfigPropertyHolder propertyHolder;
|
||||
private final Logger logger;
|
||||
|
||||
// configs:
|
||||
private final Path javadocsLocation;
|
||||
private final String javadocsBaseLink;
|
||||
private final String anchor;
|
||||
private final String moduleName;
|
||||
|
||||
public ConfigurationPropertyCollector(ConfigPropertyHolder propertyHolder, Logger logger, Path javadocsLocation,
|
||||
String javadocsBaseLink, String anchor, String moduleName) {
|
||||
this.propertyHolder = propertyHolder;
|
||||
this.logger = logger;
|
||||
this.javadocsLocation = javadocsLocation;
|
||||
this.javadocsBaseLink = javadocsBaseLink;
|
||||
this.anchor = anchor;
|
||||
this.moduleName = moduleName;
|
||||
|
||||
}
|
||||
|
||||
public void processClasses() {
|
||||
processClasses( locateConstants() );
|
||||
}
|
||||
|
||||
private void processClasses(Document constants) {
|
||||
for ( Element table : constants.select( "table.constantsSummary" ) ) {
|
||||
String className = table.selectFirst( "caption" ).text();
|
||||
if ( className.endsWith( "Settings" ) && !className.contains( ".impl." ) && !className.contains( ".internal." ) ) {
|
||||
// assume that such class is a config class and we want to collect properties from it.
|
||||
Optional<Document> javadoc = obtainJavadoc( className );
|
||||
javadoc.ifPresent( doc -> {
|
||||
// go through constants:
|
||||
for ( Element row : table.select( "tr" ) ) {
|
||||
if ( row.hasClass( "altColor" ) || row.hasClass( "rowColor" ) ) {
|
||||
propertyHolder.add(
|
||||
new ConfigurationProperty()
|
||||
.key( stripQuotes( row.selectFirst( ".colLast" ).text() ) )
|
||||
.javadoc(
|
||||
extractJavadoc(
|
||||
doc,
|
||||
className,
|
||||
withoutPackagePrefix( row.selectFirst( ".colFirst a" ).id() )
|
||||
)
|
||||
)
|
||||
.sourceClass( className )
|
||||
.anchorPrefix( anchor )
|
||||
.moduleName( moduleName )
|
||||
);
|
||||
}
|
||||
}
|
||||
} );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String stripQuotes(String value) {
|
||||
if ( value.startsWith( "\"" ) && value.endsWith( "\"" ) ) {
|
||||
return value.substring( 1, value.length() - 1 );
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private String extractJavadoc(Document javadoc, String className, String constant) {
|
||||
org.jsoup.nodes.Element block = javadoc.selectFirst( "#" + constant + " + ul li.blockList" );
|
||||
if ( block != null ) {
|
||||
for ( org.jsoup.nodes.Element link : block.getElementsByTag( "a" ) ) {
|
||||
String href = link.attr( "href" );
|
||||
// only update links if they are not external:
|
||||
if ( !link.hasClass( "external-link" ) ) {
|
||||
if ( href.startsWith( "#" ) ) {
|
||||
href = withoutPackagePrefix( className ) + ".html" + href;
|
||||
}
|
||||
String packagePath = packagePrefix(className).replace( ".", File.separator );
|
||||
href = javadocsBaseLink + packagePath + "/" + href;
|
||||
}
|
||||
else if ( href.contains( "/build/parents/" ) && href.contains( "/apidocs" ) ) {
|
||||
// means a link was to a class from other module and javadoc plugin generated some external link
|
||||
// that won't work. So we replace it:
|
||||
href = javadocsBaseLink + href.substring( href.indexOf( "/apidocs" ) + "/apidocs".length() );
|
||||
}
|
||||
link.attr( "href", href );
|
||||
}
|
||||
|
||||
org.jsoup.nodes.Element result = new org.jsoup.nodes.Element( "div" );
|
||||
for ( org.jsoup.nodes.Element child : block.children() ) {
|
||||
if ( "h4".equalsIgnoreCase( child.tagName() ) || "pre".equalsIgnoreCase( child.tagName() ) ) {
|
||||
continue;
|
||||
}
|
||||
result.appendChild( child );
|
||||
}
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private String withoutPackagePrefix(String className) {
|
||||
return className.substring( className.lastIndexOf( '.' ) + 1 );
|
||||
}
|
||||
|
||||
private String packagePrefix(String className) {
|
||||
return className.substring( 0, className.lastIndexOf( '.' ) );
|
||||
}
|
||||
|
||||
private Optional<Document> obtainJavadoc(String enclosingClass) {
|
||||
try {
|
||||
Path docs = javadocsLocation.resolve(
|
||||
enclosingClass.replace( ".", File.separator ) + ".html"
|
||||
);
|
||||
|
||||
return Optional.of( Jsoup.parse( docs.toFile() ) );
|
||||
}
|
||||
catch (IOException e) {
|
||||
logger.error( "Unable to access javadocs for " + enclosingClass, e );
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private Document locateConstants() {
|
||||
try {
|
||||
Path docs = javadocsLocation.resolve( "constant-values.html" );
|
||||
|
||||
return Jsoup.parse( docs.toFile() );
|
||||
}
|
||||
catch (IOException e) {
|
||||
logger.error( "Unable to access javadocs `constant-values.html`", e );
|
||||
throw new IllegalStateException( e );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,111 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.orm.properties.processor;
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.TreeSet;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class AsciiDocWriter implements BiConsumer<Map<String, ConfigurationProperty>, Writer> {
|
||||
|
||||
@Override
|
||||
public void accept(Map<String, ConfigurationProperty> propertyMap, Writer writer) {
|
||||
Map<String, Collection<ConfigurationProperty>> groups = propertyMap.entrySet().stream()
|
||||
.map( Map.Entry::getValue )
|
||||
.collect(
|
||||
Collectors.groupingBy(
|
||||
ConfigurationProperty::moduleName,
|
||||
TreeMap::new,
|
||||
Collectors.toCollection( TreeSet::new )
|
||||
)
|
||||
);
|
||||
|
||||
if ( groups.isEmpty() ) {
|
||||
// nothing to write - return fast.
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
for ( Map.Entry<String, Collection<ConfigurationProperty>> entry : groups.entrySet() ) {
|
||||
tryToWriteLine( writer, "[[configuration-properties-aggregated-", entry.getValue().iterator().next().anchorPrefix(), "]]" );
|
||||
tryToWriteLine( writer, "=== ", entry.getKey() );
|
||||
writer.write( '\n' );
|
||||
for ( ConfigurationProperty el : entry.getValue() ) {
|
||||
Iterator<String> keys = el.key().resolvedKeys().iterator();
|
||||
String firstKey = keys.next();
|
||||
writer.write( "[[" );
|
||||
writer.write( "configuration-properties-aggregated-" );
|
||||
writer.write( el.anchorPrefix() );
|
||||
writer.write( firstKey.replaceAll( "[^\\w-.]", "_" ) );
|
||||
writer.write( "]] " );
|
||||
|
||||
writer.write( '`' );
|
||||
writer.write( firstKey );
|
||||
writer.write( '`' );
|
||||
writer.write( "::\n" );
|
||||
|
||||
// using inline passthrough for javadocs to not render HTML.
|
||||
writer.write( "+++ " );
|
||||
writer.write( el.javadoc() );
|
||||
writer.write( " +++ " );
|
||||
|
||||
writer.write( '\n' );
|
||||
|
||||
printOtherKeyVariants( writer, keys );
|
||||
}
|
||||
}
|
||||
writer.write( '\n' );
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException( e );
|
||||
}
|
||||
}
|
||||
|
||||
private void printOtherKeyVariants(Writer writer, Iterator<String> keys) throws IOException {
|
||||
boolean hasMultipleKeys = false;
|
||||
if ( keys.hasNext() ) {
|
||||
hasMultipleKeys = true;
|
||||
writer.write( "+\n" );
|
||||
writer.write( ".Variants of this configuration property (Click here):\n" );
|
||||
writer.write( "[%collapsible]\n" );
|
||||
writer.write( "====\n" );
|
||||
}
|
||||
while ( keys.hasNext() ) {
|
||||
writer.write( '`' );
|
||||
writer.write( keys.next() );
|
||||
writer.write( '`' );
|
||||
if ( keys.hasNext() ) {
|
||||
writer.write( ", " );
|
||||
}
|
||||
}
|
||||
|
||||
if ( hasMultipleKeys ) {
|
||||
writer.write( "\n====\n" );
|
||||
}
|
||||
}
|
||||
|
||||
private void tryToWriteLine(Writer writer, String prefix, String value, String... other) {
|
||||
try {
|
||||
writer.write( prefix );
|
||||
writer.write( value );
|
||||
for ( String s : other ) {
|
||||
writer.write( s );
|
||||
}
|
||||
writer.write( "\n" );
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException( e );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.orm.properties.processor;
|
||||
|
||||
/**
|
||||
* Lists the config parameters that can be passed to this annotation processor via {@code -A.....}.
|
||||
*/
|
||||
public final class Configuration {
|
||||
private Configuration() {
|
||||
}
|
||||
|
||||
private static final String HIBERNATE_ORM_CPCAP_PREFIX = "org.hibernate.orm.cpcap.";
|
||||
|
||||
/**
|
||||
* Use to define a base URL for Hibernate ORM Javadoc. As we are getting parts of Javadoc links in it should
|
||||
* be adjusted to point to somewhere where the docs actually live.
|
||||
*/
|
||||
public static final String JAVADOC_LINK = HIBERNATE_ORM_CPCAP_PREFIX + "javadoc.link";
|
||||
/**
|
||||
* Use to define a pattern for classes to be ignored by this collector. We can have some {@code *Settings} classes
|
||||
* in {@code impl} packages. And we don't need to collect properties from those.
|
||||
*/
|
||||
public static final String IGNORE_PATTERN = HIBERNATE_ORM_CPCAP_PREFIX + "ignore.pattern";
|
||||
/**
|
||||
* Use to define a pattern for property key values that should be ignored. By default, we will ignore keys that end
|
||||
* with a dot {@code '.'}.
|
||||
*/
|
||||
public static final String IGNORE_KEY_VALUE_PATTERN = HIBERNATE_ORM_CPCAP_PREFIX + "ignore.key.value.pattern";
|
||||
/**
|
||||
* Used to group properties in sections and as a title of that section.
|
||||
*/
|
||||
public static final String MODULE_TITLE = HIBERNATE_ORM_CPCAP_PREFIX + "module.title";
|
||||
/**
|
||||
* Used to group properties in sections and as a title of that section.
|
||||
*/
|
||||
public static final String MODULE_LINK_ANCHOR = HIBERNATE_ORM_CPCAP_PREFIX + "module.link.anchor";
|
||||
}
|
|
@ -1,155 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.orm.properties.processor;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.annotation.processing.Messager;
|
||||
import javax.annotation.processing.ProcessingEnvironment;
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ElementKind;
|
||||
import javax.lang.model.element.Name;
|
||||
import javax.lang.model.element.PackageElement;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.element.VariableElement;
|
||||
import javax.lang.model.util.Elements;
|
||||
import javax.tools.Diagnostic;
|
||||
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
|
||||
public class ConfigurationPropertyCollector {
|
||||
|
||||
private final Set<Name> processedTypes = new HashSet<>();
|
||||
private final ConfigPropertyHolder properties;
|
||||
private final Elements elementUtils;
|
||||
private final String title;
|
||||
private final String anchor;
|
||||
private final Path javadocsLocation;
|
||||
private final String javadocsBaseLink;
|
||||
private final Pattern ignoreKeys;
|
||||
private final Messager messager;
|
||||
|
||||
public ConfigurationPropertyCollector(ConfigPropertyHolder properties, ProcessingEnvironment processingEnvironment,
|
||||
String title,
|
||||
String anchor, Path javadocsLocation, Pattern ignoreKeys,
|
||||
String javadocsBaseLink) {
|
||||
this.properties = properties;
|
||||
this.elementUtils = processingEnvironment.getElementUtils();
|
||||
this.title = title;
|
||||
this.anchor = anchor;
|
||||
this.javadocsLocation = javadocsLocation;
|
||||
this.javadocsBaseLink = javadocsBaseLink;
|
||||
this.ignoreKeys = ignoreKeys;
|
||||
this.messager = processingEnvironment.getMessager();
|
||||
}
|
||||
|
||||
public void visitType(TypeElement element) {
|
||||
Name qualifiedName = element.getQualifiedName();
|
||||
if ( !processedTypes.contains( qualifiedName ) ) {
|
||||
processedTypes.add( qualifiedName );
|
||||
|
||||
for ( Element inner : elementUtils.getAllMembers( element ) ) {
|
||||
if ( inner.getKind().equals( ElementKind.FIELD ) && inner instanceof VariableElement ) {
|
||||
processConstant( ( (VariableElement) inner ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void processConstant(VariableElement constant) {
|
||||
ConfigurationProperty.Key key = extractKey( constant );
|
||||
if ( !key.matches( ignoreKeys ) ) {
|
||||
properties.put(
|
||||
constant.getEnclosingElement().toString() + "#" + constant.getSimpleName().toString(),
|
||||
new ConfigurationProperty()
|
||||
.javadoc( extractJavadoc( constant ) )
|
||||
.key( key )
|
||||
.sourceClass( constant.getEnclosingElement().toString() )
|
||||
.withModuleName( this.title )
|
||||
.withAnchorPrefix( this.anchor )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private ConfigurationProperty.Key extractKey(VariableElement constant) {
|
||||
return new ConfigurationProperty.Key(
|
||||
Objects.toString( constant.getConstantValue(), "NOT_FOUND#" + constant.getSimpleName() )
|
||||
);
|
||||
}
|
||||
|
||||
private String extractJavadoc(VariableElement constant) {
|
||||
try {
|
||||
Element enclosingClass = constant.getEnclosingElement();
|
||||
Path docs = javadocsLocation.resolve(
|
||||
enclosingClass.toString().replace( ".", File.separator ) + ".html"
|
||||
);
|
||||
|
||||
String packagePath = packageElement( enclosingClass ).getQualifiedName().toString().replace(
|
||||
".", File.separator );
|
||||
|
||||
Document javadoc = Jsoup.parse( docs.toFile() );
|
||||
|
||||
org.jsoup.nodes.Element block = javadoc.selectFirst(
|
||||
"#" + constant.getSimpleName() + " + ul li.blockList" );
|
||||
if ( block != null ) {
|
||||
for ( org.jsoup.nodes.Element link : block.getElementsByTag( "a" ) ) {
|
||||
String href = link.attr( "href" );
|
||||
// only update links if they are not external:
|
||||
if ( !link.hasClass( "external-link" ) ) {
|
||||
if ( href.startsWith( "#" ) ) {
|
||||
href = enclosingClass.getSimpleName().toString() + ".html" + href;
|
||||
}
|
||||
href = javadocsBaseLink + packagePath + "/" + href;
|
||||
}
|
||||
else if ( href.contains( "/build/parents/" ) && href.contains( "/apidocs" ) ) {
|
||||
// means a link was to a class from other module and javadoc plugin generated some external link
|
||||
// that won't work. So we replace it:
|
||||
href = javadocsBaseLink + href.substring( href.indexOf( "/apidocs" ) + "/apidocs".length() );
|
||||
}
|
||||
link.attr( "href", href );
|
||||
}
|
||||
|
||||
org.jsoup.nodes.Element result = new org.jsoup.nodes.Element( "div" );
|
||||
for ( org.jsoup.nodes.Element child : block.children() ) {
|
||||
if ( "h4".equalsIgnoreCase( child.tagName() ) || "pre".equalsIgnoreCase( child.tagName() ) ) {
|
||||
continue;
|
||||
}
|
||||
result.appendChild( child );
|
||||
}
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
else {
|
||||
return elementUtils.getDocComment( constant );
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
messager.printMessage(
|
||||
Diagnostic.Kind.NOTE,
|
||||
"Wasn't able to find rendered javadocs for " + constant + ". Trying to read plain javadoc comment."
|
||||
);
|
||||
return elementUtils.getDocComment( constant );
|
||||
}
|
||||
}
|
||||
|
||||
private PackageElement packageElement(Element element) {
|
||||
Element packageElement = element;
|
||||
while ( !( packageElement instanceof PackageElement ) && packageElement.getEnclosingElement() != null ) {
|
||||
packageElement = packageElement.getEnclosingElement();
|
||||
}
|
||||
|
||||
return packageElement instanceof PackageElement ? (PackageElement) packageElement : null;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,105 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.orm.properties.processor;
|
||||
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.annotation.processing.AbstractProcessor;
|
||||
import javax.annotation.processing.ProcessingEnvironment;
|
||||
import javax.annotation.processing.RoundEnvironment;
|
||||
import javax.annotation.processing.SupportedAnnotationTypes;
|
||||
import javax.annotation.processing.SupportedOptions;
|
||||
import javax.annotation.processing.SupportedSourceVersion;
|
||||
import javax.lang.model.SourceVersion;
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ElementKind;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
|
||||
|
||||
@SupportedAnnotationTypes("*")
|
||||
@SupportedSourceVersion(SourceVersion.RELEASE_8)
|
||||
@SupportedOptions({
|
||||
Configuration.JAVADOC_LINK,
|
||||
Configuration.IGNORE_PATTERN,
|
||||
Configuration.IGNORE_KEY_VALUE_PATTERN,
|
||||
Configuration.MODULE_TITLE,
|
||||
Configuration.MODULE_LINK_ANCHOR
|
||||
})
|
||||
public class ConfigurationPropertyProcessor extends AbstractProcessor {
|
||||
|
||||
private ConfigurationPropertyCollector propertyCollector;
|
||||
private Optional<Pattern> ignore;
|
||||
private final Path javadocFolder;
|
||||
private final ConfigPropertyHolder properties;
|
||||
|
||||
public ConfigurationPropertyProcessor(Path javadocFolder, ConfigPropertyHolder properties) {
|
||||
this.javadocFolder = javadocFolder;
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public synchronized void init(ProcessingEnvironment processingEnv) {
|
||||
super.init( processingEnv );
|
||||
|
||||
String pattern = processingEnv.getOptions().get( Configuration.IGNORE_PATTERN );
|
||||
this.ignore = Optional.ofNullable( pattern ).map( Pattern::compile );
|
||||
String title = processingEnv.getOptions().getOrDefault( Configuration.MODULE_TITLE, "Unknown" );
|
||||
String anchor = processingEnv.getOptions().getOrDefault( Configuration.MODULE_LINK_ANCHOR, "hibernate-orm-" );
|
||||
|
||||
String javadocsBaseLink = processingEnv.getOptions().getOrDefault( Configuration.JAVADOC_LINK, "" );
|
||||
|
||||
String keyPattern = processingEnv.getOptions().getOrDefault( Configuration.IGNORE_KEY_VALUE_PATTERN, ".*\\.$" );
|
||||
Pattern ignoreKeys = Pattern.compile( keyPattern );
|
||||
|
||||
this.propertyCollector = new ConfigurationPropertyCollector(
|
||||
properties,
|
||||
processingEnv,
|
||||
title,
|
||||
anchor,
|
||||
javadocFolder,
|
||||
ignoreKeys,
|
||||
javadocsBaseLink
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
|
||||
Set<? extends Element> rootElements = roundEnv.getRootElements();
|
||||
|
||||
// first let's go through all root elements and see if we can find *Settings classes:
|
||||
for ( Element element : rootElements ) {
|
||||
if ( isSettingsClass( element ) ) {
|
||||
process( propertyCollector, element );
|
||||
}
|
||||
}
|
||||
|
||||
if ( roundEnv.processingOver() ) {
|
||||
beforeExit();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void beforeExit() {
|
||||
// processor won't generate anything another gradle task would create an asciidoc file.
|
||||
}
|
||||
|
||||
private void process(ConfigurationPropertyCollector propertyCollector, Element element) {
|
||||
if ( !ignore.map( p -> p.matcher( element.toString() ).matches() ).orElse( Boolean.FALSE ) ) {
|
||||
propertyCollector.visitType( (TypeElement) element );
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isSettingsClass(Element element) {
|
||||
return ( element.getKind().equals( ElementKind.CLASS ) || element.getKind().equals( ElementKind.INTERFACE ) ) &&
|
||||
element.getSimpleName().toString().endsWith( "Settings" );
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue