src/java/isac/wsdialog/DialogGuide.java
author akremp
Thu, 24 Jun 2004 21:55:29 +0200
changeset 1629 732007b81637
parent 1622 d8b40594358e
child 1637 0847aa6924e1
permissions -rw-r--r--
*** empty log message ***
     1 package isac.wsdialog;
     2 
     3 import isac.bridge.*;
     4 import isac.util.*;
     5 import isac.util.formulae.*;
     6 import isac.util.interfaces.*;
     7 import isac.util.tactics.*;
     8 
     9 import java.io.Serializable;
    10 import java.net.MalformedURLException;
    11 import java.rmi.*;
    12 import java.rmi.registry.LocateRegistry;
    13 import java.rmi.server.UnicastRemoteObject;
    14 import java.util.Vector;
    15 
    16 /**
    17  * The DialogGuide moderates the communication between two 
    18  * instances working on the same CalcTree object.
    19  * One of these instances is the user, the other a math engine.
    20  * Most probably, the user's GUI, the DialogGuide and the math engine 
    21  * reside on different machines and communicate with each other by means of RMI. 
    22  * 
    23  * @author Alan Krempler
    24  */
    25 public class DialogGuide
    26   extends UnicastRemoteObject
    27   implements DGuide, /*IToCalc,*/ IToUser, Serializable {
    28 
    29 
    30   protected CalcTree calc_tree_;
    31   protected CalcHead calc_head_;
    32   protected MathEngine math_engine_;
    33   protected int phase_;
    34   private Vector datachange_listeners_;
    35   private IToWorksheet ui_control_listener_;
    36 
    37 
    38   /**
    39    * @param ME_path URL of the math engine to be used
    40    * @throws RemoteException
    41    */
    42   public DialogGuide(String ME_path) throws RemoteException {
    43     super();
    44     this.rmiBind();
    45     datachange_listeners_ = new Vector();
    46     MathEngine.init(ME_path);
    47     math_engine_ = MathEngine.getMathEngine();
    48     phase_ = DIALOGPHASE_IDLE;
    49 
    50   }
    51 
    52   public void attach(CalcTree calc_tree) {
    53 
    54   }
    55 
    56   public CalcHead startSpecifying(
    57     int user_id,
    58     Formalization f,
    59     int start_from,
    60     int requested_calchead_view) {
    61 
    62     calc_head_ = math_engine_.startSpecifying(f);
    63 
    64     // for the moment, all requests for a view are honored
    65     calc_head_.setViewStyle(requested_calchead_view);
    66 
    67     // for testing purposes: if starting an example from the collection,
    68     // have everything filled in by the KI
    69     if (start_from == STARTFROM_EXAMPLE) {
    70       math_engine_.completeCalcHead(calc_head_);
    71 
    72       // old-style filling the fields of the calc-head by setting
    73       // the HELP_ME flag 
    74       // calc_head_.setCalcHeadStatus(CalcHead.CALCHEAD_HELP_ME);
    75     }
    76 
    77     // test code; this protocol is now controlled by the presentation layer
    78     // do {
    79     // checkCalcHead()
    80     // } while (false); // status != ok
    81     // newCalculation(calc_head_);
    82 		phase_ = DIALOGPHASE_SPECIFY;
    83     return calc_head_;
    84   }
    85 
    86   public void newCalculation(CalcHead calcHead) {
    87     try {
    88       calc_tree_ = math_engine_.startSolving(calcHead);
    89     } catch (Exception e) {
    90       // TODO Auto-generated catch block
    91       e.printStackTrace();
    92     }
    93     // calc_tree_ = MathEngine.getMathEngine().startSolving(calcHead);
    94     calc_tree_.addDataChangeListener(this);
    95 		phase_ = DIALOGPHASE_SOLVE;
    96   }
    97 
    98   /* (non-Javadoc)
    99    * @see isac.wsdialog.IToUser#calcChanged(isac.wsdialog.CalcChangedEvent)
   100    */
   101   public void calcChanged(CalcChangedEvent event) {
   102     for (int i = 0; i < datachange_listeners_.size(); i++) {
   103       ((IToUser) datachange_listeners_.elementAt(i)).calcChanged(event);
   104     }
   105   }
   106 
   107   /**
   108    * @deprecated Use {@link #notifyUserAction(IUserAction)} instead
   109    */
   110   public void modifyCalcHead(CalcHead calc_head) {
   111     // MathEngine.getMathEngine().modifyCalcHead(calc_head);
   112     math_engine_.modifyCalcHead(calc_head);
   113   }
   114 
   115   /* (non-Javadoc)
   116    * @see isac.wsdialog.IToCalc#iterator()
   117    */
   118   public ICalcIterator iterator() {
   119     return new DialogIterator((CalcIterator) calc_tree_.iterator());
   120   }
   121 
   122   /* (non-Javadoc)
   123    * @see isac.wsdialog.IToCalc#addListener(isac.wsdialog.IToUser)
   124    */
   125   public boolean addDataChangeListener(IToUser listener) {
   126     if (datachange_listeners_.contains(listener)) {
   127       return false;
   128     } else {
   129       datachange_listeners_.add(listener);
   130     }
   131     return true;
   132   }
   133 
   134   public boolean registerUIControlListener(IToWorksheet listener) {
   135     if (ui_control_listener_ != null) {
   136       ui_control_listener_.doUIAction(new UserAction(UI_DO_DETACH));
   137     }
   138     ui_control_listener_ = listener;
   139     return true;
   140   }
   141 
   142   public Tactic fetchProposedTactic() {
   143     return calc_tree_.fetchProposedTactic();
   144   }
   145 
   146   public Tactic[] fetchApplicableTactics(int scope) {
   147     return calc_tree_.fetchApplicableTactics(scope);
   148   }
   149 
   150   /**
   151    * Find out whether a problem matches the current calculation
   152    * TODO: might be obsolete
   153    *  
   154    * @param problem Problem to be matched to the current calculation
   155    * @return CalcHead checked by the math engine
   156    */
   157   public CalcHead matchProblem(CalcHeadCompoundID problem) {
   158     CalcHead matching_result, current_calchead;
   159     ICalcIterator root_iterator;
   160 
   161     // clone active CalcHead
   162     matching_result = new CalcHead();
   163     root_iterator = calc_tree_.iterator();
   164     current_calchead = (CalcHead) root_iterator.getElement();
   165     matching_result.setPosition(current_calchead.getPosition());
   166     matching_result.setFind(current_calchead.getFind());
   167     matching_result.setWhere(current_calchead.getWhere());
   168     matching_result.setGiven(current_calchead.getGiven());
   169     Specification spec = new Specification();
   170     spec.setTheory(current_calchead.getSpecification().getTheory());
   171     spec.setMethod(current_calchead.getSpecification().getMethod());
   172     matching_result.setRelate(current_calchead.getRelate());
   173 
   174     // Enter passed Problem into cloned CalcHead
   175     spec.setProblem(problem);
   176     // ask CalcTree to match it
   177     matching_result.setSpecification(spec);
   178     //	calc_tree_.checkCalcHead(matching_result);
   179     return matching_result;
   180   }
   181 
   182   /**
   183    * @deprecated Use {@link #notifyUserAction(IUserAction)} instead
   184    */
   185   public int setNextTactic(Tactic tactic) {
   186     return calc_tree_.setNextTactic(tactic);
   187   }
   188 
   189   /**
   190    * @deprecated Use {@link #notifyUserAction(IUserAction)} instead
   191    */
   192   public int autoCalculate(int scope, int nSteps) {
   193     return calc_tree_.autoCalculate(scope, nSteps);
   194   }
   195 
   196   /**
   197    * @deprecated Use {@link #notifyUserAction(IUserAction)} instead
   198    */
   199   public void tryMatch(CalcHead ch, CalcHeadCompoundID problemID)
   200     throws NotInSpecificationPhaseException {
   201 
   202     // MathEngine.getMathEngine().tryMatch(ch, problemID);
   203     math_engine_.tryMatch(ch, problemID);
   204   }
   205 
   206   /**
   207    * @deprecated Use {@link #notifyUserAction(IUserAction)} instead
   208    */
   209   public void tryRefine(CalcHead ch, CalcHeadCompoundID problemID)
   210     throws NotInSpecificationPhaseException {
   211 
   212     // MathEngine.getMathEngine().tryRefine(ch , problemID);
   213     math_engine_.tryRefine(ch, problemID);
   214   }
   215 
   216   public ICalcIterator getActiveFormula() {
   217     return calc_tree_.getActiveFormula();
   218   }
   219 
   220   /**
   221    * @deprecated Use {@link #notifyUserAction(IUserAction)} instead
   222    */
   223   public int replaceFormula(Formula newFormula) {
   224     return calc_tree_.replaceFormula(newFormula);
   225   }
   226 
   227   /**
   228    * @deprecated Use {@link #notifyUserAction(IUserAction)} instead
   229    */
   230   public int appendFormula(Formula newFormula) {
   231     return calc_tree_.appendFormula(newFormula);
   232   }
   233 
   234   /**
   235    * @deprecated Use {@link #notifyUserAction(IUserAction)} instead
   236    */
   237   public void moveActiveFormula(ICalcIterator newActiveFormula) {
   238     calc_tree_.moveActiveFormula(newActiveFormula);
   239   }
   240 
   241   /**
   242    * Notify the Dialog Guide about interaction from the User
   243    * @param action 
   244    * @return true, if the action has been processed, false if the processing the action has been denied 
   245    * 
   246    */
   247   public boolean notifyUserAction(IUserAction action)
   248     throws DialogProtocolException {
   249     int request = action.getActionID();
   250     
   251     switch (phase_) {
   252     	case DIALOGPHASE_IDLE:
   253     		throw new DialogProtocolException(request, phase_);
   254 			case DIALOGPHASE_SPECIFY:
   255 				if (request < UI_DUMMY_FIRST_SPECIFY || request > UI_DUMMY_LAST_SPECIFY)
   256 					throw new DialogProtocolException(request, phase_);
   257 				break;
   258 			case DIALOGPHASE_SOLVE:
   259 				if (request < UI_DUMMY_FIRST_SOLVE|| request > UI_DUMMY_LAST_SOLVE)
   260 					throw new DialogProtocolException(request, phase_);
   261 				break;
   262 	   }
   263 	    
   264     switch (request) {
   265       case UI_SPECIFY_TRY_MATCH :
   266         try {
   267           tryMatch(
   268             calc_head_,
   269             ((UserActionOnCalcHeadCompoundID) action).getObjectID());
   270         } catch (NotInSpecificationPhaseException e) {
   271           throw new DialogMathException(request, phase_, e);
   272         }
   273         break;
   274 
   275       case UI_SPECIFY_TRY_REFINE :
   276         try {
   277           tryRefine(
   278             calc_head_,
   279             ((UserActionOnCalcHeadCompoundID) action).getObjectID());
   280         } catch (NotInSpecificationPhaseException e) {
   281           throw new DialogMathException(request, phase_, e);
   282         }
   283         break;
   284 
   285       case UI_SPECIFY_CHANGE_VIEW :
   286         calc_head_.setViewStyle(((UserActionOnInt) action).getInt());
   287         break;
   288 
   289       case UI_SPECIFY_COMPLETE_CALCHEAD :
   290         math_engine_.completeCalcHead(calc_head_);
   291         // old-style filling the fields of the calc-head by setting
   292         // the HELP_ME flag 
   293         // calc_head_.setCalcHeadStatus(CalcHead.CALCHEAD_HELP_ME);
   294         // modifyCalcHead(calc_head_);
   295         break;
   296 
   297       case UI_SPECIFY_COMPLETE_METHOD :
   298       case UI_SPECIFY_COMPLETE_THEORY :
   299       case UI_SPECIFY_COMPLETE_PROBLEM :
   300       case UI_SPECIFY_COMPLETE_GIVEN :
   301       case UI_SPECIFY_COMPLETE_FIND :
   302       case UI_SPECIFY_COMPLETE_RELATE :
   303         throw new DialogNotImplementedException(request, phase_);
   304 
   305       case UI_SPECIFY_CHECK_CALCHEAD :
   306         modifyCalcHead(calc_head_);
   307         break;
   308        
   309       // was: newCalculation()  
   310 			case UI_SPECIFY_CALCULATE_1 :
   311       case UI_SPECIFY_CALCULATE_ALL :
   312 	  		modifyCalcHead(calc_head_);
   313 	  		if (calc_head_.getCalcHeadStatus()!=CalcHead.CALCHEAD_CORRECT) return false; 
   314 	  		
   315 		  	try {
   316 					calc_tree_ = math_engine_.startSolving(calc_head_);
   317 			  } catch (Exception e) {
   318 					// TODO Auto-generated catch block
   319 					e.printStackTrace();
   320 			  }
   321 			  // calc_tree_ = MathEngine.getMathEngine().startSolving(calcHead);
   322 			  calc_tree_.addDataChangeListener(this);
   323 				phase_ = DIALOGPHASE_SOLVE;
   324 			// fall through to calculate
   325       	
   326       case UI_SOLVE_CALCULATE_1 :
   327 	    case UI_SOLVE_CALCULATE_ALL :
   328 	      switch (request) {
   329 					case UI_SPECIFY_CALCULATE_ALL :
   330 	      	case UI_SOLVE_CALCULATE_ALL :
   331         		autoCalculate(SCOPE_CALCULATION, 0);
   332         		break;
   333         	case UI_SPECIFY_CALCULATE_1 :
   334         	  break;
   335         	default :
   336 						autoCalculate(SCOPE_CALCULATION, 1);
   337 						break;
   338 	      }
   339         break;
   340 
   341 
   342       case UI_SOLVE_CALCULATE_SUBPROBLEM :
   343         autoCalculate(SCOPE_SUBPROBLEM, 0);
   344         break;
   345 
   346       case UI_SOLVE_EDIT_ACTIVE_FORMULA :
   347         ui_control_listener_.doUIAction(new UserAction(UI_DO_EDIT_FORMULA));
   348         break;
   349 
   350       case UI_SOLVE_EDIT_ACTIVE_FORMULA_COMPLETE :
   351         replaceFormula(
   352           (Formula) ((UserActionOnCalcElement) action).getCalcElement());
   353         break;
   354 
   355       case UI_SOLVE_APPEND_USER_FORMULA :
   356         // appendFormula((Formula) ((UserActionOnCalcElement) action).getCalcElement());
   357         ui_control_listener_.doUIAction(new UserAction(UI_DO_APPEND_FORMULA));
   358         break;
   359 
   360       case UI_SOLVE_MOVE_ACTIVE_FORMULA :
   361         moveActiveFormula(((UserActionOnIterator) action).getPosition());
   362         break;
   363 
   364       case UI_SOLVE_GET_PROPOSED_TACTIC :
   365         throw new DialogNotImplementedException(request, phase_);
   366 
   367       case UI_SOLVE_GET_APPLICABLE_TACTICS :
   368         throw new DialogNotImplementedException(request, phase_);
   369 
   370       case UI_SOLVE_SET_NEXT_TACTIC :
   371         setNextTactic(
   372           (Tactic) ((UserActionOnCalcElement) action).getCalcElement());
   373         break;
   374 
   375       case UI_SOLVE_HELP_ENTERING_FORMULA :
   376         throw new DialogNotImplementedException(request, phase_);
   377 
   378       case UI_SOLVE_SHOW_ASSUMPTIONS :
   379         throw new DialogNotImplementedException(request, phase_);
   380 
   381       case UI_SOLVE_SHOW_DETAILS :
   382         throw new DialogNotImplementedException(request, phase_);
   383 
   384       default :
   385         throw new DialogUnknownActionException(request, phase_);
   386     }
   387     return true;
   388   }
   389 
   390   private void rmiBind() {
   391     if (System.getSecurityManager() == null) {
   392       System.setSecurityManager(new RMISecurityManager());
   393     }
   394 
   395     try {
   396       LocateRegistry.createRegistry(1099);
   397     } catch (java.rmi.RemoteException exc2) {
   398       System.err.println("can not create registry: " + exc2.getMessage());
   399     }
   400 
   401     String name = "//localhost/isac-DialogGuide";
   402     try {
   403       System.out.println("try to bind as " + name);
   404       Naming.rebind(name, this);
   405       System.out.println("Object Manager bound to " + name);
   406     } catch (java.rmi.ConnectException e) {
   407       System.err.println(
   408         "failed to contact as "
   409           + name
   410           + " (creating RMI-Server on localhost: 1099)");
   411     } catch (RemoteException e) {
   412       // TODO Auto-generated catch block
   413       e.printStackTrace();
   414     } catch (MalformedURLException e) {
   415       // TODO Auto-generated catch block
   416       e.printStackTrace();
   417     }
   418   }
   419 
   420   public static void main(String[] args) {
   421     try {
   422       new DialogGuide(args[0]);
   423     } catch (RemoteException e) {
   424       e.printStackTrace();
   425     }
   426   }
   427 
   428 }