Extract CLASS_REGISTRY from VKeyTranslatorFactory (#1440)

* Add annotation for unit test file

* Extract CLASS_REGISTRY from VKeyTranslatorFactory

* Improve test cases and docs
This commit is contained in:
Rachel Guan
2021-12-06 16:41:17 -05:00
committed by GitHub
parent f23d2ca315
commit ecc3d9f75d
6 changed files with 249 additions and 26 deletions
@@ -0,0 +1,63 @@
// Copyright 2021 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.model.common;
import static com.google.common.base.Functions.identity;
import static com.google.common.base.Preconditions.checkArgument;
import static google.registry.model.EntityClasses.ALL_CLASSES;
import com.google.common.annotations.VisibleForTesting;
import com.googlecode.objectify.annotation.EntitySubclass;
import java.util.Map;
import java.util.stream.Collectors;
/** A helper to manage class name and class path mapping. */
public class ClassPathManager {
/**
* Class registry allowing us to restore the original class object from the unqualified class
* name, which is all the datastore key gives us. Note that entities annotated
* with @EntitySubclass are removed because they share the same kind of the key with their parent
* class.
*/
public static final Map<String, Class<?>> CLASS_REGISTRY =
ALL_CLASSES.stream()
.filter(clazz -> !clazz.isAnnotationPresent(EntitySubclass.class))
.collect(Collectors.toMap(com.googlecode.objectify.Key::getKind, identity()));
/**
* Class name registry allowing us to obtain the class name the unqualified class, which is all
* the datastore key gives us. Note that entities annotated with @EntitySubclass are removed
* because they share the same kind of the key with their parent class.
*/
public static final Map<Class<?>, String> CLASS_NAME_REGISTRY =
ALL_CLASSES.stream()
.filter(clazz -> !clazz.isAnnotationPresent(EntitySubclass.class))
.collect(Collectors.toMap(identity(), com.googlecode.objectify.Key::getKind));
@VisibleForTesting
public static void addTestEntityClass(Class<?> clazz) {
CLASS_REGISTRY.put(com.googlecode.objectify.Key.getKind(clazz), clazz);
}
public static <T> Class<T> getClass(String className) {
checkArgument(CLASS_REGISTRY.containsKey(className), "Class not found in class registry");
return (Class<T>) CLASS_REGISTRY.get(className);
}
public static <T> String getClassName(Class<T> clazz) {
checkArgument(CLASS_NAME_REGISTRY.containsKey(clazz), "Class not found in class name registry");
return CLASS_NAME_REGISTRY.get(clazz);
}
}
@@ -14,18 +14,13 @@
package google.registry.model.translators;
import static com.google.common.base.Functions.identity;
import static com.google.common.base.Preconditions.checkArgument;
import static google.registry.model.EntityClasses.ALL_CLASSES;
import com.google.appengine.api.datastore.Key;
import com.google.common.annotations.VisibleForTesting;
import com.googlecode.objectify.annotation.EntitySubclass;
import google.registry.model.common.ClassPathManager;
import google.registry.persistence.VKey;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
/**
@@ -36,15 +31,6 @@ import javax.annotation.Nullable;
*/
public class VKeyTranslatorFactory extends AbstractSimpleTranslatorFactory<VKey, Key> {
// Class registry allowing us to restore the original class object from the unqualified class
// name, which is all the datastore key gives us.
// Note that entities annotated with @EntitySubclass are removed because they share the same
// kind of the key with their parent class.
private static final Map<String, Class<?>> CLASS_REGISTRY =
ALL_CLASSES.stream()
.filter(clazz -> !clazz.isAnnotationPresent(EntitySubclass.class))
.collect(Collectors.toMap(com.googlecode.objectify.Key::getKind, identity()));
public VKeyTranslatorFactory() {
super(VKey.class);
}
@@ -67,7 +53,7 @@ public class VKeyTranslatorFactory extends AbstractSimpleTranslatorFactory<VKey,
}
// Try to create the VKey from its reference type.
Class<T> clazz = (Class<T>) CLASS_REGISTRY.get(key.getKind());
Class<T> clazz = ClassPathManager.getClass(key.getKind());
checkArgument(clazz != null, "Unknown Key type: %s", key.getKind());
try {
Method createVKeyMethod =
@@ -92,11 +78,6 @@ public class VKeyTranslatorFactory extends AbstractSimpleTranslatorFactory<VKey,
}
}
@VisibleForTesting
public static void addTestEntityClass(Class<?> clazz) {
CLASS_REGISTRY.put(com.googlecode.objectify.Key.getKind(clazz), clazz);
}
@Override
public SimpleTranslator<VKey, Key> createTranslator() {
return new SimpleTranslator<VKey, Key>() {