Skip to content

Commit

Permalink
Merge pull request #6 from Cmyna/development-alpha
Browse files Browse the repository at this point in the history
FIX issues
  • Loading branch information
Cmyna authored Feb 28, 2023
2 parents 2682424 + 0509dbb commit 59e3e29
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 22 deletions.
1 change: 1 addition & 0 deletions api/src/main/kotlin/net/myna/mnbt/Mnbt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@ open class Mnbt {

init {
// register codec
this.codecProxy.registerCodec(BinaryCodecInstances.nullTagCodec, IdTagEnd)
this.codecProxy.registerCodec(BinaryCodecInstances.byteCodec, IdTagByte)
this.codecProxy.registerCodec(BinaryCodecInstances.shortCodec, IdTagShort)
this.codecProxy.registerCodec(BinaryCodecInstances.intCodec, IdTagInt)
Expand Down
20 changes: 2 additions & 18 deletions api/src/main/kotlin/net/myna/mnbt/converter/ReflectiveConverter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import net.myna.mnbt.annotations.LocateAt
import net.myna.mnbt.utils.NbtPathTool
import net.myna.mnbt.converter.procedure.ToNestTagProcedure
import net.myna.mnbt.exceptions.InvalidInstanceAsClassException
import net.myna.mnbt.reflect.InstanceAsTool
import net.myna.mnbt.reflect.MTypeToken
import net.myna.mnbt.reflect.ObjectInstanceHandler
import net.myna.mnbt.reflect.TypeCheckTool
Expand Down Expand Up @@ -231,24 +232,7 @@ class ReflectiveConverter(override var proxy: TagConverter<Any>): HierarchicalTa
field
)
val instanceAsAnnotation = field.getAnnotation(InstanceAs::class.java)
val fieldTypeToken = if (instanceAsAnnotation != null) {
val wrappedClass = instanceAsAnnotation.instanceClass.java
val token = MTypeToken.of(wrappedClass)
if (!TypeCheckTool.isCastable(token, MTypeToken.of(field.genericType))) {
throw InvalidInstanceAsClassException(
wrappedClass,
field.type,
InvalidInstanceAsClassException.ExceptionType.NOT_SUBTYPE
)
}
if (wrappedClass.isInterface || Modifier.isAbstract(wrappedClass.modifiers)) {
throw InvalidInstanceAsClassException(
wrappedClass, field.type,
InvalidInstanceAsClassException.ExceptionType.IS_ABSTRACT
)
}
token
} else MTypeToken.of(field.genericType)
val fieldTypeToken = InstanceAsTool.resolveAnnotation(field)
//val fieldTypeToken = MTypeToken.of(field.genericType)

val fieldTag = NbtPathTool.findTag(dataEntryTag, it.value) ?: return@mapValues null
Expand Down
41 changes: 41 additions & 0 deletions api/src/main/kotlin/net/myna/mnbt/reflect/InstanceAsTool.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package net.myna.mnbt.reflect

import net.myna.mnbt.annotations.InstanceAs
import net.myna.mnbt.codec.binary.RArray
import net.myna.mnbt.exceptions.InvalidInstanceAsClassException
import net.myna.mnbt.reflect.TypeCheckTool.isInterfaceOrAbstract
import java.lang.reflect.Field
import java.lang.reflect.Modifier

object InstanceAsTool {

fun resolveAnnotation(field: Field):MTypeToken<out Any> {
val instanceAsAnnotation = field.getAnnotation(InstanceAs::class.java)
if (instanceAsAnnotation!=null) {
val wrappedClass = instanceAsAnnotation.instanceClass.java
val token = MTypeToken.of(wrappedClass)
//val declaredType = if (field.type.isArray) field.type.componentType else field.type
val declaredType = field.type

if (!TypeCheckTool.isCastable(token, MTypeToken.of(declaredType))) {
throw InvalidInstanceAsClassException(
wrappedClass,
declaredType,
InvalidInstanceAsClassException.ExceptionType.NOT_SUBTYPE
)
}
if (isInterfaceOrAbstract(wrappedClass)) {
throw InvalidInstanceAsClassException(
wrappedClass, declaredType,
InvalidInstanceAsClassException.ExceptionType.IS_ABSTRACT
)
}

// if (field.type.isArray) {
// // return array type declaration
// return RArray.newInstance(token.rawType, 0).javaClass.let { MTypeToken.of(it) }
// }
return token
} else return MTypeToken.of(field.genericType)
}
}
10 changes: 10 additions & 0 deletions api/src/main/kotlin/net/myna/mnbt/reflect/TypeCheckTool.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package net.myna.mnbt.reflect

import net.myna.mnbt.reflect.MTypeToken
import java.lang.reflect.GenericArrayType
import java.lang.reflect.Modifier
import java.lang.reflect.Type

object TypeCheckTool {
Expand Down Expand Up @@ -66,4 +67,13 @@ object TypeCheckTool {
return null // unsupported type, return null
}

fun isInterfaceOrAbstract(clazz: Class<*>):Boolean {
if (clazz.isInterface) return true
if (clazz.isArray) {
return isInterfaceOrAbstract(clazz.componentType)
}
if (Modifier.isAbstract(clazz.modifiers)) return true
return false
}

}
28 changes: 24 additions & 4 deletions api/src/test/kotlin/net/myna/mnbt/annotationTest/InstanceAtTest.kt
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package net.myna.mnbt.annotationTest

import net.myna.mnbt.IdTagCompound
import net.myna.mnbt.Mnbt
import net.myna.mnbt.annotations.InstanceAs
import net.myna.mnbt.annotations.LocateAt
import net.myna.mnbt.exceptions.InvalidInstanceAsClassException
import net.myna.mnbt.reflect.MTypeToken
import net.myna.mnbt.tag.CompoundTag
import net.myna.mnbt.tag.IntTag
import net.myna.mnbt.tag.ListTag
import net.myna.mnbt.tag.StringTag
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertTrue
Expand All @@ -19,15 +21,23 @@ class InstanceAtTest {
fun test() {
// create target tag
val testClassTag = CompoundTag("root")
val member1 = CompoundTag("member1").also { testClassTag.add(it) }
member1.add(IntTag("int tag", 5387))
member1.add(StringTag("string tag", "some string value ab789"))
val member1 = createTestInterfaceImplRelatedTag("member1").also { testClassTag.add(it) }
val arrayTag = ListTag<CompoundTag>(IdTagCompound, "arrayType").also { testClassTag.add(it) }
repeat(3) {
arrayTag.add(createTestInterfaceImplRelatedTag(null))
}

val mnbt = Mnbt()
val obj = mnbt.fromTag(testClassTag, object:MTypeToken<TestClass>() {})!!.second
assertTrue(obj.member1 is TestInterfaceImpl)
assertEquals(5387, obj.member1.i)
assertEquals("some string value ab789", obj.member1.j)

// check array type
assertEquals(3, obj.arrayType.size)
assertTrue(obj.arrayType[0] is TestInterfaceImpl)
assertEquals(5387, obj.arrayType[0].i)

}

@Test
Expand All @@ -49,6 +59,13 @@ class InstanceAtTest {
}.also { it.printStackTrace() }
}

private fun createTestInterfaceImplRelatedTag(name:String?):CompoundTag {
val target = CompoundTag(name)
target.add(IntTag("int tag", 5387))
target.add(StringTag("string tag", "some string value ab789"))
return target
}

private interface TestInterface {
val i:Int
val j:String
Expand All @@ -58,7 +75,9 @@ class InstanceAtTest {

private class TestClass(
@InstanceAs(TestInterfaceImpl::class)
val member1:TestInterface
val member1:TestInterface,
@InstanceAs(Array<TestInterfaceImpl>::class)
val arrayType:Array<TestInterface>
)

private class TestClass2(
Expand All @@ -71,6 +90,7 @@ class InstanceAtTest {
val member1:TestInterface
)


private class TestInterfaceImpl(
@LocateAt("int tag")
override val i: Int,
Expand Down

0 comments on commit 59e3e29

Please sign in to comment.