Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for inheritence #24 #27

Merged
merged 8 commits into from
Sep 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 92 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
root = true

[*]
insert_final_newline = true
disabled_rules = no-wildcard-imports, filename, import-ordering

[{*.kt,*.kts}]
ij_kotlin_code_style_defaults = KOTLIN_OFFICIAL
ij_continuation_indent_size = 2
max_line_length = 140
ij_kotlin_packages_to_use_import_on_demand = ^
ij_kotlin_align_in_columns_case_branch = false
ij_kotlin_align_multiline_binary_operation = false
ij_kotlin_align_multiline_extends_list = false
ij_kotlin_align_multiline_method_parentheses = false
ij_kotlin_align_multiline_parameters = true
ij_kotlin_align_multiline_parameters_in_calls = false
ij_kotlin_allow_trailing_comma = true
ij_kotlin_allow_trailing_comma_on_call_site = false
ij_kotlin_assignment_wrap = normal
ij_kotlin_blank_lines_after_class_header = 0
ij_kotlin_blank_lines_around_block_when_branches = 0
ij_kotlin_blank_lines_before_declaration_with_comment_or_annotation_on_separate_line = 1
ij_kotlin_block_comment_at_first_column = true
ij_kotlin_call_parameters_new_line_after_left_paren = true
ij_kotlin_call_parameters_right_paren_on_new_line = true
ij_kotlin_call_parameters_wrap = on_every_item
ij_kotlin_catch_on_new_line = false
ij_kotlin_class_annotation_wrap = split_into_lines
ij_kotlin_continuation_indent_for_chained_calls = true
ij_kotlin_continuation_indent_for_expression_bodies = false
ij_kotlin_continuation_indent_in_argument_lists = false
ij_kotlin_continuation_indent_in_elvis = true
ij_kotlin_continuation_indent_in_if_conditions = true
ij_kotlin_continuation_indent_in_parameter_lists = false
ij_kotlin_continuation_indent_in_supertype_lists = true
ij_kotlin_else_on_new_line = false
ij_kotlin_enum_constants_wrap = split_into_lines
ij_kotlin_extends_list_wrap = on_every_item
ij_kotlin_field_annotation_wrap = normal
ij_kotlin_finally_on_new_line = false
ij_kotlin_if_rparen_on_new_line = true
ij_kotlin_import_nested_classes = true
ij_kotlin_imports_layout = *, kotlin.**, ^
ij_kotlin_insert_whitespaces_in_simple_one_line_method = true
ij_kotlin_keep_blank_lines_before_right_brace = 0
ij_kotlin_keep_blank_lines_in_code = 1
ij_kotlin_keep_blank_lines_in_declarations = 1
ij_kotlin_keep_first_column_comment = true
ij_kotlin_keep_indents_on_empty_lines = false
ij_kotlin_keep_line_breaks = true
ij_kotlin_lbrace_on_next_line = false
ij_kotlin_line_comment_add_space = true
ij_kotlin_line_comment_at_first_column = false
ij_kotlin_method_annotation_wrap = normal
ij_kotlin_method_call_chain_wrap = on_every_item
ij_kotlin_method_parameters_new_line_after_left_paren = true
ij_kotlin_method_parameters_right_paren_on_new_line = true
ij_kotlin_method_parameters_wrap = split_into_lines
ij_kotlin_name_count_to_use_star_import = 999
ij_kotlin_name_count_to_use_star_import_for_members = 999
ij_kotlin_parameter_annotation_wrap = off
ij_kotlin_space_after_comma = true
ij_kotlin_space_after_extend_colon = true
ij_kotlin_space_after_type_colon = true
ij_kotlin_space_before_catch_parentheses = true
ij_kotlin_space_before_comma = false
ij_kotlin_space_before_extend_colon = true
ij_kotlin_space_before_for_parentheses = true
ij_kotlin_space_before_if_parentheses = true
ij_kotlin_space_before_lambda_arrow = true
ij_kotlin_space_before_type_colon = false
ij_kotlin_space_before_when_parentheses = true
ij_kotlin_space_before_while_parentheses = true
ij_kotlin_spaces_around_additive_operators = true
ij_kotlin_spaces_around_assignment_operators = true
ij_kotlin_spaces_around_equality_operators = true
ij_kotlin_spaces_around_function_type_arrow = true
ij_kotlin_spaces_around_logical_operators = true
ij_kotlin_spaces_around_multiplicative_operators = true
ij_kotlin_spaces_around_range = false
ij_kotlin_spaces_around_relational_operators = true
ij_kotlin_spaces_around_unary_operator = false
ij_kotlin_spaces_around_when_arrow = true
ij_kotlin_variable_annotation_wrap = off
ij_kotlin_while_on_new_line = false
ij_kotlin_wrap_elvis_expressions = 1
ij_kotlin_wrap_expression_body_functions = 1
ij_kotlin_wrap_first_method_in_call_chain = false

