Skip to content

Commit

Permalink
Improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
aartiPl committed Aug 21, 2023
1 parent cc03e1d commit 4f86adb
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 35 deletions.
29 changes: 14 additions & 15 deletions src/main/kotlin/net/igsoft/typeutils/globalcontext/GlobalContext.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ package net.igsoft.typeutils.globalcontext
import net.igsoft.typeutils.marker.Marker
import net.igsoft.typeutils.marker.TypedMarker
import net.igsoft.typeutils.property.ImmutableTypedProperties
import net.igsoft.typeutils.property.TypedProperties
import java.util.concurrent.ConcurrentHashMap

@Suppress("UNCHECKED_CAST", "unused")
@Suppress("unused")
object GlobalContext : ImmutableTypedProperties {
private val context: MutableMap<Marker, Any?> = ConcurrentHashMap()
private val context: TypedProperties = TypedProperties(ConcurrentHashMap())

fun <T> register(key: TypedMarker<T>, value: T) {
require(!context.containsKey(key)) {
Expand All @@ -28,29 +29,27 @@ object GlobalContext : ImmutableTypedProperties {
return getOrElse(marker) { error(message) }
}

override operator fun <T> get(marker: TypedMarker<T>) = context[marker] as T?

override fun get(key: Marker): Any? = context[key]

override fun <T> getValue(marker: TypedMarker<T>): T = context.getValue(marker) as T
override operator fun <T> get(marker: TypedMarker<T>) = context[marker]

override fun getValue(marker: Marker): Any? = context.getValue(marker)

override fun <T> getValue(marker: TypedMarker<T>): T = context.getValue(marker)

override fun <T> getOrDefault(marker: TypedMarker<T>, defaultValue: T): T =
context.getOrDefault(marker, defaultValue) as T
context.getOrDefault(marker, defaultValue)

override fun <T> getOrElse(marker: TypedMarker<T>, calculateValue: () -> T): T =
context.getOrElse(marker, calculateValue) as T
context.getOrElse(marker, calculateValue)

override val entries: Set<Map.Entry<Marker, Any?>>
get() = context.entries
override val entries: Set<Map.Entry<Marker, Any?>> get() = context.entries

override val keys: Set<Marker>
get() = context.keys
override val keys: Set<Marker> get() = context.keys

override val size: Int
get() = context.size
override val size: Int get() = context.size

override val values: Collection<Any?>
get() = context.values
override val values: Collection<Any?> get() = context.values

override fun containsKey(key: Marker): Boolean = context.containsKey(key)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,8 @@ class AutoTypedMarker<T> internal constructor(override val id: Any, override val
private val intGenerator = IntGenerator()

@JvmStatic
fun <T> create(clazz: Class<T>) =
AutoTypedMarker(intGenerator.next(), clazz)
fun <T> create(clazz: Class<T>) = AutoTypedMarker(intGenerator.next(), clazz)

inline fun <reified T> create() =
create(T::class.java)
inline fun <reified T> create() = create(T::class.java)
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package net.igsoft.typeutils.marker

abstract class AbstractMarker(override val id: Any, override val clazz: Class<*>) : Marker {
open class DefaultMarker(override val id: Any, override val clazz: Class<*>) : Marker {
constructor(marker: Marker) : this(marker.id, marker.clazz)

final override fun equals(other: Any?): Boolean = Markers.markerEquals(this, other)
final override fun hashCode(): Int = Markers.markerHashCode(this)
override fun toString(): String = Markers.markerToString(this, id, clazz)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import kotlin.properties.ReadOnlyProperty

@Suppress("unused")
open class DefaultTypedMarker<T>(override val id: Any, override val clazz: Class<T>) : TypedMarker<T>,
AbstractMarker(id, clazz) {
DefaultMarker(id, clazz) {

//Copying constructor (de facto alias of marker)
constructor(marker: TypedMarker<T>) : this(marker.id, marker.clazz)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@ import net.igsoft.typeutils.marker.Marker
import net.igsoft.typeutils.marker.TypedMarker

interface ImmutableTypedProperties : Map<Marker, Any?>, Iterable<Map.Entry<Marker, Any?>> {
override operator fun get(key: Marker): Any?
operator fun <T> get(marker: TypedMarker<T>): T?

fun getValue(marker: Marker): Any?
fun <T> getValue(marker: TypedMarker<T>): T

fun <T> getOrDefault(marker: TypedMarker<T>, defaultValue: T): T
fun <T> getOrElse(marker: TypedMarker<T>, calculateValue: () -> T): T
}
29 changes: 15 additions & 14 deletions src/main/kotlin/net/igsoft/typeutils/property/TypedProperties.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,17 @@ class TypedProperties(private val map: MutableMap<Marker, Any?>) : MutableTypedP
map[marker] = value
}

override fun get(key: Marker): Any? =
map[key]
override fun get(key: Marker): Any? = map[key]

override fun <T> get(marker: TypedMarker<T>): T? =
map[marker] as? T
override fun <T> get(marker: TypedMarker<T>): T? = map[marker] as? T

override fun getValue(marker: Marker): Any? {
if (isPropertyKeyMissing(null, marker)) {
throw NoSuchElementException("Marker $marker is missing in the properties")
}

return map.getValue(marker)
}

override fun <T> getValue(marker: TypedMarker<T>): T {
val value = map[marker]
Expand Down Expand Up @@ -57,17 +63,13 @@ class TypedProperties(private val map: MutableMap<Marker, Any?>) : MutableTypedP
return value as T
}

override val size: Int
get() = map.size
override val size: Int get() = map.size

override val entries: MutableSet<MutableMap.MutableEntry<Marker, Any?>>
get() = map.entries
override val entries: MutableSet<MutableMap.MutableEntry<Marker, Any?>> get() = map.entries

override val keys: MutableSet<Marker>
get() = map.keys
override val keys: MutableSet<Marker> get() = map.keys

override val values: MutableCollection<Any?>
get() = map.values
override val values: MutableCollection<Any?> get() = map.values

override fun isEmpty(): Boolean = map.isEmpty()

Expand All @@ -87,6 +89,5 @@ class TypedProperties(private val map: MutableMap<Marker, Any?>) : MutableTypedP

fun remove(key: Marker): Any? = map.remove(key)

private fun isPropertyKeyMissing(any: Any?, marker: Marker) =
any == null && !map.containsKey(marker)
private fun isPropertyKeyMissing(any: Any?, marker: Marker) = any == null && !map.containsKey(marker)
}
13 changes: 13 additions & 0 deletions src/test/kotlin/net/igsoft/typeutils/marker/AutoTypedMarkerTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package net.igsoft.typeutils.marker

import assertk.assertThat
import assertk.assertions.isNotEqualTo
import org.junit.jupiter.api.Test

class AutoTypedMarkerTest {

@Test
fun `Assert that creation of two AutoTypedMarkers generates unique 'id's`() {
assertThat(AutoTypedMarker.create<Int>().id).isNotEqualTo(AutoTypedMarker.create<Int>().id)
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package net.igsoft.typeutils.property

import assertk.assertFailure
import assertk.assertThat
import assertk.assertions.*
import net.igsoft.typeutils.marker.DefaultTypedMarker
import net.igsoft.typeutils.marker.Marker
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test

class TypedPropertiesTest {
private lateinit var properties: TypedProperties

private val firstname by DefaultTypedMarker.create<String>()
private val surname by DefaultTypedMarker.create<String>()
private val age by DefaultTypedMarker.create<Int>()
Expand Down Expand Up @@ -35,6 +38,36 @@ class TypedPropertiesTest {
}
}

@Test
fun `Assert that getting properties is possible`() {
assertThat(properties[firstname]).isEqualTo("Gregory")
assertThat(properties[surname]).isEqualTo("Iksiński")
assertThat(properties[shoeSize]).isNull()

val untypedFirstname: Marker = firstname
val untypedSurname: Marker = surname
val untypedShoeSize: Marker = shoeSize

assertThat(properties[untypedFirstname]).isNotNull().isInstanceOf<String>().isEqualTo("Gregory")
assertThat(properties[untypedSurname]).isNotNull().isInstanceOf<String>().isEqualTo("Iksiński")
assertThat(properties[untypedShoeSize]).isNull()
}

@Test
fun `Assert that getting not null properties is possible`() {
assertThat(properties.getValue(firstname)).isEqualTo("Gregory")
assertThat(properties.getValue(surname)).isEqualTo("Iksiński")
assertFailure { properties.getValue(shoeSize) }.hasMessage("Marker DefaultTypedMarker(id=shoeSize, clazz=java.lang.Integer) is missing in the properties")

val untypedFirstname: Marker = firstname
val untypedSurname: Marker = surname
val untypedShoeSize: Marker = shoeSize

assertThat(properties.getValue(untypedFirstname)).isNotNull().isInstanceOf<String>().isEqualTo("Gregory")
assertThat(properties.getValue(untypedSurname)).isNotNull().isInstanceOf<String>().isEqualTo("Iksiński")
assertFailure { properties.getValue(untypedShoeSize) }.hasMessage("Marker DefaultTypedMarker(id=shoeSize, clazz=java.lang.Integer) is missing in the properties")
}

@Test
fun `Assert that putting new properties is possible`() {
properties[shoeSize] = 32
Expand Down

0 comments on commit 4f86adb

Please sign in to comment.