src/java/isac/wsdialog/WorksheetDialog.java
author wneuper
Thu, 17 Jan 2008 16:27:03 +0100
changeset 3881 72f0be16d83b
parent 3641 1c9136644c78
child 3928 d38196e9b162
permissions -rw-r--r--
start-work-070517 merged into HEAD
     1 package isac.wsdialog;
     2 
     3 import isac.bridge.*;
     4 import isac.browserdialog.ExampleDialog;
     5 import isac.browserdialog.IContextPresenter;
     6 import isac.browserdialog.MethodDialog;
     7 import isac.browserdialog.ProblemDialog;
     8 import isac.browserdialog.TheoryDialog;
     9 import isac.interfaces.*;
    10 import isac.useractions.EUIContext;
    11 import isac.useractions.EUIElement;
    12 import isac.useractions.IUIAction;
    13 import isac.useractions.IUserAction;
    14 import isac.useractions.UIAction;
    15 import isac.useractions.UIActionOnCalcElement;
    16 import isac.useractions.UserActionOnCalcElement;
    17 import isac.useractions.UserActionOnPosition;
    18 import isac.users.IUserSettings;
    19 import isac.users.UserLogger;
    20 import isac.users.User;
    21 import isac.users.UserLanguage;
    22 import isac.users.UserSettings;
    23 import isac.util.*;
    24 import isac.util.formulae.*;
    25 import isac.util.tactics.*;
    26 import isac.session.Session;
    27 import isac.session.SessionManager;
    28 import isac.session.ISessionManager;
    29 import isac.users.UserManager;
    30 
    31 import java.io.Serializable;
    32 import java.net.MalformedURLException;
    33 import java.rmi.*;
    34 import java.rmi.registry.LocateRegistry;
    35 import java.rmi.server.UnicastRemoteObject;
    36 import java.util.Iterator;
    37 import java.util.Vector;
    38 
    39 import org.apache.log4j.Logger;
    40 
    41 /**
    42  * The WorksheetDialog moderates the communication between two instances working
    43  * on the same CalcTree object. One of these instances is the user, the other a
    44  * math engine. Most probably, the user's GUI, the WorksheetDialog and the math
    45  * engine reside on different machines and communicate with each other by means
    46  * of RMI.
    47  * 
    48  * @author Alan Krempler 2003
    49  * @author Manuel Koschuch 2005
    50  */
    51 public class WorksheetDialog extends UnicastRemoteObject implements
    52         IWorksheetDialog, IToUser, Serializable, IContextProvider {
    53 
    54     static final long serialVersionUID = 4952921581668118572L;
    55 
    56     private static final Logger logger = Logger.getLogger(WorksheetDialog.class
    57             .getName());
    58 
    59     protected MathEngine math_engine_;
    60 
    61     protected CalcTree calc_tree_;
    62 
    63     /**
    64      * The active formula in the mathematic engine
    65      */
    66     protected ICalcIterator active_formula_;
    67 
    68     /**
    69      * Represents the formula on which the context depends. It is the last
    70      * selected formula in the worksheet or the active formula from the
    71      * mathematic engine
    72      * 
    73      */
    74     protected ICalcIterator context_formula_;
    75 
    76     protected Session session_;
    77 
    78     /**
    79      * determines if the calculation on the worksheet is ready
    80      */
    81     protected boolean worksheet_ready_;
    82 
    83     protected int phase_;
    84 
    85     /**
    86      * A calculation is finished successfully if a result (this is a specific
    87      * position on the Worksheet) has been obtained. This variable is set once;
    88      * i.e. trials on the calculation after the first result are <em>not</em>
    89      * recorded.
    90      */
    91     private boolean calculation_finished_successfully_ = false;
    92 
    93     private Vector<IToUser> datachange_listeners_;
    94 
    95     private IToGUI ui_control_listener_;
    96 
    97     protected String worksheet_id_;
    98 
    99     protected UserSettings user_settings_;// hold whole hashmap locally
   100 
   101     protected ISessionManager session_manager_;
   102 
   103     protected UserLanguage user_language_;
   104 
   105     protected UserLogger user_logger_;
   106 
   107     /**
   108      * @param ME_path
   109      *            URL of the math engine to be used
   110      * @param user_path
   111      *            path(without URL) to UserSettings, UserModel
   112      * @param session_dialog
   113      * @param session_id
   114      *            which create the WorksheetDialog and Worksheet
   115      * @throws RemoteException
   116      */
   117     public WorksheetDialog(String ME_path, Session session,
   118             String worksheet_id, Formalization f) throws RemoteException {
   119         initialise(ME_path, session, worksheet_id, f);
   120     }
   121 
   122     public WorksheetDialog(String ME_path, Session session, String worksheet_id)
   123             throws RemoteException {
   124         initialise(ME_path, session, worksheet_id, new Formalization());
   125     }
   126 
   127     void initialise(String ME_path, Session session, String worksheet_id,
   128             Formalization f) throws RemoteException {
   129         this.rmiBind();
   130         datachange_listeners_ = new Vector<IToUser>();
   131 
   132         MathEngine.init(ME_path);
   133         math_engine_ = MathEngine.getMathEngine();
   134 
   135         phase_ = DIALOGPHASE_IDLE;
   136 
   137         session_ = session;
   138 
   139         User user = null;
   140 
   141         user = UserManager.getInstance().getUser(session.getId());
   142 
   143         user_settings_ = user.getUserSettings();
   144         user_language_ = user.getLanguage();
   145 
   146         worksheet_id_ = worksheet_id;
   147 
   148         session_manager_ = SessionManager.getInstance();
   149 
   150         user_logger_ = session_.getUserLogger();
   151 
   152         getCalcTree(f);
   153     }
   154 
   155     public String getWorksheetID() {
   156         return worksheet_id_;
   157     }
   158 
   159     public CalcTree getCalcTree() {
   160         return calc_tree_;
   161     }
   162 
   163     /**
   164      * start a calculation
   165      */
   166     public void getCalcTree(Formalization f) {
   167         // do administrative stuff
   168         calc_tree_ = math_engine_.getCalcTree(f);
   169         calc_tree_.addDataChangeListener(this);
   170 
   171         switch (user_settings_.getValue(IUserSettings.KEY1_START_SPECIFY)) {
   172         case IUserSettings.VAL1_SKIP_SPECIFY_TO_START_SOLVE:
   173             phase_ = DIALOGPHASE_SOLVE;
   174             break;
   175         case IUserSettings.VAL1_POP_CALCHEAD_WITH_DESCRIPTIONS:
   176             phase_ = DIALOGPHASE_SPECIFY;
   177             break;
   178         }
   179 
   180         return;
   181     }
   182 
   183     /**
   184      * enter the specifying-phase; 2 cases: (1) at the beginning of a
   185      * calculation as well as of a subproblem; sets the Descriptions in the
   186      * Model (to support user-input) and in CAS-commands completes the Model.
   187      * (2) for inspection of a "correct" CalcHead somewhere above the
   188      * activeFormula; in this case the CalcHead is not updated, it is just the
   189      * starting point into the math-knowledge.
   190      * 
   191      * @return CalcHead eg. for providing CalcHead#VIEWSTYLE_*
   192      * 
   193      * @see isac.wsdialog.IWorksheetDialog#startSpecifying()
   194      */
   195     private void startSpecifying(CalcHead calc_head) {
   196         phase_ = DIALOGPHASE_SPECIFY;
   197         try {
   198             // remove solving buttons
   199             removeNextAndAutoButtonForWorksheet();
   200             if (calc_head.getStatusString().equals("incorrect")) {
   201                 // case (1)
   202                 // -----------------------------------------------------------
   203                 // if you think, modelProblem should only set the descriptions
   204                 // in the Model (and NOT complete it for CAS-commands)
   205                 // search the sml-code for WN060225-modelProblem
   206                 calc_head = calc_tree_.modelProblem();
   207                 // -----------------------------------------------------------
   208                 doUIAction(new UIActionOnCalcElement(
   209                         EUIElement.UI_SPECIFY_OPEN_CALCHEAD,
   210                         EUIContext.UI_CONTEXT_SWITCH_PHASES, user_language_,
   211                         calc_head));
   212                 addCalcHeadPanelButtons();
   213                 addNextAndAutoButtonsForCalchead();
   214 
   215             } else {// case (2)
   216                 // only Button Close
   217                 doUIAction(new UIActionOnCalcElement(
   218                         EUIElement.UI_SPECIFY_OPEN_CALCHEAD,
   219                         EUIContext.UI_CONTEXT_SWITCH_PHASES, user_language_,
   220                         calc_head));
   221                 ui_control_listener_.addUIElement(new UIAction(
   222                         EUIElement.UI_SPECIFY_CLOSE_CALCHEAD,
   223                         EUIContext.UI_CONTEXT_CALCHEAD, user_language_));
   224                 addNextAndAutoButtonForWorksheet();
   225             }
   226 
   227         } catch (RemoteException e) {
   228             e.printStackTrace();
   229         }
   230 
   231     }
   232 
   233     /**
   234      * @see isac.wsdialog.IWorksheetDialog#startCalculate()
   235      */
   236     public void startCalculate() {
   237         calc_tree_.startCalculate();
   238     }
   239 
   240     /**
   241      * dismiss the CalcHeadPanel and start WorksheetDialog#DIALOGPHASE_SOLVE
   242      * 
   243      * @see isac.interfaces.IToCalc#startSolving()
   244      */
   245     private void startSolving() {
   246         try {
   247             removeCalcHeadPanelButtons();
   248             removeNextAndAutoButtonsForCalchead();
   249             addNextAndAutoButtonForWorksheet();
   250 
   251         } catch (RemoteException e) {
   252             e.printStackTrace();
   253         }
   254         phase_ = DIALOGPHASE_SOLVE;
   255     }
   256 
   257     private void buildUIElementsContextCalcElements() {
   258         try {
   259             // ui_control_listener_.addUIElement(new UIAction(
   260             // UI_SOLVE_GET_APPLICABLE_TACTICS,
   261             // EUIContext.UI_CONTEXT_CALCELEMENTS));
   262             ui_control_listener_.addUIElement(new UIAction(
   263                     EUIElement.UI_SOLVE_SHOW_ASSUMPTIONS,
   264                     EUIContext.UI_CONTEXT_CALCELEMENTS, user_language_));
   265             ui_control_listener_.addUIElement(new UIAction(
   266                     EUIElement.UI_SOLVE_TACTIC_APPLIED,
   267                     EUIContext.UI_CONTEXT_CALCELEMENTS, user_language_));
   268             ui_control_listener_.addUIElement(new UIAction(
   269                     EUIElement.UI_SOLVE_SHOW_INTERMEDIATE_STEPS,
   270                     EUIContext.UI_CONTEXT_CALCELEMENTS, user_language_));
   271         } catch (RemoteException e) {
   272             e.printStackTrace();
   273         }
   274     }
   275 
   276     private void addNextAndAutoButtonForWorksheet() throws RemoteException {
   277         // Button next
   278         ui_control_listener_.addUIElement(new UIAction(
   279                 EUIElement.UI_SOLVE_CALCULATE_1,
   280                 EUIContext.UI_CONTEXT_CALCULATION, user_language_));
   281         // Button auto
   282         ui_control_listener_.addUIElement(new UIAction(
   283                 EUIElement.UI_SOLVE_CALCULATE_ALL,
   284                 EUIContext.UI_CONTEXT_CALCULATION, user_language_));
   285     }
   286 
   287     private void removeNextAndAutoButtonForWorksheet() throws RemoteException {
   288         // Button next
   289         ui_control_listener_.removeUIElement(new UIAction(
   290                 EUIElement.UI_SOLVE_CALCULATE_1,
   291                 EUIContext.UI_CONTEXT_CALCULATION, user_language_));
   292         // Button auto
   293         ui_control_listener_.removeUIElement(new UIAction(
   294                 EUIElement.UI_SOLVE_CALCULATE_ALL,
   295                 EUIContext.UI_CONTEXT_CALCULATION, user_language_));
   296 
   297     }
   298 
   299     private void addCalcHeadPanelButtons() throws RemoteException {
   300         // Button Complete
   301         ui_control_listener_.addUIElement(new UIAction(
   302                 EUIElement.UI_SPECIFY_COMPLETE_CALCHEAD,
   303                 EUIContext.UI_CONTEXT_CALCHEAD, user_language_));
   304         // // Button Check
   305         // ui_control_listener_.addUIElement(new UIAction(
   306         // UI_SPECIFY_CHECK_CALCHEAD, EUIContext.UI_CONTEXT_CALCHEAD));
   307         // Button reset
   308         ui_control_listener_.addUIElement(new UIAction(
   309                 EUIElement.UI_SPECIFY_RESET, EUIContext.UI_CONTEXT_CALCHEAD,
   310                 user_language_));
   311         // Button Start Solving
   312         ui_control_listener_.addUIElement(new UIAction(
   313                 EUIElement.UI_SPECIFY_TO_SOLVE, EUIContext.UI_CONTEXT_CALCHEAD,
   314                 user_language_));
   315 
   316     }
   317 
   318     private void removeCalcHeadPanelButtons() throws RemoteException {
   319         // Button Complete
   320         ui_control_listener_.removeUIElement(new UIAction(
   321                 EUIElement.UI_SPECIFY_COMPLETE_CALCHEAD,
   322                 EUIContext.UI_CONTEXT_CALCHEAD, user_language_));
   323         // Button Start Solving
   324         ui_control_listener_.removeUIElement(new UIAction(
   325                 EUIElement.UI_SPECIFY_TO_SOLVE, EUIContext.UI_CONTEXT_CALCHEAD,
   326                 user_language_));
   327         // // Button Check
   328         // ui_control_listener_.removeUIElement(new UIAction(
   329         // UI_SPECIFY_CHECK_CALCHEAD, EUIContext.UI_CONTEXT_CALCHEAD));
   330         // Button reset
   331         ui_control_listener_.removeUIElement(new UIAction(
   332                 EUIElement.UI_SPECIFY_RESET, EUIContext.UI_CONTEXT_CALCHEAD,
   333                 user_language_));
   334     }
   335 
   336     /**
   337      * add next and auto Button to WindowApplication
   338      */
   339     // Context Calculation is used instead of context calchead,
   340     // because buttons have to be added to windowapplication and not to
   341     // calcheadpanel
   342     private void addNextAndAutoButtonsForCalchead() {
   343         try {
   344             // add next Button
   345             ui_control_listener_.addUIElement(new UIAction(
   346                     EUIElement.UI_SPECIFY_COMPLETE_STEPWISE,
   347                     EUIContext.UI_CONTEXT_CALCULATION, user_language_));
   348             // add auto Button
   349             ui_control_listener_.addUIElement(new UIAction(
   350                     EUIElement.UI_SPECIFY_CALCULATE_ALL,
   351                     EUIContext.UI_CONTEXT_CALCULATION, user_language_));
   352         } catch (RemoteException e) {
   353             e.printStackTrace();
   354         }
   355     }
   356 
   357     /**
   358      * 
   359      */
   360     private void removeNextAndAutoButtonsForCalchead() {
   361 
   362         // Context Calculation is used instead of context calchead,
   363         // because buttons have to be added to windowapplication and not to
   364         // calcheadpanel
   365         try {
   366             // add next Button
   367             ui_control_listener_.removeUIElement(new UIAction(
   368                     EUIElement.UI_SPECIFY_COMPLETE_STEPWISE,
   369                     EUIContext.UI_CONTEXT_CALCULATION, user_language_));
   370             // add auto Button
   371             ui_control_listener_.removeUIElement(new UIAction(
   372                     EUIElement.UI_SPECIFY_CALCULATE_ALL,
   373                     EUIContext.UI_CONTEXT_CALCULATION, user_language_));
   374         } catch (RemoteException e) {
   375             e.printStackTrace();
   376         }
   377     }
   378 
   379     /**
   380      * accept the response of the bridge on an operation on a calculation; this
   381      * can be a <code>CalcChanged</code>-information or a
   382      * <code>CalcMessage</code>; pass them to the Worksheet (on different
   383      * ways: the <code>CalcMessage</code> is passed as a <code>UIAction</code>
   384      * TODO.WN0710)
   385      * 
   386      * @see isac.wsdialog.IToUser#calcResponse(isac.wsdialog.CalcChanged)
   387      */
   388     public void calcResponse(CalcEvent event) throws RemoteException {
   389         if (event instanceof CalcChanged) {
   390             CalcChanged ccevent = (CalcChanged) event;
   391             worksheet_ready_ = false;
   392             if (logger.isInfoEnabled())
   393                 logger.info(" WS<-. . : calcChanged (unc="
   394                         + ccevent.getLastUnchangedFormula().toSMLString()
   395                         + ", del="
   396                         + ccevent.getLastDeletedFormula().toSMLString()
   397                         + ", gen="
   398                         + ccevent.getLastGeneratedFormula().toSMLString());
   399             try {
   400                 for (int i = 0; i < datachange_listeners_.size(); i++) {
   401                     CalcChanged wrappedEvent = new CalcChanged(event
   402                             .getTransactionId(), ccevent.isCompleted(),
   403                             new DialogIterator((CalcIterator) ccevent
   404                                     .getLastUnchangedFormula(), this),
   405                             new DialogIterator((CalcIterator) ccevent
   406                                     .getLastDeletedFormula(), this),
   407                             new DialogIterator((CalcIterator) ccevent
   408                                     .getLastGeneratedFormula(), this));
   409                     ((IToUser) datachange_listeners_.elementAt(i))
   410                             .calcResponse(wrappedEvent);
   411                 }
   412             } catch (Exception e) {
   413                 e.printStackTrace();
   414             }
   415             addUIElementsContextOneElement(ccevent);
   416 
   417             active_formula_ = ccevent.getLastGeneratedFormula();
   418             if (!ccevent.getLastGeneratedFormula().onCalcHead()
   419             // ..a calculation cannot finish with a CalcHead
   420                     && !calculation_finished_successfully_)
   421                 // ..calculation_finished_successfully_ = true: only once
   422                 calculation_finished_successfully_ = ((CalcFormula) (active_formula_
   423                         .getElement())).getPosition().onEndOfCalculation();
   424 
   425             context_formula_ = (ICalcIterator) ccevent
   426                     .getLastGeneratedFormula().cloneIterator();
   427 
   428             user_logger_.logCalcChanged(worksheet_id_, ccevent);
   429 
   430             updateContextFormulaOnWorksheet(context_formula_);
   431 
   432             notifyContextPresenter();
   433 
   434             if (active_formula_.onCalcHead()) {
   435                 switch (user_settings_.getValue("KEY1_START_SPECIFY")) {
   436                 case IUserSettings.VAL1_SKIP_SPECIFY_TO_START_SOLVE:
   437                     // WN050728
   438                     // instead
   439                     // calc_tree_.autoCalculate(IToCalc.SCOPE_CALCULATION,
   440                     // 1);
   441                     // ...NEW Model_Problem (inserting Descriptions into the
   442                     // Model)
   443                     // without causing CalcChanged (would loop in
   444                     // calcChanged!)
   445                     startSolving();
   446                     break;
   447                 case IUserSettings.VAL1_POP_CALCHEAD_WITH_DESCRIPTIONS:
   448                     startSpecifying((CalcHead) active_formula_.getElement());
   449                     break;
   450                 default:
   451                     try {
   452                         throw new Exception(
   453                                 "WorksheetDialog#calcChanged:switch"
   454                                         + " (user_settings_.getValue(KEY1_START_SPECIFY)");
   455                     } catch (Exception e1) {
   456                         e1.printStackTrace();
   457                     }
   458                 }
   459             }
   460         } else {// CalcMessage
   461             // TODO.WN0710 pass on to gui via UIAction
   462             user_logger_.logCalcMessage(worksheet_id_, active_formula_
   463                     .toSMLString(), ((CalcMessage) event).getText());
   464         }
   465     }
   466 
   467     /**
   468      * construct the context-menu on one specific calcelement (e.g. with
   469      * 'Calchead' and without)
   470      * 
   471      */
   472     private void addUIElementsContextOneElement(CalcChanged event) {
   473         ICalcIterator from = event.getLastUnchangedFormula();
   474         ICalcIterator to = event.getLastGeneratedFormula();
   475 
   476         Vector calc_formulae = null;
   477 
   478         try {
   479             calc_formulae = from.getFormulaeFromTo(to, new Integer(0), false);
   480         } catch (RemoteException e1) {
   481             e1.printStackTrace();
   482         }
   483 
   484         if (calc_formulae == null)
   485             return;
   486 
   487         Iterator vector_it = calc_formulae.iterator();
   488 
   489         while (vector_it.hasNext()) {
   490             CalcFormula cf = (CalcFormula) vector_it.next();
   491 
   492             if (cf.getPosition().getKind().equals("Pbl")
   493                     || cf.getPosition().getKind().equals("Met")) {
   494                 try {
   495                     ui_control_listener_.addUIElement(new UIAction(
   496                             EUIElement.UI_SOLVE_SHOW_CALCHEAD,
   497                             EUIContext.UI_CONTEXT_ONEELEMENT, cf.getPosition(),
   498                             user_language_));
   499                 } catch (RemoteException e) {
   500                     e.printStackTrace();
   501                 }
   502             }
   503         }
   504     }
   505 
   506     /***************************************************************************
   507      * This method sends the applicable tactics to the specific item in the
   508      * worksheet determined by the Position of the iterator
   509      * 
   510      * @param it
   511      */
   512     private void sendApplicableTacticsToWorksheet(ICalcIterator it) {
   513         try {
   514             Vector tactics = it.getApplicableTactics(ICalcIterator.TACTICS_ALL);
   515 
   516             if (tactics != null) {
   517                 for (int i = 0; i < tactics.size(); i++)
   518                     ui_control_listener_
   519                             .addUIElement(new UIActionOnCalcElement(
   520                                     EUIElement.UI_SOLVE_SET_NEXT_TACTIC,
   521                                     EUIContext.UI_CONTEXT_APPLICABLE_TACTIC,
   522                                     user_language_, it.getPosition(),
   523                                     (Tactic) tactics.get(i)));
   524             }
   525         } catch (RemoteException e) {
   526             e.printStackTrace();
   527         }
   528     }
   529 
   530     private void updateContextFormulaOnWorksheet(ICalcIterator it) {
   531         if (ui_control_listener_ != null)
   532             try {
   533                 ui_control_listener_.doUIAction(new UIAction(
   534                         EUIElement.UI_SOLVE_CHANGE_CONTEXT_FORMULA,
   535                         EUIContext.UI_CONTEXT_ONEELEMENT, it.getPosition(),
   536                         user_language_));
   537             } catch (RemoteException e) {
   538                 e.printStackTrace();
   539             }
   540     }
   541 
   542     /**
   543      * @see isac.wsdialog.IWorksheetDialog#iterator(CalcIterator,
   544      *      IWorksheetDialog)
   545      * @see isac.interfaces.IToCalc#iterator()
   546      */
   547     public ICalcIterator iterator(CalcIterator it, IWorksheetDialog dg) {
   548         try {
   549             return new DialogIterator(it, dg);
   550         } catch (RemoteException e) {
   551             e.printStackTrace();
   552         }
   553         return null;
   554     }
   555 
   556     /**
   557      * @see isac.wsdialog.IToCalc#addListener(isac.wsdialog.IToUser)
   558      */
   559     public boolean addDataChangeListener(IToUser listener)
   560             throws RemoteException {
   561         if (datachange_listeners_.contains(listener)) {
   562             return false;
   563         } else {
   564             datachange_listeners_.add(listener);
   565         }
   566         return true;
   567     }
   568 
   569     public boolean registerUIControlListener(IToGUI listener)
   570             throws RemoteException {
   571         ui_control_listener_ = listener;
   572         buildUIElementsContextCalcElements();
   573         return true;
   574     }
   575 
   576     /**
   577      * Notify the Dialog Guide about interaction from the User DO NOT MODIFY THE
   578      * SEQUENCE OF THE CASE BLOCKS IN THE SWITCH STATEMENTS!!
   579      * 
   580      * @param action
   581      * @return true, if the action has been processed, false if the processing
   582      *         the action has been denied
   583      * @throws RemoteException
   584      * 
   585      */
   586     public boolean notifyUserAction(IUserAction action)
   587             throws DialogProtocolException, RemoteException {
   588         EUIElement request = action.getActionID();
   589         CalcHead calc_head = new CalcHead();
   590         CalcHead ch_to_check = new CalcHead();
   591 
   592         if (logger.isInfoEnabled())
   593             logger.info(" WS->DG: notifyUserAction request= " + request);
   594         System.out.println(" WS->DG: notifyUserAction request= " + request);
   595 
   596         if (request == EUIElement.UI_CLOSE_WORKSHEET)
   597             user_logger_.logCloseWorksheet(worksheet_id_,
   598                     calculation_finished_successfully_);
   599         else
   600             user_logger_.logUserAction("worksheet", action);
   601 
   602         // / the requests that do not depend on the phase
   603         switch (request) {
   604         case UI_CLOSE_WORKSHEET:
   605             calc_tree_.destruct();
   606             session_.getWSDialogManager().closeWSDialog(worksheet_id_);
   607             if (session_.getWSDialogManager().numberOpenedWSDialoges() == 0)
   608                 removeNextAndAutoButtonForWorksheet();
   609             IContextPresenter bdg = session_.getContextPresenter();
   610             ContextUnknown context_unknown = new ContextUnknown();
   611             bdg.presentContext(context_unknown);
   612             return true;
   613         case UI_ACTIVE_WORKSHEET:
   614             session_.getWSDialogManager().setActiveWSDialog(worksheet_id_);
   615             notifyContextPresenter();
   616             return true;
   617         }
   618 
   619         switch (phase_) {
   620         case DIALOGPHASE_IDLE:
   621             throw new DialogProtocolException(request, phase_);
   622         case DIALOGPHASE_SPECIFY:
   623             if (request.ordinal() < EUIElement.UI_DUMMY_FIRST_SPECIFY.ordinal()
   624                     || request.ordinal() > EUIElement.UI_DUMMY_LAST_SPECIFY
   625                             .ordinal())
   626                 throw new DialogProtocolException(request, phase_);
   627             break;
   628         case DIALOGPHASE_SOLVE:
   629             if (request.ordinal() < EUIElement.UI_DUMMY_FIRST_SOLVE.ordinal()
   630                     || request.ordinal() > EUIElement.UI_DUMMY_LAST_SOLVE
   631                             .ordinal())
   632                 throw new DialogProtocolException(request, phase_);
   633             break;
   634         }
   635 
   636         // *********** handle IUserAction's **********************
   637 
   638         switch (request) {
   639         // in solve-phase request open a CalcHead by context-menu
   640         case UI_SOLVE_SHOW_CALCHEAD:
   641             calc_head = (CalcHead) context_formula_.getElement();
   642             // calc_head = (CalcHead) ((UserActionOnIterator) action)
   643             // .getPosition().getElement();
   644             startSpecifying(calc_head);
   645             // FIXXME RK 060712 here was:
   646             // problem_browser_dialog_.setContext(worksheet_id_);
   647             break;
   648 
   649         // Enter pressed after typing formula
   650         case UI_SPECIFY_EDIT_ACTIVE_FORMULA_COMPLETE:
   651             ch_to_check = (CalcHead) ((UserActionOnCalcElement) action)
   652                     .getCalcElement();
   653             calc_head = calc_tree_.checkCalcHead(ch_to_check);
   654             doUIAction(new UIActionOnCalcElement(
   655                     EUIElement.UI_SPECIFY_CHECK_CALCHEAD,
   656                     EUIContext.UI_CONTEXT_CALCHEAD, user_language_, calc_head));
   657             break;
   658 
   659         // Complete pressed
   660         case UI_SPECIFY_COMPLETE_CALCHEAD:
   661             if (!calc_head.isComplete()) {
   662                 calc_head = calc_tree_.completeCalcHead();
   663                 doUIAction(new UIActionOnCalcElement(
   664                         EUIElement.UI_SPECIFY_COMPLETE_CALCHEAD,
   665                         EUIContext.UI_CONTEXT_CALCHEAD, user_language_,
   666                         calc_head));
   667             }
   668             break;
   669         // Radiobutton for Method/Problem clicked
   670         // case UI_SPECIFY_TOGGLE_METHOD_PROBLEM:
   671         // System.out.println("toggle");
   672         // // WN050830 use UI_SPECIFY_SWITCH_TO_GUARD and
   673         // // UI_SPECIFY_SWITCH_TO_MODEL instead,
   674         // // and use some of this code ...
   675         // // ICalcIterator ci = calc_tree_.getActiveFormula();
   676         // // ci.switchToGuard();
   677         // // CalcHead ch = (CalcHead) ci.getElement();
   678         // //
   679         // // TODO MK add code here to get new CalcHead with either Met or Pbl
   680         // // Elements
   681         //
   682         // // ch_to_check = (CalcHead) ((UserActionOnCalcElement) action)
   683         // // .getCalcElement();
   684         // // calc_head = calc_tree_.checkCalcHead(ch_to_check);
   685         // // doUIAction(new
   686         // UIActionOnCalcElement(EUIElement.UI_SPECIFY_CHECK_CALCHEAD,
   687         // // EUIContext.UI_CONTEXT_CALCHEAD, user_language_, user_language_,
   688         // calc_head));
   689         // break;
   690 
   691         case UI_SPECIFY_METHOD:
   692         case UI_SPECIFY_THEORY:
   693         case UI_SPECIFY_PROBLEM:
   694         case UI_SPECIFY_COMPLETE_GIVEN:
   695         case UI_SPECIFY_COMPLETE_FIND:
   696         case UI_SPECIFY_COMPLETE_RELATE:
   697             throw new DialogNotImplementedException(request, phase_);
   698 
   699         // check pressed
   700         case UI_SPECIFY_CHECK_CALCHEAD:
   701             ch_to_check = (CalcHead) ((UserActionOnCalcElement) action)
   702                     .getCalcElement();
   703             calc_head = calc_tree_.checkCalcHead(ch_to_check);
   704             doUIAction(new UIActionOnCalcElement(
   705                     EUIElement.UI_SPECIFY_CHECK_CALCHEAD,
   706                     EUIContext.UI_CONTEXT_CALCHEAD, user_language_, calc_head));
   707             break;
   708 
   709         // next pressed
   710         case UI_SPECIFY_COMPLETE_STEPWISE:
   711             if (!calc_head.isComplete()) {
   712                 calc_head = calc_tree_.nextSpecify();
   713                 doUIAction(new UIActionOnCalcElement(
   714                         EUIElement.UI_SPECIFY_COMPLETE_STEPWISE,
   715                         EUIContext.UI_CONTEXT_CALCHEAD, user_language_,
   716                         calc_head));
   717             }
   718             break;
   719 
   720         // close pressed
   721         case UI_SPECIFY_CLOSE_CALCHEAD:
   722             // this action is enabled _ONLY_ if the Panel was opened read-only
   723             // on a complete CalcHead just for inspection
   724             doUIAction(new UIAction(EUIElement.UI_SPECIFY_CLOSE_CALCHEAD,
   725                     EUIContext.UI_CONTEXT_SWITCH_PHASES, user_language_));
   726             phase_ = DIALOGPHASE_SOLVE;
   727             // FIXXME RK 060712 here was:
   728             // problem_browser_dialog_.setContext("");
   729             break;
   730 
   731         // reset pressed
   732         case UI_SPECIFY_RESET:
   733             calc_tree_.resetCalcHead();
   734             calc_head = calc_tree_.modelProblem();
   735             doUIAction(new UIActionOnCalcElement(EUIElement.UI_SPECIFY_RESET,
   736                     EUIContext.UI_CONTEXT_CALCHEAD, user_language_, calc_head));
   737             break;
   738 
   739         // start solving pressed
   740         case UI_SPECIFY_TO_SOLVE:
   741         // FIXXME RK 060712 here was: problem_browser_dialog_.setContext("");
   742 
   743         // ch_to_check = (CalcHead) ((UserActionOnCalcElement) action)
   744         // .getCalcElement();
   745         // calc_head = calc_tree_.checkCalcHead(ch_to_check);
   746         // if (!calc_head.isComplete()) {
   747         // calc_head = calc_tree_.completeCalcHead();
   748         // doUIAction(new
   749         // UIActionOnCalcElement(EUIElement.UI_SPECIFY_CHECK_CALCHEAD,
   750         // EUIContext.UI_CONTEXT_CALCHEAD, user_language_, user_language_,
   751         // calc_head));
   752         // break;
   753         // }
   754 
   755         // auto pressed
   756         case UI_SPECIFY_CALCULATE_ALL:
   757             if (!calc_head.isComplete()) {
   758                 calc_head = calc_tree_.completeCalcHead();
   759                 if (!calc_head.isComplete()) {
   760                     calc_tree_.resetCalcHead();
   761                     calc_head = calc_tree_.completeCalcHead();
   762                 }
   763             }
   764 
   765             doUIAction(new UIActionOnCalcElement(
   766                     EUIElement.UI_SPECIFY_CALCULATE_ALL,
   767                     EUIContext.UI_CONTEXT_CALCHEAD, user_language_, calc_head));
   768             doUIAction(new UIAction(EUIElement.UI_SPECIFY_CLOSE_CALCHEAD,
   769                     EUIContext.UI_CONTEXT_SWITCH_PHASES, user_language_));
   770             startSolving();
   771 
   772         // --------------solving phase------------------------------------
   773         case UI_SOLVE_CALCULATE_1:
   774             // handle the CalcHead such that its HeadLine can be
   775             // presented like a CalcFormula
   776             if (active_formula_.onCalcHead()) {
   777                 calc_tree_.completeCalcHead();
   778                 try {
   779                     calc_tree_.startSolving();
   780                 } catch (AutoCalculateException e1) {
   781                     e1.printStackTrace();
   782                 }
   783             } else {
   784                 calc_tree_.autoCalculate(IToCalc.SCOPE_CALCULATION, 1);
   785             }
   786             break;
   787 
   788         case UI_SOLVE_CALCULATE_ALL:
   789             switch (request) {
   790             case UI_SPECIFY_CALCULATE_ALL:
   791             case UI_SOLVE_CALCULATE_ALL:
   792                 calc_tree_.autoCalculate(IToCalc.SCOPE_CALCULATION, 0);
   793                 break;
   794             case UI_SPECIFY_TO_SOLVE:
   795             default:
   796             }
   797             break;
   798 
   799         case UI_SOLVE_CALCULATE_SUBPROBLEM:
   800             calc_tree_.autoCalculate(IToCalc.SCOPE_SUBPROBLEM, 0);
   801             break;
   802 
   803         case UI_SOLVE_EDIT_ACTIVE_FORMULA:
   804             ui_control_listener_.doUIAction(new UIAction(
   805                     EUIElement.UI_DO_EDIT_FORMULA,
   806                     EUIContext.UI_CONTEXT_ONEELEMENT, user_language_));
   807             break;
   808 
   809         case UI_SOLVE_EDIT_ACTIVE_FORMULA_COMPLETE:
   810             System.out.println("**********XXX****************");
   811             CalcFormula formula = (CalcFormula) ((UserActionOnCalcElement) action)
   812                     .getCalcElement();
   813             // if the position is null, the formula did not exist, so we try to
   814             // append a new formula
   815             if (formula.getPosition() == null) {
   816                 calc_tree_.appendFormula(formula);
   817             } else {
   818                 active_formula_ = new CalcIterator(calc_tree_, formula
   819                         .getPosition());
   820                 calc_tree_.replaceFormula(formula);
   821             }
   822             break;
   823 
   824         case UI_SOLVE_APPEND_USER_FORMULA:
   825             ui_control_listener_.doUIAction(new UIAction(
   826                     EUIElement.UI_DO_APPEND_FORMULA,
   827                     EUIContext.UI_CONTEXT_ONEELEMENT, user_language_));
   828             break;
   829 
   830         case UI_SOLVE_MOVE_ACTIVE_FORMULA: {
   831             UserActionOnPosition uaop = (UserActionOnPosition) action;
   832             Position activePosition = uaop.getPosition();
   833             ICalcIterator iterator = new CalcIterator(calc_tree_,
   834                     activePosition);
   835             calc_tree_.moveActiveFormula(iterator);
   836         }
   837             break;
   838 
   839         case UI_SOLVE_CHANGE_CONTEXT_FORMULA: {
   840             UserActionOnPosition uaop = (UserActionOnPosition) action;
   841             Position activePosition = uaop.getPosition();
   842             if (activePosition != null) {
   843                 context_formula_ = new CalcIterator(calc_tree_, activePosition);
   844                 notifyContextPresenter();
   845             }
   846         }
   847             break;
   848 
   849         case UI_SOLVE_GET_PROPOSED_TACTIC:
   850             throw new DialogNotImplementedException(request, phase_);
   851 
   852         case UI_SOLVE_GET_APPLICABLE_TACTICS:
   853             sendApplicableTacticsToWorksheet(context_formula_);
   854             doUIAction(new UIAction(
   855                     EUIElement.UI_SOLVE_SHOW_APPLICABLE_TACTICS,
   856                     EUIContext.UI_CONTEXT_ONEELEMENT, user_language_));
   857             break;
   858 
   859         case UI_SOLVE_SET_NEXT_TACTIC:
   860             UserActionOnCalcElement uaoce = (UserActionOnCalcElement) action;
   861 
   862             calc_tree_.moveActiveFormula(new CalcIterator(calc_tree_, uaoce
   863                     .getPosition()));
   864             calc_tree_.setNextTactic((Tactic) uaoce.getCalcElement());
   865             calc_tree_.autoCalculate(IToCalc.SCOPE_CALCULATION, 1);
   866             break;
   867 
   868         case UI_SOLVE_HELP_ENTERING_FORMULA:
   869             throw new DialogNotImplementedException(request, phase_);
   870 
   871         case UI_SOLVE_SHOW_ASSUMPTIONS: {
   872             Assumptions asm = context_formula_.getAssumptions();
   873             System.out.println("in WSDialog: asm = " + asm.toSMLString());
   874             doUIAction(new UIActionOnCalcElement(
   875                     EUIElement.UI_SOLVE_SHOW_ASSUMPTIONS,
   876                     EUIContext.UI_CONTEXT_CALCELEMENTS, user_language_, asm));
   877         }
   878             break;
   879 
   880         case UI_SOLVE_SHOW_INTERMEDIATE_STEPS: {
   881             calc_tree_.intermediateSteps(context_formula_);
   882         }
   883             break;
   884 
   885         case UI_SOLVE_TACTIC_APPLIED: {
   886             Tactic ta = context_formula_.getTactic();
   887             doUIAction(new UIActionOnCalcElement(
   888                     EUIElement.UI_SOLVE_TACTIC_APPLIED,
   889                     EUIContext.UI_CONTEXT_CALCELEMENTS, user_language_, ta));
   890             break;
   891         }
   892 
   893         case UI_SPECIFY_OPEN_CALCHEAD:
   894             System.out.println("Pressed!");
   895             break;
   896 
   897         default:
   898             throw new DialogUnknownActionException(request, phase_);
   899         }
   900         return true;
   901     }
   902 
   903     private void rmiBind() {
   904         if (System.getSecurityManager() == null) {
   905             System.setSecurityManager(new RMISecurityManager());
   906         }
   907 
   908         try {
   909             LocateRegistry
   910                     .createRegistry(ObjectManagerPaths.OBJECT_MANAGER_PORT);
   911         } catch (java.rmi.RemoteException exc2) {
   912             System.err.println("can not create registry: " + exc2.getMessage());
   913         }
   914 
   915         // fixed path name =
   916         // //localhost/isac-WorksheetDialog...Naming.rebind(name, this);
   917         String name = ObjectManagerPaths.WORKSHEET_DIALOG_PATH; // "//localhost/isac-WorksheetDialog";
   918         try {
   919             System.out.println("try to bind as " + name);
   920             Naming.rebind(name, this);
   921             System.out.println("Dialog Guide bound to " + name);
   922             // WN040906 was Object Manager ...
   923         } catch (java.rmi.ConnectException e) {
   924             System.err.println("failed to contact as " + name
   925                     + " (creating RMI-Server on localhost: 1099)");
   926         } catch (RemoteException e) {
   927             e.printStackTrace();
   928         } catch (MalformedURLException e) {
   929             e.printStackTrace();
   930         }
   931     }
   932 
   933     /**
   934      * @see isac.wsdialog.IWorksheetDialog#notifyGUIReady()
   935      */
   936     public void notifyGUIReady() throws RemoteException {
   937         worksheet_ready_ = true;
   938     }
   939 
   940     /**
   941      * @see isac.interfaces.IToGUI#doUIAction(isac.wsdialog.EUIContext) LK
   942      *      introduced worksheet_ready_ which required new Runnable
   943      */
   944     public synchronized void doUIAction(final IUIAction action)
   945             throws RemoteException {
   946         Thread t = new Thread(new Runnable() {
   947 
   948             public void run() {
   949                 try {
   950                     while (worksheet_ready_ == false) {
   951                         try {
   952                             Thread.sleep(1000);
   953                         } catch (InterruptedException e1) {
   954                             e1.printStackTrace();
   955                         }
   956                     }
   957                     ui_control_listener_.doUIAction(action);
   958                 } catch (RemoteException e) {
   959                     e.printStackTrace();
   960                 }
   961             }
   962         });
   963         t.run();
   964     }
   965 
   966     /**
   967      * request the gui to add an interactive element
   968      * 
   969      * @see isac.interfaces.IToGUI#addUIElement(isac.wsdialog.IUIAction)
   970      */
   971     public synchronized void addUIElement(final IUIAction action)
   972             throws RemoteException {
   973         Thread t = new Thread(new Runnable() {
   974 
   975             public void run() {
   976                 try {
   977                     while (worksheet_ready_ == false) {
   978                         try {
   979                             Thread.sleep(1000);
   980                         } catch (InterruptedException e1) {
   981                             e1.printStackTrace();
   982                         }
   983                     }
   984                     ui_control_listener_.addUIElement(action);
   985                 } catch (RemoteException e) {
   986                     e.printStackTrace();
   987                 }
   988             }
   989         });
   990         t.run();
   991     }
   992 
   993     /**
   994      * request the gui to remove an interactive element
   995      * 
   996      * @see isac.interfaces.IToGUI#removeUIElement(isac.wsdialog.IUIAction)
   997      */
   998     public synchronized void removeUIElement(final IUIAction action)
   999             throws RemoteException {
  1000         Thread t = new Thread(new Runnable() {
  1001 
  1002             public void run() {
  1003                 try {
  1004                     while (worksheet_ready_ == false) {
  1005                         try {
  1006                             Thread.sleep(1000);
  1007                         } catch (InterruptedException e1) {
  1008                             e1.printStackTrace();
  1009                         }
  1010                     }
  1011                     ui_control_listener_.removeUIElement(action);
  1012                     // ???worksheet_ready_ = false;
  1013                 } catch (RemoteException e) {
  1014                     e.printStackTrace();
  1015                 }
  1016             }
  1017         });
  1018         t.run();
  1019     }
  1020 
  1021     /***************************************************************************
  1022      * TODO: notify the active context presenter that something happened
  1023      */
  1024     private void notifyContextPresenter() {
  1025         System.out.println("In WorksheetDialog::notifyContextPresenter !!");
  1026 
  1027         Context current_context = new ContextUnknown();
  1028         IContextPresenter bdg = session_.getContextPresenter();
  1029 
  1030         if (bdg == null) {
  1031             System.out.println("No dialog");
  1032             return;
  1033         }
  1034 
  1035         if (bdg instanceof ExampleDialog) {
  1036             System.out.println("Example dialog");
  1037             current_context = initContext(ContextType.CONTEXT_EXAMPLES);
  1038         } else if (bdg instanceof ProblemDialog) {
  1039             System.out.println("Problem dialog");
  1040             current_context = initContext(ContextType.CONTEXT_PROBLEMS);
  1041         } else if (bdg instanceof MethodDialog) {
  1042             System.out.println("Method dialog");
  1043             current_context = initContext(ContextType.CONTEXT_METHODS);
  1044         } else if (bdg instanceof TheoryDialog) {
  1045             System.out.println("Theory dialog");
  1046             current_context = initContext(ContextType.CONTEXT_THEORIES);
  1047         }
  1048 
  1049         bdg.presentContext(current_context);
  1050     }
  1051 
  1052     /**
  1053      * @see isac.wsdialog.IContextProvider#initContext(ContextMethod)
  1054      * 
  1055      * @throws RemoteException
  1056      * 
  1057      */
  1058     public Context initContext(ContextType type) {
  1059         System.out.println("In WorksheetDialog::initContext() : type is "
  1060                 + type);
  1061 
  1062         Context current_context = new ContextUnknown();
  1063 
  1064         switch (type) {
  1065         case CONTEXT_EXAMPLES:
  1066             current_context = new ContextExample();
  1067             current_context.setKEStoreKey(session_
  1068                     .getExampleOfWorksheet(worksheet_id_));
  1069             break;
  1070         case CONTEXT_METHODS:
  1071         case CONTEXT_PROBLEMS:
  1072         case CONTEXT_THEORIES:
  1073             try {
  1074                 current_context = context_formula_.initContext(type);
  1075             } catch (RemoteException e) {
  1076                 e.printStackTrace();
  1077             }
  1078             break;
  1079         }
  1080 
  1081         System.out.println("current context:" + current_context);
  1082 
  1083         if (current_context == null)
  1084             return new ContextUnknown();
  1085         else
  1086             return current_context;
  1087     }
  1088 
  1089     /*
  1090      * (non-Javadoc)
  1091      * 
  1092      * @see isac.wsdialog.IContextProvider#refineContext(isac.util.formulae.Context)
  1093      */
  1094     public Context refineContext(Context context) {
  1095 
  1096         Context current_context = null;
  1097 
  1098         try {
  1099             current_context = context_formula_.refineProblem(context);
  1100         } catch (RemoteException e) {
  1101             e.printStackTrace();
  1102         }
  1103 
  1104         if (current_context == null)
  1105             return new ContextUnknown();
  1106         else
  1107             return current_context;
  1108     }
  1109 
  1110     public void setContext(Context context) {
  1111         CalcHead ch = null;
  1112 
  1113         try {
  1114             if (context instanceof ContextTheory) {
  1115                 System.out.println("In WSDialog::setContext() : Theory");
  1116                 context_formula_.setContext((ContextTheory) context);
  1117                 return;
  1118             } else if (context instanceof ContextMethod) {
  1119                 System.out.println("In WSDialog::setContext() : Method");
  1120                 ch = context_formula_.setContext((ContextMethod) context);
  1121             } else if (context instanceof ContextProblem) {
  1122                 System.out.println("In WSDialog::setContext() : Problem");
  1123                 ch = context_formula_.setContext((ContextProblem) context);
  1124             } else {
  1125                 System.out
  1126                         .println("Can not set this context (Basis class, ContextExample or ContextUnknown)");
  1127                 return;
  1128             }
  1129 
  1130             if (ch != null) {
  1131                 doUIAction(new UIActionOnCalcElement(
  1132                         EUIElement.UI_SPECIFY_CHECK_CALCHEAD,
  1133                         EUIContext.UI_CONTEXT_CALCHEAD, user_language_, ch));
  1134             }
  1135 
  1136         } catch (RemoteException e) {
  1137             e.printStackTrace();
  1138         }
  1139 
  1140         return;
  1141     }
  1142 
  1143     /*
  1144      * (non-Javadoc)
  1145      * 
  1146      * @see isac.wsdialog.IContextProvider#checkContext(isac.util.formulae.Context)
  1147      */
  1148     public Context checkContext(Context context) {
  1149         Context current_context = null;
  1150 
  1151         try {
  1152             current_context = context_formula_.checkContext(context);
  1153         } catch (RemoteException e) {
  1154             e.printStackTrace();
  1155         }
  1156 
  1157         if (current_context == null)
  1158             return new ContextUnknown();
  1159         else
  1160             return current_context;
  1161     }
  1162 
  1163     /**
  1164      * @see isac.wsdialog.IContextProvider#getWorksheetState()
  1165      */
  1166     public WorksheetState getWorksheetState() {
  1167         // try {
  1168         // WorksheetState wsstate = new WorksheetState(
  1169         // context_formula_.onCalcHead() );
  1170         // return wsstate;
  1171         // } catch (RemoteException e) {
  1172         // e.printStackTrace();
  1173         // }
  1174 
  1175         return new WorksheetState(phase_ == DIALOGPHASE_SPECIFY);
  1176     }
  1177 
  1178 }