Add annotation processor to generate converter for VKey (#566)

This commit is contained in:
Shicong Huang 2020-04-29 17:29:05 -04:00 committed by GitHub
parent d3df6bcb52
commit 0bf8c45102
44 changed files with 695 additions and 51 deletions

View file

@ -295,6 +295,8 @@ dependencies {
testAnnotationProcessor deps['com.google.auto.value:auto-value'] testAnnotationProcessor deps['com.google.auto.value:auto-value']
annotationProcessor deps['com.google.dagger:dagger-compiler'] annotationProcessor deps['com.google.dagger:dagger-compiler']
testAnnotationProcessor deps['com.google.dagger:dagger-compiler'] testAnnotationProcessor deps['com.google.dagger:dagger-compiler']
annotationProcessor project(':processor')
testAnnotationProcessor project(':processor')
testCompile deps['com.google.appengine:appengine-testing'] testCompile deps['com.google.appengine:appengine-testing']
testCompile deps['com.google.guava:guava-testlib'] testCompile deps['com.google.guava:guava-testlib']

View file

@ -12,24 +12,24 @@ com.google.dagger:dagger-producers:2.21
com.google.dagger:dagger-spi:2.21 com.google.dagger:dagger-spi:2.21
com.google.dagger:dagger:2.21 com.google.dagger:dagger:2.21
com.google.errorprone:error_prone_annotation:2.3.3 com.google.errorprone:error_prone_annotation:2.3.3
com.google.errorprone:error_prone_annotations:2.3.3 com.google.errorprone:error_prone_annotations:2.3.4
com.google.errorprone:error_prone_check_api:2.3.3 com.google.errorprone:error_prone_check_api:2.3.3
com.google.errorprone:error_prone_core:2.3.3 com.google.errorprone:error_prone_core:2.3.3
com.google.errorprone:error_prone_type_annotations:2.3.3 com.google.errorprone:error_prone_type_annotations:2.3.3
com.google.errorprone:javac-shaded:9-dev-r4023-3 com.google.errorprone:javac-shaded:9-dev-r4023-3
com.google.googlejavaformat:google-java-format:1.5 com.google.googlejavaformat:google-java-format:1.5
com.google.guava:failureaccess:1.0.1 com.google.guava:failureaccess:1.0.1
com.google.guava:guava:27.0.1-jre com.google.guava:guava:28.2-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.j2objc:j2objc-annotations:1.1 com.google.j2objc:j2objc-annotations:1.3
com.google.protobuf:protobuf-java:3.4.0 com.google.protobuf:protobuf-java:3.4.0
com.googlecode.java-diff-utils:diffutils:1.3.0 com.googlecode.java-diff-utils:diffutils:1.3.0
com.squareup:javapoet:1.11.1 com.squareup:javapoet:1.12.1
javax.annotation:jsr250-api:1.0 javax.annotation:jsr250-api:1.0
javax.inject:javax.inject:1 javax.inject:javax.inject:1
javax.persistence:javax.persistence-api:2.2
org.checkerframework:checker-compat-qual:2.5.3 org.checkerframework:checker-compat-qual:2.5.3
org.checkerframework:checker-qual:2.5.3 org.checkerframework:checker-qual:2.10.0
org.checkerframework:dataflow:2.5.3 org.checkerframework:dataflow:2.5.3
org.checkerframework:javacutil:2.5.3 org.checkerframework:javacutil:2.5.3
org.codehaus.mojo:animal-sniffer-annotations:1.17
org.pcollections:pcollections:2.1.2 org.pcollections:pcollections:2.1.2

View file

@ -12,24 +12,24 @@ com.google.dagger:dagger-producers:2.21
com.google.dagger:dagger-spi:2.21 com.google.dagger:dagger-spi:2.21
com.google.dagger:dagger:2.21 com.google.dagger:dagger:2.21
com.google.errorprone:error_prone_annotation:2.3.3 com.google.errorprone:error_prone_annotation:2.3.3
com.google.errorprone:error_prone_annotations:2.3.3 com.google.errorprone:error_prone_annotations:2.3.4
com.google.errorprone:error_prone_check_api:2.3.3 com.google.errorprone:error_prone_check_api:2.3.3
com.google.errorprone:error_prone_core:2.3.3 com.google.errorprone:error_prone_core:2.3.3
com.google.errorprone:error_prone_type_annotations:2.3.3 com.google.errorprone:error_prone_type_annotations:2.3.3
com.google.errorprone:javac-shaded:9-dev-r4023-3 com.google.errorprone:javac-shaded:9-dev-r4023-3
com.google.googlejavaformat:google-java-format:1.5 com.google.googlejavaformat:google-java-format:1.5
com.google.guava:failureaccess:1.0.1 com.google.guava:failureaccess:1.0.1
com.google.guava:guava:27.0.1-jre com.google.guava:guava:28.2-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.j2objc:j2objc-annotations:1.1 com.google.j2objc:j2objc-annotations:1.3
com.google.protobuf:protobuf-java:3.4.0 com.google.protobuf:protobuf-java:3.4.0
com.googlecode.java-diff-utils:diffutils:1.3.0 com.googlecode.java-diff-utils:diffutils:1.3.0
com.squareup:javapoet:1.11.1 com.squareup:javapoet:1.12.1
javax.annotation:jsr250-api:1.0 javax.annotation:jsr250-api:1.0
javax.inject:javax.inject:1 javax.inject:javax.inject:1
javax.persistence:javax.persistence-api:2.2
org.checkerframework:checker-compat-qual:2.5.3 org.checkerframework:checker-compat-qual:2.5.3
org.checkerframework:checker-qual:2.5.3 org.checkerframework:checker-qual:2.10.0
org.checkerframework:dataflow:2.5.3 org.checkerframework:dataflow:2.5.3
org.checkerframework:javacutil:2.5.3 org.checkerframework:javacutil:2.5.3
org.codehaus.mojo:animal-sniffer-annotations:1.17
org.pcollections:pcollections:2.1.2 org.pcollections:pcollections:2.1.2

View file

@ -135,7 +135,7 @@ public abstract class EppResource extends BackupGroupRoot implements Buildable {
@Transient @Transient
ImmutableSortedMap<DateTime, Key<CommitLogManifest>> revisions = ImmutableSortedMap.of(); ImmutableSortedMap<DateTime, Key<CommitLogManifest>> revisions = ImmutableSortedMap.of();
public final String getRepoId() { public String getRepoId() {
return repoId; return repoId;
} }

View file

@ -77,7 +77,6 @@ import javax.annotation.Nullable;
import javax.persistence.AttributeOverride; import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides; import javax.persistence.AttributeOverrides;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Convert;
import javax.persistence.ElementCollection; import javax.persistence.ElementCollection;
import javax.persistence.Embedded; import javax.persistence.Embedded;
import javax.persistence.JoinTable; import javax.persistence.JoinTable;
@ -147,7 +146,6 @@ public class DomainBase extends EppResource
@Ignore @Ignore
@ElementCollection @ElementCollection
@JoinTable(name = "DomainHost") @JoinTable(name = "DomainHost")
@Convert(converter = HostResource.VKeyHostResourceConverter.class)
Set<VKey<HostResource>> nsHostVKeys; Set<VKey<HostResource>> nsHostVKeys;
/** /**

View file

@ -34,7 +34,7 @@ import google.registry.model.annotations.ReportedOn;
import google.registry.model.domain.DomainBase; import google.registry.model.domain.DomainBase;
import google.registry.model.transfer.TransferData; import google.registry.model.transfer.TransferData;
import google.registry.persistence.VKey; import google.registry.persistence.VKey;
import google.registry.persistence.converter.VKeyConverter; import google.registry.persistence.WithStringVKey;
import java.net.InetAddress; import java.net.InetAddress;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
@ -54,6 +54,7 @@ import org.joda.time.DateTime;
@Entity @Entity
@javax.persistence.Entity @javax.persistence.Entity
@ExternalMessagingName("host") @ExternalMessagingName("host")
@WithStringVKey
public class HostResource extends EppResource implements ForeignKeyedEppResource { public class HostResource extends EppResource implements ForeignKeyedEppResource {
/** /**
@ -212,11 +213,4 @@ public class HostResource extends EppResource implements ForeignKeyedEppResource
return this; return this;
} }
} }
public static class VKeyHostResourceConverter extends VKeyConverter<HostResource> {
@Override
protected Class<HostResource> getAttributeClass() {
return HostResource.class;
}
}
} }

View file

@ -15,6 +15,7 @@
package google.registry.persistence; package google.registry.persistence;
import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Preconditions.checkState;
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
import google.registry.model.ImmutableObject; import google.registry.model.ImmutableObject;
import java.util.Optional; import java.util.Optional;
@ -41,20 +42,31 @@ public class VKey<T> extends ImmutableObject {
this.primaryKey = primaryKey; this.primaryKey = primaryKey;
} }
public static <T> VKey<T> createSql(Class<? extends T> kind, Object primaryKey) { /** Creates a {@link VKey} which only contains the sql primary key. */
return new VKey(kind, null, primaryKey); public static <T> VKey<T> createSql(Class<? extends T> kind, Object sqlKey) {
checkArgumentNotNull(kind, "kind must not be null");
checkArgumentNotNull(sqlKey, "sqlKey must not be null");
return new VKey(kind, null, sqlKey);
} }
/** Creates a {@link VKey} which only contains the ofy primary key. */
public static <T> VKey<T> createOfy( public static <T> VKey<T> createOfy(
Class<? extends T> kind, com.googlecode.objectify.Key<T> ofyKey) { Class<? extends T> kind, com.googlecode.objectify.Key<? extends T> ofyKey) {
checkArgumentNotNull(kind, "kind must not be null");
checkArgumentNotNull(ofyKey, "ofyKey must not be null");
return new VKey(kind, ofyKey, null); return new VKey(kind, ofyKey, null);
} }
/** Creates a {@link VKey} which only contains both sql and ofy primary key. */
public static <T> VKey<T> create( public static <T> VKey<T> create(
Class<? extends T> kind, Object primaryKey, com.googlecode.objectify.Key ofyKey) { Class<? extends T> kind, Object sqlKey, com.googlecode.objectify.Key ofyKey) {
return new VKey(kind, ofyKey, primaryKey); checkArgumentNotNull(kind, "kind must not be null");
checkArgumentNotNull(sqlKey, "sqlKey must not be null");
checkArgumentNotNull(ofyKey, "ofyKey must not be null");
return new VKey(kind, ofyKey, sqlKey);
} }
/** Returns the type of the entity. */
public Class<? extends T> getKind() { public Class<? extends T> getKind() {
return this.kind; return this.kind;
} }

View file

@ -0,0 +1,34 @@
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
//
// 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.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.persistence;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
import javax.persistence.AttributeConverter;
import javax.persistence.Entity;
/**
* Annotation for {@link Entity} which id is long type and needs an {@link AttributeConverter} for
* its VKey.
*/
@Target({ElementType.TYPE})
public @interface WithLongVKey {
/**
* Sets the suffix of the class name for the {@link AttributeConverter} generated by
* LongVKeyProcessor. If not set, the suffix will be the type name of the VKey. Note that the
* class name will be "VKeyConverter_" concatenated with the suffix.
*/
String classNameSuffix() default "";
}

View file

@ -0,0 +1,34 @@
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
//
// 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.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.persistence;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
import javax.persistence.AttributeConverter;
import javax.persistence.Entity;
/**
* Annotation for {@link Entity} which id is string type and needs an {@link AttributeConverter} for
* its VKey.
*/
@Target({ElementType.TYPE})
public @interface WithStringVKey {
/**
* Sets the suffix of the class name for the {@link AttributeConverter} generated by
* StringVKeyProcessor. If not set, the suffix will be the type name of the VKey. Note that the
* class name will be "VKeyConverter_" concatenated with the suffix.
*/
String classNameSuffix() default "";
}

View file

@ -19,16 +19,16 @@ import javax.annotation.Nullable;
import javax.persistence.AttributeConverter; import javax.persistence.AttributeConverter;
/** Converts VKey to a string column. */ /** Converts VKey to a string column. */
public abstract class VKeyConverter<T> implements AttributeConverter<VKey<T>, String> { public abstract class VKeyConverter<T, C> implements AttributeConverter<VKey<? extends T>, C> {
@Override @Override
@Nullable @Nullable
public String convertToDatabaseColumn(@Nullable VKey<T> attribute) { public C convertToDatabaseColumn(@Nullable VKey<? extends T> attribute) {
return attribute == null ? null : (String) attribute.getSqlKey(); return attribute == null ? null : (C) attribute.getSqlKey();
} }
@Override @Override
@Nullable @Nullable
public VKey<T> convertToEntityAttribute(@Nullable String dbData) { public VKey<? extends T> convertToEntityAttribute(@Nullable C dbData) {
return dbData == null ? null : VKey.createSql(getAttributeClass(), dbData); return dbData == null ? null : VKey.createSql(getAttributeClass(), dbData);
} }

View file

@ -48,9 +48,11 @@
<class>google.registry.persistence.converter.StringListConverter</class> <class>google.registry.persistence.converter.StringListConverter</class>
<class>google.registry.persistence.converter.StringSetConverter</class> <class>google.registry.persistence.converter.StringSetConverter</class>
<class>google.registry.persistence.converter.UpdateAutoTimestampConverter</class> <class>google.registry.persistence.converter.UpdateAutoTimestampConverter</class>
<class>google.registry.persistence.converter.VKeyConverter</class>
<class>google.registry.persistence.converter.ZonedDateTimeConverter</class> <class>google.registry.persistence.converter.ZonedDateTimeConverter</class>
<!-- Generated converters for VKey -->
<class>google.registry.model.host.VKeyConverter_HostResource</class>
<!-- TODO(weiminyu): check out application-layer validation. --> <!-- TODO(weiminyu): check out application-layer validation. -->
<validation-mode>NONE</validation-mode> <validation-mode>NONE</validation-mode>
</persistence-unit> </persistence-unit>

View file

@ -37,9 +37,10 @@ public class VKeyTest {
@Test @Test
public void testOptionalAccessors() { public void testOptionalAccessors() {
VKey<TestObject> key = VKey.create(TestObject.class, null, null); VKey<TestObject> key =
assertThat(key.maybeGetSqlKey().isPresent()).isFalse(); VKey.create(TestObject.class, "foo", Key.create(TestObject.create("foo")));
assertThat(key.maybeGetOfyKey().isPresent()).isFalse(); assertThat(key.maybeGetSqlKey().isPresent()).isTrue();
assertThat(key.maybeGetOfyKey().isPresent()).isTrue();
Key<TestObject> ofyKey = Key.create(TestObject.create("foo")); Key<TestObject> ofyKey = Key.create(TestObject.create("foo"));
assertThat(VKey.createOfy(TestObject.class, ofyKey).maybeGetOfyKey().get()).isEqualTo(ofyKey); assertThat(VKey.createOfy(TestObject.class, ofyKey).maybeGetOfyKey().get()).isEqualTo(ofyKey);

View file

@ -0,0 +1,65 @@
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
//
// 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.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.persistence.converter;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
import google.registry.persistence.VKey;
import google.registry.persistence.WithLongVKey;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestRule;
import javax.persistence.Entity;
import javax.persistence.Id;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/** Test SQL persistence of VKey. */
@RunWith(JUnit4.class)
public class LongVKeyConverterTest {
@Rule
public final JpaUnitTestRule jpaRule =
new JpaTestRules.Builder()
.withEntityClass(TestEntity.class, VKeyConverter_LongType.class)
.buildUnitTestRule();
@Test
public void testRoundTrip() {
TestEntity original = new TestEntity(VKey.createSql(TestEntity.class, 10L));
jpaTm().transact(() -> jpaTm().getEntityManager().persist(original));
TestEntity retrieved =
jpaTm().transact(() -> jpaTm().getEntityManager().find(TestEntity.class, "id"));
assertThat(retrieved.number.getSqlKey()).isEqualTo(10L);
}
@Entity(name = "TestEntity")
@WithLongVKey(classNameSuffix = "LongType")
static class TestEntity {
@Id String id = "id";
VKey<TestEntity> number;
TestEntity(VKey<TestEntity> number) {
this.number = number;
}
/** Default constructor, needed for hibernate. */
public TestEntity() {}
}
}

View file

@ -18,9 +18,9 @@ import static com.google.common.truth.Truth.assertThat;
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm; import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
import google.registry.persistence.VKey; import google.registry.persistence.VKey;
import google.registry.persistence.WithStringVKey;
import google.registry.persistence.transaction.JpaTestRules; import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestRule; import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestRule;
import javax.persistence.Convert;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.Id; import javax.persistence.Id;
import org.junit.Rule; import org.junit.Rule;
@ -30,13 +30,15 @@ import org.junit.runners.JUnit4;
/** Test SQL persistence of VKey. */ /** Test SQL persistence of VKey. */
@RunWith(JUnit4.class) @RunWith(JUnit4.class)
public class VKeyConverterTest { public class StringVKeyConverterTest {
@Rule @Rule
public final JpaUnitTestRule jpaRule = public final JpaUnitTestRule jpaRule =
new JpaTestRules.Builder().withEntityClass(TestEntity.class).buildUnitTestRule(); new JpaTestRules.Builder()
.withEntityClass(TestEntity.class, VKeyConverter_StringType.class)
.buildUnitTestRule();
public VKeyConverterTest() {} public StringVKeyConverterTest() {}
@Test @Test
public void testRoundTrip() { public void testRoundTrip() {
@ -50,21 +52,11 @@ public class VKeyConverterTest {
assertThat(retrieved.other.getSqlKey()).isEqualTo("ImSpartacus!"); assertThat(retrieved.other.getSqlKey()).isEqualTo("ImSpartacus!");
} }
static class TestEntityVKeyConverter extends VKeyConverter<TestEntity> {
@Override
protected Class<TestEntity> getAttributeClass() {
return TestEntity.class;
}
}
@Entity(name = "TestEntity") @Entity(name = "TestEntity")
@WithStringVKey(classNameSuffix = "StringType")
static class TestEntity { static class TestEntity {
@Id String id; @Id String id;
// Specifying "@Converter(autoApply = true) on TestEntityVKeyConverter this doesn't seem to
// work.
@Convert(converter = TestEntityVKeyConverter.class)
VKey<TestEntity> other; VKey<TestEntity> other;
TestEntity(String id, VKey<TestEntity> other) { TestEntity(String id, VKey<TestEntity> other) {

View file

@ -78,6 +78,7 @@ ext {
'com.googlecode.json-simple:json-simple:1.1.1', 'com.googlecode.json-simple:json-simple:1.1.1',
'com.ibm.icu:icu4j:57.1', 'com.ibm.icu:icu4j:57.1',
'com.jcraft:jsch:0.1.55', 'com.jcraft:jsch:0.1.55',
'com.squareup:javapoet:1.12.1',
'com.sun.activation:javax.activation:1.2.0', 'com.sun.activation:javax.activation:1.2.0',
'com.sun.xml.bind:jaxb-impl:2.2.11', 'com.sun.xml.bind:jaxb-impl:2.2.11',
'com.sun.xml.bind:jaxb-osgi:2.2.11', 'com.sun.xml.bind:jaxb-osgi:2.2.11',

25
processor/build.gradle Normal file
View file

@ -0,0 +1,25 @@
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
//
// 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.
// See the License for the specific language governing permissions and
// limitations under the License.
plugins {
id 'java-library'
}
dependencies {
def deps = rootProject.dependencyMap
compile deps['com.google.code.findbugs:jsr305']
compile deps['com.google.guava:guava']
compile deps['com.squareup:javapoet']
compile deps['javax.persistence:javax.persistence-api']
}

View file

@ -0,0 +1,24 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.github.kevinstern:software-and-algorithms:1.0
com.github.stephenc.jcip:jcip-annotations:1.0-1
com.google.auto:auto-common:0.10
com.google.code.findbugs:jFormatString:3.0.0
com.google.code.findbugs:jsr305:3.0.2
com.google.errorprone:error_prone_annotation:2.3.3
com.google.errorprone:error_prone_annotations:2.3.3
com.google.errorprone:error_prone_check_api:2.3.3
com.google.errorprone:error_prone_core:2.3.3
com.google.errorprone:error_prone_type_annotations:2.3.3
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:27.0.1-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.j2objc:j2objc-annotations:1.1
com.google.protobuf:protobuf-java:3.4.0
com.googlecode.java-diff-utils:diffutils:1.3.0
org.checkerframework:checker-qual:2.5.3
org.checkerframework:dataflow:2.5.3
org.checkerframework:javacutil:2.5.3
org.codehaus.mojo:animal-sniffer-annotations:1.17
org.pcollections:pcollections:2.1.2

View file

@ -0,0 +1,3 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.

View file

@ -0,0 +1,3 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.

View file

@ -0,0 +1,3 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.

View file

@ -0,0 +1,18 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
antlr:antlr:2.7.7
com.google.code.findbugs:jsr305:3.0.2
com.google.errorprone:error_prone_annotations:2.3.2
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:28.1-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.j2objc:j2objc-annotations:1.3
com.puppycrawl.tools:checkstyle:8.27
commons-beanutils:commons-beanutils:1.9.4
commons-collections:commons-collections:3.2.2
info.picocli:picocli:4.1.1
net.sf.saxon:Saxon-HE:9.9.1-5
org.antlr:antlr4-runtime:4.7.2
org.checkerframework:checker-qual:2.8.1
org.codehaus.mojo:animal-sniffer-annotations:1.18

View file

@ -0,0 +1,12 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.google.code.findbugs:jsr305:3.0.2
com.google.errorprone:error_prone_annotations:2.3.4
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:28.2-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.j2objc:j2objc-annotations:1.3
com.squareup:javapoet:1.12.1
javax.persistence:javax.persistence-api:2.2
org.checkerframework:checker-qual:2.10.0

View file

@ -0,0 +1,12 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.google.code.findbugs:jsr305:3.0.2
com.google.errorprone:error_prone_annotations:2.3.4
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:28.2-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.j2objc:j2objc-annotations:1.3
com.squareup:javapoet:1.12.1
javax.persistence:javax.persistence-api:2.2
org.checkerframework:checker-qual:2.10.0

View file

@ -0,0 +1,3 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.

View file

@ -0,0 +1,12 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.google.code.findbugs:jsr305:3.0.2
com.google.errorprone:error_prone_annotations:2.3.4
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:28.2-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.j2objc:j2objc-annotations:1.3
com.squareup:javapoet:1.12.1
javax.persistence:javax.persistence-api:2.2
org.checkerframework:checker-qual:2.10.0

View file

@ -0,0 +1,12 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.google.code.findbugs:jsr305:3.0.2
com.google.errorprone:error_prone_annotations:2.3.4
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:28.2-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.j2objc:j2objc-annotations:1.3
com.squareup:javapoet:1.12.1
javax.persistence:javax.persistence-api:2.2
org.checkerframework:checker-qual:2.10.0

View file

@ -0,0 +1,24 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.github.kevinstern:software-and-algorithms:1.0
com.github.stephenc.jcip:jcip-annotations:1.0-1
com.google.auto:auto-common:0.10
com.google.code.findbugs:jFormatString:3.0.0
com.google.code.findbugs:jsr305:3.0.2
com.google.errorprone:error_prone_annotation:2.3.3
com.google.errorprone:error_prone_annotations:2.3.3
com.google.errorprone:error_prone_check_api:2.3.3
com.google.errorprone:error_prone_core:2.3.3
com.google.errorprone:error_prone_type_annotations:2.3.3
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:27.0.1-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.j2objc:j2objc-annotations:1.1
com.google.protobuf:protobuf-java:3.4.0
com.googlecode.java-diff-utils:diffutils:1.3.0
org.checkerframework:checker-qual:2.5.3
org.checkerframework:dataflow:2.5.3
org.checkerframework:javacutil:2.5.3
org.codehaus.mojo:animal-sniffer-annotations:1.17
org.pcollections:pcollections:2.1.2

View file

@ -0,0 +1,4 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.google.errorprone:javac:9+181-r4173-1

View file

@ -0,0 +1,4 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
org.jacoco:org.jacoco.agent:0.8.5

View file

@ -0,0 +1,11 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
org.jacoco:org.jacoco.agent:0.8.5
org.jacoco:org.jacoco.ant:0.8.5
org.jacoco:org.jacoco.core:0.8.5
org.jacoco:org.jacoco.report:0.8.5
org.ow2.asm:asm-analysis:7.2
org.ow2.asm:asm-commons:7.2
org.ow2.asm:asm-tree:7.2
org.ow2.asm:asm:7.2

View file

@ -0,0 +1,12 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.google.code.findbugs:jsr305:3.0.2
com.google.errorprone:error_prone_annotations:2.3.4
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:28.2-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.j2objc:j2objc-annotations:1.3
com.squareup:javapoet:1.12.1
javax.persistence:javax.persistence-api:2.2
org.checkerframework:checker-qual:2.10.0

View file

@ -0,0 +1,12 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.google.code.findbugs:jsr305:3.0.2
com.google.errorprone:error_prone_annotations:2.3.4
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:28.2-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.j2objc:j2objc-annotations:1.3
com.squareup:javapoet:1.12.1
javax.persistence:javax.persistence-api:2.2
org.checkerframework:checker-qual:2.10.0

View file

@ -0,0 +1,24 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.github.kevinstern:software-and-algorithms:1.0
com.github.stephenc.jcip:jcip-annotations:1.0-1
com.google.auto:auto-common:0.10
com.google.code.findbugs:jFormatString:3.0.0
com.google.code.findbugs:jsr305:3.0.2
com.google.errorprone:error_prone_annotation:2.3.3
com.google.errorprone:error_prone_annotations:2.3.3
com.google.errorprone:error_prone_check_api:2.3.3
com.google.errorprone:error_prone_core:2.3.3
com.google.errorprone:error_prone_type_annotations:2.3.3
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:27.0.1-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.j2objc:j2objc-annotations:1.1
com.google.protobuf:protobuf-java:3.4.0
com.googlecode.java-diff-utils:diffutils:1.3.0
org.checkerframework:checker-qual:2.5.3
org.checkerframework:dataflow:2.5.3
org.checkerframework:javacutil:2.5.3
org.codehaus.mojo:animal-sniffer-annotations:1.17
org.pcollections:pcollections:2.1.2

View file

@ -0,0 +1,3 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.

View file

@ -0,0 +1,12 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.google.code.findbugs:jsr305:3.0.2
com.google.errorprone:error_prone_annotations:2.3.4
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:28.2-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.j2objc:j2objc-annotations:1.3
com.squareup:javapoet:1.12.1
javax.persistence:javax.persistence-api:2.2
org.checkerframework:checker-qual:2.10.0

View file

@ -0,0 +1,12 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.google.code.findbugs:jsr305:3.0.2
com.google.errorprone:error_prone_annotations:2.3.4
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:28.2-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.j2objc:j2objc-annotations:1.3
com.squareup:javapoet:1.12.1
javax.persistence:javax.persistence-api:2.2
org.checkerframework:checker-qual:2.10.0

View file

@ -0,0 +1,3 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.

View file

@ -0,0 +1,12 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.google.code.findbugs:jsr305:3.0.2
com.google.errorprone:error_prone_annotations:2.3.4
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:28.2-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.j2objc:j2objc-annotations:1.3
com.squareup:javapoet:1.12.1
javax.persistence:javax.persistence-api:2.2
org.checkerframework:checker-qual:2.10.0

View file

@ -0,0 +1,12 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.google.code.findbugs:jsr305:3.0.2
com.google.errorprone:error_prone_annotations:2.3.4
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:28.2-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.j2objc:j2objc-annotations:1.3
com.squareup:javapoet:1.12.1
javax.persistence:javax.persistence-api:2.2
org.checkerframework:checker-qual:2.10.0

View file

@ -0,0 +1,160 @@
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
//
// 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.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.processors;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.collect.ImmutableList.toImmutableList;
import com.squareup.javapoet.AnnotationSpec;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.ParameterizedTypeName;
import com.squareup.javapoet.TypeName;
import com.squareup.javapoet.TypeSpec;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.List;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.ElementFilter;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
/** Abstract processor to generate {@link AttributeConverter} for VKey type. */
public abstract class AbstractVKeyProcessor extends AbstractProcessor {
private static final String CONVERTER_CLASS_NAME_TEMP = "VKeyConverter_%s";
// The method with same name should be defined in StringVKey and LongVKey
private static final String CLASS_NAME_SUFFIX_KEY = "classNameSuffix";
abstract Class<?> getSqlColumnType();
abstract String getAnnotationSimpleName();
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
annotations.forEach(
vKeyAnnotationType -> {
ElementFilter.typesIn(roundEnv.getElementsAnnotatedWith(vKeyAnnotationType))
.forEach(
annotatedTypeElement -> {
DeclaredType entityType = getDeclaredType(annotatedTypeElement);
List<AnnotationMirror> actualAnnotation =
annotatedTypeElement.getAnnotationMirrors().stream()
.filter(
annotationType ->
annotationType
.getAnnotationType()
.asElement()
.equals(vKeyAnnotationType))
.collect(toImmutableList());
checkState(
actualAnnotation.size() == 1,
String.format(
"type can have only 1 %s annotation", getAnnotationSimpleName()));
String converterClassNameSuffix =
actualAnnotation.get(0).getElementValues().entrySet().stream()
.filter(
entry ->
entry
.getKey()
.getSimpleName()
.toString()
.equals(CLASS_NAME_SUFFIX_KEY))
.map(entry -> ((String) entry.getValue().getValue()).trim())
.findFirst()
.orElse("");
if (converterClassNameSuffix.isEmpty()) {
converterClassNameSuffix =
getTypeUtils().asElement(entityType).getSimpleName().toString();
}
try {
createJavaFile(
getPackageName(annotatedTypeElement),
String.format(CONVERTER_CLASS_NAME_TEMP, converterClassNameSuffix),
entityType)
.writeTo(processingEnv.getFiler());
} catch (IOException e) {
throw new UncheckedIOException(e);
}
});
});
return false;
}
private JavaFile createJavaFile(
String packageName, String converterClassName, TypeMirror entityTypeMirror) {
TypeName entityType = ClassName.get(entityTypeMirror);
ParameterizedTypeName attributeConverter =
ParameterizedTypeName.get(
ClassName.get("google.registry.persistence.converter", "VKeyConverter"),
entityType,
ClassName.get(getSqlColumnType()));
MethodSpec getAttributeClass =
MethodSpec.methodBuilder("getAttributeClass")
.addAnnotation(Override.class)
.addModifiers(Modifier.PROTECTED)
.returns(
ParameterizedTypeName.get(
ClassName.get(Class.class), ClassName.get(entityTypeMirror)))
.addStatement("return $T.class", entityType)
.build();
TypeSpec vKeyConverter =
TypeSpec.classBuilder(converterClassName)
.addAnnotation(
AnnotationSpec.builder(ClassName.get(Converter.class))
.addMember("autoApply", "true")
.build())
.addModifiers(Modifier.FINAL)
.superclass(attributeConverter)
.addMethod(getAttributeClass)
.build();
return JavaFile.builder(packageName, vKeyConverter).build();
}
private DeclaredType getDeclaredType(Element element) {
checkState(element.asType().getKind() == TypeKind.DECLARED, "element is not a DeclaredType");
return (DeclaredType) element.asType();
}
private String getPackageName(Element element) {
return getElementUtils().getPackageOf(element).getQualifiedName().toString();
}
private Elements getElementUtils() {
return processingEnv.getElementUtils();
}
private Types getTypeUtils() {
return processingEnv.getTypeUtils();
}
}

View file

@ -0,0 +1,37 @@
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
//
// 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.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.processors;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
/** Annotation processor for entity that is annotated with WithLongVKey. */
@SupportedAnnotationTypes("google.registry.persistence.WithLongVKey")
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class LongVKeyProcessor extends AbstractVKeyProcessor {
private static final String ANNOTATION_SIMPLE_NAME = "WithStringVKey";
@Override
Class<?> getSqlColumnType() {
return Long.class;
}
@Override
String getAnnotationSimpleName() {
return ANNOTATION_SIMPLE_NAME;
}
}

View file

@ -0,0 +1,37 @@
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
//
// 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.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.processors;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
/** Annotation processor for entity that is annotated with WithStringVKey. */
@SupportedAnnotationTypes("google.registry.persistence.WithStringVKey")
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class StringVKeyProcessor extends AbstractVKeyProcessor {
private static final String ANNOTATION_SIMPLE_NAME = "WithStringVKey";
@Override
Class<?> getSqlColumnType() {
return String.class;
}
@Override
String getAnnotationSimpleName() {
return ANNOTATION_SIMPLE_NAME;
}
}

View file

@ -0,0 +1,2 @@
google.registry.processors.StringVKeyProcessor
google.registry.processors.LongVKeyProcessor

View file

@ -32,6 +32,7 @@ include 'core'
include 'db' include 'db'
include 'integration' include 'integration'
include 'networking' include 'networking'
include 'processor'
include 'prober' include 'prober'
include 'proxy' include 'proxy'
include 'util' include 'util'