Initial commit. Woot!

This commit is contained in:
JesseBrault0709 2024-05-03 12:01:45 +02:00
commit 093a73d046
5 changed files with 104 additions and 0 deletions

8
build.gradle Normal file
View File

@ -0,0 +1,8 @@
plugins {
id 'GroowtConventions'
id 'java-library'
}
dependencies {
compileOnlyApi libs.jetbrains.anotations
}

View File

@ -0,0 +1,68 @@
package groowt.util.extensible;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.function.Consumer;
public abstract class AbstractExtensionContainer<E, F> implements ExtensionContainer<E, F> {
private final F extensionFactory;
private final Collection<E> extensions = new ArrayList<>();
public AbstractExtensionContainer(F extensionFactory) {
this.extensionFactory = extensionFactory;
}
/**
* @return A <strong>copy</strong> of the registered extensions.
*/
protected Collection<E> getRegisteredExtensions() {
return new ArrayList<>(this.extensions);
}
protected void registerExtension(E extension) {
this.extensions.add(extension);
}
@Override
public <T extends E> @Nullable T findExtension(Class<T> extensionClass) {
return this.extensions.stream()
.filter(extensionClass::isInstance)
.findFirst()
.map(extensionClass::cast)
.orElse(null);
}
/**
* @implNote While this {@link AbstractExtensionContainer} calls
* {@link #getExtension}, which will throw if there is no registered
* extension, this method may be overridden to not use {@link #getExtension}
* and instead implement custom handling logic to avoid throwing, etc.
*/
@Override
public <T extends E> void configureExtension(Class<T> extensionClass, Consumer<? super T> configure) {
configure.accept(this.getExtension(extensionClass));
}
@Override
public <T extends E> T getExtension(Class<T> extensionClass) {
return this.extensions.stream()
.filter(extensionClass::isInstance)
.findFirst()
.map(extensionClass::cast)
.orElseThrow(() -> new IllegalArgumentException("There is no registered extension for " + extensionClass.getName()));
}
@Override
public boolean hasExtension(Class<? extends E> extensionClass) {
return this.extensions.stream().anyMatch(extensionClass::isInstance);
}
@Override
public F getExtensionFactory() {
return this.extensionFactory;
}
}

View File

@ -0,0 +1,11 @@
package groowt.util.extensible;
import org.jetbrains.annotations.Nullable;
import java.util.function.Consumer;
// TODO: groovy methods to handle getting extensions via property accessors
public interface Extensible<E, F, C extends ExtensionContainer<E, F>> extends ExtensionAware<E> {
<T extends E> T createExtension(Class<T> extensionClass, Object... constructorArgs);
C getExtensionContainer();
}

View File

@ -0,0 +1,12 @@
package groowt.util.extensible;
import org.jetbrains.annotations.Nullable;
import java.util.function.Consumer;
public interface ExtensionAware<E> {
@Nullable <T extends E> T findExtension(Class<T> extensionClass);
<T extends E> void configureExtension(Class<T> extensionClass, Consumer<? super T> configure);
<T extends E> T getExtension(Class<T> extensionClass);
boolean hasExtension(Class<? extends E> extensionClass);
}

View File

@ -0,0 +1,5 @@
package groowt.util.extensible;
public interface ExtensionContainer<E, F> extends ExtensionAware<E> {
F getExtensionFactory();
}