5 import isac.util.formulae.*;
6 import isac.util.interfaces.*;
7 import isac.util.tactics.*;
8 import isac.util.usersettings.UserSettings;
10 import java.io.Serializable;
11 import java.net.MalformedURLException;
13 import java.rmi.registry.LocateRegistry;
14 import java.rmi.server.UnicastRemoteObject;
15 import java.util.Vector;
17 import org.apache.log4j.Logger;
20 * The DialogGuide moderates the communication between two instances working on
21 * the same CalcTree object. One of these instances is the user, the other a
22 * math engine. Most probably, the user's GUI, the DialogGuide and the math
23 * engine reside on different machines and communicate with each other by means
26 * @author Alan Krempler
28 public class DialogGuide extends UnicastRemoteObject implements DGuide,
29 IToUser, Serializable {
31 static Logger logger_ = Logger.getLogger(BridgeRMI.class.getName());
33 protected CalcTree calc_tree_;
35 //protected CalcHead calc_head_;
37 protected CalcHead calc_head_sub_;
39 protected MathEngine math_engine_;
43 private Vector datachange_listeners_;
45 private IToWorksheet ui_control_listener_;
47 protected UserSettings user_settings_;
51 * URL of the math engine to be used
52 * @throws RemoteException
54 public DialogGuide(String ME_path) throws RemoteException {
57 datachange_listeners_ = new Vector();
58 MathEngine.init(ME_path);
59 math_engine_ = MathEngine.getMathEngine();
60 phase_ = DIALOGPHASE_IDLE;
64 * at the beginning of a calculation as well as of a subproblem
67 * empty (formalization stored invisibly in the calcTree)
68 * @return calc_head with viestyle set
70 // FIXME.WN040906 do NOT return calc_head, like Formula in solve-phase
71 // and like trymatch etc. see below
72 CalcHead startSpecifying(CalcHead calc_head) {
76 // set viewstyle according to user settings
78 // dummy return of getValue() call until class is completed
79 // setting_value = user_settings_.getValue("DefaultCalcHeadView");
82 if (setting_value == null)
83 calchead_view = CalcHead.VIEWSTYLE_SINGLELINE;
85 calchead_view = Integer.parseInt(setting_value);
86 calc_head.setViewStyle(calchead_view);
89 phase_ = DIALOGPHASE_SPECIFY;
91 // dummy return of getValue() call until class is completed
92 // if (user_settings_.getValue("SkipSpecifyingPhase").equals("1")) {
95 calc_tree_.completeCalcHead();
97 notifyUserAction(new UserAction(IUIElement.UI_SPECIFY_CALCULATE_1));
98 } catch (RemoteException e) {
99 // TODO Auto-generated catch block
101 } catch (DialogProtocolException e) {
102 // TODO Auto-generated catch block
107 return calc_head; //WN040906 this is NOT completed !!!
108 // FIXME.WN040906 do NOT return calc_head, like Formula in solve-phase
111 // FIXME.WN040906 do NOT return calc_head, like Formula in solve-phase
112 public CalcTree startCalculation(int user_id, Formalization f,
113 int start_from, int requested_calchead_view) {
115 ICalcIterator temp_iterator;
117 calc_tree_ = math_engine_.startCalculation(f);
118 temp_iterator = calc_tree_.iterator();
120 temp_iterator.moveRoot();
121 startSpecifying((CalcHead) temp_iterator.getFormula());
122 } catch (RemoteException e) {
123 // TODO Auto-generated catch block
126 // AK removed duplicate completeCalcHead() call 20050222
127 // the correct call is in startCalculation()
128 // calc_tree_.completeCalcHead();
130 // for the moment, all requests for a view are honored
131 // WN040825 calc_head_.setViewStyle(requested_calchead_view);
132 // --->startSpecifying
134 // for testing purposes: if starting an example from the collection,
135 // have everything filled in by the KI
136 // WN040825 if (start_from == STARTFROM_EXAMPLE) { --->startSpecifying ?
138 // old-style filling the fields of the calc-head by setting
140 // calc_head_.setCalcHeadStatus(CalcHead.CALCHEAD_HELP_ME);
143 // test code; this protocol is now controlled by the presentation layer
146 // } while (false); // status != ok
147 // newCalculation(calc_head_);
148 phase_ = DIALOGPHASE_SPECIFY;
149 //WN040825 return calc_head_;
153 public void newCalculation(CalcHead calcHead) {
155 calc_tree_.startSolving();
156 } catch (Exception e) {
157 // TODO Auto-generated catch block
160 // calc_tree_ = MathEngine.getMathEngine().startSolving(calcHead);
161 calc_tree_.addDataChangeListener(this);
162 phase_ = DIALOGPHASE_SOLVE;//WN041122 nein ???!!!???
168 * @see isac.wsdialog.IToUser#calcChanged(isac.wsdialog.CalcChangedEvent)
170 public void calcChanged(CalcChangedEvent event) throws RemoteException {
171 logger_.fatal(" WS<-. . : calcChanged (unc="
172 + event.getLastUnchangedFormula().toSMLString() + ", del="
173 + event.getLastDeletedFormula().toSMLString() + ", gen="
174 + event.getLastGeneratedFormula().toSMLString());
175 ICalcElement calc_elem;
178 for (int i = 0; i < datachange_listeners_.size(); i++) {
179 ((IToUser) datachange_listeners_.elementAt(i))
182 ICalcIterator last_formula = event.getFirstChangedFormula();
183 // while searching for last formula, mark intermediate CalcHeads as
187 // while (!last_formula.isLast()) {
188 // if (last_formula.getElement().getType() == ICalcElement.CALCEL_CALCHEAD) {
189 // last_formula.getElement().setViewStyle(
190 // CalcHead.VIEWSTYLE_IN_CALC);
192 // last_formula.moveDown();
193 // //TODO last_formula.moveDown.. WN040824 DG may limit the level
197 // // for now, do not specify the CalcHead, just display it.
198 // calc_elem = last_formula.getElement();
200 // if (calc_elem.getType() == ICalcElement.CALCEL_CALCHEAD) {
201 // //WN040826 phase_ = DIALOGPHASE_SPECIFY; --->startSpecifying
203 // // calc_elem.setViewStyle(CalcHead.VIEWSTYLE_SINGLELINE);--->startSpecifying
205 // //WN040826calc_head = startSpecifying((CalcHead) calc_elem);
206 // // --->startSpecifying
207 // startSpecifying((CalcHead) calc_elem);
208 // //WN040826 math_engine_.completeCalcHead(calc_head);
209 // // --->startSpecifying
211 // phase_ = DIALOGPHASE_SOLVE;
213 } catch (Exception e) {
219 * @deprecated Use {@link #notifyUserAction(IUserAction)}instead
221 public void modifyCalcHead(CalcHead calc_head) {
222 // MathEngine.getMathEngine().modifyCalcHead(calc_head);
223 calc_tree_.modifyCalcHead(calc_head);
229 * @see isac.wsdialog.IToCalc#iterator()
231 public ICalcIterator iterator() {
233 return new DialogIterator((CalcIterator) calc_tree_.iterator());
234 } catch (Exception e) {
241 * @see isac.wsdialog.IToCalc#addListener(isac.wsdialog.IToUser)
243 public boolean addDataChangeListener(IToUser listener)
244 throws RemoteException {
245 if (datachange_listeners_.contains(listener)) {
248 datachange_listeners_.add(listener);
253 public boolean registerUIControlListener(IToWorksheet listener)
254 throws RemoteException {
255 // if (ui_control_listener_ != null) {
256 // ui_control_listener_.doUIAction(new UserAction(UI_DO_DETACH));
258 ui_control_listener_ = listener;
262 public Tactic fetchProposedTactic() {
263 return calc_tree_.fetchProposedTactic();
266 public Tactic[] fetchApplicableTactics(int scope) {
267 return calc_tree_.fetchApplicableTactics(scope);
271 * @deprecated Use {@link #notifyUserAction(IUserAction)}instead
273 public int setNextTactic(Tactic tactic) {
274 return calc_tree_.setNextTactic(tactic);
278 * @deprecated Use {@link #notifyUserAction(IUserAction)}instead
280 public int autoCalculate(int scope, int nSteps) {
281 return calc_tree_.autoCalculate(scope, nSteps);
285 * @deprecated Use {@link #notifyUserAction(IUserAction)}instead
287 public void tryMatch(CalcHead ch, CalcHeadCompoundID problemID)
288 throws NotInSpecificationPhaseException {
290 // MathEngine.getMathEngine().tryMatch(ch, problemID);
291 math_engine_.tryMatch(ch, problemID);
295 * @deprecated Use {@link #notifyUserAction(IUserAction)}instead
297 public void tryRefine(CalcHead ch, CalcHeadCompoundID problemID)
298 throws NotInSpecificationPhaseException {
300 // MathEngine.getMathEngine().tryRefine(ch , problemID);
301 math_engine_.tryRefine(ch, problemID);
304 public ICalcIterator getActiveFormula() {
305 return calc_tree_.getActiveFormula();
309 * @throws RemoteException
310 * @deprecated Use {@link #notifyUserAction(IUserAction)}instead
312 public int replaceFormula(CalcFormula newFormula) throws RemoteException {
313 return calc_tree_.replaceFormula(newFormula);
317 * @throws RemoteException
318 * @deprecated Use {@link #notifyUserAction(IUserAction)}instead
320 public int appendFormula(CalcFormula newFormula) throws RemoteException {
321 return calc_tree_.appendFormula(newFormula);
325 * @deprecated Use {@link #notifyUserAction(IUserAction)}instead
327 public void moveActiveFormula(ICalcIterator newActiveFormula) {
328 calc_tree_.moveActiveFormula(newActiveFormula);
332 * Notify the Dialog Guide about interaction from the User
335 * @return true, if the action has been processed, false if the processing
336 * the action has been denied
337 * @throws RemoteException
340 public boolean notifyUserAction(IUserAction action)
341 throws DialogProtocolException, RemoteException {
342 int request = action.getActionID();
343 logger_.fatal(" WS->DG: notifyUserAction request= " + request);
345 //*********** set and check DIALOGPHASE *******************
346 // two userActions dont care about the dialogphase
348 case (UI_CALCULATE_1):
349 if (getActiveFormula().onCalcHead()) {
350 request = UI_SPECIFY_CALCULATE_1;
351 phase_ = DIALOGPHASE_SPECIFY;
353 request = UI_SOLVE_CALCULATE_1;
354 phase_ = DIALOGPHASE_SOLVE;
357 case (UI_CALCULATE_ALL):
358 if (getActiveFormula().onCalcHead()) {
359 request = UI_SPECIFY_CALCULATE_ALL;
360 phase_ = DIALOGPHASE_SPECIFY;
362 request = UI_SOLVE_CALCULATE_ALL;
363 phase_ = DIALOGPHASE_SOLVE;
367 // al other userActions belong to a certain dialogphase
369 case DIALOGPHASE_IDLE:
370 throw new DialogProtocolException(request, phase_);
371 case DIALOGPHASE_SPECIFY:
372 if (request < UI_DUMMY_FIRST_SPECIFY
373 || request > UI_DUMMY_LAST_SPECIFY)
374 throw new DialogProtocolException(request, phase_);
376 case DIALOGPHASE_SOLVE:
377 if (request < UI_DUMMY_FIRST_SOLVE || request > UI_DUMMY_LAST_SOLVE)
378 throw new DialogProtocolException(request, phase_);
382 //*********** handle IUserAction's **********************
383 CalcHead calc_head = new CalcHead();//?WN0502023?????????
385 calc_head = (CalcHead) calc_tree_.iterator().getFormula();
386 } catch (Exception e) {
390 case UI_SPECIFY_TRY_MATCH:
392 tryMatch(calc_head, ((UserActionOnCalcHeadCompoundID) action)
394 } catch (NotInSpecificationPhaseException e) {
395 throw new DialogMathException(request, phase_, e);
399 case UI_SPECIFY_TRY_REFINE:
401 tryRefine(calc_head, ((UserActionOnCalcHeadCompoundID) action)
403 } catch (NotInSpecificationPhaseException e) {
404 throw new DialogMathException(request, phase_, e);
408 case UI_SPECIFY_CHANGE_VIEW:
409 calc_head.setViewStyle(((UserActionOnInt) action).getInt());
412 case UI_SPECIFY_COMPLETE_CALCHEAD:
413 calc_tree_.completeCalcHead();
414 // old-style filling the fields of the calc-head by setting
416 // calc_head_.setCalcHeadStatus(CalcHead.CALCHEAD_HELP_ME);
417 // modifyCalcHead(calc_head_);
419 case UI_SPECIFY_COMPLETE_METHOD:
420 case UI_SPECIFY_COMPLETE_THEORY:
421 case UI_SPECIFY_COMPLETE_PROBLEM:
422 case UI_SPECIFY_COMPLETE_GIVEN:
423 case UI_SPECIFY_COMPLETE_FIND:
424 case UI_SPECIFY_COMPLETE_RELATE:
425 throw new DialogNotImplementedException(request, phase_);
427 case UI_SPECIFY_CHECK_CALCHEAD:
428 modifyCalcHead(calc_head);
431 // was: newCalculation()
432 case UI_SPECIFY_CALCULATE_1:
433 case UI_SPECIFY_CALCULATE_ALL:
434 modifyCalcHead(calc_head);
435 if (calc_head.getCalcHeadStatus() != CalcHead.CALCHEAD_CORRECT)
439 calc_tree_.startSolving();
440 } catch (Exception e) {
441 // TODO Auto-generated catch block
444 // calc_tree_ = MathEngine.getMathEngine().startSolving(calcHead);
445 calc_tree_.addDataChangeListener(this);
446 //if (user_settings_.getValue(""))
447 calc_tree_.completeCalcHead();
450 phase_ = DIALOGPHASE_SOLVE;
451 // fall through to calculate
453 case UI_SOLVE_CALCULATE_1:
454 //why not at (*) here ?
455 case UI_SOLVE_CALCULATE_ALL:
457 case UI_SPECIFY_CALCULATE_ALL:
458 case UI_SOLVE_CALCULATE_ALL:
459 autoCalculate(SCOPE_CALCULATION, 0);
461 case UI_SPECIFY_CALCULATE_1://???
464 autoCalculate(SCOPE_CALCULATION, 1);//why not at (*) above ?
469 case UI_SOLVE_CALCULATE_SUBPROBLEM:
470 autoCalculate(SCOPE_SUBPROBLEM, 0);
473 case UI_SOLVE_EDIT_ACTIVE_FORMULA:
474 ui_control_listener_.doUIAction(new UserAction(UI_DO_EDIT_FORMULA));
477 case UI_SOLVE_EDIT_ACTIVE_FORMULA_COMPLETE:
478 CalcFormula formula = (CalcFormula) ((UserActionOnCalcElement) action)
480 // if the position is null, the formula did not exist, so we try to
481 // append a new formula
482 if (formula.getPosition() == null) {
483 appendFormula(formula);
485 replaceFormula(formula);
489 case UI_SOLVE_APPEND_USER_FORMULA:
490 // appendFormula((Formula) ((UserActionOnCalcElement)
491 // action).getCalcElement());
493 .doUIAction(new UserAction(UI_DO_APPEND_FORMULA));
496 case UI_SOLVE_MOVE_ACTIVE_FORMULA:
497 moveActiveFormula(((UserActionOnIterator) action).getPosition());
500 case UI_SOLVE_GET_PROPOSED_TACTIC:
501 throw new DialogNotImplementedException(request, phase_);
503 case UI_SOLVE_GET_APPLICABLE_TACTICS:
504 throw new DialogNotImplementedException(request, phase_);
506 case UI_SOLVE_SET_NEXT_TACTIC:
507 setNextTactic((Tactic) ((UserActionOnCalcElement) action)
509 //WN041126 extracted from isac.bridge.CalcTree#setNextTactic @@@
510 //autoCalculate(SCOPE_CALCULATION, 1);
513 case UI_SOLVE_HELP_ENTERING_FORMULA:
514 throw new DialogNotImplementedException(request, phase_);
516 case UI_SOLVE_SHOW_ASSUMPTIONS:
517 throw new DialogNotImplementedException(request, phase_);
519 case UI_SOLVE_SHOW_DETAILS:
520 throw new DialogNotImplementedException(request, phase_);
523 throw new DialogUnknownActionException(request, phase_);
528 private void rmiBind() {
529 if (System.getSecurityManager() == null) {
530 System.setSecurityManager(new RMISecurityManager());
534 LocateRegistry.createRegistry(1099);
535 } catch (java.rmi.RemoteException exc2) {
536 System.err.println("can not create registry: " + exc2.getMessage());
539 String name = "//localhost/isac-DialogGuide";
541 System.out.println("try to bind as " + name);
542 Naming.rebind(name, this);
543 System.out.println("Dialog Guide bound to " + name);
544 //WN040906 was Object Manager ...
545 } catch (java.rmi.ConnectException e) {
546 System.err.println("failed to contact as " + name
547 + " (creating RMI-Server on localhost: 1099)");
548 } catch (RemoteException e) {
549 // TODO Auto-generated catch block
551 } catch (MalformedURLException e) {
552 // TODO Auto-generated catch block
557 public static void main(String[] args) {
559 new DialogGuide(args[0]);
561 } catch (RemoteException e) {
569 * @see isac.util.interfaces.IToCalc#startSolving()
571 public void startSolving() throws Exception {
572 // TODO Auto-generated method stub
579 * @see isac.util.interfaces.IToCalc#completeCalcHead(isac.util.formulae.CalcHead)
581 public void completeCalcHead(CalcHead calcHead) {
582 // TODO Auto-generated method stub
589 * @see isac.util.interfaces.IToCalc#completeCalcHead(isac.util.formulae.CalcHead,
592 public void completeCalcHead(CalcHead calcHead, int completeItem) {
593 // TODO Auto-generated method stub
600 * @see isac.util.interfaces.IToCalc#completeCalcHead()
602 public void completeCalcHead() throws RemoteException {
603 // TODO Auto-generated method stub WN050223
608 * @deprecated Use {@link #notifyUserAction(IUserAction)}instead
610 * @see isac.util.interfaces.IToCalc#intermediateSteps(isac.util.interfaces.ICalcIterator)
612 public int intermediateSteps(ICalcIterator i) throws RemoteException {
613 // TODO Auto-generated method stub
620 * @see isac.util.interfaces.IToCalc#getElementsFromTo(isac.util.interfaces.ICalcIterator,
621 * isac.util.interfaces.ICalcIterator, java.lang.Integer, boolean)
623 public Vector getElementsFromTo(ICalcIterator iterator_from,
624 ICalcIterator iterator_to, Integer level,
625 boolean result_includes_tactics) throws RemoteException {
626 // TODO Auto-generated method stub