String methodName = null;
// 3rd. argument (unbound variable)
a3 = a3.dereference();
if (!a3.isVariable()) {
throw new IllegalTypeException(this, 3, "variable", a3);
}
try {
// 1st. argument (atom or java term)
a1 = a1.dereference();
if (a1.isVariable()) {
throw new PInstantiationException(this, 1);
} else if (a1.isSymbol()) { // class
clazz = Class.forName(((SymbolTerm) a1).name());
} else if (a1.isJavaObject()) { // instance
instance = ((JavaObjectTerm) a1).object();
clazz = ((JavaObjectTerm) a1).getClazz();
} else {
throw new IllegalTypeException(this, 1, "atom_or_java", a1);
}
// 2nd. argument (atom or callable term)
a2 = a2.dereference();
if (a2.isVariable()) {
throw new PInstantiationException(this, 2);
} else if (a2.isSymbol()) { // No argument method
m = clazz.getDeclaredMethod(((SymbolTerm) a2).name());
m.setAccessible(true);
value = m.invoke(instance);
} else if (a2.isStructure()) { // Parameterized method
methodName = ((StructureTerm) a2).name();
arity = ((StructureTerm) a2).arity();
methods = clazz.getDeclaredMethods();
if (methods.length == 0) {
throw new ExistenceException(this, 2, "method", a2, "");
}
pArgs = ((StructureTerm) a2).args();
jArgs = new Object[arity];
for (int i = 0; i < arity; i++) {
pArgs[i] = pArgs[i].dereference();
if (!pArgs[i].isJavaObject()) {
pArgs[i] = new JavaObjectTerm(pArgs[i]);
}
jArgs[i] = pArgs[i].toJava();
}
for (Method method : methods) {
if (method.getName().equals(methodName)
&& checkParameterTypes(method.getParameterTypes(),
pArgs)) {
try {
m = method;
m.setAccessible(true);
value = m.invoke(instance, jArgs);
break; // Succeeds to invoke the method
} catch (Exception e) {
m = null; // Back to loop
}
}
}
if (m == null) {
throw new ExistenceException(this, 2, "method", a2, "");
}
} else {
throw new IllegalTypeException(this, 2, "callable", a2);
}
if (value == null) {
return cont;
}
if (!a3.unify(toPrologTerm(value), engine.trail)) {