# HG changeset patch
# User Ernst Reissner <rei3ner@arcor.de>
# Date 1471342068 -7200
#      Tue Aug 16 12:07:48 2016 +0200
# Node ID 13532692228e1726b88b08a3d046846d2caf1e88
# Parent  5083119bd75e56dba6f61b6ec74cdc95dfd2cef3
bugfix 48795: additional changes because of bug in former patch.

diff -r 5083119bd75e -r 13532692228e scripts/java/org/octave/ClassHelper.java
--- a/scripts/java/org/octave/ClassHelper.java	Tue Aug 16 11:58:24 2016 +0200
+++ b/scripts/java/org/octave/ClassHelper.java	Tue Aug 16 12:07:48 2016 +0200
@@ -593,10 +593,12 @@
     return getConstructors (obj.getClass ());
   }
 
-
   //! Return the first method found in class @c cls
-  //! with name @c name and parameter types @c argTypes
+  //! with name @c name, declared @c static if @c staticOnly 
+  //! and parameter types @c argTypes
   //! or @c null if no such method is found.
+  //!
+  //! CAUTION:
   //! Note that if there are more than one method fitting the criteria,
   //! an arbitrary one is returned, and there is no notification,
   //! that the solution is not unique.
@@ -605,66 +607,52 @@
   //!    the class of the method.
   //! @param name
   //!    the name of the method.
+  //! @param staticOnly
+  //!    whether static methods are allowed only.
+  //!    If this is not set,
+  //!    both, static methods and member methods are allowed.
   //! @param argTypes
   //!    the argument types of the method.
   //! @return
-  //!    a method in class @c cls, 
+  //!    a method in class @c cls,
   //!    with name @c name and parameter types @c argTypes
   //!    or @c null if no such method exists.
-  private static Method findMethod (Class cls, String name, Class[] argTypes)
+  private static Method findMethod (Class cls, String name, boolean staticOnly, 
+                                    Class[] argTypes)
   {
     try
       {
-        return cls.getMethod (name, argTypes);
+       Method meth = cls.getMethod (name, argTypes);
+       if (!staticOnly || Modifier.isStatic(meth.getModifiers()))
+         {
+           return meth;
+         }
+       // fall through: same as for catch block 
+       // FIXME: control flow realized by try-catch
       }
-    catch (NoSuchMethodException e)
+    catch (NoSuchMethodException e)// NOPMD: rulecheck suspended
       {
-        Method[] mList = cls.getMethods ();
-        Method m;
-        for (int i = 0; i < mList.length; i++)
+       // fall through: same as if try branch is left regurarly 
+      }
+ 
+    Method[] mList = cls.getMethods ();
+    Method meth;
+    for (int i = 0; i < mList.length; i++)
+      {
+        meth = mList[i];
+        if (meth.getName ().equals (name)
+            && (!staticOnly || Modifier.isStatic(meth.getModifiers()))
+            && meth.getParameterTypes ().length == argTypes.length
+            && isCallableFrom (meth, argTypes))
           {
-            m = mList[i];
-            if (m.getName ().equals (name)
-                && m.getParameterTypes ().length == argTypes.length
-                && isCallableFrom (m, argTypes))
-              {
-                return m;
-              }
+            // FIXME: returns with the first possibility instead of optimizing
+            return meth;
           }
-
-        return null;
       }
+    // FIXME: very bad: null instead of exception
+    return null;
   }
 
-  //! Return the first method found in class @c cls
-  //! with name @c name, static if and only if @c isStatic 
-  //! and with parameter types @c argTypes
-  //! or @c null if no such method is found.
-  //! Note that if there are more than one method fitting the criteria,
-  //! an arbitrary one is returned, and there is no notification,
-  //! that the solution is not unique.
-  //!
-  //! @param cls
-  //!    the class of the method.
-  //! @param name
-  //!    the name of the method.
-  //! @param isStatic
-  //!    whether the method to be returned is static. 
-  //! @param argTypes
-  //!    the argument types of the method.
-  //! @return
-  //!    a method in class @c cls, static if and only if @c isStatic, 
-  //!    with name @c name and parameter types @c argTypes
-  //!    or @c null if no such method exists.
-  private static Method findMethod (Class cls, String name, boolean isStatic, 
-                                    Class[] argTypes)
-  {
-    Method meth = findMethod (cls, name, argTypes);
-    return (meth == null || Modifier.isStatic(meth.getModifiers()) != isStatic)
-      ? null : meth;
-  }
-
-
   //! Return the first constructor in class @c cls
   //! with parameter types @c argTypes
   //! or @c null if no such constructor is found.