[{src/test/**.kt,src/test/**.kts}]
max_line_length = 200
44 changes: 27 additions & 17 deletions kediatr-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>com.trendyol</groupId>
<artifactId>kediatr-core</artifactId>
<version>1.0.18</version>
<version>1.1.1</version>
<packaging>jar</packaging>

<parent>
Expand Down Expand Up @@ -138,14 +138,13 @@

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<kotlin.version>1.5.30</kotlin.version>
<kotlin.version>1.7.10</kotlin.version>
<kotlin.code.style>official</kotlin.code.style>
<junit.version>5.7.0-M1</junit.version>

<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<kotlin.compiler.jvmTarget>1.8</kotlin.compiler.jvmTarget>
<kotlinx.coroutines.version>1.5.2</kotlinx.coroutines.version>
<kotlinx.coroutines.version>1.6.4</kotlinx.coroutines.version>
<junit.version>5.9.1</junit.version>
</properties>

<pluginRepositories>
Expand Down Expand Up @@ -196,11 +195,6 @@
<jvmTarget>1.8</jvmTarget>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M5</version>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
Expand All @@ -221,6 +215,10 @@
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
</plugin>
</plugins>
</build>

Expand All @@ -240,27 +238,34 @@
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.junit</groupId>
<artifactId>junit-bom</artifactId>
<version>${junit.version}</version>
<type>pom</type>
<scope>import</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</dependencyManagement>

<dependencies>
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.9.11</version>
<version>0.10.2</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-test-junit</artifactId>
<version>${kotlin.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlinx</groupId>
<artifactId>kotlinx-coroutines-core</artifactId>
Expand All @@ -270,6 +275,11 @@
<artifactId>kotlin-reflect</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>

</dependencies>
</project>
41 changes: 41 additions & 0 deletions kediatr-core/src/main/kotlin/com/trendyol/kediatr/AsyncRegistry.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.trendyol.kediatr

import com.trendyol.kediatr.common.AsyncNotificationProvider
import com.trendyol.kediatr.common.AsyncPipelineProvider
import com.trendyol.kediatr.common.AsyncQueryProvider

@Suppress("UNCHECKED_CAST")
internal class AsyncRegistry(dependencyProvider: DependencyProvider) : Registrar() {
val commandMap = HashMap<Class<*>, AsyncCommandProvider<AsyncCommandHandler<Command>>>()
val queryMap = HashMap<Class<*>, AsyncQueryProvider<AsyncQueryHandler<*, *>>>()
val notificationMap = HashMap<Class<*>, MutableList<AsyncNotificationProvider<AsyncNotificationHandler<*>>>>()
val pipelineSet = HashSet<AsyncPipelineProvider<*>>()
val commandWithResultMap = HashMap<Class<*>, AsyncCommandWithResultProvider<*>>()

init {

registerFor<AsyncQueryHandler<Query<*>, *>, Query<*>>(dependencyProvider) { key, value ->
queryMap[key] = AsyncQueryProvider(dependencyProvider, value as Class<AsyncQueryHandler<*, *>>)
}

registerFor<AsyncCommandHandler<Command>, Command>(dependencyProvider) { key, value ->
commandMap[key] = AsyncCommandProvider(dependencyProvider, value)
}

registerFor<AsyncCommandWithResultHandler<CommandWithResult<*>, *>, CommandWithResult<*>>(dependencyProvider) { key, value ->
commandWithResultMap[key] = AsyncCommandWithResultProvider(
dependencyProvider,
value as Class<AsyncCommandWithResultHandler<*, *>>
)
}

registerFor<AsyncNotificationHandler<Notification>, Notification>(dependencyProvider) { key, value ->
notificationMap.getOrPut(key) { mutableListOf() }
.add(AsyncNotificationProvider(dependencyProvider, value as Class<AsyncNotificationHandler<*>>))
}

registerFor<AsyncPipelineBehavior>(dependencyProvider) { handler ->
pipelineSet.add(AsyncPipelineProvider(dependencyProvider, handler))
}
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package com.trendyol.kediatr

class CommandBusBuilder(
private val dependencyProvider: DependencyProvider
private val dependencyProvider: DependencyProvider,
) {
private var publishStrategy: PublishStrategy = StopOnExceptionPublishStrategy()
internal var publishStrategy: PublishStrategy = StopOnExceptionPublishStrategy()
private set

/**
* Overrides default notification publishing strategy.
Expand All @@ -24,4 +25,4 @@ class CommandBusBuilder(
fun build(registry: Registry = RegistryImpl(dependencyProvider)): CommandBus {
return CommandBusImpl(registry, publishStrategy)
}
}
}
71 changes: 71 additions & 0 deletions kediatr-core/src/main/kotlin/com/trendyol/kediatr/Registrar.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package com.trendyol.kediatr

import java.lang.reflect.ParameterizedType

@Suppress("UNCHECKED_CAST")
abstract class Registrar {

protected inline fun <reified THandler : Any, TParameter> registerFor(
dependencyProvider: DependencyProvider,
registrar: (key: Class<TParameter>, value: Class<THandler>) -> Unit,
) = dependencyProvider.getSubTypesOf(THandler::class.java).forEach {
registerFor<THandler, TParameter>(it) { key, value ->
registrar(key as Class<TParameter>, value as Class<THandler>)
}
}

protected inline fun <reified THandler : Any, TParameter> registerFor(
handler: Class<*>,
registrar: (key: Class<*>, value: Class<*>) -> Unit,
) {
val interfaceOrBaseClass = THandler::class.java
if (!interfaceOrBaseClass.isAssignableFrom(handler)) return

handler.genericInterfaces
.filterIsInstance<ParameterizedType>()
.map { extractParameter<TParameter>(it) }
.forEach { registrar(it, handler) }

when (handler.genericSuperclass) {
is ParameterizedType -> {
val inheritedHandler = (handler.genericSuperclass as ParameterizedType).rawType as Class<*>
inheritedHandler.genericInterfaces
.filterIsInstance<ParameterizedType>()
.map { extractParameter<TParameter>(handler.genericSuperclass as ParameterizedType) }
.forEach { registrar(it, handler) }
}

is Class<*> -> {
val inheritedHandler = handler.genericSuperclass as Class<*>
if (interfaceOrBaseClass.isAssignableFrom(inheritedHandler)) {
inheritedHandler.genericInterfaces
.filterIsInstance<ParameterizedType>()
.map { extractParameter<TParameter>(it) }
.forEach { registrar(it, handler) }
}
}
}
}

protected inline fun <reified T> registerFor(
dependencyProvider: DependencyProvider,
registrar: (value: Class<T>) -> Unit,
) = dependencyProvider.getSubTypesOf(T::class.java).forEach { handler ->
registerFor<T>(handler) { value -> registrar(value as Class<T>) }
}

protected inline fun <reified T> registerFor(
handler: Class<*>,
registrar: (value: Class<*>) -> Unit,
) {
val interfaceOrBaseClass = T::class.java
if (!interfaceOrBaseClass.isAssignableFrom(handler)) return
registrar(handler)
}

protected fun <T> extractParameter(genericInterface: ParameterizedType): Class<out T> =
when (val typeArgument = genericInterface.actualTypeArguments[0]) {
is ParameterizedType -> typeArgument.rawType as Class<out T>
else -> typeArgument as Class<out T>
}
}
Loading