# HG changeset patch
# User Ernst Reissner <rei3ner@arcor.de>
# Date 1471344823 -7200
#      Tue Aug 16 12:53:43 2016 +0200
# Node ID 40632d3936d8bb9c9fc120ffa95e5d7fd8614642
# Parent  13532692228e1726b88b08a3d046846d2caf1e88
ClassHelper: redesign concerning findMethod/Constructor and invokeMethod/Constructor

diff -r 13532692228e -r 40632d3936d8 scripts/java/org/octave/ClassHelper.java
--- a/scripts/java/org/octave/ClassHelper.java	Tue Aug 16 12:07:48 2016 +0200
+++ b/scripts/java/org/octave/ClassHelper.java	Tue Aug 16 12:53:43 2016 +0200
@@ -615,10 +615,13 @@
   //!    the argument types of the method.
   //! @return
   //!    a method in class @c cls,
-  //!    with name @c name and parameter types @c argTypes
-  //!    or @c null if no such method exists.
+  //!    with name @c name and parameter types @c argTypes.
+  //! @throws NoSuchMethodException
+  //!    if no such method exists.
+  // used in invokeMethod and in invokeStaticMethod only 
   private static Method findMethod (Class cls, String name, boolean staticOnly, 
                                     Class[] argTypes)
+    throws NoSuchMethodException
   {
     try
       {
@@ -649,8 +652,8 @@
             return meth;
           }
       }
-    // FIXME: very bad: null instead of exception
-    return null;
+
+    throw new NoSuchMethodException (name);
   }
 
   //! Return the first constructor in class @c cls
@@ -668,7 +671,11 @@
   //!    a constructor in class @c cls
   //!    with parameter types @c argTypes
   //!    or @c null if no such constructor exists.
+  //! @throws NoSuchMethodException
+  //!    if no such constructor exists.
+  // used in invokeConstructor only 
   private static Constructor findConstructor (Class cls, Class[] argTypes)
+    throws NoSuchMethodException
   {
     try
       {
@@ -687,7 +694,7 @@
                 return c;
               }
           }
-        return null;
+        throw e;
       }
   }
 
@@ -777,7 +784,7 @@
   }
 
   //! Apply method named @c name to object @c target
-  //! with arguments @c args of types @c argTYpes. 
+  //! with arguments @c args of types @c argTypes. 
   //!
   //! This method is preferrably used for member methods, 
   //! but is also applicable for class methods. 
@@ -805,13 +812,10 @@
   //! @see ::getField(Object, String)
   public static Object invokeMethod (Object target, String name, 
                                      Object[] args, Class[] argTypes)
