1 package fr.ove.openmath.mathematica;
2
3 import javax.swing.*;
4 import java.awt.*;
5 import java.util.*;
6 import java.io.*;
7 import fr.ove.openmath.mathematica.*;
8 import fr.ove.openmath.mathematica.events.*;
9 import fr.ove.utils.*;
10
11 /***
12 *
13 */
14 public class OMWorkSheet extends WorkSheet implements PanelJomesListener, Savable, Runnable {
15 /***
16 * The current element in the work sheet
17 */
18 private PanelJomes current;
19
20 /***
21 * The list of elements in the work sheet
22 */
23 private Vector listElements = new Vector();
24
25 /***
26 * The work book for the frame contaninng the instance.
27 */
28 private WorkBook workbook;
29
30 /***
31 * Indicates if the instance need to be saved.
32 */
33 private boolean needed = true;
34
35 /***
36 * The connection factory
37 */
38 private Connection connection;
39
40 /***
41 * The result reader.
42 */
43 private ResponseReader reader = new ResponseReader();
44
45 /***
46 * The claculation queue
47 */
48 private fr.ove.utils.Queue calculations = new fr.ove.utils.Queue();
49
50 /***
51 * The constructor.
52 */
53 public OMWorkSheet(WorkBook workbook, ConnectionFactory factory) {
54 super();
55 this.workbook = workbook;
56
57 connection = factory.createConnection();
58 try {
59 connection.open();
60 }
61 catch (IOException ioe) {
62 String errorMsg = "failed to open a connection to [" +
63 connection.getHostName() + ", " + connection.getPortNumber() +
64 "]";
65 JOptionPane jop = new JOptionPane(errorMsg, JOptionPane.ERROR_MESSAGE);
66 JDialog dialog = jop.createDialog(workbook, "Connection Failed");
67 dialog.show();
68 }
69
70 addNewElement();
71
72 Thread t = new Thread(this);
73 t.start();
74 }
75
76 /***
77 * Adds a new element to the work sheet.
78 */
79 public void addNewElement() {
80 if (current != null)
81 current.setSelected(false);
82
83 current = new PanelJomes();
84 current.addPanelJomesListener(this);
85 listElements.addElement(current);
86 add(current);
87 needed = true;
88 }
89
90 /***
91 * Inserts a new element.
92 */
93 public void insertNewElement() {
94 int indexCurrent = -1;
95
96 if (current != null) {
97 current.setSelected(false);
98 indexCurrent = listElements.indexOf(current);
99 }
100
101 current = new PanelJomes();
102 current.addPanelJomesListener(this);
103 if (indexCurrent != -1) {
104 listElements.insertElementAt(current, indexCurrent);
105 add(current, indexCurrent);
106 }
107 else {
108 listElements.addElement(current);
109 add(current);
110 }
111
112 needed = true;
113
114 workbook.fireStateChanged();
115 validate();
116 repaint();
117 }
118
119 /***
120 * Removes the specified component from the instance.
121 * @param comp the component to remove
122 */
123 public void remove(Component comp) {
124 super.remove(comp);
125 listElements.removeElement(comp);
126 needed = true;
127 }
128
129 /***
130 * Removes the component at the specified index from the instance.
131 * @param index the index of the component to remove
132 */
133 public void remove(int index) {
134 super.remove(index);
135 listElements.removeElementAt(index);
136 needed = true;
137 }
138
139 /***
140 * Removes all the components from the instance
141 */
142 public void removeAll() {
143 super.removeAll();
144 listElements.setSize(0);
145 needed = true;
146 }
147
148 /***
149 * Remove the current element in the worksheet
150 */
151 public void removeCurrent() {
152
153 int index = listElements.indexOf(current);
154 remove(current);
155 int nbElements = listElements.size();
156 if (nbElements > 0) {
157 index = (index >= nbElements) ? nbElements - 1 : index;
158 current = (PanelJomes) listElements.elementAt(index);
159 current.setSelected(true);
160 }
161 else
162 addNewElement();
163
164 workbook.fireStateChanged();
165 validate();
166 repaint();
167 }
168
169 /***
170 * Initializes the work sheet, i.e. removes all the existing elements and
171 * and put an empty one.
172 */
173 public void initialize() {
174 super.removeAll();
175 listElements.setSize(0);
176 addNewElement();
177 workbook.fireStateChanged();
178 validate();
179 repaint();
180 }
181
182 /***
183 * Returns the current element in the worksheet
184 */
185 public PanelJomes getCurrentElement() {
186 return current;
187 }
188
189 /***
190 * Returns the preferred size.
191 */
192 public Dimension getPreferredSize() {
193 return new Dimension(450, 300);
194 }
195
196 /***
197 * Returns the connection.
198 */
199 public Connection getConnection() {
200 return connection;
201 }
202
203 /***
204 * Runs the current request
205 */
206 public void runCurrentRequest() {
207
208 calculations.enqueue(current);
209 }
210
211 /***
212 * Runs the work sheet.
213 */
214 public void runWorkSheet() {
215
216
217
218
219
220
221
222
223
224 Thread t = new Thread(
225 new Runnable() {
226 public void run() {
227 PanelJomes pj;
228 for (Enumeration e = listElements.elements(); e.hasMoreElements(); ) {
229 pj = (PanelJomes) e.nextElement();
230 if (!OMWorkSheet.this.run(pj))
231 return;
232
233 try {
234 Thread.sleep(100);
235 }
236 catch (Exception exc) {
237 }
238 }
239 }
240 }
241 );
242 t.start();
243
244 }
245
246 /***
247 * Runs the specified element.
248 * @param element the element to run.
249 * @return <CODE>true</CODE> if run succeeds. <CODE>false</CODE> otherwise.
250 */
251 private boolean run(PanelJomes element) {
252 String request = element.getOpenMathRequest();
253 if (connection.isOpened() && !request.equals("")) {
254 try {
255 connection.getOutputStream().write(request.getBytes());
256 String response = reader.read(connection.getInputStream());
257 if (response != null) {
258 element.setOpenMathResult(response);
259 return true;
260 }
261
262 return false;
263 }
264 catch (IOException ioe) {
265 String errorMsg = "Failed to execute calculation : I/O Problems encountered";
266 JOptionPane jop = new JOptionPane(errorMsg, JOptionPane.ERROR_MESSAGE);
267 JDialog dialog = jop.createDialog(workbook, "Caculation Failed : I/O Problems");
268 dialog.show();
269 return false;
270 }
271 }
272 else
273 return false;
274 }
275
276
277
278
279 /***
280 * Consumes (i.e. treats) the event received.
281 * @param panelJomesEvent the event to consume.
282 */
283 public void consumePanelJomesEvent(PanelJomesEvent panelJomesEvent) {
284 int action = panelJomesEvent.getAction();
285 switch (action) {
286 case PanelJomesEvent.UPDATE_REQUEST :
287 case PanelJomesEvent.UPDATE :
288 needed = true;
289 workbook.fireStateChanged();
290 break;
291 case PanelJomesEvent.UPDATE_RESULT :
292 needed = true;
293 workbook.fireStateChanged();
294 break;
295 case PanelJomesEvent.UPDATE_SELECTION :
296 current = (PanelJomes) panelJomesEvent.getSource();
297
298 for (Enumeration e = listElements.elements(); e.hasMoreElements(); )
299 ((PanelJomes) e.nextElement()).setSelected(false);
300
301 current.setSelected(true);
302 workbook.fireStateChanged();
303 repaint();
304 }
305 }
306
307
308
309 /***
310 * Saves the instance.
311 * @returns the result of the save action. Should be <CODE>null</CODE> if nothing
312 * is expected after the save operation. The saved object otherwise.
313 * The instance is saved as the concatenation of all the OpenMath object request contained.
314 */
315 public Object save() {
316 StringBuffer buffer = new StringBuffer();
317 for (Enumeration e = listElements.elements(); e.hasMoreElements(); )
318 buffer.append(((PanelJomes) e.nextElement()).getOpenMathRequest() + "\n");
319
320 setSaveNeeded(false);
321
322 return buffer.toString();
323 }
324
325 /***
326 * Saves the instance into the specified file.
327 * @returns the result of the save action. Should be <CODE>null</CODE> if nothing
328 * is expected after the save operation. The saved object otherwise.
329 */
330 public Object save(File file) {
331 return null;
332 }
333
334 /***
335 * Saves the instance with the specified name.
336 * @param name the specified name.
337 * @returns the result of the save action. Should be <CODE>null</CODE> if nothing
338 * is expected after the save operation. The saved object otherwise.
339 */
340 public Object saveAs(String name) {
341 return null;
342 }
343
344 /***
345 * Checks if the instance need to be saved.
346 * @return <CODE>true</CODE> if the instance need to be saved. <CODE>false</CODE> otherwise.
347 */
348 public boolean isSaveNeeded() {
349 return needed;
350 }
351
352 /***
353 * Sets if the instance need to be saved.
354 * @param needed <CODE>true</CODE> if the instance need to be saved. <CODE>false</CODE> otherwise.
355 */
356 public void setSaveNeeded(boolean needed) {
357 this.needed = needed;
358 }
359
360
361
362 /***
363 * run the thread
364 */
365 public void run() {
366 while (true) {
367 try {
368 Thread.sleep(100);
369 }
370 catch (Exception e) {
371 }
372
373 while (!calculations.isEmpty()) {
374 run((PanelJomes) calculations.dequeue());
375 }
376 }
377 }
378 }