Skip to content

Commit

Permalink
working ksp round trip
Browse files Browse the repository at this point in the history
  • Loading branch information
evanchooly committed Jun 4, 2024
1 parent adc104c commit 899844c
Show file tree
Hide file tree
Showing 26 changed files with 759 additions and 101 deletions.
95 changes: 79 additions & 16 deletions build-plugins/src/main/java/util/AnnotationBuilders.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.StringJoiner;
import java.util.TreeMap;
import java.util.stream.Collectors;

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
Expand All @@ -32,12 +35,22 @@

@Mojo(name = "morphia-annotations", defaultPhase = LifecyclePhase.GENERATE_SOURCES)
public class AnnotationBuilders extends AbstractMojo {

private Map<String, JavaClassSource> builders = new TreeMap<>();

private MethodSource<JavaClassSource> factoryMethod;

@Parameter(defaultValue = "${project}", required = true, readonly = true)
private MavenProject project;

private JavaClassSource factory;

private JavaClassSource builder;

private JavaAnnotationSource source;

private File generated;

private final FileFilter filter = pathname -> pathname.getName().endsWith(".java")
&& !pathname.getName().endsWith("Handler.java")
&& !pathname.getName().endsWith("Helper.java")
Expand All @@ -52,15 +65,53 @@ public void execute() throws MojoExecutionException {
files.addAll(find(project.getBasedir() + "/src/main/java/dev/morphia/annotations"));
project.addCompileSourceRoot(generated.getAbsolutePath());

for (File file : files) {
try {
emitBuilder(file);
} catch (ParserException e) {
throw new MojoExecutionException("Could not parse " + file, e);
} catch (IOException e) {
throw new MojoExecutionException(e.getMessage(), e);
try {
for (File file : files) {
try {
emitBuilder(file);
} catch (ParserException e) {
throw new MojoExecutionException("Could not parse " + file, e);
}
}
emitFactory();
} catch (IOException e) {
throw new MojoExecutionException(e.getMessage(), e);
}
}

private void emitFactory() throws IOException {
if (factory == null) {
factory = createClass("AnnotationFactory");

factoryMethod = factory.addMethod()
.setReturnType("K")
.setPublic()
.setStatic(true);
factoryMethod
.setName("build")
.addParameter("Class<K>", "kind");

factoryMethod.addTypeVariable()
.setName("K");
var code = builders.entrySet().stream()
.map(entry -> {
JavaClassSource builder = entry.getValue();
return "if (kind.equals(%s.class)) return (K)%s.%s().build();".formatted(entry.getKey(), builder.getQualifiedName(),
methodCase(builder.getName()));
})
.collect(Collectors.joining("\n"));
code += "\nthrow new UnsupportedOperationException(kind.getName());";
factoryMethod.setBody(code);
}

var outputFile = new File(generated, factory.getQualifiedName().replace('.', '/') + ".java");
if (!outputFile.getParentFile().mkdirs() && !outputFile.getParentFile().exists()) {
throw new IOException(format("Could not create directory: %s", outputFile.getParentFile()));
}
try (var writer = new FileWriter(outputFile)) {
writer.write(factory.toString());
}

}

private JavaClassSource annotationType(JavaAnnotationSource source, JavaClassSource builder) {
Expand Down Expand Up @@ -112,15 +163,8 @@ private void copyBuilder(JavaAnnotationSource source, List<AnnotationElementSour
private void emitBuilder(File sourceFile) throws IOException {
source = Roaster.parse(JavaAnnotationSource.class, sourceFile);
if (source.isPublic()) {
builder = Roaster.create(JavaClassSource.class)
.setName(source.getName() + "Builder")
.setPackage(source.getPackage() + ".internal")
.setFinal(true);
builder.addAnnotation("dev.morphia.annotations.internal.MorphiaInternal");
JavaDocSource<JavaClassSource> javaDoc = builder.getJavaDoc();
javaDoc.addTagValue("@since", "2.3");
javaDoc.addTagValue("@hidden", "");
javaDoc.addTagValue("@morphia.internal", "");
builder = createClass(source.getName() + "Builder");
builders.put(source.getQualifiedName(), builder);

MethodSource<JavaClassSource> constructor = builder.addMethod()
.setConstructor(true)
Expand Down Expand Up @@ -185,6 +229,20 @@ private void emitBuilder(File sourceFile) throws IOException {
}
}

private JavaClassSource createClass(String name) {
var classBuilder = Roaster.create(JavaClassSource.class)
.setName(name)
.setPackage(source.getPackage() + ".internal")
.setFinal(true);
classBuilder.addAnnotation("dev.morphia.annotations.internal.MorphiaInternal");
JavaDocSource<JavaClassSource> javaDoc = classBuilder.getJavaDoc();
javaDoc.addTagValue("@since", "2.3");
javaDoc.addTagValue("@hidden", "");
javaDoc.addTagValue("@morphia.internal", "");

return classBuilder;
}

private String parameterType(AnnotationElementSource element) {
return element.getType().toString();
}
Expand Down Expand Up @@ -270,4 +328,9 @@ private void setDefaults(MethodSource<JavaClassSource> constructor, JavaAnnotati
constructor.setBody(body);

}

String methodCase(String name) {
return name.substring(0, 1).toLowerCase() + name.substring(1);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
*/
@MorphiaInternal
@SuppressWarnings("removal")
public final class PropertyModel {
public class PropertyModel {
private boolean isFinal;

private String name;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package dev.morphia.mapping.codec.pojo.critter;

import dev.morphia.annotations.Entity;
import dev.morphia.mapping.Mapper;
import dev.morphia.mapping.codec.pojo.EntityModel;

public abstract class CritterEntityModel extends EntityModel {
private Entity entityAnnotation;

public CritterEntityModel(Mapper mapper, Class<?> type) {
super(mapper, type);
}

@Override
public Entity getEntityAnnotation() {
if (entityAnnotation == null) {
entityAnnotation = entityAnnotation();
}
return entityAnnotation;
}

protected abstract Entity entityAnnotation();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package dev.morphia.mapping.codec.pojo.critter;

import java.lang.annotation.Annotation;
import java.util.List;

import dev.morphia.mapping.codec.pojo.EntityModel;
import dev.morphia.mapping.codec.pojo.PropertyModel;
import dev.morphia.mapping.codec.pojo.TypeData;

import org.bson.codecs.pojo.PropertyAccessor;
import org.bson.codecs.pojo.PropertySerialization;

public abstract class CritterPropertyModel extends PropertyModel {
public CritterPropertyModel(EntityModel entityModel) {
super(entityModel);
}

@Override
public abstract PropertyAccessor<Object> getAccessor();

@Override
public abstract <A extends Annotation> A getAnnotation(Class<A> type);

@Override
public abstract List<Annotation> getAnnotations();

@Override
public abstract boolean isFinal();

@Override
public abstract String getFullName();

@Override
public abstract List<String> getLoadNames();

@Override
public abstract String getMappedName();

@Override
public abstract String getName();

@Override
public abstract Class<?> getNormalizedType();

@Override
public abstract Class<?> getType();

@Override
public abstract TypeData<?> getTypeData();

@Override
public abstract boolean isArray();

@Override
public abstract boolean isMap();

@Override
public abstract boolean isMultipleValues();

@Override
public abstract boolean isReference();

@Override
public abstract boolean isScalarValue();

@Override
public abstract boolean isSet();

@Override
public abstract boolean isTransient();

@Override
public abstract PropertyModel serialization(PropertySerialization serialization);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package dev.morphia.mapping.conventions;

import dev.morphia.mapping.Mapper;

public interface MappingConvention<M> {
/**
* This method applies this Convention to the given builder
*
* @param mapper the mapper to use
* @param model the model to apply the convention to
*/
void apply(Mapper mapper, M model);
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,9 @@
package dev.morphia.mapping.conventions;

import dev.morphia.mapping.Mapper;
import dev.morphia.mapping.codec.pojo.EntityModel;

/**
* Applies certain conventions specific for Morphia
*/
public interface MorphiaConvention {
/**
* This method applies this Convention to the given builder
*
* @param mapper
* @param builder the builder to apply the convention to
*/
void apply(Mapper mapper, EntityModel builder);
public interface MorphiaConvention extends MappingConvention<EntityModel> {
}
50 changes: 32 additions & 18 deletions critter/core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,9 @@
<relativePath>../pom.xml</relativePath>
</parent>

<artifactId>core</artifactId>
<artifactId>critter-core</artifactId>

<properties>
<kotlin.version>1.9.24</kotlin.version>
<roaster.version>2.29.0.Final</roaster.version>
</properties>

Expand All @@ -28,35 +27,50 @@
<artifactId>jdk-classfile-preview</artifactId>
<version>23.beta1</version>
</dependency>
<dependency>
<groupId>io.quarkus.gizmo</groupId>
<artifactId>gizmo</artifactId>
<version>1.8.0</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-reflect</artifactId>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
</dependency>
<dependency>
<groupId>com.google.devtools.ksp</groupId>
<artifactId>symbol-processing-api</artifactId>
<version>2.0.0-1.0.21</version>
</dependency>
<dependency>
<groupId>com.google.devtools.ksp</groupId>
<artifactId>symbol-processing-common-deps</artifactId>
<version>2.0.0-1.0.21</version>
</dependency>
<dependency>
<groupId>com.google.devtools.ksp</groupId>
<artifactId>symbol-processing-aa-embeddable</artifactId>
<version>2.0.0-1.0.21</version>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.5.0</version>
<executions>
<execution>
<id>test-sources</id>
<goals>
<goal>add-test-source</goal>
</goals>
<configuration>
<sources>
<source>src/test/resources/sources</source>
</sources>
</configuration>
</execution>
</executions>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration>
<!-- Need to disable default annotation processing since apt-maven-plugin takes over -->
<compilerArgument>-proc:none</compilerArgument>
</configuration>
</plugin>
</plugins>
</build>
Expand Down
Loading

0 comments on commit 899844c

Please sign in to comment.