Skip to content
This repository has been archived by the owner on Dec 28, 2023. It is now read-only.

Support specifying classpath for additional velocity tool classes #222

Merged
merged 2 commits into from
Jan 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.charset.Charset;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;
import javax.inject.Inject;
import org.apache.avro.Conversion;
Expand All @@ -42,10 +42,8 @@
import org.gradle.api.provider.Property;
import org.gradle.api.provider.Provider;
import org.gradle.api.specs.NotSpec;
import org.gradle.api.tasks.CacheableTask;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.*;
import org.gradle.api.tasks.Optional;
import org.gradle.api.tasks.TaskAction;

/**
* Task to generate Java source files based on Avro protocol files and Avro schema files using {@link Protocol} and
Expand All @@ -54,6 +52,7 @@
@SuppressWarnings("WeakerAccess")
@CacheableTask
public class GenerateAvroJavaTask extends OutputDirTask {
private FileCollection classpath;
private static Set<String> SUPPORTED_EXTENSIONS =
new SetBuilder<String>().add(Constants.PROTOCOL_EXTENSION).add(Constants.SCHEMA_EXTENSION).build();

Expand All @@ -79,6 +78,7 @@ public class GenerateAvroJavaTask extends OutputDirTask {
@Inject
public GenerateAvroJavaTask(ObjectFactory objects) {
super();
this.classpath = GradleCompatibility.createConfigurableFileCollection(getProject());
this.outputCharacterEncoding = objects.property(String.class);
this.stringType = objects.property(String.class).convention(Constants.DEFAULT_STRING_TYPE);
this.fieldVisibility = objects.property(String.class).convention(Constants.DEFAULT_FIELD_VISIBILITY);
Expand All @@ -103,6 +103,19 @@ public GenerateAvroJavaTask(ObjectFactory objects) {
this.resolver = new SchemaResolver(projectLayout, getLogger());
}

public void setClasspath(FileCollection classpath) {
this.classpath = classpath;
}

public void classpath(Object... paths) {
this.classpath.plus(getProject().files(paths));
}

@Classpath
public FileCollection getClasspath() {
return this.classpath;
}

@Optional
@Input
public Property<String> getOutputCharacterEncoding() {
Expand Down Expand Up @@ -340,10 +353,11 @@ private void compile(SpecificCompiler compiler, File sourceFile) throws IOExcept
compiler.setTemplateDir(getTemplateDirectory().get());
}
if (getAdditionalVelocityToolClasses().isPresent()) {
ClassLoader loader = assembleClassLoader();
List<Object> tools = getAdditionalVelocityToolClasses().get().stream()
.map(s -> {
try {
return Class.forName(s);
return Class.forName(s, true, loader);
} catch (ClassNotFoundException e) {
throw new RuntimeException("unable to load velocity tool class " + s, e);
}
Expand Down Expand Up @@ -394,4 +408,17 @@ private void registerLogicalTypes() {
private void registerCustomConversions(SpecificCompiler compiler) {
customConversions.get().forEach(compiler::addCustomConversion);
}

private ClassLoader assembleClassLoader() {
getLogger().debug("Using additional classpath: {}", classpath.getFiles());
List<URL> urls = new LinkedList<>();
for (File file : classpath) {
try {
urls.add(file.toURI().toURL());
} catch (MalformedURLException e) {
getLogger().debug(e.getMessage());
}
}
return new URLClassLoader(urls.toArray(new URL[0]), Thread.currentThread().getContextClassLoader());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
*/
package com.github.davidmc24.gradle.plugin.avro

import com.github.davidmc24.gradle.plugin.avro.test.custom.CommentGenerator
import com.github.davidmc24.gradle.plugin.avro.test.custom.TimestampGenerator

import static org.gradle.testkit.runner.TaskOutcome.SUCCESS

class AvroBasePluginFunctionalSpec extends FunctionalSpec {
Expand Down Expand Up @@ -125,4 +128,50 @@ class AvroBasePluginFunctionalSpec extends FunctionalSpec {
projectFile("build/generated-main-avro-avsc/org/apache/avro/Node.avsc").file
projectFile("build/generated-main-avro-avsc/org/apache/avro/Interop.avsc").file
}

def "supports classpath property for instantiating of velocity tools"() {
given:
copyAvroTools("src/main/java")
def templatesDir = projectFolder("templates")
copyResource("user.avsc", avroDir)
copyResource("record-tools.vm", templatesDir, "record.vm")
applyPlugin("java")
buildFile << """
|avro {
| templateDirectory = "${templatesDir.toString()}/"
| additionalVelocityToolClasses = ['com.github.davidmc24.gradle.plugin.avro.test.custom.TimestampGenerator',
| 'com.github.davidmc24.gradle.plugin.avro.test.custom.CommentGenerator']
|}
|tasks.register("compileTools", JavaCompile) {
| source = sourceSets.main.java
| classpath = sourceSets.main.compileClasspath
| destinationDir = file("build/classes/java/main")
|}
|tasks.register("generateAvro", com.github.davidmc24.gradle.plugin.avro.GenerateAvroJavaTask) {
| dependsOn compileTools
| classpath = files("build/classes/java/main")
| source file("src/main/avro")
| include("**/*.avsc")
| outputDir = file("build/generated-main-avro-java")
|}
|""".stripMargin()

when:
def result = run("generateAvro")

then: "the task succeeds"
result.task(":generateAvro").outcome == SUCCESS
def content = projectFile("build/generated-main-avro-java/example/avro/User.java").text

and: "the velocity tools have been applied"
content.contains(CommentGenerator.CUSTOM_COMMENT)
content.contains(TimestampGenerator.MESSAGE_PREFIX)
}

private void copyAvroTools(String destDir) {
copyFile("src/test/java", destDir,
"com/github/davidmc24/gradle/plugin/avro/test/custom/CommentGenerator.java")
copyFile("src/test/java", destDir,
"com/github/davidmc24/gradle/plugin/avro/test/custom/TimestampGenerator.java")
}
}