diff --git a/crane4j-core/src/main/java/cn/crane4j/core/container/PartitionContainerProvider.java b/crane4j-core/src/main/java/cn/crane4j/core/container/PartitionContainerProvider.java new file mode 100644 index 00000000..e0e58d59 --- /dev/null +++ b/crane4j-core/src/main/java/cn/crane4j/core/container/PartitionContainerProvider.java @@ -0,0 +1,65 @@ +package cn.crane4j.core.container; + +import lombok.Setter; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.function.Function; + +/** + *

A {@link ContainerProvider} implementation for conveniently registering container.
+ * When get container by given namespace, it will return the container registered by {@link #registerContainer(Container)}, + * if not exist, it will return the container created by {@link #defaultContainerFactory}. + * + * @author huangchengxing + */ +public class PartitionContainerProvider implements ContainerProvider { + + /** + * Container map. + */ + private final Map> containerMap = new HashMap<>(); + + /** + * Default container factory for non-existent container. + */ + @NonNull + @Setter + private Function> defaultContainerFactory = namespace -> Containers.empty(); + + /** + * Get container comparator by given namespace + * + * @param namespace namespace of container + * @return container comparator + */ + @SuppressWarnings("unchecked") + @Override + public @Nullable Container getContainer(String namespace) { + return (Container)containerMap.getOrDefault(namespace, defaultContainerFactory.apply(namespace)); + } + + /** + * Register container. + * + * @param container container + */ + public void registerContainer(@NonNull Container container) { + Objects.requireNonNull(container, "Container must not null"); + containerMap.put(container.getNamespace(), container); + } + + /** + * Whether this provider has container of given {@code namespace}. + * + * @param namespace namespace + * @return boolean + */ + @Override + public boolean containsContainer(String namespace) { + return Objects.nonNull(getContainer(namespace)); + } +} diff --git a/crane4j-core/src/main/java/cn/crane4j/core/parser/handler/AbstractAssembleAnnotationHandler.java b/crane4j-core/src/main/java/cn/crane4j/core/parser/handler/AbstractAssembleAnnotationHandler.java index 1ce31b2b..8c4f00c3 100644 --- a/crane4j-core/src/main/java/cn/crane4j/core/parser/handler/AbstractAssembleAnnotationHandler.java +++ b/crane4j-core/src/main/java/cn/crane4j/core/parser/handler/AbstractAssembleAnnotationHandler.java @@ -20,8 +20,10 @@ import cn.crane4j.core.util.ReflectUtils; import lombok.Getter; import lombok.RequiredArgsConstructor; +import lombok.Setter; import lombok.experimental.Accessors; import lombok.extern.slf4j.Slf4j; +import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import java.lang.annotation.Annotation; @@ -51,11 +53,13 @@ public abstract class AbstractAssembleAnnotationHandler im protected final Class annotationType; protected final AnnotationFinder annotationFinder; - protected final Comparator operationComparator; + @NonNull + @Setter + protected Comparator operationComparator; protected final Crane4jGlobalConfiguration globalConfiguration; /** - * Create an {@link AbstractAssembleAnnotationHandler} comparator. + * Create an {@link AbstractAssembleAnnotationHandler} instance. * * @param annotationType annotation type * @param annotationFinder annotation finder @@ -64,13 +68,25 @@ public abstract class AbstractAssembleAnnotationHandler im */ protected AbstractAssembleAnnotationHandler( Class annotationType, AnnotationFinder annotationFinder, - Comparator operationComparator, Crane4jGlobalConfiguration globalConfiguration) { + @NonNull Comparator operationComparator, Crane4jGlobalConfiguration globalConfiguration) { this.annotationType = annotationType; this.annotationFinder = annotationFinder; this.operationComparator = operationComparator; this.globalConfiguration = globalConfiguration; } + /** + * Create an {@link AbstractAssembleAnnotationHandler} instance. + * + * @param annotationType annotation type + * @param annotationFinder annotation finder + * @param globalConfiguration global configuration + */ + protected AbstractAssembleAnnotationHandler( + Class annotationType, AnnotationFinder annotationFinder, Crane4jGlobalConfiguration globalConfiguration) { + this(annotationType, annotationFinder, Crane4jGlobalSorter.comparator(), globalConfiguration); + } + /** * Resolve operations from type *