src/java/isac/wsdialog/DialogGuide.java
author akirchst
Fri, 24 Sep 2004 10:23:21 +0200
changeset 1871 e27c218ae459
parent 1815 edd5e07b3c34
child 1877 22e5390b6728
permissions -rw-r--r--
remote iterator
     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 /* TODO:
    17  * 
    18  * * recognize CalcHead in Changed Formula -> switch to DILAOGPAHSE_SPECIFY_SUBPROBLEM
    19  * * differentiate CalcHeads 
    20  * 
    21  *
    22  */
    23 
    24 /**
    25  * The DialogGuide moderates the communication between two instances working on
    26  * the same CalcTree object. One of these instances is the user, the other a
    27  * math engine. Most probably, the user's GUI, the DialogGuide and the math
    28  * engine reside on different machines and communicate with each other by means
    29  * of RMI.
    30  * 
    31  * @author Alan Krempler
    32  */
    33 public class DialogGuide extends UnicastRemoteObject implements DGuide,
    34 		IToUser, Serializable {
    35 
    36 	protected CalcTree calc_tree_;
    37 
    38 	protected CalcHead calc_head_;
    39 
    40 	protected CalcHead calc_head_sub_;
    41 
    42 	protected MathEngine math_engine_;
    43 
    44 	protected int phase_;
    45 
    46 	private Vector datachange_listeners_;
    47 
    48 	private IToWorksheet ui_control_listener_;
    49 
    50 	/**
    51 	 * @param ME_path
    52 	 *            URL of the math engine to be used
    53 	 * @throws RemoteException
    54 	 */
    55 	public DialogGuide(String ME_path) throws RemoteException {
    56 		super();
    57 		this.rmiBind();
    58 		datachange_listeners_ = new Vector();
    59 		MathEngine.init(ME_path);
    60 		math_engine_ = MathEngine.getMathEngine();
    61 		phase_ = DIALOGPHASE_IDLE;
    62 
    63 	}
    64 
    65 	/**
    66 	 * at the beginning of a calculation as well as of a subproblem
    67 	 * 
    68 	 * @param calc_head
    69 	 *            empty (formalization stored invisibly in the calcTree)
    70 	 * @return calc_head with viestyle set
    71 	 */
    72 	// FIXME.WN040906 do NOT return calc_head, like Formula in solve-phase
    73 	// and like trymatch etc. see below
    74 	CalcHead startSpecifying(CalcHead calc_head) {
    75 
    76 		//  WN040825 if (start_from == STARTFROM_EXAMPLE) { <---startSpecifying ?
    77 
    78 		int calchead_view = CalcHead.VIEWSTYLE_SINGLELINE;
    79 		//WN040824 VIEWSTYLE_IN_CALC depends on UserModel
    80 		//WN040824 VIEWSTYLE_IN_CALC is appropriate for equations, not for
    81 		// maximumexpl
    82 		//WN040825 appropriate for pbl-class [univatiate,equation]
    83 		//WN040825 NOT -"- for maximum-expl
    84 		calc_head.setCalcHeadStatus(calchead_view);
    85 		math_engine_.completeCalcHead(calc_head);
    86 
    87 		phase_ = DIALOGPHASE_SPECIFY;
    88 		return calc_head; //WN040906 this is NOT completed !!!
    89 		// FIXME.WN040906 do NOT return calc_head, like Formula in solve-phase
    90 	}
    91 
    92 	// FIXME.WN040906 do NOT return calc_head, like Formula in solve-phase
    93 	public CalcHead startCalculation(int user_id, Formalization f,
    94 			int start_from, int requested_calchead_view) {
    95 
    96 		calc_head_ = math_engine_.startCalculation(f);
    97 
    98 		// for the moment, all requests for a view are honored
    99 		//  WN040825 calc_head_.setViewStyle(requested_calchead_view);
   100 		// --->startSpecifying
   101 
   102 		// for testing purposes: if starting an example from the collection,
   103 		// have everything filled in by the KI
   104 		//  WN040825 if (start_from == STARTFROM_EXAMPLE) { --->startSpecifying ?
   105 
   106 		// old-style filling the fields of the calc-head by setting
   107 		// the HELP_ME flag
   108 		// calc_head_.setCalcHeadStatus(CalcHead.CALCHEAD_HELP_ME);
   109 		// }
   110 
   111 		// test code; this protocol is now controlled by the presentation layer
   112 		// do {
   113 		// checkCalcHead()
   114 		// } while (false); // status != ok
   115 		// newCalculation(calc_head_);
   116 		//WN040825 phase_ = DIALOGPHASE_SPECIFY; --->startSpecifying
   117 		//WN040825 return calc_head_;
   118 		return startSpecifying(calc_head_);
   119 	}
   120 
   121 	public void newCalculation(CalcHead calcHead) {
   122 		try {
   123 			calc_tree_ = math_engine_.startSolving(calcHead);
   124 		} catch (Exception e) {
   125 			// TODO Auto-generated catch block
   126 			e.printStackTrace();
   127 		}
   128 		// calc_tree_ = MathEngine.getMathEngine().startSolving(calcHead);
   129 		calc_tree_.addDataChangeListener(this);
   130 		phase_ = DIALOGPHASE_SOLVE;
   131 	}
   132 
   133 	/*
   134 	 * (non-Javadoc)
   135 	 * 
   136 	 * @see isac.wsdialog.IToUser#calcChanged(isac.wsdialog.CalcChangedEvent)
   137 	 */
   138 	public void calcChanged(CalcChangedEvent event) {
   139 
   140 		ICalcElement calc_elem;
   141 
   142 		for (int i = 0; i < datachange_listeners_.size(); i++) {
   143 			((IToUser) datachange_listeners_.elementAt(i)).calcChanged(event);
   144 		}
   145 		ICalcIterator last_formula = event.getFirstChangedFormula();
   146 		// while searching for last formula, mark intermediate CalcHeads as not
   147 		// to be edited
   148     try {
   149 		while (!last_formula.isLast()) {
   150 			if (last_formula.getElement().getType() == ICalcElement.CALCEL_CALCHEAD) {
   151 				last_formula.getElement().setViewStyle(
   152 						CalcHead.VIEWSTYLE_IN_CALC);
   153 			}
   154 			last_formula.moveDown();
   155 			//TODO last_formula.moveDown.. WN040824 DG may limit the level down
   156 		}
   157 
   158 		// for now, do not specify the CalcHead, just display it.
   159 		calc_elem = last_formula.getElement();
   160 
   161 		if (calc_elem.getType() == ICalcElement.CALCEL_CALCHEAD) {
   162 			//WN040826 phase_ = DIALOGPHASE_SPECIFY; --->startSpecifying
   163 			//WN040826
   164 			// calc_elem.setViewStyle(CalcHead.VIEWSTYLE_SINGLELINE);--->startSpecifying
   165 
   166 			//WN040826calc_head = startSpecifying((CalcHead) calc_elem);
   167 			// --->startSpecifying
   168 			startSpecifying((CalcHead) calc_elem);
   169 			//WN040826 math_engine_.completeCalcHead(calc_head);
   170 			// --->startSpecifying
   171 		} else {
   172 			phase_ = DIALOGPHASE_SOLVE;
   173 		}
   174     } catch (Exception e) {
   175       e.printStackTrace();
   176     }
   177 	}
   178 
   179 	/**
   180 	 * @deprecated Use {@link #notifyUserAction(IUserAction)}instead
   181 	 */
   182 	public void modifyCalcHead(CalcHead calc_head) {
   183 		// MathEngine.getMathEngine().modifyCalcHead(calc_head);
   184 		math_engine_.modifyCalcHead(calc_head);
   185 	}
   186 
   187 	/*
   188 	 * (non-Javadoc)
   189 	 * 
   190 	 * @see isac.wsdialog.IToCalc#iterator()
   191 	 */
   192 	public ICalcIterator iterator() {
   193     try {
   194 		return new DialogIterator((CalcIterator) calc_tree_.iterator());
   195     } catch (Exception e){
   196       e.printStackTrace();
   197     }
   198     return null;
   199   }
   200 
   201 	/*
   202 	 * (non-Javadoc)
   203 	 * 
   204 	 * @see isac.wsdialog.IToCalc#addListener(isac.wsdialog.IToUser)
   205 	 */
   206 	public boolean addDataChangeListener(IToUser listener) {
   207 		if (datachange_listeners_.contains(listener)) {
   208 			return false;
   209 		} else {
   210 			datachange_listeners_.add(listener);
   211 		}
   212 		return true;
   213 	}
   214 
   215 	public boolean registerUIControlListener(IToWorksheet listener) {
   216 		if (ui_control_listener_ != null) {
   217 			ui_control_listener_.doUIAction(new UserAction(UI_DO_DETACH));
   218 		}
   219 		ui_control_listener_ = listener;
   220 		return true;
   221 	}
   222 
   223 	public Tactic fetchProposedTactic() {
   224 		return calc_tree_.fetchProposedTactic();
   225 	}
   226 
   227 	public Tactic[] fetchApplicableTactics(int scope) {
   228 		return calc_tree_.fetchApplicableTactics(scope);
   229 	}
   230 
   231 	/**
   232 	 * @deprecated Use {@link #notifyUserAction(IUserAction)}instead
   233 	 */
   234 	public int setNextTactic(Tactic tactic) {
   235 		return calc_tree_.setNextTactic(tactic);
   236 	}
   237 
   238 	/**
   239 	 * @deprecated Use {@link #notifyUserAction(IUserAction)}instead
   240 	 */
   241 	public int autoCalculate(int scope, int nSteps) {
   242 		return calc_tree_.autoCalculate(scope, nSteps);
   243 	}
   244 
   245 	/**
   246 	 * @deprecated Use {@link #notifyUserAction(IUserAction)}instead
   247 	 */
   248 	public void tryMatch(CalcHead ch, CalcHeadCompoundID problemID)
   249 			throws NotInSpecificationPhaseException {
   250 
   251 		// MathEngine.getMathEngine().tryMatch(ch, problemID);
   252 		math_engine_.tryMatch(ch, problemID);
   253 	}
   254 
   255 	/**
   256 	 * @deprecated Use {@link #notifyUserAction(IUserAction)}instead
   257 	 */
   258 	public void tryRefine(CalcHead ch, CalcHeadCompoundID problemID)
   259 			throws NotInSpecificationPhaseException {
   260 
   261 		// MathEngine.getMathEngine().tryRefine(ch , problemID);
   262 		math_engine_.tryRefine(ch, problemID);
   263 	}
   264 
   265 	public ICalcIterator getActiveFormula() {
   266 		return calc_tree_.getActiveFormula();
   267 	}
   268 
   269 	/**
   270 	 * @deprecated Use {@link #notifyUserAction(IUserAction)}instead
   271 	 */
   272 	public int replaceFormula(Formula newFormula) {
   273 		return calc_tree_.replaceFormula(newFormula);
   274 	}
   275 
   276 	/**
   277 	 * @deprecated Use {@link #notifyUserAction(IUserAction)}instead
   278 	 */
   279 	public int appendFormula(Formula newFormula) {
   280 		return calc_tree_.appendFormula(newFormula);
   281 	}
   282 
   283 	/**
   284 	 * @deprecated Use {@link #notifyUserAction(IUserAction)}instead
   285 	 */
   286 	public void moveActiveFormula(ICalcIterator newActiveFormula) {
   287 		calc_tree_.moveActiveFormula(newActiveFormula);
   288 	}
   289 
   290 	/**
   291 	 * Notify the Dialog Guide about interaction from the User
   292 	 * 
   293 	 * @param action
   294 	 * @return true, if the action has been processed, false if the processing
   295 	 *         the action has been denied
   296 	 *  
   297 	 */
   298 	public boolean notifyUserAction(IUserAction action)
   299 			throws DialogProtocolException {
   300 		int request = action.getActionID();
   301 
   302 		switch (phase_) {
   303 		case DIALOGPHASE_IDLE:
   304 			throw new DialogProtocolException(request, phase_);
   305 		//case DIALOGPHASE_SPECIFY: WN040826
   306 		case DIALOGPHASE_SPECIFY: //_SUBPROBLEM WN040826
   307 			if (request < UI_DUMMY_FIRST_SPECIFY
   308 					|| request > UI_DUMMY_LAST_SPECIFY)
   309 				throw new DialogProtocolException(request, phase_);
   310 			break;
   311 		case DIALOGPHASE_SOLVE:
   312 			if (request < UI_DUMMY_FIRST_SOLVE || request > UI_DUMMY_LAST_SOLVE)
   313 				throw new DialogProtocolException(request, phase_);
   314 			break;
   315 		}
   316 
   317 		switch (request) {
   318 		case UI_SPECIFY_TRY_MATCH:
   319 			try {
   320 				tryMatch(calc_head_, ((UserActionOnCalcHeadCompoundID) action)
   321 						.getObjectID());
   322 			} catch (NotInSpecificationPhaseException e) {
   323 				throw new DialogMathException(request, phase_, e);
   324 			}
   325 			break;
   326 
   327 		case UI_SPECIFY_TRY_REFINE:
   328 			try {
   329 				tryRefine(calc_head_, ((UserActionOnCalcHeadCompoundID) action)
   330 						.getObjectID());
   331 			} catch (NotInSpecificationPhaseException e) {
   332 				throw new DialogMathException(request, phase_, e);
   333 			}
   334 			break;
   335 
   336 		case UI_SPECIFY_CHANGE_VIEW:
   337 			calc_head_.setViewStyle(((UserActionOnInt) action).getInt());
   338 			break;
   339 
   340 		case UI_SPECIFY_COMPLETE_CALCHEAD:
   341 			math_engine_.completeCalcHead(calc_head_);
   342 			// old-style filling the fields of the calc-head by setting
   343 			// the HELP_ME flag
   344 			// calc_head_.setCalcHeadStatus(CalcHead.CALCHEAD_HELP_ME);
   345 			// modifyCalcHead(calc_head_);
   346 			break;
   347 
   348 		case UI_SPECIFY_COMPLETE_METHOD:
   349 		case UI_SPECIFY_COMPLETE_THEORY:
   350 		case UI_SPECIFY_COMPLETE_PROBLEM:
   351 		case UI_SPECIFY_COMPLETE_GIVEN:
   352 		case UI_SPECIFY_COMPLETE_FIND:
   353 		case UI_SPECIFY_COMPLETE_RELATE:
   354 			throw new DialogNotImplementedException(request, phase_);
   355 
   356 		case UI_SPECIFY_CHECK_CALCHEAD:
   357 			modifyCalcHead(calc_head_);
   358 			break;
   359 
   360 		// was: newCalculation()
   361 		case UI_SPECIFY_CALCULATE_1:
   362 		case UI_SPECIFY_CALCULATE_ALL:
   363 			modifyCalcHead(calc_head_);
   364 			if (calc_head_.getCalcHeadStatus() != CalcHead.CALCHEAD_CORRECT)
   365 				return false;
   366 
   367 			try {
   368 				calc_tree_ = math_engine_.startSolving(calc_head_);
   369 			} catch (Exception e) {
   370 				// TODO Auto-generated catch block
   371 				e.printStackTrace();
   372 			}
   373 			// calc_tree_ = MathEngine.getMathEngine().startSolving(calcHead);
   374 			calc_tree_.addDataChangeListener(this);
   375 			phase_ = DIALOGPHASE_SOLVE;
   376 		// fall through to calculate
   377 
   378 		case UI_SOLVE_CALCULATE_1:
   379 		case UI_SOLVE_CALCULATE_ALL:
   380 			switch (request) {
   381 			case UI_SPECIFY_CALCULATE_ALL:
   382 			case UI_SOLVE_CALCULATE_ALL:
   383 				autoCalculate(SCOPE_CALCULATION, 0);
   384 				break;
   385 			case UI_SPECIFY_CALCULATE_1:
   386 				break;
   387 			default:
   388 				autoCalculate(SCOPE_CALCULATION, 1);
   389 				break;
   390 			}
   391 			break;
   392 
   393 		case UI_SOLVE_CALCULATE_SUBPROBLEM:
   394 			autoCalculate(SCOPE_SUBPROBLEM, 0);
   395 			break;
   396 
   397 		case UI_SOLVE_EDIT_ACTIVE_FORMULA:
   398 			ui_control_listener_.doUIAction(new UserAction(UI_DO_EDIT_FORMULA));
   399 			break;
   400 
   401 		case UI_SOLVE_EDIT_ACTIVE_FORMULA_COMPLETE:
   402 			replaceFormula((Formula) ((UserActionOnCalcElement) action)
   403 					.getCalcElement());
   404 			break;
   405 
   406 		case UI_SOLVE_APPEND_USER_FORMULA:
   407 			// appendFormula((Formula) ((UserActionOnCalcElement)
   408 			// action).getCalcElement());
   409 			ui_control_listener_
   410 					.doUIAction(new UserAction(UI_DO_APPEND_FORMULA));
   411 			break;
   412 
   413 		case UI_SOLVE_MOVE_ACTIVE_FORMULA:
   414 			moveActiveFormula(((UserActionOnIterator) action).getPosition());
   415 			break;
   416 
   417 		case UI_SOLVE_GET_PROPOSED_TACTIC:
   418 			throw new DialogNotImplementedException(request, phase_);
   419 
   420 		case UI_SOLVE_GET_APPLICABLE_TACTICS:
   421 			throw new DialogNotImplementedException(request, phase_);
   422 
   423 		case UI_SOLVE_SET_NEXT_TACTIC:
   424 			setNextTactic((Tactic) ((UserActionOnCalcElement) action)
   425 					.getCalcElement());
   426 			break;
   427 
   428 		case UI_SOLVE_HELP_ENTERING_FORMULA:
   429 			throw new DialogNotImplementedException(request, phase_);
   430 
   431 		case UI_SOLVE_SHOW_ASSUMPTIONS:
   432 			throw new DialogNotImplementedException(request, phase_);
   433 
   434 		case UI_SOLVE_SHOW_DETAILS:
   435 			throw new DialogNotImplementedException(request, phase_);
   436 
   437 		default:
   438 			throw new DialogUnknownActionException(request, phase_);
   439 		}
   440 		return true;
   441 	}
   442 
   443 	private void rmiBind() {
   444 		if (System.getSecurityManager() == null) {
   445 			System.setSecurityManager(new RMISecurityManager());
   446 		}
   447 
   448 		try {
   449 			LocateRegistry.createRegistry(1099);
   450 		} catch (java.rmi.RemoteException exc2) {
   451 			System.err.println("can not create registry: " + exc2.getMessage());
   452 		}
   453 
   454 		String name = "//localhost/isac-DialogGuide";
   455 		try {
   456 			System.out.println("try to bind as " + name);
   457 			Naming.rebind(name, this);
   458 			System.out.println("Dialog Guide bound to " + name);
   459 			//WN040906      was Object Manager ...
   460 		} catch (java.rmi.ConnectException e) {
   461 			System.err.println("failed to contact as " + name
   462 					+ " (creating RMI-Server on localhost: 1099)");
   463 		} catch (RemoteException e) {
   464 			// TODO Auto-generated catch block
   465 			e.printStackTrace();
   466 		} catch (MalformedURLException e) {
   467 			// TODO Auto-generated catch block
   468 			e.printStackTrace();
   469 		}
   470 	}
   471 
   472 	public static void main(String[] args) {
   473 		try {
   474 			new DialogGuide(args[0]);
   475 		} catch (RemoteException e) {
   476 			e.printStackTrace();
   477 		}
   478 	}
   479 
   480 }