diff --git a/core/interpreter/src/main/java/org/overture/interpreter/util/Delegate.java b/core/interpreter/src/main/java/org/overture/interpreter/util/Delegate.java index 91d1ad967b..158aa840c9 100644 --- a/core/interpreter/src/main/java/org/overture/interpreter/util/Delegate.java +++ b/core/interpreter/src/main/java/org/overture/interpreter/util/Delegate.java @@ -24,7 +24,9 @@ package org.overture.interpreter.util; import java.io.IOException; +import java.io.PrintWriter; import java.io.Serializable; +import java.io.StringWriter; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; @@ -183,24 +185,35 @@ private Method getDelegateMethod(String title, Context ctxt) + title); } - try + // search with no context and default package + org.overture.lib + InternalException searchException = null; + Method basicMathod = null; + try { + basicMathod = getDelegateMethod(mname, ptypes); + }catch(InternalException e) { - Class[] array = new Class[0]; - m = delegateClass.getMethod(mname, ptypes.toArray(array)); + searchException = e; + } - if (!m.getReturnType().equals(Value.class)) - { - throw new InternalException(58, "Native method does not return Value: " - + m); - } - } catch (SecurityException e) + // search with context and default package + org.overture.lib this is preferred over no context + try { + ptypes.add(0,Context.class); + m = getJavaDelegateMethod(mname, ptypes); + }catch(InternalException e) + { + searchException = e; + } + + if(m==null) { - throw new InternalException(60, "Cannot access native method: " - + e.getMessage()); - } catch (NoSuchMethodException e) + m = basicMathod; + } + + + + if(m==null && searchException!=null) { - throw new InternalException(61, "Cannot find native method: " - + e.getMessage()); + throw searchException; } delegateMethods.put(title, m); @@ -209,6 +222,54 @@ private Method getDelegateMethod(String title, Context ctxt) return m; } + private Method getDelegateMethod(String mname, List> ptypes) { + Method m = null; + InternalException searchException = null; + try { + m = getJavaDelegateMethod(mname, ptypes); + }catch(InternalException e) + { + searchException = e; + } + if(m == null) + { + try { + m = getJavaDelegateMethod("org.overture.lib."+mname, ptypes); + }catch(InternalException e) + { + searchException = e; + } + } + if(m==null && searchException!=null) { + throw searchException; + } + return m; + } + + private Method getJavaDelegateMethod(String mname, List> ptypes) { + Method m; + try + { + Class[] array = new Class[0]; + m = delegateClass.getMethod(mname, ptypes.toArray(array)); + + if (!m.getReturnType().equals(Value.class)) + { + throw new InternalException(58, "Native method does not return Value: " + + m); + } + } catch (SecurityException e) + { + throw new InternalException(60, "Cannot access native method: " + + e.getMessage()); + } catch (NoSuchMethodException e) + { + throw new InternalException(61, "Cannot find native method: " + + e.getMessage()); + } + return m; + } + public Value invokeDelegate(Object delegateObject, Context ctxt) { Method m = getDelegateMethod(ctxt.title, ctxt); @@ -219,10 +280,23 @@ public Value invokeDelegate(Object delegateObject, Context ctxt) + m.getName()); } + boolean useContext = m.getParameterTypes().length >0 && m.getParameterTypes()[0].equals(Context.class); + LexNameList anames = delegateArgs.get(ctxt.title); - Object[] avals = new Object[anames.size()]; + + int argCount = anames.size(); + if(useContext) + { + argCount++; + } + Object[] avals = new Object[argCount]; int a = 0; + if(useContext) + { + avals[a++] = ctxt; + } + for (ILexNameToken arg : anames) { avals[a++] = ctxt.get(arg); @@ -253,8 +327,12 @@ public Value invokeDelegate(Object delegateObject, Context ctxt) // { // throw (ValueException)e.getTargetException(); // } + + StringWriter strOut = new StringWriter(); + strOut.append(e.getTargetException().getMessage()+"\n"); + e.getTargetException().printStackTrace(new PrintWriter(strOut)); throw new InternalException(59, "Failed in native method: " - + e.getTargetException().getMessage()); + + strOut); } }