fix code analyze issue

This commit is contained in:
2022-07-19 11:34:31 +08:00
parent 248d9a57d4
commit c4ff209d72
38 changed files with 117 additions and 131 deletions

1
.gitignore vendored
View File

@@ -1,6 +1,5 @@
.* .*
gradlew* gradlew*
build build
gradle
!.gitignore !.gitignore

View File

@@ -1,11 +1,12 @@
buildscript { buildscript {
ext { ext {
kotlin_version = '1.3.72' kotlin_version = '1.7.0'
spring_version = "2.7.0"
} }
repositories { repositories {
mavenLocal() mavenLocal()
maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' } maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
mavenCentral() mavenCentral()
} }
@@ -15,40 +16,38 @@ buildscript {
} }
allprojects { allprojects {
ext {
version '2.0'
}
group 'com.synebula' group 'com.synebula'
version version version version
} }
subprojects { subprojects {
ext {
version '0.13.1'
spring_version = "2.3.0.RELEASE"
}
buildscript { buildscript {
repositories { repositories {
mavenLocal() mavenLocal()
maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' } maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
mavenCentral() mavenCentral()
} }
} }
repositories { repositories {
mavenLocal() mavenLocal()
maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' } maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
mavenCentral() mavenCentral()
} }
apply plugin: 'idea' apply plugin: 'idea'
apply plugin: 'java' apply plugin: 'java'
apply plugin: 'kotlin' apply plugin: 'kotlin'
apply plugin: 'maven'
apply plugin: 'maven-publish' apply plugin: 'maven-publish'
dependencies { dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" api "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" api "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
testCompile group: 'junit', name: 'junit', version: '4.12' testApi group: 'junit', name: 'junit', version: '4.12'
} }
sourceCompatibility = 1.8 sourceCompatibility = 1.8

BIN
gradle/wrapper/gradle-wrapper.jar vendored Normal file

Binary file not shown.

View File

@@ -0,0 +1,6 @@
#Mon May 18 17:21:26 CST 2020
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-all.zip
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME

View File

@@ -1,4 +1,4 @@
rootProject.name = 'myths.gaea' rootProject.name = 'gaea'
include 'src:gaea' include 'src:gaea'
include 'src:gaea.app' include 'src:gaea.app'
include 'src:gaea.mongo' include 'src:gaea.mongo'

View File

@@ -7,16 +7,16 @@ buildscript {
apply plugin: 'kotlin-spring' apply plugin: 'kotlin-spring'
dependencies { dependencies {
compile project(":src:gaea") api project(":src:gaea")
compile("org.springframework.boot:spring-boot-starter-web:$spring_version") api("org.springframework.boot:spring-boot-starter-web:$spring_version")
compile("org.springframework.boot:spring-boot-starter-aop:$spring_version") api("org.springframework.boot:spring-boot-starter-aop:$spring_version")
compile("org.springframework.boot:spring-boot-starter-mail:$spring_version") api("org.springframework.boot:spring-boot-starter-mail:$spring_version")
compile("org.springframework.boot:spring-boot-starter-security:$spring_version") api("org.springframework.boot:spring-boot-starter-security:$spring_version")
compile group: 'net.sf.dozer', name: 'dozer', version: '5.5.1' api group: 'net.sf.dozer', name: 'dozer', version: '5.5.1'
compile group: 'org.apache.poi', name: 'poi-ooxml', version: '5.0.0' api group: 'org.apache.poi', name: 'poi-ooxml', version: '5.0.0'
compile group: 'com.google.code.gson', name: 'gson', version: '2.8.6' api group: 'com.google.code.gson', name: 'gson', version: '2.8.6'
compile group: 'com.google.guava', name: 'guava', version: '30.1.1-jre' api group: 'com.google.guava', name: 'guava', version: '30.1.1-jre'
compile group: 'com.auth0', name: 'java-jwt', version: '3.14.0' api group: 'com.auth0', name: 'java-jwt', version: '3.14.0'
} }
publishing { publishing {

View File

@@ -2,9 +2,7 @@ package com.synebula.gaea.app.cmd
import com.synebula.gaea.data.serialization.json.IJsonSerializer import com.synebula.gaea.data.serialization.json.IJsonSerializer
import com.synebula.gaea.domain.model.IAggregateRoot import com.synebula.gaea.domain.model.IAggregateRoot
import com.synebula.gaea.domain.service.ICommand
import com.synebula.gaea.domain.service.ILazyService import com.synebula.gaea.domain.service.ILazyService
import com.synebula.gaea.domain.service.IService
import com.synebula.gaea.log.ILogger import com.synebula.gaea.log.ILogger
import javax.annotation.Resource import javax.annotation.Resource

View File

@@ -9,7 +9,7 @@ import java.util.concurrent.ConcurrentHashMap
/** /**
* 使用 log4j進行日志记录。 * 使用 log4j進行日志记录。
* *
* @author reize * @author alex
* @version 0.0.1 * @version 0.0.1
* @since 2016年9月18日 下午2:13:43 * @since 2016年9月18日 下午2:13:43
*/ */

View File

@@ -72,11 +72,10 @@ abstract class AppAspect {
} }
} }
var message = "$moduleName - $funcName 异常" var message = "$moduleName - $funcName 异常"
if (ex is NoticeUserException) { message = if (ex is NoticeUserException) {
message = "$message: ${ex.message}" "$message: ${ex.message}"
} else { } else {
message = "$message" "$message"
} }
logger.error( logger.error(
ex, ex,

View File

@@ -1,14 +1,14 @@
package com.synebula.gaea.app.component package com.synebula.gaea.app.component.bus
import com.google.common.eventbus.AsyncEventBus import com.google.common.eventbus.AsyncEventBus
import com.google.common.eventbus.EventBus import com.google.common.eventbus.EventBus
import com.synebula.gaea.event.IEvent import com.synebula.gaea.bus.IMessage
import com.synebula.gaea.event.IEventBus import com.synebula.gaea.bus.IMessageBus
import org.springframework.stereotype.Component import org.springframework.stereotype.Component
import java.util.concurrent.Executors import java.util.concurrent.Executors
@Component @Component
class EventBus : IEventBus { class EventBus : IMessageBus {
/** /**
* 同步事件总线 * 同步事件总线
@@ -30,12 +30,12 @@ class EventBus : IEventBus {
asyncEventBus.unregister(obj) asyncEventBus.unregister(obj)
} }
override fun publish(event: IEvent) { override fun publish(message: IMessage) {
eventBus.post(event) eventBus.post(message)
} }
override fun publishAsync(event: IEvent) { override fun publishAsync(message: IMessage) {
asyncEventBus.post(event) asyncEventBus.post(message)
} }
} }

View File

@@ -1,7 +1,7 @@
package com.synebula.gaea.app.component package com.synebula.gaea.app.component.bus
import com.google.common.eventbus.Subscribe import com.google.common.eventbus.Subscribe
import com.synebula.gaea.event.IEventBus import com.synebula.gaea.bus.IMessageBus
import org.springframework.beans.BeansException import org.springframework.beans.BeansException
import org.springframework.beans.factory.annotation.Autowired import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.config.BeanPostProcessor import org.springframework.beans.factory.config.BeanPostProcessor
@@ -14,7 +14,7 @@ class EventBusSubscriberProcessor : BeanPostProcessor {
// 事件总线bean由Spring IoC容器负责创建这里只需要通过@Autowired注解注入该bean即可使用事件总线 // 事件总线bean由Spring IoC容器负责创建这里只需要通过@Autowired注解注入该bean即可使用事件总线
@Autowired @Autowired
var eventBus: IEventBus? = null var messageBus: IMessageBus? = null
@Throws(BeansException::class) @Throws(BeansException::class)
override fun postProcessBeforeInitialization(bean: Any, beanName: String): Any { override fun postProcessBeforeInitialization(bean: Any, beanName: String): Any {
@@ -28,13 +28,13 @@ class EventBusSubscriberProcessor : BeanPostProcessor {
val methods: Array<Method> = bean.javaClass.methods val methods: Array<Method> = bean.javaClass.methods
for (method in methods) { for (method in methods) {
// check the annotations on that method // check the annotations on that method
val annotations: Array<Annotation> = method.getAnnotations() val annotations: Array<Annotation> = method.annotations
for (annotation in annotations) { for (annotation in annotations) {
// if it contains the Subscribe annotation // if it contains Subscribe annotation
if (annotation.annotationClass == Subscribe::class) { if (annotation.annotationClass == Subscribe::class) {
// 如果这是一个Guava @Subscribe注解的事件监听器方法说明所在bean实例 // 如果这是一个Guava @Subscribe注解的事件监听器方法说明所在bean实例
// 对应一个Guava事件监听器类将该bean实例注册到Guava事件总线 // 对应一个Guava事件监听器类将该bean实例注册到Guava事件总线
eventBus?.register(bean) messageBus?.register(bean)
return bean return bean
} }
} }

View File

@@ -1,6 +1,6 @@
dependencies { dependencies {
compile project(":src:gaea") api project(":src:gaea")
compile("org.springframework.boot:spring-boot-starter-data-mongodb:$spring_version") api("org.springframework.boot:spring-boot-starter-data-mongodb:$spring_version")
} }
publishing { publishing {

View File

@@ -55,7 +55,7 @@ fun Query.where(
list.add(tryRangeWhere(param.key, value, onFieldType)) list.add(tryRangeWhere(param.key, value, onFieldType))
} else { } else {
//判断执行查询子元素还是本字段 //判断执行查询子元素还是本字段
val field = if (where.children.isEmpty()) key else where.children val field = where.children.ifEmpty { key }
var criteria = Criteria.where(field) var criteria = Criteria.where(field)
criteria = when (where.operator) { criteria = when (where.operator) {
Operator.eq -> criteria.`is`(value) Operator.eq -> criteria.`is`(value)

View File

@@ -92,7 +92,7 @@ open class MongoQuery(var template: MongoTemplate, var logger: ILogger? = null)
if (!validViewCollection || this.template.collectionExists(name)) if (!validViewCollection || this.template.collectionExists(name))
name name
else { else {
throw RuntimeException("找不到名为[$table]的集合") throw RuntimeException("找不到名为[${clazz.name}]的集合")
} }
} }
} }

View File

@@ -0,0 +1,3 @@
package com.synebula.gaea.bus
interface IMessage

View File

@@ -1,6 +1,6 @@
package com.synebula.gaea.event package com.synebula.gaea.bus
interface IEventBus { interface IMessageBus {
/** /**
* 注册事件Listener * 注册事件Listener
@@ -16,13 +16,13 @@ interface IEventBus {
/** /**
* 同步发布事件 * 同步发布事件
* @param event 事件 * @param message 事件
*/ */
fun publish(event: IEvent) fun publish(message: IMessage)
/** /**
* 异步发布事件 * 异步发布事件
* @param event 事件 * @param message 事件
*/ */
fun publishAsync(event: IEvent) fun publishAsync(message: IMessage)
} }

View File

@@ -11,13 +11,13 @@ import java.util.*
* 参数:年=y月=M日=d时=H分=m秒=s毫秒=S。位数最好使用默认最大长度。 * 参数:年=y月=M日=d时=H分=m秒=s毫秒=S。位数最好使用默认最大长度。
*/ */
class DateCode(pattern: String = "yyyyMMdd") : ICodeGenerator<Long> { class DateCode(pattern: String = "yyyyMMdd") : ICodeGenerator<Long> {
var formator = SimpleDateFormat() var formatter = SimpleDateFormat()
init { init {
formator.applyPattern(pattern) formatter.applyPattern(pattern)
} }
override fun generate(): Long { override fun generate(): Long {
return java.lang.Long.parseLong(formator.format(Date())) return java.lang.Long.parseLong(formatter.format(Date()))
} }
} }

View File

@@ -1,6 +1,7 @@
package com.synebula.gaea.data.code package com.synebula.gaea.data.code
import java.util.* import java.util.*
import kotlin.math.pow
/** /**
* 固定长度随机编号生成。 * 固定长度随机编号生成。
@@ -9,8 +10,8 @@ import java.util.*
* @since 2016年10月24日 上午10:58:05 * @since 2016年10月24日 上午10:58:05
*/ */
class FixedRandomCode( class FixedRandomCode(
//生成的随机编号长度。 //生成的随机编号长度。
var length: Int var length: Int,
) : ICodeGenerator<String> { ) : ICodeGenerator<String> {
/** /**
@@ -32,12 +33,12 @@ class FixedRandomCode(
var format = String.format("%s%d%dd", "%", 0, calcMaxLength) var format = String.format("%s%d%dd", "%", 0, calcMaxLength)
val count = this.length / calcMaxLength val count = this.length / calcMaxLength
for (i in 0 until count) { for (i in 0 until count) {
buffer.append(String.format(format, (random.nextDouble() * Math.pow(10.0, calcMaxLength.toDouble())).toInt())) buffer.append(String.format(format, (random.nextDouble() * 10.0.pow(calcMaxLength.toDouble())).toInt()))
} }
val last = this.length % calcMaxLength val last = this.length % calcMaxLength
if (last != 0) { if (last != 0) {
format = String.format("%s%d%dd", "%", 0, last) format = String.format("%s%d%dd", "%", 0, last)
buffer.append(String.format(format, (random.nextDouble() * Math.pow(10.0, last.toDouble())).toInt())) buffer.append(String.format(format, (random.nextDouble() * 10.0.pow(last.toDouble())).toInt()))
} }
return buffer.toString() return buffer.toString()
} }

View File

@@ -13,7 +13,7 @@ package com.synebula.gaea.data.code
* 0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000 <br></br> * 0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000 <br></br>
* 1位标识由于long基本类型在Java中是带符号的最高位是符号位正数是0负数是1所以id一般是正数最高位是0<br></br> * 1位标识由于long基本类型在Java中是带符号的最高位是符号位正数是0负数是1所以id一般是正数最高位是0<br></br>
* 41位时间截(毫秒级)注意41位时间截不是存储当前时间的时间截而是存储时间截的差值当前时间截 - 开始时间截)<br></br> * 41位时间截(毫秒级)注意41位时间截不是存储当前时间的时间截而是存储时间截的差值当前时间截 - 开始时间截)<br></br>
* 得到的值这里的的开始时间截一般是我们的id生成器开始使用的时间由我们程序来指定的如下下面程序Snowflake类的twepoch属性)。<br></br> * 得到的值这里的的开始时间截一般是我们的id生成器开始使用的时间由我们程序来指定的如下下面程序Snowflake类的origin属性)。<br></br>
* 41位的时间截可以使用69年年T = (1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69 <br></br> * 41位的时间截可以使用69年年T = (1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69 <br></br>
* 10位的数据机器位可以部署在1024个节点包括5位datacenter和5位worker <br></br> * 10位的数据机器位可以部署在1024个节点包括5位datacenter和5位worker <br></br>
* 12位序列毫秒内的计数12位的计数顺序号支持每个节点每毫秒(同一机器,同一时间截)产生4096个ID序号<br></br> * 12位序列毫秒内的计数12位的计数顺序号支持每个节点每毫秒(同一机器,同一时间截)产生4096个ID序号<br></br>
@@ -35,7 +35,7 @@ open class SnowflakeCode(
/** /**
* 开始时间截 (2018-01-01) * 开始时间截 (2018-01-01)
*/ */
private val twepoch = 1514736000000L private val origin = 1514736000000L
/** /**
* 机器id所占的位数 * 机器id所占的位数
@@ -142,7 +142,7 @@ open class SnowflakeCode(
lastTimestamp = current lastTimestamp = current
//移位并通过或运算拼到一起组成64位的ID //移位并通过或运算拼到一起组成64位的ID
return (current - twepoch shl timestampLeftShift return (current - origin shl timestampLeftShift
or (datacenter shl datacenterShift) or (datacenter shl datacenterShift)
or (worker shl workerShift) or (worker shl workerShift)
or sequence) or sequence)

View File

@@ -275,7 +275,6 @@ class DateTime() : Comparable<DateTime> {
* @return true or false * @return true or false
*/ */
fun isBetween(start: DateTime, end: DateTime): Boolean { fun isBetween(start: DateTime, end: DateTime): Boolean {
//return this in start..end
return start.dateNoTime.compareTo(this.dateNoTime) * this.dateNoTime.compareTo(end.dateNoTime) >= 0 return start.dateNoTime.compareTo(this.dateNoTime) * this.dateNoTime.compareTo(end.dateNoTime) >= 0
} }

View File

@@ -1,21 +0,0 @@
package com.synebula.gaea.domain.model
import java.util.*
/**
* 记录聚合根
* 聚合根外添加了创建和修改的人\时间信息
*/
abstract class AggregateRecord<TKey> : AggregateRoot<TKey>() {
var creator: String? = null
var creatorName: String? = null
var created: Date = Date()
set(value) {
field = value
modified = value
}
var modifier: String? = null
var modifierName: String? = null
var modified: Date = Date()
}

View File

@@ -1,3 +0,0 @@
package com.synebula.gaea.domain.model.complex
abstract class ComplexAggregateRoot<TKey, TSecond> : ComplexEntity<TKey, TSecond>(), IComplexAggregateRoot<TKey, TSecond>

View File

@@ -1,5 +0,0 @@
package com.synebula.gaea.domain.model.complex
abstract class ComplexEntity<TKey, TSecond> : IComplexEntity<TKey, TSecond> {
}

View File

@@ -1,9 +0,0 @@
package com.synebula.gaea.domain.model.complex
/**
* 继承本接口,说明对象为聚合根。
*
* @param <TKey> 主键的类型。
* @author alex
*/
interface IComplexAggregateRoot<TKey, TSecond> : IComplexEntity<TKey, TSecond>

View File

@@ -1,7 +0,0 @@
package com.synebula.gaea.domain.model.complex
import com.synebula.gaea.domain.model.IEntity
interface IComplexEntity<TKey, TSecond> : IEntity<TKey> {
var secondary: TSecond?
}

View File

@@ -0,0 +1,21 @@
package com.synebula.gaea.domain.record
import java.util.*
/**
* 记录信息
* 添加了创建和修改的人\时间信息
*/
abstract class Record<TKey> {
//记录增加信息
var creator: String? = null
var creatorName: String? = null
var createTime: Date = Date()
//记录修改信息
var modifier: String? = null
var modifierName: String? = null
var modifyTime: Date = Date()
}

View File

@@ -8,5 +8,6 @@ package com.synebula.gaea.domain.service
* @since 2020-05-15 * @since 2020-05-15
*/ */
open class Command : ICommand { open class Command : ICommand {
override var payload = ""
override var timestamp = 0L override var timestamp = 0L
} }

View File

@@ -8,6 +8,12 @@ package com.synebula.gaea.domain.service
* @since 2020-05-15 * @since 2020-05-15
*/ */
interface ICommand { interface ICommand {
/**
* 命令载荷, 实际的业务数据
*/
var payload: String
/** /**
* 时间戳。 * 时间戳。
*/ */

View File

@@ -1,6 +1,5 @@
package com.synebula.gaea.domain.service package com.synebula.gaea.domain.service
import com.synebula.gaea.data.IObjectConverter
import com.synebula.gaea.data.message.DataMessage import com.synebula.gaea.data.message.DataMessage
import com.synebula.gaea.data.message.Message import com.synebula.gaea.data.message.Message
import com.synebula.gaea.domain.model.IAggregateRoot import com.synebula.gaea.domain.model.IAggregateRoot

View File

@@ -1,4 +0,0 @@
package com.synebula.gaea.event
interface IEvent {
}

View File

@@ -34,10 +34,11 @@ object ClassPath {
// 判断路径最后一个字符是不是"/",如果不是加上 // 判断路径最后一个字符是不是"/",如果不是加上
path = if (path.lastIndexOf("/") != path.length - 1) "$path/" else path path = if (path.lastIndexOf("/") != path.length - 1) "$path/" else path
var resources: Enumeration<URL>? = null val resources: Enumeration<URL>?
try { try {
resources = ClassLoaderContext.get().getResources(path) resources = ClassLoaderContext.get().getResources(path)
} catch (e: IOException) { } catch (ex: IOException) {
throw RuntimeException(ex)
} }
while (resources!!.hasMoreElements()) { while (resources!!.hasMoreElements()) {

View File

@@ -30,7 +30,8 @@ class ClassScanner(private var packageName: String) {
/** /**
* 文件过滤器 * 文件过滤器
*/ */
private val fileFilter = FileFilter { file -> file.isDirectory || file.name.endsWith(".class") || file.name.endsWith(".jar") } private val fileFilter =
FileFilter { file -> file.isDirectory || file.name.endsWith(".class") || file.name.endsWith(".jar") }
/** /**
@@ -81,12 +82,15 @@ class ClassScanner(private var packageName: String) {
val files = scanDirectory(realPath) val files = scanDirectory(realPath)
for (file in files) { for (file in files) {
val fileName = file.toString() val fileName = file.toString()
if (fileName.contains(".jar") && !fileName.endsWith(".class")) if (fileName.contains(".jar") && !fileName.endsWith(".class")) {
scanJar(file) scanJar(file)
else if (fileName.endsWith(".class")) }
scanClass(realPath, file) // else if (fileName.endsWith(".class")) {
// }
scanClass(realPath, file)
} }
} catch (e: UnsupportedEncodingException) { } catch (ex: UnsupportedEncodingException) {
throw ex
} }
} }
} }
@@ -145,6 +149,7 @@ class ClassScanner(private var packageName: String) {
} }
jar.close() jar.close()
} catch (ex: Throwable) { } catch (ex: Throwable) {
throw ex
} }
} }
@@ -191,7 +196,7 @@ class ClassScanner(private var packageName: String) {
} }
} }
} catch (ex: Throwable) { } catch (ex: Throwable) {
throw ex
} }
} }

View File

@@ -2,25 +2,28 @@ package com.synebula.gaea.log
/** /**
* 日志等级 * 日志等级
* @author Looly
*/ */
enum class Level { enum class Level {
/** /**
* 'TRACE' log level. * 'TRACE' log level.
*/ */
TRACE, TRACE,
/** /**
* 'DEBUG' log level. * 'DEBUG' log level.
*/ */
DEBUG, DEBUG,
/** /**
* 'INFO' log level. * 'INFO' log level.
*/ */
INFO, INFO,
/** /**
* 'WARN' log level. * 'WARN' log level.
*/ */
WARN, WARN,
/** /**
* 'ERROR' log level. * 'ERROR' log level.
*/ */

View File

@@ -3,7 +3,6 @@ package com.synebula.gaea.log.logger
/** /**
* DEBUG级别日志接口 * DEBUG级别日志接口
* *
* @author Looly
*/ */
interface IDebugLogger { interface IDebugLogger {
/** /**

View File

@@ -2,7 +2,6 @@ package com.synebula.gaea.log.logger
/** /**
* ERROR级别日志接口 * ERROR级别日志接口
* @author Looly
*/ */
interface IErrorLogger { interface IErrorLogger {
/** /**

View File

@@ -2,7 +2,6 @@ package com.synebula.gaea.log.logger
/** /**
* INFO级别日志接口 * INFO级别日志接口
* @author Looly
*/ */
interface IInfoLogger { interface IInfoLogger {
/** /**

View File

@@ -3,7 +3,6 @@ package com.synebula.gaea.log.logger
/** /**
* TRACE级别日志接口 * TRACE级别日志接口
* *
* @author Looly
*/ */
interface ITraceLogger { interface ITraceLogger {
/** /**

View File

@@ -2,7 +2,6 @@ package com.synebula.gaea.log.logger
/** /**
* WARN级别日志接口 * WARN级别日志接口
* @author Looly
*/ */
interface IWarnLogger { interface IWarnLogger {
/** /**