广汽安道拓Acura项目MES后台
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

224 lines
6.6 KiB

// Copyright (c) Shenyang Leading Edge Intelligent Technology Co., Ltd. All rights reserved.
package container
import (
"LAPP_ACURA_MOM_BACKEND/global"
"errors"
"fmt"
"github.com/kataras/iris/v12/context"
"github.com/kataras/iris/v12/core/router"
"reflect"
"strings"
)
const (
ServicesPackageName = "services"
ServiceNameSuffix = "Service"
PathSeparator = "/"
HttpPost HttpMethod = "POST"
HttpPut HttpMethod = "POU"
HttpGet HttpMethod = "Get"
HttpDelete HttpMethod = "DELETE"
)
var ServiceNameSuffixLength = len([]rune(ServiceNameSuffix))
type HttpMethod string
type (
// 调用器
// 参数
// 1.参数列表
// 返回值:
// 1.返回值列表
Caller = func([]reflect.Value) []reflect.Value
// 调用器工厂
// 参数
// 1.会话标识
// 2.用户信息
// 返回值:
// 1.调用器
// 2.错误
CallerFactory = func(string, *global.User) (Caller, error)
// 路由
Router = context.Handler
// 路由创建器
// 参数
// 1.会话管理器
// 2.服务类型
// 3.服务方法名
// 3.服务方法类型
// 返回值:
// 1.HTTP请求方法
// 2.附加路径
// 3.路由
// 4.错误
RouterBuilder = func(CallerFactory, string, reflect.Type) (HttpMethod, string, Router, error)
)
// *SessionContext类型常量
var sessionContextType = reflect.TypeOf((*SessionContext)(nil))
// 空参数列表
var emptyParameters []reflect.Value
// Factory零值
var zeroOfFactory = Factory(reflect.ValueOf(nil))
// *error 类型常量
var errorType = reflect.TypeOf((*error)(nil)).Elem()
// *RequestContext类型常量
var RequestContextType = reflect.TypeOf((*RequestContext)(nil))
// 无会话(XORM会话)上下文
var ContextOfNoSession = NewNoSessionBrokerBuilder()
// 新会话(XORM会话)上下文
var ContextOfNewSession = NewNewSessionBrokerBuilder()
// 新事务代理创建器上下文
var ContextOfNewTransaction = NewNewTransactionBrokerBuilder()
//
//// 组件信息管理器
//var currentInformationManager = NewInformationManager()
// 解析组件工厂,返回:组件工厂Value,组件模块名,组件接口,错误
// 参数
// 1.工厂方法
// 返回值:
// 1.组件工厂
// 2.组件接口类型
// 异常:
// 1.工厂不能为空
// 2.工厂必须是func
// 3.工厂不能有参数
// 4.工厂必值需有返回值
// 5.工厂只能有一个返回值
// 6.工厂的返回值必需是interface
func parseFactory(factory interface{}) (Factory, Interface) {
if factory == nil {
panic(fmt.Sprintf("工厂不能为空!"))
}
valueOfFactory := reflect.ValueOf(factory)
typeOfFactory := valueOfFactory.Type()
if typeOfFactory.Kind() != reflect.Func {
panic(fmt.Sprintf("工厂必须是func!"))
}
if typeOfFactory.NumIn() != 0 {
panic(fmt.Sprintf("工厂不能有参数!"))
}
if typeOfFactory.NumOut() < 1 {
panic(fmt.Sprintf("工厂必值需有返回值!"))
}
if typeOfFactory.NumOut() > 1 {
panic(fmt.Sprintf("工厂只能有一个返回值!"))
}
if typeOfFactory.Out(0).Kind() != reflect.Interface {
panic(fmt.Sprintf("工厂的返回值必需是interface!"))
}
componentType := typeOfFactory.Out(0)
return Factory(valueOfFactory), componentType
}
// Caller相等性判断
// 参数
// 1.比较对象1
// 3.比较对象2
// 返回值:
// 1.判断结果
func CallerEqual(caller1 Caller, caller2 Caller) bool {
if caller1 == nil {
if caller2 == nil {
return true
} else {
return false
}
} else {
if caller2 == nil {
return false
} else {
return reflect.ValueOf(caller1).Pointer() == reflect.ValueOf(caller2).Pointer()
}
}
}
var GlobalInformations = NewInformationManager()
// 注册路由
// 参数:
// 1.路由分组
// 2.组件信息管理器
// 3.事务句柄工厂
// 返回值:
// 1.错误
// 异常:
// 1.组件信息管理器不能为空
// 2.事务句柄工厂不能为空
// 3.服务不在包或他的子包之下
// 4.组件接口名称的后缀不正确
func RegisterRoutes(party router.Party, defaultRouterBuilder RouterBuilder, informationManager InformationManager, transactionHandlerFactory TransactionHandlerFactory) {
sessionManager := NewSessionManager(informationManager, transactionHandlerFactory)
groups := make(map[string][]*ServiceInformation, 10)
for _, information := range informationManager.Items() {
if serviceInformation, ok := information.(*ServiceInformation); ok {
packagePath := serviceInformation.Interface().PkgPath()
group, ok := groups[packagePath]
if !ok {
group = make([]*ServiceInformation, 0, 10)
}
groups[packagePath] = append(group, serviceInformation)
}
for packagePath, group := range groups {
packageList := strings.Split(packagePath, PathSeparator)
moudlePath := ""
for index, packageName := range packageList {
if strings.ToLower(packageName) == ServicesPackageName {
moudlePath = strings.Join(packageList[index+1:], PathSeparator)
break
}
}
if moudlePath == "" {
panic(fmt.Sprintf("包%s不在包%s或他的子包之下!", packagePath, ServicesPackageName))
}
moudleParty := party.Party(fmt.Sprintf("/%s", strings.ToLower(moudlePath)))
for _, serviceInformation := range group {
serviceType := serviceInformation.Interface()
serviceName := serviceType.Name()
if !strings.HasSuffix(serviceName, ServiceNameSuffix) {
panic(fmt.Sprintf("组件%s接口名称的后缀不是%s!", serviceName, ServiceNameSuffix))
}
runesOfserviceName := []rune(serviceName)
serviceParty := moudleParty.Party(fmt.Sprintf("/%s", strings.ToLower(string(runesOfserviceName[:len(runesOfserviceName)-ServiceNameSuffixLength]))))
for _, serviceMethodInformation := range serviceInformation.Methods() {
methodName := serviceMethodInformation.MethodName()
routerBuilder := serviceMethodInformation.RouterBuilder()
if routerBuilder == nil {
routerBuilder = defaultRouterBuilder
}
var callerFactory = func(sessionId string, user *global.User) (Caller, error) {
session, err := sessionManager.GetSession(sessionId, user)
if err != nil {
return nil, err
}
serviceHandler, ok := session.Handlers().Handler(serviceType).(*ServiceHandler)
if !ok {
return nil, errors.New(fmt.Sprintf("竟然没找到服务组件句柄!"))
}
return serviceHandler.Method(methodName).Caller(), nil
}
serviceMethodName := fmt.Sprintf("%s.%s", serviceName, methodName)
httpMethod, addedPath, irisRouter, err := routerBuilder(callerFactory, serviceMethodName, serviceMethodInformation.MethodType())
if err != nil {
panic(err.Error())
}
serviceParty.Handle(string(httpMethod), fmt.Sprintf("/%s", strings.ToLower(methodName)+addedPath), irisRouter)
}
}
}
}
}