00001
00002
00003
00004
00005
00006
00007
00008
00009 package com.declarativa.interprolog;
00010 import com.declarativa.interprolog.util.*;
00011 import java.io.*;
00012 import java.net.*;
00013 import java.util.Vector;
00014 import java.lang.reflect.*;
00015
00019 public abstract class PrologEngine{
00020 protected static int numberOfInstances = 0;
00022 public final static String version = "2.0b1";
00024 public String startPrologCommand;
00025 protected long startTime;
00027 public final static String nl = System.getProperty("line.separator");
00029 protected File tempDirectory;
00030
00032 protected ObjectRegistry knownObjects;
00033 protected boolean shutingDown = false;
00035 public boolean interrupting = false;
00036 protected boolean debug=false;
00037 protected boolean topGoalHasStarted=false;
00039 protected int goalTimestamp;
00040
00042 Vector goalsToExecute;
00044 Vector messagesExecuting;
00045
00047 final Method getRealJavaObjectMethod;
00049 public final String firstJavaMessageName = "firstJavaMessage";
00051
00052
00053
00054
00055 public static final int MAX_INT_VALUE = 134217727;
00057 public static final int MIN_INT_VALUE = -134217728;
00058
00063 public PrologEngine(String startPrologCommand, boolean debug){
00064 startTime= System.currentTimeMillis();
00065 if (startPrologCommand==null)
00066 throw new IPException("PrologEngine with null startPrologCommand");
00067 setDebug(debug);
00068 this.startPrologCommand = startPrologCommand;
00069 numberOfInstances++;
00070 makeTempDirectory();
00071 knownObjects = new ObjectRegistry();
00072 goalsToExecute = new Vector();
00073 messagesExecuting = new Vector();
00074
00075 try{ getRealJavaObjectMethod = findMethod (getClass(),"getRealJavaObject",new Class[]{Object.class});}
00076 catch(Exception ex){throw new IPException("could not find special getRealJavaObject method:"+ex);}
00077 }
00078
00080 public abstract void shutdown();
00081
00083 protected boolean isShutingDown(){
00084 return false;
00085 }
00086
00087 void makeTempDirectory(){
00088 if (tempDirectory!=null)
00089 throw new IPException("Inconsistency in makeTempDirectory");
00090 try{
00091 File dummyFile = File.createTempFile("IP_","");
00092 if (!dummyFile.delete())
00093 throw new IPException("Could not delete dummy file");
00094 tempDirectory = new File(dummyFile.getAbsolutePath());
00095 if (!tempDirectory.mkdir())
00096 throw new IPException("Could not create temporary directory");
00097 tempDirectory.deleteOnExit();
00098 } catch (IOException e){
00099 throw new IPException("Problems creating temporary directory:"+e);
00100 }
00101 }
00102
00104 public File getJarDirectory(){
00105 return getJarDirectory(getClass());
00106 }
00107
00109 public static File getJarDirectory(Class aClass){
00110 String classPath=aClass.getName().replace('.','/') + ".class";
00111 URL u = aClass.getClassLoader().getResource(classPath);
00112 if (!u.getProtocol().equals("jar")) return null;
00113 String s = u.getFile();
00114 if (!s.startsWith("file:/"))
00115 throw new IPException("Jar file is not in the local file system");
00116 int end = s.indexOf("!");
00117 if (end==-1) throw new IPException("Bad jar URL");
00118
00119 String path = s.substring(5,end);
00120 if (!path.endsWith(".jar"))
00121 throw new IPException("Jar file name does not end with .jar");
00122 path=path.replace('/',File.separatorChar);
00123 return new File(path).getParentFile();
00124 }
00125
00126 File copyToTemp(String filename,Object requester){
00127 File tempFile = null;
00128 Class rc;
00129 if (requester instanceof Class) rc = (Class)requester;
00130 else rc = requester.getClass();
00131
00132
00133 String className = rc.getName();
00134 String packageName = className.substring(0,className.lastIndexOf('.'));
00135 String path = packageName.replace('.','/' );
00136
00137 if (filename.indexOf('.')==-1) throw new IPException("File name missing extension");
00138 String suffix = filename.substring(filename.lastIndexOf('.'));
00139 String rootName = filename.substring(0,filename.lastIndexOf('.'));
00140 try {
00141
00142 String resourceName = path+'/'+filename;
00143 InputStream resourceStream =
00144 rc.getClassLoader().getResourceAsStream(resourceName);
00145 if (resourceStream==null) throw new IPException("Resource not found");
00146
00147
00148 tempFile = new File(tempDirectory,filename);
00149 tempFile.deleteOnExit();
00150
00151 FileOutputStream fos = new FileOutputStream(tempFile);
00152 byte[] buffer = new byte[512]; int len;
00153 while ((len = resourceStream.read(buffer, 0, buffer.length)) != -1)
00154 fos.write(buffer, 0, len);
00155 fos.close(); resourceStream.close();
00156 } catch (IOException e){
00157 throw new IPException("I/O problem obtaining "+filename+": "+e);
00158 }
00159 return tempFile;
00160 }
00161
00173 public void consultFromPackage(String filename,Object requester){
00174 if (filename.indexOf('.')==-1) filename=filename+".P";
00175 String path = copyToTemp(filename,requester).getPath();
00176 progressMessage("consultFromPackage:"+path);
00177
00178 if (!command("reconsult('"+path+"')"))
00179 throw new IPException("Problem consulting from package archive");
00180 }
00181
00187 public void consultRelative(String filename,Object requester){
00188 operationRelative("reconsult", filename, requester);
00189 }
00190
00191 public void load_dynRelative(String filename,Object requester){
00192 operationRelative("load_dyn", filename, requester);
00193 }
00194
00195 protected void operationRelative(String operation,String filename,Object requester){
00196 Class rc;
00197 if (requester instanceof Class) rc = (Class)requester;
00198 else rc = requester.getClass();
00199 String path = rc.getPackage().getName().replace('.',File.separatorChar);
00200 path=getJarDirectory().getPath()+File.separatorChar+path;
00201
00202
00203 filename = path+File.separatorChar+filename;
00204 String g = "((library_directory('"+path+"')->true;assert(library_directory('"+path+"'))), "+
00205 operation+"('"+filename+"'))";
00206 if (!command(g))
00207 throw new IPException("Problem in operationRelative");
00208 }
00209
00210
00211
00214 public void interrupt(){
00215 interrupting = true;
00216 doInterrupt();
00217 waitUntilIdle();
00218 interrupting = false;
00219 }
00220
00221 protected abstract void doInterrupt();
00222
00224 public boolean command(String s){
00225 if (topGoalHasStarted) return deterministicGoal(s);
00226 else return realCommand(s);
00227 }
00228
00231 protected abstract boolean realCommand(String s);
00232
00234 public void progressMessage(String s){
00235 if (debug) System.out.println(System.currentTimeMillis()-startTime+ "ms: "+s);
00236 }
00237
00240 public boolean isDebug(){ return debug;}
00241
00242 public void setDebug(boolean d){debug=d;}
00243
00245 public static void printBindings(Object[] b){
00246 if (b==null) System.out.println("Empty bindings");
00247 else
00248 for (int i=0;i<b.length;i++) System.out.println("Binding "+i+":"+b[i]);
00249 }
00250
00251 protected final void teachIPobjects(ObjectOutputStream obs) throws IOException{
00252 Object [] oa1 = {new Integer(13)};
00253 obs.writeObject(
00254 new ObjectExamplePair(
00255 "GoalFromJava",
00256 new GoalFromJava(1,"a","aa",new Object[0],"A"),
00257 new GoalFromJava(2,"b","bb",oa1,"B")
00258 ));
00259 obs.writeObject(
00260 new ObjectExamplePair(
00261 "ResultFromProlog",
00262 new ResultFromProlog(1,true,0,null),
00263 new ResultFromProlog(2,false,1,"some error")
00264 ));
00265 MessageFromProlog mpA = new MessageFromProlog();
00266 mpA.methodName="methodA";
00267 mpA.arguments=new Object[0];
00268 mpA.returnArguments=true;
00269 MessageFromProlog mpB = new MessageFromProlog();
00270 mpB.timestamp=2;
00271 mpB.target = "target";
00272 mpB.methodName="methodB";
00273 mpB.arguments=new Object[1];
00274 mpB.returnArguments=false;
00275 obs.writeObject(
00276 new ObjectExamplePair("MessageFromProlog",mpA,mpB)
00277 );
00278
00279 obs.writeObject(
00280 new ObjectExamplePair("ResultFromJava",
00281 new ResultFromJava(1,null,null,new Object[0]),
00282 new ResultFromJava(2,"result here","new Exception()...",new Object[1])
00283 )
00284 );
00285 obs.writeObject(
00286 new ObjectExamplePair("InvisibleObject",new InvisibleObject(1),new InvisibleObject(2))
00287 );
00288 obs.writeObject(
00289 new ObjectExamplePair("IPClassObject",new IPClassObject("A"),new IPClassObject("B"))
00290 );
00291 obs.writeObject(
00292 new ObjectExamplePair("IPClassVariable",
00293 new IPClassVariable("ClassA","VariableA"), new IPClassVariable("ClassB","VariableB")
00294 )
00295 );
00296 }
00297
00302 protected void teachBasicObjects(ObjectOutputStream obs) throws IOException{
00303 obs.writeObject(
00304 new ObjectExamplePair(
00305 "boolean",new BasicTypeWrapper(new Boolean(true)),new BasicTypeWrapper(new Boolean(false))
00306 ));
00307 obs.writeObject(
00308 new ObjectExamplePair(
00309 "byte",
00310 new BasicTypeWrapper(new Byte((new Integer(1)).byteValue())),
00311 new BasicTypeWrapper(new Byte((new Integer(2)).byteValue()))
00312 ));
00313 obs.writeObject(
00314 new ObjectExamplePair(
00315 "char",new BasicTypeWrapper(new Character('A')),new BasicTypeWrapper(new Character('B'))
00316 ));
00317 obs.writeObject(
00318 new ObjectExamplePair(
00319 "double",new BasicTypeWrapper(new Double(1)),new BasicTypeWrapper(new Double(2))
00320 ));
00321 obs.writeObject(
00322 new ObjectExamplePair(
00323 "float",new BasicTypeWrapper(new Float(1)),new BasicTypeWrapper(new Float(2))
00324 ));
00325 obs.writeObject(
00326 new ObjectExamplePair(
00327 "int",new BasicTypeWrapper(new Integer(1)),new BasicTypeWrapper(new Integer(2))
00328 ));
00329 obs.writeObject(
00330 new ObjectExamplePair(
00331 "long",new BasicTypeWrapper(new Long(1)),new BasicTypeWrapper(new Long(2))
00332 ));
00333 obs.writeObject(
00334 new ObjectExamplePair(
00335 "short",
00336 new BasicTypeWrapper(new Short( (new Integer(1)).shortValue() )),
00337 new BasicTypeWrapper(new Short( (new Integer(2)).shortValue() ))
00338 ));
00339 obs.writeObject(new ObjectExamplePair(new Boolean(true),new Boolean(false)));
00340 obs.writeObject(new ObjectExamplePair(new Integer(1),new Integer(2)));
00341 obs.writeObject(new ObjectExamplePair(new Float(20.59375),new Float(2)));
00342 obs.writeObject(TermModel.example());
00343 obs.writeObject(VariableNode.example());
00344 obs.writeObject(new ObjectExamplePair("ArrayOfTermModel",new TermModel[0],new TermModel[1]));
00345 obs.writeObject(new ObjectExamplePair("ArrayOfString",new String[0]));
00346 obs.writeObject(new ObjectExamplePair("ArrayOfObject",new Object[0]));
00347 }
00348
00351 public boolean teachOneObject(Object example){
00352 return teachMoreObjects(new Object[]{example});
00353 }
00354
00357 public boolean teachMoreObjects(Object[] examples){
00358 if (examples[0] instanceof ObjectExamplePair)
00359 throw new IPException("Bad method invocation in teachMoreObjects");
00360 ObjectExamplePair[] pairs = new ObjectExamplePair[examples.length];
00361 for (int i=0;i<pairs.length;i++)
00362 pairs[i] = new ObjectExamplePair(examples[i]);
00363 return teachMoreObjects(pairs);
00364 }
00365
00370 public boolean teachMoreObjects(ObjectExamplePair[] examples){
00371
00372 Object[] temp = new Object[examples.length];
00373 for (int i=0;i<examples.length;i++)
00374 temp[i] = examples[i];
00375 return deterministicGoal("ipProcessExamples(Examples)", "Examples", temp);
00376 }
00377
00378 protected GoalFromJava makeDGoalObject(String G, String OVar, Object[] objectsP, String RVars,int timestamp){
00379
00380 if (G==null)
00381 throw new IPException ("Null Goal in deterministicGoal");
00382 if (OVar==null)
00383 OVar="_";
00384 if (objectsP == null)
00385 objectsP = new Object[0];
00386 if (G.trim ().endsWith ("."))
00387 throw new IPException ("Goal argument should have no trailing '.', in deterministicGoal");
00388 return new GoalFromJava(timestamp,G,OVar,objectsP,RVars);
00389 }
00390
00405 public Object[] deterministicGoal(String G, String OVar, Object[] objectsP, String RVars){
00406
00407 int mytimestamp = incGoalTimestamp();
00408 GoalFromJava GO = makeDGoalObject(G, OVar, objectsP, RVars, mytimestamp);
00409 Object[] resultToReturn=null;
00410 try{
00411 progressMessage("Schedulling (in PrologEngine) goal "+G+", timestamp "+mytimestamp+" in thread "+Thread.currentThread().getName());
00412 GoalToExecute goalToDo = new GoalToExecute(GO);
00413 scheduleGoal(goalToDo);
00414 ResultFromProlog result = goalToDo.waitForResult();
00415
00416
00417 if (result==null) throw new IPException("Problems in goal result");
00418 if (goalToDo.wasAborted()) throw new IPAbortedException(G+" was aborted");
00419 if (goalToDo.wasInterrupted()) throw new IPInterruptedException(G+" was interrupted");
00420 if (result.error!=null) throw new IPException (result.error);
00421 if (result.timestamp!=mytimestamp)
00422 throw new IPException ("bad timestamp in deterministicGoal, got "+result.timestamp+" instead of "+goalTimestamp);
00423 if (result.succeeded)
00424 resultToReturn = result.rVars;
00425 } catch (IPException e) {
00426 throw e;
00427 } catch (Exception e) {
00428 throw new IPException ("Problem in deterministicGoal:"+e);
00429 }
00430 return resultToReturn;
00431 }
00432
00434 public boolean deterministicGoal(String G){
00435 return (deterministicGoal(G, null,null,"[]")!=null);
00436 }
00437
00439 public Object[] deterministicGoal(String G,String RVars){
00440 return deterministicGoal(G,null,null,RVars);
00441 }
00442
00444 public boolean deterministicGoal(String G, String OVar, Object[] objectsP){
00445 return (deterministicGoal(G, OVar,objectsP,"[]")!=null);
00446 }
00447
00448
00449 protected int incGoalTimestamp(){
00450 goalTimestamp++;
00451 if (goalTimestamp<0) throw new IPException("goalTimestamp did wrap around, please improve it...");
00452 return goalTimestamp;
00453 }
00454
00456 protected synchronized void scheduleGoal(GoalToExecute g){
00457 goalsToExecute.addElement(g);
00458 }
00459
00460 protected synchronized GoalToExecute moreRecentToExecute(){
00461 for (int i=goalsToExecute.size()-1; i>=0; i--){
00462 GoalToExecute gte = (GoalToExecute)goalsToExecute.elementAt(i);
00463 if (!gte.hasStarted()) return gte;
00464 }
00465 return null;
00466 }
00467
00470 protected synchronized GoalToExecute forgetGoal(int timestamp){
00471 for (int i=0; i<goalsToExecute.size(); i++){
00472 GoalToExecute gte = (GoalToExecute)goalsToExecute.elementAt(i);
00473 if (gte.getTimestamp()==timestamp){
00474 goalsToExecute.removeElementAt(i);
00475 return gte;
00476 }
00477 }
00478 return null;
00479 }
00480
00482 protected synchronized void addMessage(MessageExecuting m){
00483 messagesExecuting.addElement(m);
00484 }
00485
00486 protected synchronized void forgetMessage(MessageExecuting m){
00487 messagesExecuting.removeElement(m);
00488 }
00489
00490 protected synchronized MessageExecuting lastMessageRequest(){
00491 MessageExecuting last;
00492 if (messagesExecuting.size()==0) last=null;
00493 else last = (MessageExecuting)messagesExecuting.lastElement();
00494 return last;
00495 }
00496
00498 public synchronized boolean isIdle(){
00499 return messagesExecuting.size()==0 && goalsToExecute.size()==0;
00500 }
00501
00503 public synchronized void abortTasks(){
00504 for (int i=0; i<goalsToExecute.size(); i++){
00505 GoalToExecute gte = (GoalToExecute)goalsToExecute.elementAt(i);
00506 gte.abort();
00507 }
00508 goalsToExecute.removeAllElements();
00509 messagesExecuting.removeAllElements();
00510 }
00511
00513 public synchronized void interruptTasks(){
00514 for (int i=0; i<goalsToExecute.size(); i++){
00515 GoalToExecute gte = (GoalToExecute)goalsToExecute.elementAt(i);
00516 gte.interrupt();
00517 }
00518 goalsToExecute.removeAllElements();
00519 messagesExecuting.removeAllElements();
00520 }
00521
00523 public boolean isAvailable(){
00524 return true;
00525 }
00526
00527 public void waitUntilAvailable(){
00528 try{
00529 while(!isAvailable()) Thread.sleep(0,1);
00530 } catch (InterruptedException e){
00531 throw new IPException("Bad interrupt:"+e);
00532 }
00533 }
00534
00536 public void waitUntilIdle(){
00537 try{
00538 while(!isIdle()) Thread.sleep(0,1);
00539 } catch (InterruptedException e){
00540 throw new IPException("Bad interrupt:"+e);
00541 }
00542 }
00543
00546 public Object handleCallback(Object x){
00547 progressMessage("Entering handleCallback");
00548 if (x instanceof ClassNotFoundException)
00549 return new ResultFromJava(0,null,(ClassNotFoundException)x,null);
00550 else if (x instanceof MessageFromProlog){
00551 MessageFromProlog mfp = (MessageFromProlog)x;
00552 progressMessage("handling "+mfp);
00553
00554 if (!isFirstJavaMessage(mfp)){
00555 MessageExecuting me = new MessageExecuting(mfp,this);
00556 me.start();
00557 addMessage(me);
00558 } else progressMessage("received first (dummy) javaMessage");
00559 } else if (x instanceof ResultFromProlog){
00560 ResultFromProlog rfp = (ResultFromProlog)x;
00561 progressMessage("handling "+rfp);
00562 GoalToExecute gte = forgetGoal(rfp.timestamp);
00563 progressMessage("forgot goal "+gte+"; isIdle()=="+isIdle());
00564 if (gte==null) throw new IPException("Could not find goal "+rfp.timestamp);
00565 gte.setResult(rfp);
00566 } else throw new IPException("bad object in handleCallback:"+x);
00567
00568 return doSomething();
00569 }
00571 protected Object doSomething(){
00572 while(true){
00573
00574 if (isIdle())
00575 try { Thread.sleep(0,100); }
00576 catch (InterruptedException e){throw new IPException("Bad interrupt");}
00577 else Thread.yield();
00578 MessageExecuting last = lastMessageRequest();
00579 if (last!=null && last.hasEnded()) {
00580 forgetMessage(last);
00581 return last.getResult();
00582 }
00583 GoalToExecute gte = moreRecentToExecute();
00584 if (gte!=null){
00585 gte.prologWasCalled();
00586 return gte.getGoal();
00587 }
00588 }
00589 }
00590
00591 private boolean isFirstJavaMessage(MessageFromProlog mfp){
00592 if (!mfp.methodName.equals(firstJavaMessageName)) return false;
00593 if ((mfp.target instanceof InvisibleObject)&& getRealJavaObject((InvisibleObject)mfp.target)==this)
00594 return true;
00595 else return false;
00596 }
00597
00599 public final void firstJavaMessage(){
00600 throw new IPException("This should never be called, bad javaMessage handling");
00601 }
00602
00604 public ResultFromJava doCallback(Object x){
00605 progressMessage ("Starting handling of XSB->Java callback:"+PrologEngine.nl+x);
00606 if (x==null | ! (x instanceof MessageFromProlog) )
00607 return new ResultFromJava (0,null,null,null);
00608 MessageFromProlog callback = (MessageFromProlog)x;
00609 Class formalArguments[] = new Class[callback.arguments.length];
00610 Object[] localArguments = new Object[callback.arguments.length];
00611
00612 Object target=null;
00613 Object result = null; Exception exception=null;
00614
00615 try {
00616 if (callback.target instanceof InvisibleObject){
00617 target = getRealJavaObject ((InvisibleObject)callback.target);
00618 } else if(callback.target instanceof IPClassObject){
00619 target = Class.forName (((IPClassObject)(callback.target)).classname);
00620 } else if (callback.target instanceof IPClassVariable) {
00621 IPClassVariable tempTarget = (IPClassVariable)(callback.target);
00622 Class tempClass = Class.forName (tempTarget.className);
00623 target = tempClass.getField (tempTarget.variableName).get (tempClass);
00624 } else
00625 target = callback.target;
00626
00627 for(int a=0;a<formalArguments.length;a++){
00628 localArguments[a] = callback.arguments[a];
00629 if (localArguments[a]!=null){
00630 if(localArguments[a] instanceof BasicTypeWrapper) {
00631 BasicTypeWrapper btw = (BasicTypeWrapper)(localArguments[a]);
00632 formalArguments[a] = btw.basicTypeClass ();
00633 localArguments[a] = btw.wrapper;
00634 } else if (localArguments[a] instanceof InvisibleObject) {
00635 localArguments[a] = getRealJavaObject ((InvisibleObject)localArguments[a]);
00636 formalArguments[a] = localArguments[a].getClass ();
00637 } else if (localArguments[a] instanceof IPClassObject) {
00638 localArguments[a] = Class.forName (((IPClassObject)(localArguments[a])).classname);
00639 formalArguments[a] = Class.class;
00640 } else if (localArguments[a] instanceof IPClassVariable) {
00641 IPClassVariable IPCV = (IPClassVariable)(localArguments[a]);
00642 Class tempClass = Class.forName (IPCV.className);
00643 localArguments[a] = tempClass.getField (IPCV.variableName).get (null);
00644 formalArguments[a] = localArguments[a].getClass ();
00645 } else formalArguments[a] = localArguments[a].getClass ();
00646 }
00647 }
00648 Method method=null;
00649 if (target instanceof Class){
00650 if (shortClassName ((Class)target).equals (callback.methodName)) {
00651
00652
00653 Constructor constructor = findConstructor ((Class)target,formalArguments);
00654 result = constructor.newInstance (localArguments);
00655 } else {
00656
00657
00658 method = findMethod ((Class)target,callback.methodName,formalArguments);
00659
00660 result = method.invoke (target,localArguments);
00661 }
00662 } else {
00663
00664
00665
00666 method = findMethod (target.getClass (),callback.methodName,formalArguments);
00667 result = method.invoke (target,localArguments);
00668 }
00669
00670
00671 if (result!=null && !(target==this && method.equals(getRealJavaObjectMethod)) && !(result instanceof InvisibleObject)
00672 && !(result instanceof String) && !(result instanceof TermModel)
00673 && ! BasicTypeWrapper.instanceOfWrapper (result))
00674 result = makeInvisible (result);
00675 } catch (Exception e) {
00676 exception=e;
00677 }
00678 if (exception!=null) {
00679 System.out.println ("Courtesy of CallbackHandler:");
00680 exception.printStackTrace ();
00681 }
00682 if (callback.returnArguments)
00683 return new ResultFromJava (callback.timestamp,result,exception,callback.arguments);
00684 else
00685 return new ResultFromJava (callback.timestamp,result,exception,null);
00686 }
00687
00692 public static Method findMethod (Class targetClass,String name,Class[] formalArguments) throws NoSuchMethodException{
00693 Method m = null;
00694 try{
00695 m = targetClass.getMethod (name,formalArguments);
00696 return m;
00697 }
00698 catch(NoSuchMethodException e) {
00699
00700 Method[] allMethods = targetClass.getMethods ();
00701 for (int i=0; i<allMethods.length;i++){
00702 if (allMethods[i].getName ().equals (name) && allMethods[i].getParameterTypes ().length == formalArguments.length){
00703 boolean compatible = true;
00704 for (int j=0; j<formalArguments.length; j++) {
00705 if (!assignableType (allMethods[i].getParameterTypes ()[j],formalArguments[j])) {
00706 compatible = false;
00707 break;
00708 }
00709 }
00710 if (compatible){
00711 m = allMethods[i];
00712 break;
00713 }
00714 }
00715 }
00716 if (m==null) {
00717
00718 System.err.println ("Could not find "+name+" in "+targetClass);
00719 System.err.println ("Argument types:");
00720 for (int i=0; i<formalArguments.length;i++)
00721 System.out.println (i+":"+formalArguments[i]);
00722
00723 throw e;
00724 }else return m;
00725 }
00726 }
00727
00729 public static Constructor findConstructor (Class targetClass,Class[] formalArguments) throws NoSuchMethodException{
00730 Constructor m = null;
00731 try{
00732 m = targetClass.getConstructor (formalArguments);
00733 return m;
00734 }
00735 catch(NoSuchMethodException e) {
00736
00737 Constructor[] allConstructors = targetClass.getConstructors ();
00738 for (int i=0; i<allConstructors.length;i++){
00739 if (allConstructors[i].getParameterTypes ().length == formalArguments.length){
00740 boolean compatible = true;
00741 for (int j=0; j<formalArguments.length; j++) {
00742 if (!assignableType (allConstructors[i].getParameterTypes ()[j],formalArguments[j])) {
00743 compatible = false;
00744 break;
00745 }
00746 }
00747 if (compatible){
00748 m = allConstructors[i];
00749 break;
00750 }
00751 }
00752 }
00753 if (m==null) throw e;
00754 else return m;
00755 }
00756 }
00757
00759 public static boolean assignableType (Class left,Class right){
00760 if (right==null) return true;
00761 else return left.isAssignableFrom (right);
00762 }
00763
00764 public static String shortClassName (Class c){
00765 String s = c.getName ();
00766 int dot = s.lastIndexOf (".");
00767 int dollar = s.lastIndexOf ("$");
00768 if (dot==-1 && dollar==-1) return s;
00769 else return s.substring (Math.max (dot,dollar)+1,s.length ());
00770 }
00771
00777 public int registerJavaObject(Object x){
00778 return knownObjects.registerJavaObject(x);
00779 }
00780
00787 public Object makeInvisible(Object x){
00788 return new InvisibleObject(knownObjects.registerJavaObject(x));
00789 }
00790
00796 public Object getRealJavaObject(InvisibleObject o){
00797 return knownObjects.getRealJavaObject(o);
00798 }
00800 public Object getRealJavaObject(int ID){
00801 return knownObjects.getRealJavaObject(ID);
00802 }
00803
00810 public Object getRealJavaObject(Object o){
00811 return o;
00812 }
00813
00814 }
00815
00816
00817
00818
00819
00820
00821