# HG changeset patch
# User Ernst Reissner <rei3ner@arcor.de>
# Date 1471958726 -7200
#      Tue Aug 23 15:25:26 2016 +0200
# Node ID b198b2ce1bbd82b4a595ce951c31c7a051ffe4c9
# Parent  5eddb9b067f87f9526e1db27893a2b00608176e1
for bugfix of 48593: separated method get_invoke_list in two halfs,
one returning a list of fields, required to implement function struct.

diff -r 5eddb9b067f8 -r b198b2ce1bbd libinterp/octave-value/ov-java.cc
--- a/libinterp/octave-value/ov-java.cc	Tue Aug 23 15:07:17 2016 +0200
+++ b/libinterp/octave-value/ov-java.cc	Tue Aug 23 15:25:26 2016 +0200
@@ -978,11 +978,99 @@
   return retval;
 }
 
-static string_vector
-get_invoke_list (JNIEnv *jni_env, void *jobj_arg)
+
+
+// static std::list<std::string>
+// get_field_list (JNIEnv *jni_env, void *jobj_arg)
+// {
+//   jobject jobj = TO_JOBJECT (jobj_arg);
+
+//   std::list<std::string> name_list;
+
+//   if (jni_env)
+//     {
+//       jclass_ref cls (jni_env, jni_env->GetObjectClass (jobj));
+//       jclass_ref ccls (jni_env, jni_env->GetObjectClass (cls));
+//       jmethodID getFields_ID = jni_env->GetMethodID
+//         (ccls, "getFields", "()[Ljava/lang/reflect/Field;");
+//       jobjectArray_ref fList (jni_env,
+//                               reinterpret_cast<jobjectArray>
+//                               (jni_env->CallObjectMethod (cls, getFields_ID)));
+//       int fLen = jni_env->GetArrayLength (fList);
+//       jclass_ref fCls (jni_env,
+//                        jni_env->FindClass ("java/lang/reflect/Field"));
+//       jmethodID f_getName_ID = jni_env->GetMethodID (fCls, "getName",
+//                                                      "()Ljava/lang/String;");
+
+
+//       for (int i = 0; i < fLen; i++)
+//         {
+//           jobject_ref field (jni_env,
+//                              jni_env->GetObjectArrayElement (fList, i));
+//           jstring_ref fieldName (jni_env,
+//                                  reinterpret_cast<jstring>
+//                                  (jni_env->CallObjectMethod
+//                                   (field, f_getName_ID)));
+//           name_list.push_back (jstring_to_string (jni_env, fieldName));
+//         }
+
+//       octave_set_default_fpucw ();
+//     }
+
+//   return name_list;
+// }
+
+// static std::list<std::string>
+// get_method_list (JNIEnv *jni_env, void *jobj_arg)
+// {
+//   jobject jobj = TO_JOBJECT (jobj_arg);
+
+//   std::list<std::string> name_list;
+
+//   if (jni_env)
+//     {
+//       jclass_ref cls (jni_env, jni_env->GetObjectClass (jobj));
+//       jclass_ref ccls (jni_env, jni_env->GetObjectClass (cls));
+//       jmethodID getMethods_ID = jni_env->GetMethodID
+//         (ccls, "getMethods", "()[Ljava/lang/reflect/Method;");
+//       jobjectArray_ref mList (jni_env,
+//                               reinterpret_cast<jobjectArray>
+//                               (jni_env->CallObjectMethod (cls, getMethods_ID)));
+//       int mLen = jni_env->GetArrayLength (mList);
+//       jclass_ref mCls (jni_env,
+//                        jni_env->FindClass ("java/lang/reflect/Method"));
+//       jmethodID m_getName_ID = jni_env->GetMethodID (mCls, "getName",
+//                                                      "()Ljava/lang/String;");
+
+//       for (int i = 0; i < mLen; i++)
+//         {
+//           jobject_ref meth (jni_env, jni_env->GetObjectArrayElement (mList, i));
+//           jstring_ref methName (jni_env, reinterpret_cast<jstring>
+//                                 (jni_env->CallObjectMethod (meth, m_getName_ID)));
+//           name_list.push_back (jstring_to_string (jni_env, methName));
+//         }
+
+//       octave_set_default_fpucw ();
+//     }
+
+//   return name_list;
+// }
+
+//! Return the list of methods or fields of @c jobj_arg.
+//!
+//! @param jni_env
+//!    the JNI environment.
+//! @param jobj_arg
+//!    the object to create the desired list from.
+//! @param isMeth
+//!    determines whether a list of field names or method names is returned.
+//! @return
+//!    the list of methods or fields of @c jobj_arg.
+static std::list<std::string>
+get_mf_list (JNIEnv *jni_env, void *jobj_arg, bool isMeth)
 {
   jobject jobj = TO_JOBJECT (jobj_arg);
-
+  std::string methField = isMeth ? "Method" : "Field";
   std::list<std::string> name_list;
 
   if (jni_env)
@@ -990,54 +1078,121 @@
       jclass_ref cls (jni_env, jni_env->GetObjectClass (jobj));
       jclass_ref ccls (jni_env, jni_env->GetObjectClass (cls));
       jmethodID getMethods_ID = jni_env->GetMethodID
-        (ccls, "getMethods", "()[Ljava/lang/reflect/Method;");
-      jmethodID getFields_ID = jni_env->GetMethodID
-        (ccls, "getFields", "()[Ljava/lang/reflect/Field;");
-      jobjectArray_ref mList (jni_env,
+        (ccls, 
+         ("get"+methField+"s").c_str(), 
+         ("()[Ljava/lang/reflect/"+methField+";").c_str());
+      jobjectArray_ref mfList (jni_env,
                               reinterpret_cast<jobjectArray>
                               (jni_env->CallObjectMethod (cls, getMethods_ID)));
-      jobjectArray_ref fList (jni_env,
-                              reinterpret_cast<jobjectArray>
-                              (jni_env->CallObjectMethod (cls, getFields_ID)));
-      int mLen = jni_env->GetArrayLength (mList);
-      int fLen = jni_env->GetArrayLength (fList);
-      jclass_ref mCls (jni_env,
-                       jni_env->FindClass ("java/lang/reflect/Method"));
-      jclass_ref fCls (jni_env,
-                       jni_env->FindClass ("java/lang/reflect/Field"));
-      jmethodID m_getName_ID = jni_env->GetMethodID (mCls, "getName",
-                                                     "()Ljava/lang/String;");
-      jmethodID f_getName_ID = jni_env->GetMethodID (fCls, "getName",
-                                                     "()Ljava/lang/String;");
-
-      for (int i = 0; i < mLen; i++)
+      int mfLen = jni_env->GetArrayLength (mfList);
+      jclass_ref mfCls (jni_env,
+                        jni_env->FindClass (("java/lang/reflect/"+methField)
+                                            .c_str()));
+      jmethodID mf_getName_ID = jni_env->GetMethodID (mfCls, "getName",
+                                                      "()Ljava/lang/String;");
+
+      for (int i = 0; i < mfLen; i++)
         {
-          jobject_ref meth (jni_env, jni_env->GetObjectArrayElement (mList, i));
-          jstring_ref methName (jni_env, reinterpret_cast<jstring>
-                                (jni_env->CallObjectMethod (meth, m_getName_ID)));
-          name_list.push_back (jstring_to_string (jni_env, methName));
-        }
-
-      for (int i = 0; i < fLen; i++)
-        {
-          jobject_ref field (jni_env,
-                             jni_env->GetObjectArrayElement (fList, i));
-          jstring_ref fieldName (jni_env,
-                                 reinterpret_cast<jstring>
-                                 (jni_env->CallObjectMethod
-                                  (field, f_getName_ID)));
-          name_list.push_back (jstring_to_string (jni_env, fieldName));
+          jobject_ref mf (jni_env, 
+                          jni_env->GetObjectArrayElement (mfList, i));
+          jstring_ref mfName (jni_env, reinterpret_cast<jstring>
+                              (jni_env->CallObjectMethod (mf, mf_getName_ID)));
+          name_list.push_back (jstring_to_string (jni_env, mfName));
         }
 
       octave_set_default_fpucw ();
     }
 
-  string_vector v (name_list);
+  return name_list;
+}
+
+//! Return the list of names of methods and fields of @c jobj_arg
+//! alphabetically sorted.
+//! Used in ::map_keys() only. 
+//!
+//! @param jni_env
+//!    the JNI environment.
+//! @param jobj_arg
+//!    the object to create the invoke list from.
+//! @return
+//!    the list of names of methods and fields of @c jobj_arg 
+//!    alphabetically sorted.
+static string_vector
+get_invoke_list (JNIEnv *jni_env, void *jobj_arg)
+{
+  std::list<std::string> name_lst1 = get_mf_list (jni_env, jobj_arg, false);
+  std::list<std::string> name_lst2 = get_mf_list (jni_env, jobj_arg, true);
+  while (! name_list2.empty())
+    {
+      name_list1.push_back(name_list2.back());
+      name_list2.pop_back();
+    }
+  string_vector v (name_list1);
 
   return v.sort (true);
 }
 
 
