0.3.0 完成可以开发使用的库
This commit is contained in:
@@ -21,8 +21,8 @@ allprojects {
|
||||
|
||||
subprojects {
|
||||
ext {
|
||||
version '0.2.1'
|
||||
spring_version = "2.0.0.RELEASE"
|
||||
version '0.3.0'
|
||||
spring_version = "2.3.0.RELEASE"
|
||||
}
|
||||
|
||||
buildscript {
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.synebula.gaea.app
|
||||
|
||||
import com.synebula.gaea.domain.service.ICommand
|
||||
import com.synebula.gaea.domain.service.IService
|
||||
import com.synebula.gaea.log.ILogger
|
||||
|
||||
/**
|
||||
* 指令服务,同时实现ICommandApp
|
||||
*
|
||||
* @param name 业务名称
|
||||
* @param service 业务domain服务
|
||||
* @param logger 日志组件
|
||||
*/
|
||||
open class CommandApp<TCommand : ICommand, TKey>(
|
||||
override var name: String,
|
||||
override var service: IService<TKey>?,
|
||||
override var logger: ILogger) : ICommandApp<TCommand, TKey> {
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.synebula.gaea.app
|
||||
|
||||
import com.synebula.gaea.app.components.HttpMessage
|
||||
import com.synebula.gaea.app.component.HttpMessage
|
||||
import com.synebula.gaea.data.message.Status
|
||||
import com.synebula.gaea.log.ILogger
|
||||
|
||||
@@ -24,12 +24,12 @@ interface IApplication {
|
||||
val msg = HttpMessage(Status.Success)
|
||||
try {
|
||||
process(msg)
|
||||
logger.debug("$name business execute success")
|
||||
logger.debug(this, "$name business execute success")
|
||||
} catch (ex: Exception) {
|
||||
msg.status = Status.Error
|
||||
msg.message = if (error.isEmpty()) ex.message ?: "" else error
|
||||
msg.data = ex.message
|
||||
logger.error(ex, "$error: ${ex.message}")
|
||||
logger.error(this, "$error: ${ex.message}")
|
||||
}
|
||||
return msg
|
||||
}
|
||||
@@ -41,9 +41,9 @@ interface IApplication {
|
||||
val msg = HttpMessage(Status.Success)
|
||||
try {
|
||||
process(msg)
|
||||
logger.debug("$name business execute success")
|
||||
logger.debug(this, "$name business execute success")
|
||||
} catch (ex: Exception) {
|
||||
logger.error(ex, "$error。异常消息将抛出!: ${ex.message}")
|
||||
logger.error(this, ex, "$error。异常消息将抛出!: ${ex.message}")
|
||||
throw RuntimeException(error, ex)
|
||||
}
|
||||
return msg
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.synebula.gaea.app
|
||||
|
||||
import com.synebula.gaea.app.components.HttpMessage
|
||||
import com.synebula.gaea.app.component.HttpMessage
|
||||
import com.synebula.gaea.data.message.Status
|
||||
import com.synebula.gaea.domain.service.ICommand
|
||||
import com.synebula.gaea.domain.service.IService
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.synebula.gaea.app
|
||||
|
||||
import com.synebula.gaea.app.components.HttpMessage
|
||||
import com.synebula.gaea.app.component.HttpMessage
|
||||
import com.synebula.gaea.data.message.Status
|
||||
import com.synebula.gaea.query.IQuery
|
||||
import com.synebula.gaea.query.PagingParam
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.synebula.gaea.app
|
||||
|
||||
import com.synebula.gaea.log.ILogger
|
||||
import com.synebula.gaea.query.IQuery
|
||||
|
||||
/**
|
||||
* 联合服务,同时实现了ICommandApp和IQueryApp接口
|
||||
*
|
||||
* @param name 业务名称
|
||||
* @param query 业务查询服务
|
||||
* @param logger 日志组件
|
||||
*/
|
||||
open class QueryApp<TView, TKey>(
|
||||
override var name: String,
|
||||
override var query: IQuery<TView, TKey>?,
|
||||
override var logger: ILogger) : IQueryApp<TView, TKey> {
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.synebula.gaea.app
|
||||
|
||||
import com.synebula.gaea.domain.service.ICommand
|
||||
import com.synebula.gaea.domain.service.IService
|
||||
import com.synebula.gaea.log.ILogger
|
||||
import com.synebula.gaea.query.IQuery
|
||||
|
||||
/**
|
||||
* 联合服务,同时实现了ICommandApp和IQueryApp接口
|
||||
*
|
||||
* @param name 业务名称
|
||||
* @param service 业务domain服务
|
||||
* @param query 业务查询服务
|
||||
* @param logger 日志组件
|
||||
*/
|
||||
open class UnionApp<TCommand : ICommand, TView, TKey>(
|
||||
override var name: String,
|
||||
override var service: IService<TKey>?,
|
||||
override var query: IQuery<TView, TKey>?,
|
||||
override var logger: ILogger)
|
||||
: ICommandApp<TCommand, TKey>, IQueryApp<TView, TKey> {
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.synebula.gaea.app.component
|
||||
|
||||
import org.springframework.core.type.classreading.MetadataReader
|
||||
import org.springframework.core.type.classreading.MetadataReaderFactory
|
||||
import org.springframework.core.type.filter.TypeFilter
|
||||
|
||||
class AllTypeFilter : TypeFilter {
|
||||
override fun match(metadataReader: MetadataReader, metadataReaderFactory: MetadataReaderFactory): Boolean {
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.synebula.gaea.app.component
|
||||
|
||||
import com.synebula.gaea.data.IObjectConverter
|
||||
import org.dozer.DozerBeanMapper
|
||||
import org.springframework.stereotype.Component
|
||||
|
||||
@Component
|
||||
class DozerConverter : IObjectConverter {
|
||||
private val converter = DozerBeanMapper()
|
||||
|
||||
override fun <T> convert(src: Any, dest: Class<T>): T = converter.map(src, dest)
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.synebula.gaea.app.components
|
||||
package com.synebula.gaea.app.component
|
||||
|
||||
import com.synebula.gaea.data.message.Status
|
||||
import com.synebula.gaea.data.message.Message
|
||||
@@ -0,0 +1,276 @@
|
||||
package com.synebula.gaea.app.component
|
||||
|
||||
import com.synebula.gaea.log.ILogger
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.stereotype.Component
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
/**
|
||||
* 使用 log4j進行日志记录。
|
||||
*
|
||||
* @author reize
|
||||
* @version 0.0.1
|
||||
* @since 2016年9月18日 下午2:13:43
|
||||
*/
|
||||
@Component
|
||||
class Logger : ILogger {
|
||||
|
||||
override val name: String
|
||||
get() {
|
||||
return this.logger.name
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认日志记录
|
||||
*/
|
||||
private val logger = LoggerFactory.getLogger(Logger::class.java)
|
||||
|
||||
/**
|
||||
* 特殊日志记录字典
|
||||
*/
|
||||
private val loggers = ConcurrentHashMap<Class<*>, org.slf4j.Logger>()
|
||||
|
||||
init {
|
||||
loggers[Logger::class.java] = logger
|
||||
}
|
||||
|
||||
override val isTraceEnabled: Boolean
|
||||
get() {
|
||||
return this.logger.isTraceEnabled
|
||||
}
|
||||
|
||||
|
||||
override fun trace(t: Throwable) {
|
||||
this.logger.trace(t.toString())
|
||||
}
|
||||
|
||||
|
||||
override fun trace(format: String, vararg args: Any) {
|
||||
if (this.logger.isTraceEnabled) {
|
||||
val message = String.format(format, *args)
|
||||
this.logger.trace(message)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun trace(t: Throwable, format: String, vararg args: Any) {
|
||||
if (this.logger.isTraceEnabled) {
|
||||
val message = String.format(format, *args)
|
||||
this.logger.trace(message, t)
|
||||
}
|
||||
}
|
||||
|
||||
override fun trace(obj: Any, format: String, vararg args: Any) {
|
||||
if (this.logger.isTraceEnabled) {
|
||||
val real = this.getLogger(obj)
|
||||
val message = String.format(format, *args)
|
||||
real.trace(message)
|
||||
}
|
||||
}
|
||||
|
||||
override fun trace(obj: Any, t: Throwable?, format: String, vararg args: Any) {
|
||||
if (this.logger.isTraceEnabled) {
|
||||
val real = this.getLogger(obj)
|
||||
val message = String.format(format, *args)
|
||||
real.trace(message, t)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* debug start
|
||||
*/
|
||||
override val isDebugEnabled: Boolean
|
||||
get() {
|
||||
return this.logger.isDebugEnabled
|
||||
}
|
||||
|
||||
|
||||
override fun debug(t: Throwable) {
|
||||
if (this.logger.isDebugEnabled) {
|
||||
this.logger.debug(t.toString())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun debug(format: String, vararg args: Any) {
|
||||
if (this.logger.isDebugEnabled) {
|
||||
val message = String.format(format, *args)
|
||||
this.logger.debug(message)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun debug(t: Throwable, format: String, vararg args: Any) {
|
||||
if (this.logger.isDebugEnabled) {
|
||||
val message = String.format(format, *args)
|
||||
this.logger.debug(message, t)
|
||||
}
|
||||
}
|
||||
|
||||
override fun debug(obj: Any, format: String, vararg args: Any) {
|
||||
if (this.logger.isDebugEnabled) {
|
||||
val real = this.getLogger(obj)
|
||||
val message = String.format(format, *args)
|
||||
real.debug(message)
|
||||
}
|
||||
}
|
||||
|
||||
override fun debug(obj: Any, t: Throwable?, format: String, vararg args: Any) {
|
||||
if (this.logger.isDebugEnabled) {
|
||||
val real = this.getLogger(obj)
|
||||
val message = String.format(format, *args)
|
||||
real.debug(message, t)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* info start
|
||||
*/
|
||||
override val isInfoEnabled: Boolean
|
||||
get() {
|
||||
return this.logger.isInfoEnabled
|
||||
}
|
||||
|
||||
override fun info(t: Throwable) {
|
||||
if (this.logger.isInfoEnabled) {
|
||||
this.logger.info(t.toString())
|
||||
}
|
||||
}
|
||||
|
||||
override fun info(format: String, vararg args: Any) {
|
||||
if (this.logger.isInfoEnabled) {
|
||||
val message = String.format(format, *args)
|
||||
this.logger.info(message)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun info(t: Throwable, format: String, vararg args: Any) {
|
||||
if (this.logger.isInfoEnabled) {
|
||||
val message = String.format(format, *args)
|
||||
this.logger.info(message, t)
|
||||
}
|
||||
}
|
||||
|
||||
override fun info(obj: Any, format: String, vararg args: Any) {
|
||||
if (this.logger.isInfoEnabled) {
|
||||
val real = this.getLogger(obj)
|
||||
val message = String.format(format, *args)
|
||||
real.info(message)
|
||||
}
|
||||
}
|
||||
|
||||
override fun info(obj: Any, t: Throwable?, format: String, vararg args: Any) {
|
||||
if (this.logger.isInfoEnabled) {
|
||||
val real = this.getLogger(obj)
|
||||
val message = String.format(format, *args)
|
||||
real.info(message, t)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* warn start
|
||||
*/
|
||||
override val isWarnEnabled: Boolean
|
||||
get() {
|
||||
return this.logger.isWarnEnabled
|
||||
}
|
||||
|
||||
override fun warn(t: Throwable) {
|
||||
if (this.logger.isWarnEnabled) {
|
||||
this.logger.warn(t.toString())
|
||||
}
|
||||
}
|
||||
|
||||
override fun warn(format: String, vararg args: Any) {
|
||||
if (this.logger.isWarnEnabled) {
|
||||
val message = String.format(format, *args)
|
||||
this.logger.warn(message)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun warn(t: Throwable, format: String, vararg args: Any) {
|
||||
if (this.logger.isWarnEnabled) {
|
||||
val message = String.format(format, *args)
|
||||
this.logger.warn(message, t)
|
||||
}
|
||||
}
|
||||
|
||||
override fun warn(obj: Any, format: String, vararg args: Any) {
|
||||
if (this.logger.isWarnEnabled) {
|
||||
val real = this.getLogger(obj)
|
||||
val message = String.format(format, *args)
|
||||
real.warn(message)
|
||||
}
|
||||
}
|
||||
|
||||
override fun warn(obj: Any, t: Throwable?, format: String, vararg args: Any) {
|
||||
if (this.logger.isWarnEnabled) {
|
||||
val real = this.getLogger(obj)
|
||||
val message = String.format(format, *args)
|
||||
real.warn(message, t)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* error start
|
||||
*/
|
||||
override val isErrorEnabled: Boolean
|
||||
get() {
|
||||
return this.logger.isErrorEnabled
|
||||
}
|
||||
|
||||
override fun error(t: Throwable) {
|
||||
if (this.logger.isErrorEnabled) {
|
||||
this.logger.error(t.toString())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun error(format: String, vararg args: Any) {
|
||||
if (this.logger.isErrorEnabled) {
|
||||
val message = String.format(format, *args)
|
||||
this.logger.error(message)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun error(t: Throwable, format: String, vararg args: Any) {
|
||||
if (this.logger.isErrorEnabled) {
|
||||
val message = String.format(format, *args)
|
||||
this.logger.error(message, t)
|
||||
}
|
||||
}
|
||||
|
||||
override fun error(obj: Any, format: String, vararg args: Any) {
|
||||
if (this.logger.isErrorEnabled) {
|
||||
val real = this.getLogger(obj)
|
||||
val message = String.format(format, *args)
|
||||
real.error(message)
|
||||
}
|
||||
}
|
||||
|
||||
override fun error(obj: Any, t: Throwable?, format: String, vararg args: Any) {
|
||||
if (this.logger.isErrorEnabled) {
|
||||
val real = this.getLogger(obj)
|
||||
val message = String.format(format, *args)
|
||||
real.error(message, t)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取日志记录器
|
||||
*/
|
||||
private fun getLogger(obj: Any): org.slf4j.Logger {
|
||||
var real = this.loggers.getOrDefault(obj.javaClass, null)
|
||||
if (real == null) {
|
||||
real = LoggerFactory.getLogger(obj::class.java)
|
||||
this.loggers[obj::class.java] = real
|
||||
}
|
||||
return real!!
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
package com.synebula.gaea.query.mongo
|
||||
|
||||
import com.synebula.gaea.log.ILogger
|
||||
import com.synebula.gaea.query.OrderType
|
||||
import org.springframework.data.domain.Sort
|
||||
import org.springframework.data.mongodb.core.query.Criteria
|
||||
import org.springframework.data.mongodb.core.query.Query
|
||||
import org.springframework.data.mongodb.core.query.isEqualTo
|
||||
import java.lang.reflect.Field
|
||||
|
||||
/**
|
||||
* 声明了Mongo查询的特有方法
|
||||
*/
|
||||
interface IMongoQuery<TView> {
|
||||
/**
|
||||
* 日志组件
|
||||
*/
|
||||
var logger: ILogger?
|
||||
|
||||
/**
|
||||
* 系统类型
|
||||
*/
|
||||
private fun systemClass() = arrayOf(
|
||||
"String",
|
||||
"Date",
|
||||
"Int",
|
||||
"Double",
|
||||
"Float",
|
||||
"BigDecimal",
|
||||
"Decimal")
|
||||
|
||||
/**
|
||||
* 获取ID查询条件
|
||||
*
|
||||
* @param id 业务ID
|
||||
*/
|
||||
fun idQuery(id: String): Query = Query(Criteria("_id").isEqualTo(id))
|
||||
|
||||
/**
|
||||
* 获取视图对象的字段列表
|
||||
*
|
||||
* @param clazz 视图对象类型
|
||||
*/
|
||||
fun fields(clazz: Class<TView>): List<String> {
|
||||
return analyseFields(clazz.declaredFields)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取查询条件
|
||||
*
|
||||
* @param query 查询条件
|
||||
* @param fields 字段列表
|
||||
*/
|
||||
fun select(query: Query, fields: Array<String>): Query {
|
||||
fields.forEach {
|
||||
query.fields().include(it)
|
||||
}
|
||||
return query
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据参数获取查询条件
|
||||
*
|
||||
* @param query 查询条件
|
||||
* @param params 参数列表
|
||||
* @param clazz 视图类对象
|
||||
*/
|
||||
fun where(query: Query, params: Map<String, Any>?, clazz: Class<TView>): Query {
|
||||
val criteria = Criteria()
|
||||
if (params != null) {
|
||||
for (param in params) {
|
||||
val value = this.changeFieldType(param.key, param.value, clazz)
|
||||
criteria.and(param.key).isEqualTo(value)
|
||||
}
|
||||
}
|
||||
return query.addCriteria(criteria)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取排序对象
|
||||
*
|
||||
* @param orders 排序条件字段
|
||||
*/
|
||||
fun order(orders: Map<String, OrderType>?): Sort {
|
||||
val orderList = mutableListOf<Sort.Order>()
|
||||
orders?.forEach() {
|
||||
orderList.add(Sort.Order(Sort.Direction.valueOf(it.value.name), it.key))
|
||||
}
|
||||
return if (orderList.size == 0)
|
||||
Sort.by("_id")
|
||||
else
|
||||
Sort.by(orderList)
|
||||
}
|
||||
|
||||
/**
|
||||
* 分析视图字段对象,获取深层字段列表
|
||||
*
|
||||
* @param fields 需要分析的视图字段
|
||||
*/
|
||||
fun analyseFields(fields: Array<Field>): List<String> {
|
||||
val names = mutableListOf<String>()
|
||||
fields.forEach { field ->
|
||||
names.add(field.name)
|
||||
if (!field.type.isPrimitive
|
||||
&& !field.type.isArray
|
||||
&& !this.systemClass().contains(field.type.simpleName))
|
||||
names.addAll(this.analyseFields(field.type.declaredFields).map { "${field.name}.$it" })
|
||||
}
|
||||
return names
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换查询条件指定字段的类型
|
||||
*
|
||||
* @param key 字段名称
|
||||
* @param value 字段值
|
||||
* @param clazz 视图类对象
|
||||
*/
|
||||
fun changeFieldType(key: String, value: Any, clazz: Class<TView>): Any? {
|
||||
val getter = clazz.getMethod("get${key.substring(0, 1).toUpperCase()}${key.substring(1)}")
|
||||
return this.convertType(value.toString(), getter.returnType)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 转换String到指定类型
|
||||
*
|
||||
* @param value 字段值
|
||||
* @param clazz 视图类对象
|
||||
*/
|
||||
fun convertType(value: String, clazz: Class<*>): Any? {
|
||||
if (!clazz.isPrimitive) { // 判断基本类型
|
||||
if (clazz == String::class.java) { // 如果是string则直接返回
|
||||
return value
|
||||
}
|
||||
// 如果不为null 则通过反射实例一个对象返回
|
||||
return if ("" == value) null else clazz.getConstructor(String::class.java).newInstance(value)
|
||||
}
|
||||
|
||||
// 下面处理基本类型,返回包装类
|
||||
return when (clazz.name) {
|
||||
"int" -> Integer.parseInt(value)
|
||||
"byte" -> java.lang.Byte.parseByte(value)
|
||||
"boolean" -> java.lang.Boolean.parseBoolean(value)
|
||||
"double" -> java.lang.Double.parseDouble(value)
|
||||
"float" -> java.lang.Float.parseFloat(value)
|
||||
"long" -> java.lang.Long.parseLong(value)
|
||||
"short" -> java.lang.Short.parseShort(value)
|
||||
else -> value
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,137 +1,124 @@
|
||||
package com.synebula.gaea.query.mongo
|
||||
|
||||
import com.synebula.gaea.log.ILogger
|
||||
import com.synebula.gaea.query.IQuery
|
||||
import com.synebula.gaea.query.OrderType
|
||||
import com.synebula.gaea.query.PagingData
|
||||
import com.synebula.gaea.query.PagingParam
|
||||
import org.springframework.data.domain.Sort
|
||||
import org.springframework.data.mongodb.core.MongoTemplate
|
||||
import org.springframework.data.mongodb.core.query.Criteria
|
||||
import org.springframework.data.mongodb.core.query.Query
|
||||
import org.springframework.data.mongodb.core.query.isEqualTo
|
||||
import java.lang.reflect.Field
|
||||
import java.lang.reflect.ParameterizedType
|
||||
import com.synebula.gaea.extension.*
|
||||
|
||||
/**
|
||||
* 实现IQuery的Mongo查询类
|
||||
* @param repo MongoRepo对象
|
||||
*/
|
||||
open class MongoQuery<TView>(var repo: MongoTemplate, override var logger: ILogger? = null) : IQuery<TView, String>, IMongoQuery<TView> {
|
||||
/**
|
||||
* 查询的对象类
|
||||
*/
|
||||
var clazz: Class<TView>? = null
|
||||
|
||||
open class MongoQuery<TView>(var collection: String, var repo: MongoTemplate) : IQuery<TView, String> {
|
||||
private var _collection = ""
|
||||
/**
|
||||
* 查询的集合名称
|
||||
*/
|
||||
var collection: String = ""
|
||||
set(value) {
|
||||
field = value
|
||||
}
|
||||
get() = if (this._collection.isNotEmpty())
|
||||
this._collection
|
||||
else {
|
||||
if (this.clazz != null)
|
||||
this.clazz!!.simpleName.removeSuffix("View").firstCharLowerCase()
|
||||
else
|
||||
""
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造方法
|
||||
*
|
||||
* @param clazz 视图对象类型
|
||||
* @param repo MongoRepo对象
|
||||
*/
|
||||
constructor(clazz: Class<TView>, repo: MongoTemplate)
|
||||
: this(repo) {
|
||||
this.clazz = clazz
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
protected val viewClass: Class<TView> = (javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0] as Class<TView>
|
||||
/**
|
||||
* 构造方法
|
||||
*
|
||||
* @param collection 查询的集合名称
|
||||
* @param repo MongoRepo对象
|
||||
*/
|
||||
constructor(collection: String, repo: MongoTemplate)
|
||||
: this(repo) {
|
||||
this.collection = collection
|
||||
}
|
||||
|
||||
private val _systemClass = arrayOf(
|
||||
"String",
|
||||
"Date",
|
||||
"Int",
|
||||
"Double",
|
||||
"Float",
|
||||
"BigDecimal",
|
||||
"Decimal")
|
||||
/**
|
||||
* 构造方法
|
||||
*
|
||||
* @param clazz 视图对象类型
|
||||
* @param repo MongoRepo对象
|
||||
*/
|
||||
constructor(collection: String, clazz: Class<TView>, repo: MongoTemplate)
|
||||
: this(clazz, repo) {
|
||||
this.collection = collection
|
||||
}
|
||||
|
||||
|
||||
override fun list(params: Map<String, Any>?): List<TView> {
|
||||
val viewFields = this.viewFields()
|
||||
val query = Query()
|
||||
this.where(query, params)
|
||||
this.select(query, viewFields.toTypedArray())
|
||||
return this.repo.find(query, this.viewClass, this.collection)
|
||||
this.check()
|
||||
return if (this.clazz != null) {
|
||||
val viewFields = this.fields(this.clazz!!)
|
||||
val query = Query()
|
||||
this.where(query, params, this.clazz!!)
|
||||
this.select(query, viewFields.toTypedArray())
|
||||
this.repo.find(query, this.clazz!!, this.collection)
|
||||
} else listOf()
|
||||
}
|
||||
|
||||
override fun count(params: Map<String, Any>?): Int {
|
||||
val query = Query()
|
||||
return this.repo.count(where(query, params), this.collection).toInt()
|
||||
this.check()
|
||||
return if (this.clazz != null) {
|
||||
val query = Query()
|
||||
this.repo.count(where(query, params, this.clazz!!), this.collection).toInt()
|
||||
} else 0
|
||||
}
|
||||
|
||||
override fun paging(params: PagingParam): PagingData<TView> {
|
||||
val viewFields = this.viewFields()
|
||||
val result = PagingData<TView>(1, 10)
|
||||
result.size = params.size
|
||||
result.page = params.page
|
||||
val query = Query()
|
||||
this.where(query, params.parameters)
|
||||
result.total = this.repo.count(query, this.collection).toInt()
|
||||
this.select(query, viewFields.toTypedArray())
|
||||
query.with(order(params.orderBy))
|
||||
query.skip(params.index).limit(params.size)
|
||||
result.data = this.repo.find(query, this.viewClass, this.collection)
|
||||
return result
|
||||
this.check()
|
||||
return if (this.clazz != null) {
|
||||
val viewFields = this.fields(this.clazz!!)
|
||||
val result = PagingData<TView>(1, 10)
|
||||
result.size = params.size
|
||||
result.page = params.page
|
||||
val query = Query()
|
||||
this.where(query, params.parameters, this.clazz!!)
|
||||
result.total = this.repo.count(query, this.collection).toInt()
|
||||
this.select(query, viewFields.toTypedArray())
|
||||
query.with(order(params.orderBy))
|
||||
query.skip(params.index).limit(params.size)
|
||||
result.data = this.repo.find(query, this.clazz!!, this.collection)
|
||||
result
|
||||
} else PagingData(1, 10)
|
||||
}
|
||||
|
||||
override fun get(key: String): TView? {
|
||||
return this.repo.findOne(Query.query(Criteria.where("_id").isEqualTo(key))
|
||||
, this.viewClass, this.collection)
|
||||
this.check()
|
||||
return if (this.clazz != null) {
|
||||
val view = this.repo.findOne(idQuery(key), this.clazz!!, this.collection)
|
||||
view
|
||||
} else null
|
||||
}
|
||||
|
||||
protected fun viewFields(): List<String> {
|
||||
return traversalFields(viewClass.declaredFields)
|
||||
private fun check() {
|
||||
if (this.clazz == null)
|
||||
throw RuntimeException("[${this.javaClass.name}] 没有声明查询View的类型")
|
||||
if (this._collection.isEmpty())
|
||||
this.logger?.warn(this, null, "[${this.clazz!!.name}]没有声明查询集合名称, 后续尝试使用View对象名称解析集合")
|
||||
}
|
||||
|
||||
private fun traversalFields(fields: Array<Field>): List<String> {
|
||||
val names = mutableListOf<String>()
|
||||
fields.forEach { field ->
|
||||
names.add(field.name)
|
||||
if (!field.type.isPrimitive
|
||||
&& !field.type.isArray
|
||||
&& !this._systemClass.contains(field.type.simpleName))
|
||||
names.addAll(this.traversalFields(field.type.declaredFields).map { "${field.name}.$it" })
|
||||
}
|
||||
return names
|
||||
}
|
||||
|
||||
protected open fun where(query: Query, params: Map<String, Any>?): Query {
|
||||
val criteria = Criteria()
|
||||
if (params != null) {
|
||||
for (param in params) {
|
||||
val value = this.convertFieldValueType(param.key, param.value)
|
||||
criteria.and(param.key).isEqualTo(value)
|
||||
}
|
||||
}
|
||||
return query.addCriteria(criteria)
|
||||
}
|
||||
|
||||
protected fun convertFieldValueType(key: String, value: Any): Any? {
|
||||
val getter = this.viewClass.getMethod("get${key.substring(0, 1).toUpperCase()}${key.substring(1)}")
|
||||
return this.convertClass(getter.returnType, value.toString())
|
||||
}
|
||||
|
||||
protected open fun select(query: Query, fields: Array<String>): Query {
|
||||
fields.forEach {
|
||||
query.fields().include(it)
|
||||
}
|
||||
return query
|
||||
}
|
||||
|
||||
protected open fun order(orders: MutableMap<String, OrderType>?): Sort {
|
||||
val orderList = mutableListOf<Sort.Order>()
|
||||
orders?.forEach() {
|
||||
orderList.add(Sort.Order(Sort.Direction.valueOf(it.value.name), it.key))
|
||||
}
|
||||
return if (orderList.size == 0)
|
||||
Sort.by("_id")
|
||||
else
|
||||
Sort.by(orderList)
|
||||
}
|
||||
|
||||
private fun convertClass(type: Class<*>, value: String): Any? {
|
||||
|
||||
if (!type.isPrimitive) { // 判断基本类型
|
||||
if (type == String::class.java) { // 如果是string则直接返回
|
||||
return value
|
||||
}
|
||||
// 如果不为null 则通过反射实例一个对象返回
|
||||
return if ("" == value) null else type.getConstructor(String::class.java).newInstance(value)
|
||||
}
|
||||
|
||||
// 下面处理基本类型,返回包装类
|
||||
return when (type.name) {
|
||||
"int" -> Integer.parseInt(value)
|
||||
"byte" -> java.lang.Byte.parseByte(value)
|
||||
"boolean" -> java.lang.Boolean.parseBoolean(value)
|
||||
"double" -> java.lang.Double.parseDouble(value)
|
||||
"float" -> java.lang.Float.parseFloat(value)
|
||||
"long" -> java.lang.Long.parseLong(value)
|
||||
"short" -> java.lang.Short.parseShort(value)
|
||||
else -> value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.synebula.gaea.query.mongo
|
||||
|
||||
import com.synebula.gaea.log.ILogger
|
||||
import com.synebula.gaea.query.*
|
||||
import org.springframework.data.domain.Sort
|
||||
import org.springframework.data.mongodb.core.MongoTemplate
|
||||
import org.springframework.data.mongodb.core.query.Criteria
|
||||
import org.springframework.data.mongodb.core.query.Query
|
||||
import org.springframework.data.mongodb.core.query.isEqualTo
|
||||
import java.lang.reflect.Field
|
||||
|
||||
/**
|
||||
* 实现IQuery的Mongo查询类
|
||||
* @param repo MongoRepo对象
|
||||
*/
|
||||
|
||||
open class MongoTypedQuery<TView>(var repo: MongoTemplate) : ITypedQuery<TView, String>, IMongoQuery<TView> {
|
||||
override var logger: ILogger? = null
|
||||
|
||||
override fun list(params: Map<String, Any>?, clazz: Class<TView>): List<TView> {
|
||||
val viewFields = this.fields(clazz)
|
||||
val query = Query()
|
||||
this.where(query, params, clazz)
|
||||
this.select(query, viewFields.toTypedArray())
|
||||
return this.repo.find(query, clazz, clazz.simpleName)
|
||||
}
|
||||
|
||||
override fun count(params: Map<String, Any>?, clazz: Class<TView>): Int {
|
||||
val query = Query()
|
||||
return this.repo.count(this.where(query, params, clazz), clazz.simpleName).toInt()
|
||||
}
|
||||
|
||||
override fun paging(params: PagingParam, clazz: Class<TView>): PagingData<TView> {
|
||||
val viewFields = this.fields(clazz)
|
||||
val result = PagingData<TView>(1, 10)
|
||||
result.size = params.size
|
||||
result.page = params.page
|
||||
val query = Query()
|
||||
this.where(query, params.parameters, clazz)
|
||||
result.total = this.repo.count(query, clazz.simpleName).toInt()
|
||||
this.select(query, viewFields.toTypedArray())
|
||||
query.with(order(params.orderBy))
|
||||
query.skip(params.index).limit(params.size)
|
||||
result.data = this.repo.find(query, clazz, clazz.simpleName)
|
||||
return result
|
||||
}
|
||||
|
||||
override fun get(key: String, clazz: Class<TView>): TView? {
|
||||
return this.repo.findOne(idQuery(key), clazz, clazz.simpleName)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,35 +1,57 @@
|
||||
package com.synebula.gaea.repository.mongo
|
||||
|
||||
import com.synebula.gaea.domain.model.IAggregateRoot
|
||||
import com.synebula.gaea.domain.repository.ITypedRepository
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import com.synebula.gaea.domain.repository.IRepository
|
||||
import org.springframework.data.mongodb.core.MongoTemplate
|
||||
import org.springframework.data.mongodb.core.query.Criteria
|
||||
import org.springframework.data.mongodb.core.query.Query
|
||||
import org.springframework.data.mongodb.core.query.isEqualTo
|
||||
import org.springframework.stereotype.Repository
|
||||
|
||||
@Repository
|
||||
abstract class MongoRepository<TAggregateRoot : IAggregateRoot<String>> : ITypedRepository<TAggregateRoot, String> {
|
||||
/**
|
||||
* 实现IAggregateRoot的mongo仓储类
|
||||
* @param repo MongoRepo对象
|
||||
*/
|
||||
class MongoRepository<TAggregateRoot : IAggregateRoot<String>>(private var repo: MongoTemplate)
|
||||
: IRepository<TAggregateRoot, String> {
|
||||
|
||||
@Autowired
|
||||
private lateinit var repo: MongoTemplate
|
||||
/**
|
||||
* 仓储的对象类
|
||||
*/
|
||||
override var clazz: Class<TAggregateRoot>? = null
|
||||
|
||||
override fun remove(id: String, clazz: Class<TAggregateRoot>) {
|
||||
this.repo.remove(queryId(id), clazz)
|
||||
}
|
||||
|
||||
override fun get(id: String, clazz: Class<TAggregateRoot>): TAggregateRoot {
|
||||
return this.repo.findOne(queryId(id), clazz) as TAggregateRoot
|
||||
}
|
||||
|
||||
override fun update(obj: TAggregateRoot) {
|
||||
this.repo.save(obj)
|
||||
/**
|
||||
* 构造
|
||||
* @param clazz 仓储Domain对象
|
||||
* @param repo MongoRepo对象
|
||||
*/
|
||||
constructor(clazz: Class<TAggregateRoot>, repo: MongoTemplate) : this(repo) {
|
||||
this.clazz = clazz
|
||||
}
|
||||
|
||||
override fun add(obj: TAggregateRoot) {
|
||||
this.repo.save(obj)
|
||||
}
|
||||
|
||||
protected fun queryId(id: String): Query = Query(Criteria("_id").isEqualTo(id))
|
||||
override fun update(obj: TAggregateRoot) {
|
||||
this.repo.save(obj)
|
||||
}
|
||||
|
||||
override fun remove(id: String) {
|
||||
this.repo.remove(idQuery(id), this.clazz!!)
|
||||
}
|
||||
|
||||
override fun get(id: String): TAggregateRoot {
|
||||
return this.repo.findOne(idQuery(id), clazz!!) as TAggregateRoot
|
||||
}
|
||||
|
||||
override fun <TAggregateRoot : IAggregateRoot<TKey>, TKey> get(id: TKey, clazz: Class<TAggregateRoot>): TAggregateRoot {
|
||||
return this.repo.findOne(idQuery(id.toString()), clazz) as TAggregateRoot
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取ID查询条件
|
||||
*
|
||||
* @param id 业务ID
|
||||
*/
|
||||
fun idQuery(id: String): Query = Query(Criteria("_id").isEqualTo(id))
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.synebula.gaea.repository.mongo
|
||||
|
||||
import com.synebula.gaea.domain.model.IAggregateRoot
|
||||
import com.synebula.gaea.domain.repository.IRepositoryTyped
|
||||
import org.springframework.data.mongodb.core.MongoTemplate
|
||||
import org.springframework.data.mongodb.core.query.Criteria
|
||||
import org.springframework.data.mongodb.core.query.Query
|
||||
import org.springframework.data.mongodb.core.query.isEqualTo
|
||||
|
||||
/**
|
||||
* 实现ITypedRepository的mongo仓储类
|
||||
* @param repo MongoRepo对象
|
||||
*/
|
||||
open class MongoRepositoryTyped(private var repo: MongoTemplate)
|
||||
: IRepositoryTyped {
|
||||
|
||||
override fun <TAggregateRoot : IAggregateRoot<TKey>, TKey> remove(id: TKey, clazz: Class<TAggregateRoot>) {
|
||||
this.repo.remove(idQuery(id), clazz)
|
||||
}
|
||||
|
||||
override fun <TAggregateRoot : IAggregateRoot<TKey>, TKey> get(id: TKey, clazz: Class<TAggregateRoot>): TAggregateRoot {
|
||||
return this.repo.findOne(idQuery(id), clazz) as TAggregateRoot
|
||||
}
|
||||
|
||||
override fun <TAggregateRoot : IAggregateRoot<TKey>, TKey> update(obj: TAggregateRoot, clazz: Class<TAggregateRoot>) {
|
||||
this.repo.save(obj)
|
||||
}
|
||||
|
||||
override fun <TAggregateRoot : IAggregateRoot<TKey>, TKey> add(obj: TAggregateRoot, clazz: Class<TAggregateRoot>) {
|
||||
this.repo.save(obj)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取ID查询条件
|
||||
*
|
||||
* @param id 业务ID
|
||||
*/
|
||||
fun <TKey> idQuery(id: TKey): Query = Query(Criteria("_id").isEqualTo(id))
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
package com.synebula.gaea.domain.model
|
||||
|
||||
abstract class AggregateRoot<TKey> : Entity<TKey>(), IAggregateRoot<TKey>
|
||||
abstract class AggregateRoot<TKey> : Entity<TKey>(), IAggregateRoot<TKey> {
|
||||
override var alive: Boolean = true
|
||||
}
|
||||
|
||||
@@ -5,4 +5,10 @@ package com.synebula.gaea.domain.model
|
||||
*
|
||||
* @author alex
|
||||
**/
|
||||
interface IAggregateRoot<TKey> : IEntity<TKey>
|
||||
interface IAggregateRoot<TKey> : IEntity<TKey> {
|
||||
|
||||
/**
|
||||
* 实体对象是否有效。
|
||||
*/
|
||||
var alive: Boolean
|
||||
}
|
||||
|
||||
@@ -12,10 +12,6 @@ interface IEntity<TKey> {
|
||||
/**
|
||||
* 实体ID
|
||||
*/
|
||||
var id: TKey
|
||||
var id: TKey?
|
||||
|
||||
/**
|
||||
* 实体对象是否有效。
|
||||
*/
|
||||
var alive: Boolean
|
||||
}
|
||||
|
||||
@@ -3,5 +3,5 @@ package com.synebula.gaea.domain.model.complex
|
||||
import com.synebula.gaea.domain.model.IEntity
|
||||
|
||||
interface IComplexEntity<TKey, TSecond> : IEntity<TKey> {
|
||||
var secondary: TSecond
|
||||
var secondary: TSecond?
|
||||
}
|
||||
|
||||
@@ -10,6 +10,11 @@ import com.synebula.gaea.domain.model.IAggregateRoot
|
||||
*/
|
||||
interface IRepository<TAggregateRoot : IAggregateRoot<TKey>, TKey> {
|
||||
|
||||
/**
|
||||
* 仓储的对象类
|
||||
*/
|
||||
var clazz: Class<TAggregateRoot>?
|
||||
|
||||
/**
|
||||
* 插入单个对象。
|
||||
*
|
||||
@@ -40,5 +45,15 @@ interface IRepository<TAggregateRoot : IAggregateRoot<TKey>, TKey> {
|
||||
* @param id 对象ID。
|
||||
* @return
|
||||
*/
|
||||
operator fun get(id: TKey): TAggregateRoot
|
||||
fun get(id: TKey): TAggregateRoot
|
||||
|
||||
/**
|
||||
* 根据ID获取对象。
|
||||
*
|
||||
* @param id id
|
||||
* @param clazz 操作数据的类型
|
||||
* @return 聚合根
|
||||
*/
|
||||
fun <T : IAggregateRoot<TKey>, TKey> get(id: TKey, clazz: Class<T>): T
|
||||
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import com.synebula.gaea.domain.model.complex.IComplexAggregateRoot
|
||||
* @param <TAggregateRoot> this T is the parameter
|
||||
* @author alex
|
||||
*/
|
||||
interface IComplexRepository<TAggregateRoot : IComplexAggregateRoot<TKey, TSecond>, TKey, TSecond> {
|
||||
interface IRepositoryComplex<TAggregateRoot : IComplexAggregateRoot<TKey, TSecond>, TKey, TSecond> {
|
||||
|
||||
/**
|
||||
* 插入单个对象。
|
||||
@@ -2,14 +2,14 @@ package com.synebula.gaea.domain.repository
|
||||
|
||||
import com.synebula.gaea.domain.model.IAggregateRoot
|
||||
|
||||
interface ITypedRepository<TAggregateRoot : IAggregateRoot<TKey>, TKey> {
|
||||
interface IRepositoryTyped {
|
||||
/**
|
||||
* 插入单个对象。
|
||||
*
|
||||
* @param obj 需要插入的对象。
|
||||
* @return 返回原对象,如果对象ID为自增,则补充自增ID。
|
||||
*/
|
||||
fun add(obj: TAggregateRoot)
|
||||
fun <TAggregateRoot : IAggregateRoot<TKey>, TKey> add(obj: TAggregateRoot, clazz: Class<TAggregateRoot>)
|
||||
|
||||
/**
|
||||
* 更新对象。
|
||||
@@ -17,7 +17,7 @@ interface ITypedRepository<TAggregateRoot : IAggregateRoot<TKey>, TKey> {
|
||||
* @param obj 需要更新的对象。
|
||||
* @return
|
||||
*/
|
||||
fun update(obj: TAggregateRoot)
|
||||
fun <TAggregateRoot : IAggregateRoot<TKey>, TKey> update(obj: TAggregateRoot, clazz: Class<TAggregateRoot>)
|
||||
|
||||
/**
|
||||
* 通过id删除该条数据
|
||||
@@ -25,7 +25,7 @@ interface ITypedRepository<TAggregateRoot : IAggregateRoot<TKey>, TKey> {
|
||||
* @param id id
|
||||
* @param clazz 操作数据的类型
|
||||
*/
|
||||
fun remove(id: TKey, clazz: Class<TAggregateRoot>)
|
||||
fun <TAggregateRoot : IAggregateRoot<TKey>, TKey> remove(id: TKey, clazz: Class<TAggregateRoot>)
|
||||
|
||||
/**
|
||||
* 根据ID获取对象。
|
||||
@@ -34,5 +34,5 @@ interface ITypedRepository<TAggregateRoot : IAggregateRoot<TKey>, TKey> {
|
||||
* @param clazz 操作数据的类型
|
||||
* @return 聚合根
|
||||
*/
|
||||
fun get(id: TKey, clazz: Class<TAggregateRoot>): TAggregateRoot
|
||||
fun <TAggregateRoot : IAggregateRoot<TKey>, TKey> get(id: TKey, clazz: Class<TAggregateRoot>): TAggregateRoot
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.synebula.gaea.domain.service
|
||||
|
||||
import com.synebula.gaea.data.message.Message
|
||||
import com.synebula.gaea.domain.model.IAggregateRoot
|
||||
import com.synebula.gaea.log.ILogger
|
||||
|
||||
|
||||
@@ -21,4 +22,6 @@ interface IService<TKey> {
|
||||
fun update(key: TKey, command: ICommand)
|
||||
|
||||
fun remove(key: TKey)
|
||||
|
||||
fun <TAggregateRoot : IAggregateRoot<TKey>> get(key: TKey, clazz: Class<TAggregateRoot>): TAggregateRoot
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import com.synebula.gaea.data.message.Message
|
||||
* @version 0.1
|
||||
* @since 2018 18-2-8
|
||||
*/
|
||||
interface IComplexService<TKey, TSecond> {
|
||||
interface IServiceComplex<TKey, TSecond> {
|
||||
|
||||
fun add(command: ICommand): Message<Pair<TKey, TSecond>>
|
||||
|
||||
@@ -10,20 +10,28 @@ import com.synebula.gaea.log.ILogger
|
||||
/**
|
||||
* class FlatService
|
||||
*
|
||||
* @param repository 仓储对象
|
||||
* @param rootClass 聚合根类对象
|
||||
* @param converter 对象转换组件
|
||||
* @param logger 日志组件
|
||||
* @author alex
|
||||
* @version 0.1
|
||||
* @since 2018 18-2-8
|
||||
*/
|
||||
open class Service<TAggregateRoot : IAggregateRoot<TKey>, TKey>
|
||||
(override var logger: ILogger,
|
||||
protected var repository: IRepository<TAggregateRoot, TKey>,
|
||||
protected var converter: IObjectConverter,
|
||||
protected var aggregateRootClass: Class<TAggregateRoot>) : IService<TKey> {
|
||||
open class Service<TAggregateRoot : IAggregateRoot<TKey>, TKey>(
|
||||
protected var rootClass: Class<TAggregateRoot>,
|
||||
protected var repository: IRepository<TAggregateRoot, TKey>,
|
||||
protected var converter: IObjectConverter,
|
||||
override var logger: ILogger) : IService<TKey> {
|
||||
|
||||
init {
|
||||
this.repository.clazz = rootClass
|
||||
}
|
||||
|
||||
override fun add(command: ICommand): Message<TKey> {
|
||||
val msg = Message<TKey>()
|
||||
val root = this.convert(command)
|
||||
repository.add(root)
|
||||
this.repository.add(root)
|
||||
msg.data = root.id
|
||||
return msg
|
||||
}
|
||||
@@ -31,11 +39,19 @@ open class Service<TAggregateRoot : IAggregateRoot<TKey>, TKey>
|
||||
override fun update(key: TKey, command: ICommand) {
|
||||
val root = this.convert(command)
|
||||
root.id = key
|
||||
repository.update(root)
|
||||
this.repository.update(root)
|
||||
}
|
||||
|
||||
override fun remove(key: TKey) {
|
||||
repository.remove(key)
|
||||
this.repository.remove(key)
|
||||
}
|
||||
|
||||
fun get(key: TKey): TAggregateRoot {
|
||||
return this.repository.get(key)
|
||||
}
|
||||
|
||||
override fun <T : IAggregateRoot<TKey>> get(key: TKey, clazz: Class<T>): T {
|
||||
return this.repository.get(key, clazz)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -46,7 +62,7 @@ open class Service<TAggregateRoot : IAggregateRoot<TKey>, TKey>
|
||||
*/
|
||||
protected fun convert(command: ICommand): TAggregateRoot {
|
||||
try {
|
||||
return converter.convert(command, aggregateRootClass)
|
||||
return converter.convert(command, rootClass)
|
||||
} catch (ex: Exception) {
|
||||
throw RuntimeException("command not match aggregate root", ex)
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package com.synebula.gaea.domain.service
|
||||
import com.synebula.gaea.data.IObjectConverter
|
||||
import com.synebula.gaea.data.message.Message
|
||||
import com.synebula.gaea.domain.model.complex.IComplexAggregateRoot
|
||||
import com.synebula.gaea.domain.repository.IComplexRepository
|
||||
import com.synebula.gaea.domain.repository.IRepositoryComplex
|
||||
import com.synebula.gaea.log.ILogger
|
||||
|
||||
/**
|
||||
@@ -13,16 +13,16 @@ import com.synebula.gaea.log.ILogger
|
||||
* @version 0.1
|
||||
* @since 2018 18-2-8
|
||||
*/
|
||||
open class ComplexService<TAggregateRoot : IComplexAggregateRoot<TKey, TSecond>, TKey, TSecond>
|
||||
(var logger: ILogger, protected var repository: IComplexRepository<TAggregateRoot, TKey, TSecond>,
|
||||
open class ServiceComplex<TAggregateRoot : IComplexAggregateRoot<TKey, TSecond>, TKey, TSecond>
|
||||
(var logger: ILogger, protected var repository: IRepositoryComplex<TAggregateRoot, TKey, TSecond>,
|
||||
protected var converter: IObjectConverter, protected var aggregateRootClass: Class<TAggregateRoot>)
|
||||
: IComplexService<TKey, TSecond> {
|
||||
: IServiceComplex<TKey, TSecond> {
|
||||
|
||||
override fun add(command: ICommand): Message<Pair<TKey, TSecond>> {
|
||||
val msg = Message<Pair<TKey, TSecond>>()
|
||||
val root = this.convert(command)
|
||||
repository.add(root)
|
||||
msg.data = Pair<TKey, TSecond>(root.id, root.secondary)
|
||||
msg.data = Pair<TKey, TSecond>(root.id!!, root.secondary!!)
|
||||
return msg
|
||||
}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.synebula.gaea.domain.service
|
||||
|
||||
import com.synebula.gaea.data.IObjectConverter
|
||||
import com.synebula.gaea.data.message.Message
|
||||
import com.synebula.gaea.domain.model.IAggregateRoot
|
||||
import com.synebula.gaea.domain.repository.IRepositoryTyped
|
||||
import com.synebula.gaea.log.ILogger
|
||||
|
||||
|
||||
/**
|
||||
* class FlatService
|
||||
*
|
||||
* @param repository 仓储对象
|
||||
* @param rootClass 聚合根类对象
|
||||
* @param converter 对象转换组件
|
||||
* @param logger 日志组件
|
||||
* @author alex
|
||||
* @version 0.1
|
||||
* @since 2018 18-2-8
|
||||
*/
|
||||
open class ServiceTyped<TAggregateRoot : IAggregateRoot<TKey>, TKey>(
|
||||
protected var rootClass: Class<TAggregateRoot>,
|
||||
protected var repository: IRepositoryTyped,
|
||||
protected var converter: IObjectConverter,
|
||||
override var logger: ILogger) : IService<TKey> {
|
||||
|
||||
override fun add(command: ICommand): Message<TKey> {
|
||||
val msg = Message<TKey>()
|
||||
val root = this.convert(command)
|
||||
this.repository.add(root, rootClass)
|
||||
msg.data = root.id
|
||||
return msg
|
||||
}
|
||||
|
||||
override fun update(key: TKey, command: ICommand) {
|
||||
val root = this.convert(command)
|
||||
root.id = key
|
||||
this.repository.update(root, rootClass)
|
||||
}
|
||||
|
||||
override fun remove(key: TKey) {
|
||||
this.repository.remove(key, rootClass)
|
||||
}
|
||||
|
||||
override fun <TAggregateRoot : IAggregateRoot<TKey>> get(key: TKey, clazz: Class<TAggregateRoot>): TAggregateRoot {
|
||||
return this.repository.get(key, clazz)
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换ICommand类型到聚合根类型,默认实现,根据需要进行覆写。
|
||||
*
|
||||
* @param command
|
||||
* @return
|
||||
*/
|
||||
protected fun convert(command: ICommand): TAggregateRoot {
|
||||
try {
|
||||
return converter.convert(command, rootClass)
|
||||
} catch (ex: Exception) {
|
||||
throw RuntimeException("command not match aggregate root", ex)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.synebula.gaea.extension
|
||||
|
||||
fun String.firstCharLowerCase(): String {
|
||||
if (Character.isLowerCase(this.elementAt(0)))
|
||||
return this
|
||||
else
|
||||
return StringBuilder().append(Character.toLowerCase(this.elementAt(0)))
|
||||
.append(this.substring(1)).toString()
|
||||
}
|
||||
@@ -27,43 +27,103 @@ class NullLogger : ILogger {
|
||||
override val name: String
|
||||
get() = NullLogger::class.simpleName!!
|
||||
|
||||
override fun trace(t: Throwable) {}
|
||||
override fun trace(t: Throwable) {
|
||||
|
||||
override fun trace(format: String, vararg args: Any) {}
|
||||
}
|
||||
|
||||
override fun trace(t: Throwable, format: String, vararg args: Any) {}
|
||||
override fun trace(format: String, vararg args: Any) {
|
||||
|
||||
override fun trace(obj: Any, t: Throwable, format: String, vararg args: Any) {}
|
||||
}
|
||||
|
||||
override fun debug(t: Throwable) {}
|
||||
override fun trace(t: Throwable, format: String, vararg args: Any) {
|
||||
|
||||
override fun debug(format: String, vararg args: Any) {}
|
||||
}
|
||||
|
||||
override fun debug(t: Throwable, format: String, vararg args: Any) {}
|
||||
override fun trace(obj: Any, format: String, vararg args: Any) {
|
||||
|
||||
override fun debug(obj: Any, t: Throwable, format: String, vararg args: Any) {}
|
||||
}
|
||||
|
||||
override fun info(t: Throwable) {}
|
||||
override fun trace(obj: Any, t: Throwable?, format: String, vararg args: Any) {
|
||||
|
||||
override fun info(format: String, vararg args: Any) {}
|
||||
}
|
||||
|
||||
override fun info(t: Throwable, format: String, vararg args: Any) {}
|
||||
override fun debug(t: Throwable) {
|
||||
|
||||
override fun info(obj: Any, t: Throwable, format: String, vararg args: Any) {}
|
||||
}
|
||||
|
||||
override fun warn(t: Throwable) {}
|
||||
override fun debug(format: String, vararg args: Any) {
|
||||
|
||||
override fun warn(format: String, vararg args: Any) {}
|
||||
}
|
||||
|
||||
override fun warn(t: Throwable, format: String, vararg args: Any) {}
|
||||
override fun debug(t: Throwable, format: String, vararg args: Any) {
|
||||
|
||||
override fun warn(obj: Any, t: Throwable, format: String, vararg args: Any) {}
|
||||
}
|
||||
|
||||
override fun error(t: Throwable) {}
|
||||
override fun debug(obj: Any, format: String, vararg args: Any) {
|
||||
|
||||
override fun error(format: String, vararg args: Any) {}
|
||||
}
|
||||
|
||||
override fun error(t: Throwable, format: String, vararg args: Any) {}
|
||||
override fun debug(obj: Any, t: Throwable?, format: String, vararg args: Any) {
|
||||
|
||||
override fun error(obj: Any, t: Throwable, format: String, vararg args: Any) {}
|
||||
}
|
||||
|
||||
override fun info(t: Throwable) {
|
||||
|
||||
}
|
||||
|
||||
override fun info(format: String, vararg args: Any) {
|
||||
|
||||
}
|
||||
|
||||
override fun info(t: Throwable, format: String, vararg args: Any) {
|
||||
|
||||
}
|
||||
|
||||
override fun info(obj: Any, format: String, vararg args: Any) {
|
||||
|
||||
}
|
||||
|
||||
override fun info(obj: Any, t: Throwable?, format: String, vararg args: Any) {
|
||||
|
||||
}
|
||||
|
||||
override fun warn(t: Throwable) {
|
||||
|
||||
}
|
||||
|
||||
override fun warn(format: String, vararg args: Any) {
|
||||
|
||||
}
|
||||
|
||||
override fun warn(t: Throwable, format: String, vararg args: Any) {
|
||||
|
||||
}
|
||||
|
||||
override fun warn(obj: Any, format: String, vararg args: Any) {
|
||||
|
||||
}
|
||||
|
||||
override fun warn(obj: Any, t: Throwable?, format: String, vararg args: Any) {
|
||||
|
||||
}
|
||||
|
||||
override fun error(t: Throwable) {
|
||||
|
||||
}
|
||||
|
||||
override fun error(format: String, vararg args: Any) {
|
||||
|
||||
}
|
||||
|
||||
override fun error(t: Throwable, format: String, vararg args: Any) {
|
||||
|
||||
}
|
||||
|
||||
override fun error(obj: Any, format: String, vararg args: Any) {
|
||||
|
||||
}
|
||||
|
||||
override fun error(obj: Any, t: Throwable?, format: String, vararg args: Any) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,15 @@ interface IDebugLogger {
|
||||
*/
|
||||
fun debug(t: Throwable, format: String, vararg args: Any)
|
||||
|
||||
/**
|
||||
* 打印 DEBUG 等级的日志
|
||||
*
|
||||
* @param obj 输出错误对象
|
||||
* @param format 消息模板
|
||||
* @param args 参数
|
||||
*/
|
||||
fun debug(obj: Any, format: String, vararg args: Any)
|
||||
|
||||
/**
|
||||
* 打印 DEBUG 等级的日志
|
||||
*
|
||||
@@ -43,5 +52,5 @@ interface IDebugLogger {
|
||||
* @param format 消息模板
|
||||
* @param args 参数
|
||||
*/
|
||||
fun debug(obj: Any, t: Throwable, format: String, vararg args: Any)
|
||||
fun debug(obj: Any, t: Throwable?, format: String, vararg args: Any)
|
||||
}
|
||||
|
||||
@@ -34,6 +34,15 @@ interface IErrorLogger {
|
||||
*/
|
||||
fun error(t: Throwable, format: String, vararg args: Any)
|
||||
|
||||
/**
|
||||
* 打印 ERROR 等级的日志
|
||||
*
|
||||
* @param obj 输出错误对象
|
||||
* @param format 消息模板
|
||||
* @param args 参数
|
||||
*/
|
||||
fun error(obj: Any, format: String, vararg args: Any)
|
||||
|
||||
/**
|
||||
* 打印 ERROR 等级的日志
|
||||
*
|
||||
@@ -42,5 +51,5 @@ interface IErrorLogger {
|
||||
* @param format 消息模板
|
||||
* @param args 参数
|
||||
*/
|
||||
fun error(obj: Any, t: Throwable, format: String, vararg args: Any)
|
||||
fun error(obj: Any, t: Throwable?, format: String, vararg args: Any)
|
||||
}
|
||||
|
||||
@@ -34,6 +34,15 @@ interface IInfoLogger {
|
||||
*/
|
||||
fun info(t: Throwable, format: String, vararg args: Any)
|
||||
|
||||
/**
|
||||
* 打印 INFO 等级的日志
|
||||
*
|
||||
* @param obj 输出错误对象
|
||||
* @param format 消息模板
|
||||
* @param args 参数
|
||||
*/
|
||||
fun info(obj: Any, format: String, vararg args: Any)
|
||||
|
||||
/**
|
||||
* 打印 INFO 等级的日志
|
||||
*
|
||||
@@ -42,5 +51,5 @@ interface IInfoLogger {
|
||||
* @param format 消息模板
|
||||
* @param args 参数
|
||||
*/
|
||||
fun info(obj: Any, t: Throwable, format: String, vararg args: Any)
|
||||
fun info(obj: Any, t: Throwable?, format: String, vararg args: Any)
|
||||
}
|
||||
|
||||
@@ -35,6 +35,16 @@ interface ITraceLogger {
|
||||
*/
|
||||
fun trace(t: Throwable, format: String, vararg args: Any)
|
||||
|
||||
/**
|
||||
* 打印 TRACE 等级的日志
|
||||
*
|
||||
* @param obj 输出错误对象
|
||||
* @param format 消息模板
|
||||
* @param args 参数
|
||||
*/
|
||||
fun trace(obj: Any, format: String, vararg args: Any)
|
||||
|
||||
|
||||
/**
|
||||
* 打印 TRACE 等级的日志
|
||||
*
|
||||
@@ -43,6 +53,6 @@ interface ITraceLogger {
|
||||
* @param format 消息模板
|
||||
* @param args 参数
|
||||
*/
|
||||
fun trace(obj: Any, t: Throwable, format: String, vararg args: Any)
|
||||
fun trace(obj: Any, t: Throwable?, format: String, vararg args: Any)
|
||||
|
||||
}
|
||||
|
||||
@@ -34,6 +34,16 @@ interface IWarnLogger {
|
||||
*/
|
||||
fun warn(t: Throwable, format: String, vararg args: Any)
|
||||
|
||||
|
||||
/**
|
||||
* 打印 WARN 等级的日志
|
||||
*
|
||||
* @param obj 输出错误对象
|
||||
* @param format 消息模板
|
||||
* @param args 参数
|
||||
*/
|
||||
fun warn(obj: Any, format: String, vararg args: Any)
|
||||
|
||||
/**
|
||||
* 打印 WARN 等级的日志
|
||||
*
|
||||
@@ -42,5 +52,5 @@ interface IWarnLogger {
|
||||
* @param format 消息模板
|
||||
* @param args 参数
|
||||
*/
|
||||
fun warn(obj: Any, t: Throwable, format: String, vararg args: Any)
|
||||
fun warn(obj: Any, t: Throwable?, format: String, vararg args: Any)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.synebula.gaea.query
|
||||
|
||||
/**
|
||||
* 查询基接口。
|
||||
*
|
||||
* @author alex
|
||||
*/
|
||||
interface ITypedQuery<TView, TKey> {
|
||||
|
||||
|
||||
/**
|
||||
* 根据Key获取对象。
|
||||
*
|
||||
* @param key 对象Key。
|
||||
* @return
|
||||
*/
|
||||
fun get(key: TKey, clazz: Class<TView>): TView?
|
||||
|
||||
/**
|
||||
* 根据实体类条件查询所有符合条件记录
|
||||
*
|
||||
* @param params 查询条件。
|
||||
* @return list
|
||||
*/
|
||||
fun list(params: Map<String, Any>?, clazz: Class<TView>): List<TView>
|
||||
|
||||
/**
|
||||
* 根据条件查询符合条件记录的数量
|
||||
*
|
||||
* @param params 查询条件。
|
||||
* @return int
|
||||
*/
|
||||
fun count(params: Map<String, Any>?, clazz: Class<TView>): Int
|
||||
|
||||
/**
|
||||
* 根据实体类条件查询所有符合条件记录(分页查询)
|
||||
*
|
||||
* @param params 分页条件
|
||||
* @return 分页数据
|
||||
*/
|
||||
fun paging(params: PagingParam, clazz: Class<TView>): PagingData<TView>
|
||||
}
|
||||
Reference in New Issue
Block a user