From ae5ca93ff6feb46ba7d502933d07b885e62ebbd0 Mon Sep 17 00:00:00 2001
From: MASES Public Developers Team
 <94312179+masesdevelopers@users.noreply.github.com>
Date: Fri, 27 Sep 2024 18:16:37 +0200
Subject: [PATCH] 
 https://github.com/masesgroup/JNet/issues/512#issuecomment-2379304599: Added
 invocation of base methods (#555)

* Update on #552

* https://github.com/masesgroup/JNet/issues/512#issuecomment-2379304599: Added invocation of base methods
---
 src/net/JNetReflector/InternalConst.cs       |  1 +
 src/net/JNetReflector/InternalMethods.cs     | 44 ++++++++++++++++++++
 src/net/JNetReflector/Templates/Templates.cs |  2 +
 3 files changed, 47 insertions(+)

diff --git a/src/net/JNetReflector/InternalConst.cs b/src/net/JNetReflector/InternalConst.cs
index ff0d6c1e39..86990287c4 100644
--- a/src/net/JNetReflector/InternalConst.cs
+++ b/src/net/JNetReflector/InternalConst.cs
@@ -109,6 +109,7 @@ public static string VersionPlaceHolder()
         public const string ClassSuffix = "Class";
         public const string FieldSuffix = "Field";
         public const string MethodSuffix = "Method";
+        public const string BaseMethodSuffix = "Base";
         public const string DefaultMethodSuffix = "Default";
         public const string DirectMethodSuffix = "Direct";
         public const string NamespaceSuffix = "Ns";
diff --git a/src/net/JNetReflector/InternalMethods.cs b/src/net/JNetReflector/InternalMethods.cs
index df95dd5d19..9a5000ea67 100644
--- a/src/net/JNetReflector/InternalMethods.cs
+++ b/src/net/JNetReflector/InternalMethods.cs
@@ -1967,6 +1967,36 @@ static string AnalyzeMethods(this Class classDefinition, IEnumerable<Class> clas
                 string baseHandlerName = methodIndexer == 0 ? methodName : (methodIndexer == 1 ? methodName + paramCount : methodName + paramCount + $"_{methodIndexer}");
                 if (implementMethodAsListener)
                 {
+                    if (classDefinition.IsJVMClassWithCallbacks())
+                    {
+                        // add base method
+                        jDecoration.AppendLine();
+                        jDecoration.Append(AllPackageClasses.ClassStub.MethodStub.HELP_REMARK_DEFAULT_METHOD);
+
+                        string methodNameDefault = methodName + SpecialNames.BaseMethodSuffix;
+                        template = Template.GetTemplate(Template.SingleMethodTemplate);
+                        singleMethod = template.Replace(AllPackageClasses.ClassStub.MethodStub.DECORATION, jDecoration.ToString())
+                                               .Replace(AllPackageClasses.ClassStub.MethodStub.LISTENER_HANDLER_EXECUTION, listenerHandlerType)
+                                               .Replace(AllPackageClasses.ClassStub.MethodStub.LISTENER_HANDLER_NAME, baseHandlerName)
+                                               .Replace(AllPackageClasses.ClassStub.MethodStub.MODIFIER, modifier)
+                                               .Replace(AllPackageClasses.ClassStub.MethodStub.RETURNTYPE, returnType)
+                                               .Replace(AllPackageClasses.ClassStub.MethodStub.NAME, methodNameDefault)
+                                               .Replace(AllPackageClasses.ClassStub.MethodStub.PARAMETERS, paramsString)
+                                               .Replace(AllPackageClasses.ClassStub.MethodStub.WHERECLAUSES, genericClauses.ConvertClauses(isGeneric))
+                                               .Replace(AllPackageClasses.ClassStub.MethodStub.EXECUTION, executionStub.Replace(methodNameOrigin, methodNameOrigin + SpecialNames.BaseMethodSuffix))
+                                               .Replace(AllPackageClasses.ClassStub.MethodStub.LISTENER_EXECUTION_TYPE, executionPropertyParams)
+                                               .Replace(AllPackageClasses.ClassStub.MethodStub.LISTENER_EXECUTION, listenerExecutionParamsString)
+                                               .Replace(AllPackageClasses.ClassStub.MethodStub.HELP, method.JavadocHrefUrl(JNetReflectorCore.UseCamel));
+
+                        jDecoration = new StringBuilder(jDecorationTemporary);
+                        if (!forInterface)
+                        {
+                            subClassBlock.AppendLine(singleMethod);
+                            jDecoration.AppendLine();
+                            jDecoration.AppendFormat(AllPackageClasses.ClassStub.MethodStub.HELP_REMARK_HANDLER_WITH_DEFAULT, methodNameDefault);
+                        }
+                    }
+
                     if (method.IsDefault)
                     {
                         jDecoration.AppendLine();
@@ -2340,6 +2370,20 @@ static string AnalyzeJavaMethods(this Class classDefinition, string extendingInt
 
                 subClassBlock.AppendLine(singleMethod);
 
+                if (classDefinition.IsJVMClassWithCallbacks())
+                {
+                    execStub = string.Format(isVoidMethod ? AllPackageClasses.ClassStub.MethodStub.SUPERINTERFACE_VOID_LISTENER_BASE_EXECUTION_FORMAT : AllPackageClasses.ClassStub.MethodStub.SUPERINTERFACE_TYPED_LISTENER_BASE_EXECUTION_FORMAT,
+                                             methodNameOrigin, executionParamsString.Length == 0 ? string.Empty : executionParamsString);
+
+                    var singleBaseMethod = template.Replace(AllPackageClasses.ClassStub.MethodStub.RETURNTYPE, returnType)
+                                                   .Replace(AllPackageClasses.ClassStub.MethodStub.NAME, methodNameOrigin + SpecialNames.BaseMethodSuffix)
+                                                   .Replace(AllPackageClasses.ClassStub.MethodStub.PARAMETERS, paramsString)
+                                                   .Replace(AllPackageClasses.ClassStub.MethodStub.EXTEND_EXCEPTIONS, exceptionsThrowed)
+                                                   .Replace(AllPackageClasses.ClassStub.MethodStub.EXECUTION, execStub.AddTabLevel(1));
+
+                    subClassBlock.AppendLine(singleBaseMethod);
+                }
+
                 if (method.IsDefault && isInterfaceJavaListener)
                 {
                     execStub = string.Format(isVoidMethod ? AllPackageClasses.ClassStub.MethodStub.SUPERINTERFACE_VOID_LISTENER_EXECUTION_FORMAT : AllPackageClasses.ClassStub.MethodStub.SUPERINTERFACE_TYPED_LISTENER_EXECUTION_FORMAT,
diff --git a/src/net/JNetReflector/Templates/Templates.cs b/src/net/JNetReflector/Templates/Templates.cs
index b9a0ce519d..49fed3cb6c 100644
--- a/src/net/JNetReflector/Templates/Templates.cs
+++ b/src/net/JNetReflector/Templates/Templates.cs
@@ -252,6 +252,7 @@ public class MethodStub
                 public static string VOID_LISTENER_EXECUTION_FORMAT = "org.mases.jnet.developed.JNetEventResult eventDataExchange = new org.mases.jnet.developed.JNetEventResult();" + Environment.NewLine
                                                                     + "raiseEvent(\"{0}\", eventDataExchange{1}); if (!eventDataExchange.getHasOverride()) throw new UnsupportedOperationException(\"The method shall be implemented in .NET side since does not have a default implementation within the JVM\");";
                 public const string SUPERINTERFACE_VOID_LISTENER_EXECUTION_FORMAT = "{0}.super.{1}({2});";
+                public const string SUPERINTERFACE_VOID_LISTENER_BASE_EXECUTION_FORMAT = "super.{0}({1});";
                 public static string SUPERINTERFACE_VOID_DEFAULT_EXECUTION_FORMAT = "org.mases.jnet.developed.JNetEventResult eventDataExchange = new org.mases.jnet.developed.JNetEventResult();" + Environment.NewLine
                                                                                   + "raiseEvent(\"{0}\", eventDataExchange{1}); if (!eventDataExchange.getHasOverride()) {2}.super.{3}({4});";
                 public static string SUPERINTERFACE_VOID_ADAPTER_EXECUTION_FORMAT = "org.mases.jnet.developed.JNetEventResult eventDataExchange = new org.mases.jnet.developed.JNetEventResult();" + Environment.NewLine
@@ -259,6 +260,7 @@ public class MethodStub
                 public static string TYPED_LISTENER_EXECUTION_FORMAT = "org.mases.jnet.developed.JNetEventResult eventDataExchange = new org.mases.jnet.developed.JNetEventResult();" + Environment.NewLine
                                                                      + "raiseEvent(\"{0}\", eventDataExchange{1}); if (!eventDataExchange.getHasOverride()) throw new UnsupportedOperationException(\"The method shall be implemented in .NET side since does not have a default implementation within the JVM\"); Object retVal = eventDataExchange.getReturnData(); return ({2})retVal;";
                 public const string SUPERINTERFACE_TYPED_LISTENER_EXECUTION_FORMAT = "return {0}.super.{1}({2});";
+                public const string SUPERINTERFACE_TYPED_LISTENER_BASE_EXECUTION_FORMAT = "return super.{0}({1});";
                 public static string SUPERINTERFACE_TYPED_DEFAULT_EXECUTION_FORMAT = "org.mases.jnet.developed.JNetEventResult eventDataExchange = new org.mases.jnet.developed.JNetEventResult();" + Environment.NewLine
                                                                                    + "raiseEvent(\"{0}\", eventDataExchange{1}); Object retVal; if (!eventDataExchange.getHasOverride()) retVal = {3}.super.{4}({5}); else retVal = eventDataExchange.getReturnData(); return ({2})retVal;";
                 public static string SUPERINTERFACE_TYPED_ADAPTER_EXECUTION_FORMAT = "org.mases.jnet.developed.JNetEventResult eventDataExchange = new org.mases.jnet.developed.JNetEventResult();" + Environment.NewLine