in nlpcraft/src/main/scala/org/apache/nlpcraft/internal/impl/NCModelScanner.scala [163:297]
private def invoke(cfg: NCModelConfig, mtd: Method, obj: AnyRef, args: scala.Array[AnyRef]): NCResult =
val methodObj = if Modifier.isStatic(mtd.getModifiers) then null else obj
var flag = mtd.canAccess(methodObj)
lazy val z = s"mdlId=${cfg.getId}, callback=${method2Str(mtd)}"
try
if !flag then
mtd.setAccessible(true)
flag = true
else
flag = false
mtd.invoke(methodObj, args: _*).asInstanceOf[NCResult]
catch
case e: InvocationTargetException =>
e.getTargetException match
case cause: NCIntentSkip => throw cause
case cause: NCRejection => throw cause
case cause: NCException => throw cause
case cause: Throwable => E(s"Intent callback invocation error [$z]", cause)
case e: Throwable => E(s"Unexpected intent callback invocation error [$z]", e)
finally
if flag then
try mtd.setAccessible(false)
catch case e: SecurityException => E(s"Access or security error in intent callback [$z]", e)
/**
*
* @param cfg
* @param field
* @param obj
*/
private def getFieldObject(cfg: NCModelConfig, field: Field, obj: AnyRef): AnyRef =
lazy val fStr = field2Str(field)
val fieldObj = if Modifier.isStatic(field.getModifiers) then null else obj
var flag = field.canAccess(fieldObj)
lazy val z = s"mdlId=${cfg.getId}, field=$fStr"
val res =
try
if !flag then
field.setAccessible(true)
flag = true
else
flag = false
field.get(fieldObj)
catch case e: Throwable => E(s"Unexpected field access error [$z]", e)
finally
if flag then
try field.setAccessible(false)
catch case e: SecurityException => E(s"Access or security error in field [$z]", e)
if res == null then throw new NCException(s"Field value cannot be 'null' for [$z]")
res
/**
*
* @param mtd
* @param argIdx
*/
private def arg2Str(mtd: Method, argIdx: Int): String = s"#${argIdx + 2} of ${method2Str(mtd)}"
/**
* Gets its own methods including private and accessible from parents.
*
* @param o Object.
* @return Methods.
*/
private def getAllMethods(o: AnyRef): Set[Method] =
val cls = o.getClass
(cls.getDeclaredMethods ++ cls.getMethods).toSet
/**
* Gets its own fields including private and accessible from parents.
*
* @param o Object.
* @return Fields.
*/
private def getAllFields(o: AnyRef): Set[Field] =
val cls = o.getClass
(cls.getDeclaredFields ++ cls.getFields).toSet
/**
*
* @param cfg
* @param mtd
* @param argClasses
* @param paramGenTypes
*/
private def checkTypes(cfg: NCModelConfig, mtd: Method, argClasses: Seq[Class[_]], paramGenTypes: Seq[Type]): Unit =
require(argClasses.sizeIs == paramGenTypes.length)
var warned = false
argClasses.zip(paramGenTypes).zipWithIndex.foreach { case ((argClass, paramGenType), i) =>
def mkArg(): String = arg2Str(mtd, i)
lazy val z = s"mdlId=${cfg.getId}, type=${class2Str(argClass)}, arg=${mkArg()}"
// Entity.
if argClass == CLS_ENTITY then () // No-op.
else if argClass.isArray then
val compType = argClass.getComponentType
if compType != CLS_ENTITY then
E(s"Unexpected array element type for $IT annotated argument [$z]")
// Entities collection and optionals.
else if COMP_CLS.contains(argClass) then
paramGenType match
case pt: ParameterizedType =>
val actTypes = pt.getActualTypeArguments
val compTypes = if actTypes == null then Seq.empty else actTypes.toSeq
if compTypes.sizeIs != 1 then
E(s"Unexpected generic types count for $IT annotated argument [count=${compTypes.length}, $z]")
val compType = compTypes.head
compType match
case _: Class[_] =>
val genClass = compTypes.head.asInstanceOf[Class[_]]
if genClass != CLS_ENTITY then
E(s"Unexpected generic type for $IT annotated argument [$z]")
case _: WildcardType =>
val wildcardType = compTypes.head.asInstanceOf[WildcardType]
val lowBounds = wildcardType.getLowerBounds
val upBounds = wildcardType.getUpperBounds
if lowBounds.nonEmpty || upBounds.size != 1 || upBounds(0) != CLS_ENTITY then
E(s"Unexpected generic type for $IT annotated argument [$z]")
case _ => E(s"Unexpected generic type for $IT annotated argument [$z]")
case _ =>
if COMP_CLS.exists(_ == paramGenType) then
if !warned then
warned = true
logger.warn(s"Unable to detected and type-check method argument [${method2Str(mtd)}, $z]")
end if
else
E(s"Unexpected parameter type for $IT annotated argument [$z]")
else
// Other types.
E(s"Unexpected parameter type for $IT annotated argument [$z]")
}