diff --git a/build.gradle.kts b/build.gradle.kts index 680e19cd..098f9394 100755 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -39,7 +39,7 @@ repositories { } dependencies { - implementation("org.jetbrains.kotlin:kotlin-stdlib:1.4.20") + implementation("org.jetbrains.kotlin:kotlin-stdlib:1.5.30") testImplementation("com.winterbe:expekt:0.5.0") { exclude(group = "org.jetbrains.kotlin") } diff --git a/src/main/kotlin/extensions/ExtensionsCollector.kt b/src/main/kotlin/extensions/ExtensionsCollector.kt index 3191726b..29226201 100755 --- a/src/main/kotlin/extensions/ExtensionsCollector.kt +++ b/src/main/kotlin/extensions/ExtensionsCollector.kt @@ -37,5 +37,6 @@ object ExtensionsCollector { NeedNonNullableClassesSupport, InternalModifierSupport, AddGsonExposeAnnotationSupport, + BaseClassSupport ) } diff --git a/src/main/kotlin/extensions/wu/seal/BaseClassSupport.kt b/src/main/kotlin/extensions/wu/seal/BaseClassSupport.kt new file mode 100644 index 00000000..ba872ea3 --- /dev/null +++ b/src/main/kotlin/extensions/wu/seal/BaseClassSupport.kt @@ -0,0 +1,104 @@ +package extensions.wu.seal + +import extensions.Extension +import wu.seal.jsontokotlin.model.classscodestruct.DataClass +import wu.seal.jsontokotlin.model.classscodestruct.KotlinClass +import wu.seal.jsontokotlin.ui.* +import javax.swing.JPanel + +object BaseClassSupport : Extension() { + /** + * Config key can't be private, as it will be accessed from `library` module + */ + + @Suppress("MemberVisibilityCanBePrivate") + val baseClassSupportEnabledKey = "azk.zero.baseclass_enabled" + + @Suppress("MemberVisibilityCanBePrivate") + const val baseClassImportKey = "azk.zero.baseclass_import" + + @Suppress("MemberVisibilityCanBePrivate") + const val baseClassNameKey = "azk.zero.baseclass_name" + + @Suppress("MemberVisibilityCanBePrivate") + const val baseClassPropertiesKey = "azk.zero.baseclass_properties" + + override fun createUI(): JPanel { + val classImportField = jTextInput(getConfig(baseClassImportKey), getConfig(baseClassSupportEnabledKey).toBoolean()) { + addFocusLostListener { + if (getConfig(baseClassSupportEnabledKey).toBoolean()) { + setConfig(baseClassImportKey, text) + } + } + document = ImportConventionDocument() + } + + val classNameField = jTextInput(getConfig(baseClassNameKey), getConfig(baseClassSupportEnabledKey).toBoolean()) { + addFocusLostListener { + if (getConfig(baseClassSupportEnabledKey).toBoolean()) { + setConfig(baseClassNameKey, text) + } + } + document = SuperClassConventionDocument(100) + } + + val classPropertiesField = jTextInput(getConfig(baseClassPropertiesKey), getConfig(baseClassSupportEnabledKey).toBoolean()) { + addFocusLostListener { + if (getConfig(baseClassSupportEnabledKey).toBoolean()) { + setConfig(baseClassPropertiesKey, text) + } + } + document = PropertyConventionDocument() + } + + return jVerticalLinearLayout { + jHorizontalLinearLayout{ + jCheckBox("Base Class Support?", getConfig(baseClassSupportEnabledKey).toBoolean(), { isSelected -> + setConfig(baseClassSupportEnabledKey, isSelected.toString()) + classImportField.isEnabled = isSelected + classNameField.isEnabled = isSelected + classPropertiesField.isEnabled = isSelected + }) + } + jHorizontalLinearLayout { + jLabel("Base Class Import line") + add(classImportField) + } + jHorizontalLinearLayout { + jLabel("Base Class Name, used as-is") + add(classNameField) + } + jHorizontalLinearLayout { + jLabel("Excluded Properties list, comma-separated") + add(classPropertiesField) + } + } + } + ; + override fun intercept(kotlinClass: KotlinClass): KotlinClass { +// val exclusion = listOf("error", "message", "status_code", "status", "statusCode") + return if (getConfig(baseClassSupportEnabledKey).toBoolean()) { + val exclusionNames = getConfig(baseClassPropertiesKey).split(",").map { it.trim() } + val baseClassName = getConfig(baseClassNameKey) + if (kotlinClass is DataClass) { + if (kotlinClass.isTop.not()) return kotlinClass + val newProperties = kotlinClass.properties.mapNotNull { it.takeIf { it.originName !in exclusionNames } } + kotlinClass.copy(properties = newProperties, parentClassTemplate = baseClassName) + } else kotlinClass + } else { + kotlinClass + } + } + + override fun intercept(originClassImportDeclaration: String): String { + +// val classAnnotationImportClassString = "import com.arena.banglalinkmela.app.data.model.response.base.BaseResponse" + val classAnnotationImportClassString = getConfig(baseClassImportKey) + + return if (getConfig(baseClassSupportEnabledKey).toBoolean()) { + originClassImportDeclaration.append("import $classAnnotationImportClassString") + } else { + originClassImportDeclaration + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/wu/seal/jsontokotlin/model/classscodestruct/DataClass.kt b/src/main/kotlin/wu/seal/jsontokotlin/model/classscodestruct/DataClass.kt index ce11c544..8c828b40 100755 --- a/src/main/kotlin/wu/seal/jsontokotlin/model/classscodestruct/DataClass.kt +++ b/src/main/kotlin/wu/seal/jsontokotlin/model/classscodestruct/DataClass.kt @@ -15,6 +15,7 @@ data class DataClass( val fromJsonSchema: Boolean = false, val excludedProperties: List = listOf(), val parentClass: KotlinClass? = null, + val isTop:Boolean=false, override val codeBuilder: IKotlinDataClassCodeBuilder = KotlinDataClassCodeBuilder ) : ModifiableKotlinClass, NoGenericKotlinClass { diff --git a/src/main/kotlin/wu/seal/jsontokotlin/ui/ImportConventionDocument.kt b/src/main/kotlin/wu/seal/jsontokotlin/ui/ImportConventionDocument.kt new file mode 100755 index 00000000..01fa5841 --- /dev/null +++ b/src/main/kotlin/wu/seal/jsontokotlin/ui/ImportConventionDocument.kt @@ -0,0 +1,23 @@ +package wu.seal.jsontokotlin.ui + +import javax.swing.text.AttributeSet +import javax.swing.text.PlainDocument + +/** + * Created by ted on 2019/8/21 11:08. + */ +class ImportConventionDocument(maxLength: Int) : PlainDocument() { + constructor() : this(252) + + private val maxLength: Int = if (maxLength > 252 || maxLength <= 0) 252 else maxLength + override fun insertString(offs: Int, str: String?, a: AttributeSet?) { + str ?: return + val take = maxLength - length + if (take <= 0) return + super.insertString( + offs, + str.filter { it.isLetterOrDigit() || it in listOf('_', '.') }.take(take), + a + ) + } +} \ No newline at end of file diff --git a/src/main/kotlin/wu/seal/jsontokotlin/ui/PropertyConventionDocument.kt b/src/main/kotlin/wu/seal/jsontokotlin/ui/PropertyConventionDocument.kt new file mode 100755 index 00000000..444180f4 --- /dev/null +++ b/src/main/kotlin/wu/seal/jsontokotlin/ui/PropertyConventionDocument.kt @@ -0,0 +1,23 @@ +package wu.seal.jsontokotlin.ui + +import javax.swing.text.AttributeSet +import javax.swing.text.PlainDocument + +/** + * Created by ted on 2019/8/21 11:08. + */ +class PropertyConventionDocument(maxLength: Int) : PlainDocument() { + constructor() : this(252) + + private val maxLength: Int = if (maxLength > 252 || maxLength <= 0) 252 else maxLength + override fun insertString(offs: Int, str: String?, a: AttributeSet?) { + str ?: return + val take = maxLength - length + if (take <= 0) return + super.insertString( + offs, + str.filter { it.isLetterOrDigit() || it in listOf('_', ',') }.take(take), + a + ) + } +} \ No newline at end of file diff --git a/src/main/kotlin/wu/seal/jsontokotlin/ui/SuperClassConventionDocument.kt b/src/main/kotlin/wu/seal/jsontokotlin/ui/SuperClassConventionDocument.kt new file mode 100755 index 00000000..1b25348e --- /dev/null +++ b/src/main/kotlin/wu/seal/jsontokotlin/ui/SuperClassConventionDocument.kt @@ -0,0 +1,23 @@ +package wu.seal.jsontokotlin.ui + +import javax.swing.text.AttributeSet +import javax.swing.text.PlainDocument + +/** + * Created by ted on 2019/8/21 11:08. + */ +class SuperClassConventionDocument(maxLength: Int) : PlainDocument() { + constructor() : this(252) + + private val maxLength: Int = if (maxLength > 252 || maxLength <= 0) 252 else maxLength + override fun insertString(offs: Int, str: String?, a: AttributeSet?) { + str ?: return + val take = maxLength - length + if (take <= 0) return + super.insertString( + offs, + str.filter { it.isLetterOrDigit() || it in listOf('_', '(', ')', '.') }.take(take), + a + ) + } +} \ No newline at end of file diff --git a/src/main/kotlin/wu/seal/jsontokotlin/utils/KotlinClassMaker.kt b/src/main/kotlin/wu/seal/jsontokotlin/utils/KotlinClassMaker.kt index f5e746a5..44f68d0c 100644 --- a/src/main/kotlin/wu/seal/jsontokotlin/utils/KotlinClassMaker.kt +++ b/src/main/kotlin/wu/seal/jsontokotlin/utils/KotlinClassMaker.kt @@ -18,7 +18,7 @@ class KotlinClassMaker(private val rootClassName: String, private val json: Stri DataClassGeneratorByJSONSchema(rootClassName, jsonSchema).generate() } else { when { - json.isJSONObject() -> DataClassGeneratorByJSONObject(rootClassName, Gson().fromJson(json, JsonObject::class.java)).generate() + json.isJSONObject() -> DataClassGeneratorByJSONObject(rootClassName, Gson().fromJson(json, JsonObject::class.java)).generate(isTop = true) json.isJSONArray() -> ListClassGeneratorByJSONArray(rootClassName, json).generate() else -> throw IllegalStateException("Can't generate Kotlin Data Class from a no JSON Object/JSON Object Array") } diff --git a/src/main/kotlin/wu/seal/jsontokotlin/utils/classgenerator/DataClassGeneratorByJSONObject.kt b/src/main/kotlin/wu/seal/jsontokotlin/utils/classgenerator/DataClassGeneratorByJSONObject.kt index aa083af1..c4e6cccd 100755 --- a/src/main/kotlin/wu/seal/jsontokotlin/utils/classgenerator/DataClassGeneratorByJSONObject.kt +++ b/src/main/kotlin/wu/seal/jsontokotlin/utils/classgenerator/DataClassGeneratorByJSONObject.kt @@ -14,7 +14,7 @@ import wu.seal.jsontokotlin.utils.* */ class DataClassGeneratorByJSONObject(private val className: String, private val jsonObject: JsonObject) { - fun generate(): DataClass { + fun generate(isTop:Boolean=false): DataClass { if (maybeJsonObjectBeMapType(jsonObject) && ConfigManager.enableMapType) { throw IllegalArgumentException("Can't generate data class from a Map type JSONObjcet when enable Map Type : $jsonObject") } @@ -102,7 +102,7 @@ class DataClassGeneratorByJSONObject(private val className: String, private val } val propertiesAfterConsumeBackStageProperties = properties.consumeBackstageProperties() - return DataClass(name = className, properties = propertiesAfterConsumeBackStageProperties) + return DataClass(name = className, properties = propertiesAfterConsumeBackStageProperties, isTop = isTop) } private fun mapValueIsObjectType(mapValueType: String) = (mapValueType == MAP_DEFAULT_OBJECT_VALUE_TYPE