+// static string_vector
+// get_invoke_list (JNIEnv *jni_env, void *jobj_arg)
+// {
+//   jobject jobj = TO_JOBJECT (jobj_arg);
+
+//   std::list<std::string> name_list;
+
+//   if (jni_env)
+//     {
+//       jclass_ref cls (jni_env, jni_env->GetObjectClass (jobj));
+//       jclass_ref ccls (jni_env, jni_env->GetObjectClass (cls));
+//       jmethodID getMethods_ID = jni_env->GetMethodID
+//         (ccls, "getMethods", "()[Ljava/lang/reflect/Method;");
+//       jmethodID getFields_ID = jni_env->GetMethodID
+//         (ccls, "getFields", "()[Ljava/lang/reflect/Field;");
+//       jobjectArray_ref mList (jni_env,
+//                               reinterpret_cast<jobjectArray>
+//                               (jni_env->CallObjectMethod (cls, getMethods_ID)));
+//       jobjectArray_ref fList (jni_env,
+//                               reinterpret_cast<jobjectArray>
+//                               (jni_env->CallObjectMethod (cls, getFields_ID)));
+//       int mLen = jni_env->GetArrayLength (mList);
+//       int fLen = jni_env->GetArrayLength (fList);
+//       jclass_ref mCls (jni_env,
+//                        jni_env->FindClass ("java/lang/reflect/Method"));
+//       jclass_ref fCls (jni_env,
+//                        jni_env->FindClass ("java/lang/reflect/Field"));
+//       jmethodID m_getName_ID = jni_env->GetMethodID (mCls, "getName",
+//                                                      "()Ljava/lang/String;");
+//       jmethodID f_getName_ID = jni_env->GetMethodID (fCls, "getName",
+//                                                      "()Ljava/lang/String;");
+
+//       for (int i = 0; i < mLen; i++)
+//         {
+//           jobject_ref meth (jni_env, jni_env->GetObjectArrayElement (mList, i));
+//           jstring_ref methName (jni_env, reinterpret_cast<jstring>
+//                                 (jni_env->CallObjectMethod (meth, m_getName_ID)));
+//           name_list.push_back (jstring_to_string (jni_env, methName));
+//         }
+
+//       for (int i = 0; i < fLen; i++)
+//         {
+//           jobject_ref field (jni_env,
+//                              jni_env->GetObjectArrayElement (fList, i));
+//           jstring_ref fieldName (jni_env,
+//                                  reinterpret_cast<jstring>
+//                                  (jni_env->CallObjectMethod
+//                                   (field, f_getName_ID)));
+//           name_list.push_back (jstring_to_string (jni_env, fieldName));
+//         }
+
+//       octave_set_default_fpucw ();
+//     }
+
+//   string_vector v (name_list);
+
+//   return v.sort (true);
+// }
+
+
 static octave_value
 convert_to_string (JNIEnv *jni_env, jobject java_object, bool force, char type)
 {