@@ -788,12 +776,35 @@
       } // catch IllegalAccessException
   }
 
-  // Used internally and by
-  // #do_javaMethod(void*, std::string&, octave_value_list&)
-  // in <code>ov-java.cc</code> only.
-  // getField(Object, String)
-  public static Object invokeMemberMethod (Object target, String name, 
-                                           Object[] args, Class[] argTypes)
+  //! Apply method named @c name to object @c target
+  //! with arguments @c args of types @c argTYpes. 
+  //!
+  //! This method is preferrably used for member methods, 
+  //! but is also applicable for class methods. 
+  //!
+  //! Used internally and by
+  //! #do_javaMethod(void*, std::string&, octave_value_list&)
+  //! in <code>ov-java.cc</code> only.
+  //!
+  //! @param target
+  //!    the object the specified method shall be applied to. 
+  //! @param name
+  //!    the name of the method to be applied 
+  //! @param args
+  //!    the arguments of the method call. 
+  //! @param 
+  //!    the types of arguments of the methods to be applied
+  //! @return
+  //!    the return value of the method call, 
+  //!    if no exception or error is thrown. 
+  //! @throw NoSuchMethodException
+  //!    if no such method is found. 
+  //! @throws Throwable
+  //!    if so does the invoked method applied to @c target 
+  //!    with parameters @c args. 
+  //! @see ::getField(Object, String)
+  public static Object invokeMethod (Object target, String name, 
+                                     Object[] args, Class[] argTypes)
     throws Throwable
   {
     Method m = findMethod (target.getClass (), name, false, argTypes);
@@ -815,19 +826,40 @@
         // may throw general Throwable
         throw ex.getCause ();
       }
-
   }
 
-  // using loader
-  // Used internally and by @file ov-java.cc only.
-  // getStaticField(String, String)
+  //! Apply static method named @c name of class @c cls
+  //! loaded by #loader 
+  //! with arguments @c args of types @c argTYpes. 
+  //!
+  //! Used internally and by
+  //! #do_javaMethod(void*, std::string&, std::string&, octave_value_list&)
+  //! in <code>ov-java.cc</code> only.
+  //!
+  //! @param target
+  //!    the object the specified method shall be applied to. 
+  //! @param name
+  //!    the name of the method to be applied 
+  //! @param args
+  //!    the arguments of the method call. 
+  //! @param 
+  //!    the types of arguments of the methods to be applied
+  //! @return
+  //!    the return value of the method call, 
+  //!    if no exception or error is thrown. 
+  //! @throw NoSuchMethodException
+  //!    if no such method is found. 
+  //! @throws Throwable
+  //!    if so does the invoked method applied to @c target 
+  //!    with parameters @c args. 
+  //! @see ::getStaticField(String, String)
   public static Object invokeStaticMethod (String cls, String name, 
                                            Object[] args, Class[] argTypes)
     throws ClassNotFoundException, NoSuchMethodException,
     IllegalAccessException, Throwable
   {
     
-    // forName may throw ClassNotFoundException
+    // Class.forName may throw ClassNotFoundException
     Method m = findMethod (Class.forName (cls, true, loader), 
                            name, true, argTypes);
     if (m == null)
@@ -838,8 +870,7 @@
     try
       {
         // may throw IllegalAccessException, InvocationTargetException
-        // NullPointerException if m is an instance method 
-        // FIXME: Bug #48795 
+        // no NullPointerException because m is a class method 
         Object result = m.invoke (null,
                                   castArguments (args, argTypes,
                                                  m.getParameterTypes ()));
@@ -906,8 +937,7 @@
         try
           {
             // may throw Throwable if so does method name()
-            return invokeMemberMethod (target, name, 
-                                       new Object[0], new Class[0]);
+            return invokeMethod (target, name, new Object[0], new Class[0]);
           }
         catch (NoSuchMethodException ex2)
           {
