annotate Registry methods with nullability and contract

This commit is contained in:
dfsek
2021-12-01 10:15:02 -07:00
parent 2d7cf5151f
commit 7a665d6f9c
7 changed files with 75 additions and 36 deletions
@@ -9,6 +9,8 @@ package com.dfsek.terra.api.registry;
import com.dfsek.terra.api.registry.exception.DuplicateEntryException; import com.dfsek.terra.api.registry.exception.DuplicateEntryException;
import org.jetbrains.annotations.NotNull;
public interface CheckedRegistry<T> extends Registry<T> { public interface CheckedRegistry<T> extends Registry<T> {
/** /**
@@ -19,6 +21,5 @@ public interface CheckedRegistry<T> extends Registry<T> {
* *
* @throws DuplicateEntryException If an entry with the same identifier is already present. * @throws DuplicateEntryException If an entry with the same identifier is already present.
*/ */
void register(String identifier, T value) throws DuplicateEntryException; void register(@NotNull String identifier, @NotNull T value) throws DuplicateEntryException;
} }
@@ -9,6 +9,8 @@ package com.dfsek.terra.api.registry;
import com.dfsek.terra.api.registry.exception.DuplicateEntryException; import com.dfsek.terra.api.registry.exception.DuplicateEntryException;
import org.jetbrains.annotations.NotNull;
public interface OpenRegistry<T> extends Registry<T> { public interface OpenRegistry<T> extends Registry<T> {
/** /**
@@ -17,7 +19,7 @@ public interface OpenRegistry<T> extends Registry<T> {
* @param identifier Identifier to assign value. * @param identifier Identifier to assign value.
* @param value Value to register. * @param value Value to register.
*/ */
boolean register(String identifier, T value); boolean register(@NotNull String identifier, @NotNull T value);
/** /**
* Add a value to this registry, checking whether it is present first. * Add a value to this registry, checking whether it is present first.
@@ -27,7 +29,7 @@ public interface OpenRegistry<T> extends Registry<T> {
* *
* @throws DuplicateEntryException If an entry with the same identifier is already present. * @throws DuplicateEntryException If an entry with the same identifier is already present.
*/ */
void registerChecked(String identifier, T value) throws DuplicateEntryException; void registerChecked(@NotNull String identifier, @NotNull T value) throws DuplicateEntryException;
/** /**
* Clears all entries from the registry. * Clears all entries from the registry.
@@ -9,6 +9,11 @@ package com.dfsek.terra.api.registry;
import com.dfsek.tectonic.loading.TypeLoader; import com.dfsek.tectonic.loading.TypeLoader;
import com.dfsek.terra.api.registry.exception.NoSuchEntryException;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import java.util.Collection; import java.util.Collection;
import java.util.Set; import java.util.Set;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
@@ -23,7 +28,9 @@ public interface Registry<T> extends TypeLoader<T> {
* *
* @return Value matching the identifier, {@code null} if no value is present. * @return Value matching the identifier, {@code null} if no value is present.
*/ */
T get(String identifier); @NotNull
@Contract(pure = true)
T get(@NotNull String identifier) throws NoSuchEntryException;
/** /**
* Check if the registry contains a value. * Check if the registry contains a value.
@@ -32,27 +39,30 @@ public interface Registry<T> extends TypeLoader<T> {
* *
* @return Whether the registry contains the value. * @return Whether the registry contains the value.
*/ */
boolean contains(String identifier); @Contract(pure = true)
boolean contains(@NotNull String identifier);
/** /**
* Perform the given action for every value in the registry. * Perform the given action for every value in the registry.
* *
* @param consumer Action to perform on value. * @param consumer Action to perform on value.
*/ */
void forEach(Consumer<T> consumer); void forEach(@NotNull Consumer<T> consumer);
/** /**
* Perform an action for every key-value pair in the registry. * Perform an action for every key-value pair in the registry.
* *
* @param consumer Action to perform on pair. * @param consumer Action to perform on pair.
*/ */
void forEach(BiConsumer<String, T> consumer); void forEach(@NotNull BiConsumer<String, T> consumer);
/** /**
* Get the entries of this registry as a {@link Set}. * Get the entries of this registry as a {@link Set}.
* *
* @return Set containing all entries. * @return Set containing all entries.
*/ */
@NotNull
@Contract(pure = true)
Collection<T> entries(); Collection<T> entries();
/** /**
@@ -60,5 +70,7 @@ public interface Registry<T> extends TypeLoader<T> {
* *
* @return Keys in registry * @return Keys in registry
*/ */
@NotNull
@Contract(pure = true)
Set<String> keys(); Set<String> keys();
} }
@@ -0,0 +1,11 @@
package com.dfsek.terra.api.registry.exception;
public class NoSuchEntryException extends RuntimeException {
public NoSuchEntryException(String message) {
super(message);
}
public NoSuchEntryException(String message, Throwable cause) {
super(message, cause);
}
}
@@ -29,6 +29,7 @@ import java.util.function.Consumer;
import com.dfsek.terra.api.registry.CheckedRegistry; import com.dfsek.terra.api.registry.CheckedRegistry;
import com.dfsek.terra.api.registry.OpenRegistry; import com.dfsek.terra.api.registry.OpenRegistry;
import com.dfsek.terra.api.registry.exception.DuplicateEntryException; import com.dfsek.terra.api.registry.exception.DuplicateEntryException;
import org.jetbrains.annotations.NotNull;
/** /**
@@ -44,37 +45,37 @@ public class CheckedRegistryImpl<T> implements CheckedRegistry<T> {
} }
@Override @Override
public void register(String identifier, T value) throws DuplicateEntryException { public void register(@NotNull String identifier, @NotNull T value) throws DuplicateEntryException {
registry.registerChecked(identifier, value); registry.registerChecked(identifier, value);
} }
@Override @Override
public T get(String identifier) { public @NotNull T get(@NotNull String identifier) {
return registry.get(identifier); return registry.get(identifier);
} }
@Override @Override
public boolean contains(String identifier) { public boolean contains(@NotNull String identifier) {
return registry.contains(identifier); return registry.contains(identifier);
} }
@Override @Override
public void forEach(Consumer<T> consumer) { public void forEach(@NotNull Consumer<T> consumer) {
registry.forEach(consumer); registry.forEach(consumer);
} }
@Override @Override
public void forEach(BiConsumer<String, T> consumer) { public void forEach(@NotNull BiConsumer<String, T> consumer) {
registry.forEach(consumer); registry.forEach(consumer);
} }
@Override @Override
public Collection<T> entries() { public @NotNull Collection<T> entries() {
return registry.entries(); return registry.entries();
} }
@Override @Override
public Set<String> keys() { public @NotNull Set<String> keys() {
return registry.keys(); return registry.keys();
} }
@@ -28,6 +28,8 @@ import java.util.function.Consumer;
import com.dfsek.terra.api.registry.Registry; import com.dfsek.terra.api.registry.Registry;
import org.jetbrains.annotations.NotNull;
/** /**
* Wrapper for a registry that forbids all write access. * Wrapper for a registry that forbids all write access.
@@ -42,32 +44,32 @@ public class LockedRegistryImpl<T> implements Registry<T> {
} }
@Override @Override
public T get(String identifier) { public @NotNull T get(@NotNull String identifier) {
return registry.get(identifier); return registry.get(identifier);
} }
@Override @Override
public boolean contains(String identifier) { public boolean contains(@NotNull String identifier) {
return registry.contains(identifier); return registry.contains(identifier);
} }
@Override @Override
public void forEach(Consumer<T> consumer) { public void forEach(@NotNull Consumer<T> consumer) {
registry.forEach(consumer); registry.forEach(consumer);
} }
@Override @Override
public void forEach(BiConsumer<String, T> consumer) { public void forEach(@NotNull BiConsumer<String, T> consumer) {
registry.forEach(consumer); registry.forEach(consumer);
} }
@Override @Override
public Collection<T> entries() { public @NotNull Collection<T> entries() {
return registry.entries(); return registry.entries();
} }
@Override @Override
public Set<String> keys() { public @NotNull Set<String> keys() {
return registry.keys(); return registry.keys();
} }
@@ -34,6 +34,10 @@ import java.util.stream.Collectors;
import com.dfsek.terra.api.registry.OpenRegistry; import com.dfsek.terra.api.registry.OpenRegistry;
import com.dfsek.terra.api.registry.exception.DuplicateEntryException; import com.dfsek.terra.api.registry.exception.DuplicateEntryException;
import com.dfsek.terra.api.registry.exception.NoSuchEntryException;
import org.jetbrains.annotations.NotNull;
/** /**
* Registry implementation with read/write access. For internal use only. * Registry implementation with read/write access. For internal use only.
@@ -55,24 +59,26 @@ public class OpenRegistryImpl<T> implements OpenRegistry<T> {
@Override @Override
public T load(AnnotatedType type, Object o, ConfigLoader configLoader) throws LoadException { public T load(AnnotatedType type, Object o, ConfigLoader configLoader) throws LoadException {
T obj = get((String) o); T obj;
String list = objects.keySet().stream().sorted().reduce("", (a, b) -> a + "\n - " + b); try {
obj = get((String) o);
if(objects.isEmpty()) list = "[ ]"; } catch(NoSuchEntryException e) {
String list = objects.keySet().stream().sorted().reduce("", (a, b) -> a + "\n - " + b);
if(obj == null) if(objects.isEmpty()) list = "[ ]";
throw new LoadException("No such " + type.getType().getTypeName() + " matching \"" + o + throw new LoadException("No such " + type.getType().getTypeName() + " matching \"" + o +
"\" was found in this registry. Registry contains items: " + list); "\" was found in this registry. Registry contains items: " + list);
}
return obj; return obj;
} }
@Override @Override
public boolean register(String identifier, T value) { public boolean register(@NotNull String identifier, @NotNull T value) {
return register(identifier, new Entry<>(value)); return register(identifier, new Entry<>(value));
} }
@Override @Override
public void registerChecked(String identifier, T value) throws DuplicateEntryException { public void registerChecked(@NotNull String identifier, @NotNull T value) throws DuplicateEntryException {
if(objects.containsKey(identifier)) if(objects.containsKey(identifier))
throw new DuplicateEntryException("Value with identifier \"" + identifier + "\" is already defined in registry."); throw new DuplicateEntryException("Value with identifier \"" + identifier + "\" is already defined in registry.");
register(identifier, value); register(identifier, value);
@@ -95,32 +101,36 @@ public class OpenRegistryImpl<T> implements OpenRegistry<T> {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public T get(String identifier) { public @NotNull T get(@NotNull String identifier) {
return objects.getOrDefault(identifier, (Entry<T>) NULL).getValue(); T value = objects.getOrDefault(identifier, (Entry<T>) NULL).getValue();
if(value == null) {
throw new NoSuchEntryException("Entry " + identifier + " is not present in registry.");
}
return value;
} }
@Override @Override
public boolean contains(String identifier) { public boolean contains(@NotNull String identifier) {
return objects.containsKey(identifier); return objects.containsKey(identifier);
} }
@Override @Override
public void forEach(Consumer<T> consumer) { public void forEach(@NotNull Consumer<T> consumer) {
objects.forEach((id, obj) -> consumer.accept(obj.getRaw())); objects.forEach((id, obj) -> consumer.accept(obj.getRaw()));
} }
@Override @Override
public void forEach(BiConsumer<String, T> consumer) { public void forEach(@NotNull BiConsumer<String, T> consumer) {
objects.forEach((id, entry) -> consumer.accept(id, entry.getRaw())); objects.forEach((id, entry) -> consumer.accept(id, entry.getRaw()));
} }
@Override @Override
public Collection<T> entries() { public @NotNull Collection<T> entries() {
return objects.values().stream().map(Entry::getRaw).collect(Collectors.toList()); return objects.values().stream().map(Entry::getRaw).collect(Collectors.toList());
} }
@Override @Override
public Set<String> keys() { public @NotNull Set<String> keys() {
return objects.keySet(); return objects.keySet();
} }