-    throws Throwable
+    throws NoSuchMethodException, Throwable
   {
+    // findMethod may throw NoSuchMethodException
     Method m = findMethod (target.getClass (), name, false, argTypes);
-    if (m == null)
-      {
-        throw new NoSuchMethodException (name);
-      }
 
     try
       {
@@ -830,50 +834,52 @@
 
   //! Apply static method named @c name of class @c cls
   //! loaded by #loader 
-  //! with arguments @c args of types @c argTYpes. 
+  //! 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 cls
+  //!    the class of the static method to be invoked.
   //! @param name
-  //!    the name of the method to be applied 
+  //!    the name of the method to be invoked.
   //! @param args
   //!    the arguments of the method call. 
   //! @param 
-  //!    the types of arguments of the methods to be applied
+  //!    the types of arguments of the method to be applied.
   //! @return
   //!    the return value of the method call, 
   //!    if no exception or error is thrown. 
+  //! @throws ClassNotFoundException
+  //!    if #loader could not find the class @c cls.
+  //! @throw NoSuchMethodException
+  //!    if no such method is found. 
   //! @throw NoSuchMethodException
   //!    if no such method is found. 
   //! @throws Throwable
-  //!    if so does the invoked method applied to @c target 
-  //!    with parameters @c args. 
+  //!    if so does the static method invoked with parameters @c args. 
   //! @see ::getStaticField(String, String)
-  public static Object invokeStaticMethod (String cls, String name, 
+  //! @see ::invokeConstructor(String, Object[], Class[])
+   public static Object invokeStaticMethod (String cls, String name, 
                                            Object[] args, Class[] argTypes)
     throws ClassNotFoundException, NoSuchMethodException,
-    IllegalAccessException, Throwable
+    Throwable
   {
     
     // Class.forName may throw ClassNotFoundException
-    Method m = findMethod (Class.forName (cls, true, loader), 
-                           name, true, argTypes);
-    if (m == null)
-      {
-        throw new NoSuchMethodException (name);
-      }
-
+    // findMethod may throw NoSuchMethodException
+    Method meth = findMethod (Class.forName (cls, true, loader), 
+                              name, true, argTypes);
+    // Here, meth is a class method
     try
       {
-        // may throw IllegalAccessException, InvocationTargetException
-        // no NullPointerException because m is a class method 
-        Object result = m.invoke (null,
-                                  castArguments (args, argTypes,
-                                                 m.getParameterTypes ()));
+        // invoke may throw IllegalAccessException (impossible: public), 
+        // InvocationTargetException
+        // no NullPointerException because meth is a class method 
+        Object result = meth.invoke (null,
+                                     castArguments (args, argTypes,
+                                                    meth.getParameterTypes ()));
         return result;
       }
     catch (InvocationTargetException ex)
@@ -883,30 +889,52 @@
       }
   }
 
-  // using loader
-  // Used @file ov-java.cc only.
-  public static Object invokeConstructor (String cls, Object[] args,
-                                          Class[] argTypes)
-    throws Throwable
+  //! Call constructor of class @c cls
+  //! loaded by #loader 
+  //! with arguments @c args of types @c argTypes. 
+  //!
+  //! Used by
+  //! #do_javaObject(void*, std::string&, std::string&, octave_value_list&)
+  //! in <code>ov-java.cc</code> only.
+  //!
+  //! @param cls
+  //!    the class of the constructor to be invoked.
+  //! @param args
+  //!    the arguments of the constructor call. 
+  //! @param 
+  //!    the types of arguments of the constructor to be applied.
+  //! @throws ClassNotFoundException
+  //!    if #loader could not find the class @c cls.
+  //! @throw NoSuchMethodException
+  //!    if no such constructor is found. 
+  //! @throw InstantiationException 
+  //!    if class @c cls is abstract.
+  //! @throws Throwable
+  //!    if so does the constructor invoked with parameters @c args. 
+  //! @see ::invokeStaticMethod(String, String, Object[], Class[])
+  public static Object invokeConstructor (String cls, 
+                                          Object[] args, Class[] argTypes)
+    throws ClassNotFoundException, NoSuchMethodException, 
+    InstantiationException, Throwable
   {
-    Constructor c = findConstructor (Class.forName (cls, true, loader),
-                                     argTypes);
-    if (c == null)
-      {
-        throw new NoSuchMethodException (cls);
-      }
-
+    // Class.forName may throw ClassNotFoundException
+    // findConstructor may throw NoSuchMethodException
+    Constructor constr = findConstructor (Class.forName (cls, true, loader),
+                                          argTypes);
     try
       {
-        return c.newInstance (castArguments (args, argTypes,
-                                             c.getParameterTypes ()));
+        // newInstance may throw IllegalAccessException (impossible: public),
+        // InstantiationException for abstract classes 
+        // InvocationTargetException, 
+        // ExceptionInInitializerError 
+        return constr.newInstance (castArguments (args, argTypes,
+                                                  constr.getParameterTypes ()));
       }
     catch (InvocationTargetException ex)
       {
         // may throw general Throwable
         throw ex.getCause ();
       }
-
   }
 
   //! Return the value of the field with name @c name
