1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package fr.ens.transcriptome.doelan;
23
24 import java.applet.Applet;
25 import java.io.File;
26 import java.io.FileNotFoundException;
27 import java.io.FileOutputStream;
28 import java.io.IOException;
29 import java.io.OutputStream;
30 import java.net.MalformedURLException;
31 import java.net.URL;
32
33 import javax.swing.JLabel;
34
35 import org.apache.log4j.Logger;
36
37 import fr.ens.transcriptome.doelan.algorithms.DoelanConfigure;
38 import fr.ens.transcriptome.doelan.algorithms.DoelanExecuteGlobalTests;
39 import fr.ens.transcriptome.doelan.algorithms.DoelanGenerateReport;
40 import fr.ens.transcriptome.doelan.algorithms.DoelanLoadGenepixData;
41 import fr.ens.transcriptome.doelan.algorithms.DoelanShowReport;
42 import fr.ens.transcriptome.doelan.data.QualityTestSuiteURL;
43 import fr.ens.transcriptome.doelan.gui.MainTabWidget;
44 import fr.ens.transcriptome.doelan.gui.ReportTabWidget;
45 import fr.ens.transcriptome.doelan.gui.StatusWidget;
46 import fr.ens.transcriptome.doelan.gui.TestSuitePanel;
47 import fr.ens.transcriptome.nividic.platform.Platform;
48 import fr.ens.transcriptome.nividic.platform.PlatformException;
49 import fr.ens.transcriptome.nividic.platform.PlatformRegistery;
50 import fr.ens.transcriptome.nividic.platform.workflow.SimpleWorkflowBuilder;
51 import fr.ens.transcriptome.nividic.platform.workflow.Workflow;
52 import fr.ens.transcriptome.nividic.platform.workflow.WorkflowElement;
53 import fr.ens.transcriptome.nividic.platform.workflow.WorkflowEvent;
54 import fr.ens.transcriptome.nividic.platform.workflow.WorkflowGraph;
55 import fr.ens.transcriptome.nividic.platform.workflow.WorkflowListener;
56 import fr.ens.transcriptome.nividic.platform.workflow.io.WorkflowIO;
57 import fr.ens.transcriptome.nividic.platform.workflow.io.WorkflowXMLIO;
58 import fr.ens.transcriptome.nividic.util.parameter.ParameterException;
59
60 /***
61 * Manage the Workflows
62 * @author Laurent Jourdren
63 */
64 public final class Core implements WorkflowListener {
65
66
67 private static Logger log = Logger.getLogger(Core.class);
68
69 /*** Singleton. */
70 private static Core core;
71
72 /*** Identifier of the load algorithm. */
73 public static final String LOAD_ALGORITHM = "DoelanLoadData";
74 /*** Identifier of the algorithm for executing global test. */
75 public static final String EXECUTE_GLOBAL_TESTS_ALGORITHM = "DoelanExecuteGlobalTests";
76 /*** Identifier of the generate report algorithm. */
77 public static final String GENERATE_REPORT_ALGORITHM = "DoelanGenerateReport";
78 /*** Identifier of the show report algorithm. */
79 public static final String SHOW_REPORT_ALGORITHM = "DoelanShowReport";
80 /*** Identifier of the show report algorithm. */
81 public static final String CONFIGURE_ALGORITHM = "DoelanConfigure";
82
83 private static final int NUMBER_OF_DOELAN_ALGORITHM = 4;
84
85 private String testSuiteName;
86 private int countAlgorithm;
87 private Workflow workflow;
88 private MainTabWidget mainTab;
89 private TestSuitePanel table;
90 private ReportTabWidget report;
91 private StatusWidget status;
92 private Applet applet;
93 private JLabel statusBar;
94 private URL testSuiteListURL;
95
96
97
98
99
100 /***
101 * Get the table.
102 * @return Returns the table
103 */
104 public TestSuitePanel getTable() {
105 return table;
106 }
107
108 /***
109 * Get the workflow
110 * @return Returns the workflow
111 */
112 private Workflow getWorkflow() {
113 return workflow;
114 }
115
116 /***
117 * Test if a suite is load in memory.
118 * @return true if a suite is load in memory
119 */
120 public boolean isSuite() {
121 return this.workflow != null;
122 }
123
124 /***
125 * Get the report widget
126 * @return Returns the editor
127 */
128 public ReportTabWidget getReport() {
129 return report;
130 }
131
132 /***
133 * Set the report widget.
134 * @param report The repory to set
135 */
136 public void setReport(final ReportTabWidget report) {
137 if (report != null)
138 this.report = report;
139 }
140
141 /***
142 * Test if the applet is enable.
143 * @return Returns the appletMode
144 */
145 public boolean isAppletMode() {
146 return this.applet != null;
147 }
148
149 /***
150 * Get the applet.
151 * @return Returns the applet
152 */
153 public Applet getApplet() {
154 return applet;
155 }
156
157 /***
158 * Get the status widget.
159 * @return Returns the status
160 */
161 public StatusWidget getStatus() {
162 return status;
163 }
164
165 /***
166 * Get the test suite name.
167 * @return Returns the testSuiteName
168 */
169 private String getTestSuiteName() {
170 return testSuiteName;
171 }
172
173 /***
174 * Get the status bar object.
175 * @return Returns the statusBar
176 */
177 public JLabel getStatusBar() {
178 return statusBar;
179 }
180
181 /***
182 * Get the URL of the test suite list.
183 * @return Returns the testSuiteListURL
184 */
185 public URL getTestSuiteListURL() {
186 return testSuiteListURL;
187 }
188
189 /***
190 * Get the main tab widget.
191 * @return Returns the mainTab
192 */
193 public MainTabWidget getMainTab() {
194 return mainTab;
195 }
196
197
198
199
200
201 /***
202 * Set the table.
203 * @param table The table to set
204 */
205 public void setTable(final TestSuitePanel table) {
206 this.table = table;
207 }
208
209 /***
210 * Set the workflow
211 * @param workflow The workflow to set
212 */
213 private void setWorkflow(final Workflow workflow) {
214 this.workflow = workflow;
215 }
216
217 /***
218 * Set the applet.
219 * @param applet The applet to set
220 */
221 public void setApplet(final Applet applet) {
222 this.applet = applet;
223 }
224
225 /***
226 * Set the status widget.
227 * @param status The status to set
228 */
229 public void setStatus(final StatusWidget status) {
230 this.status = status;
231 }
232
233 /***
234 * Set the test suite name.
235 * @param testSuiteName The testSuiteName to set
236 */
237 private void setTestSuiteName(final String testSuiteName) {
238 this.testSuiteName = testSuiteName;
239 }
240
241 /***
242 * Set the status bar object.
243 * @param statusBar The statusBar to set
244 */
245 public void setStatusBar(final JLabel statusBar) {
246 this.statusBar = statusBar;
247 }
248
249 /***
250 * Set the URL of the test suite list.
251 * @param testSuiteListURL The testSuiteListURL to set
252 */
253 public void setTestSuiteListURL(final URL testSuiteListURL) {
254 this.testSuiteListURL = testSuiteListURL;
255 }
256
257 /***
258 * Set the main tab widget
259 * @param mainTab The mainTab to set
260 */
261 public void setMainTab(final MainTabWidget mainTab) {
262 this.mainTab = mainTab;
263 }
264
265
266
267
268
269
270
271
272
273 /***
274 * Load an new workflow
275 * @param url url of the testsuite to load
276 * @throws DoelanException if error occurs while the initialization of the
277 * test suite.
278 */
279 public void loadNewWorkflow(final QualityTestSuiteURL url)
280 throws DoelanException {
281
282 if (url == null)
283 throw new DoelanException("Url is null");
284
285 log.info("Load workflow : " + url.getURL());
286
287 if (url.getURL() == null) {
288 createEmptyWorkflow();
289 saveWorkflow(url);
290 } else
291 loadWorkflow(url);
292 getTable().setUrl(url);
293 activateWorflow();
294
295 }
296
297 /***
298 * Save a workflow.
299 * @param url of the testsuite to save
300 * @throws DoelanException if error occurs while saving workflow
301 */
302 public void saveWorkflow(final QualityTestSuiteURL url)
303 throws DoelanException {
304
305 if (url == null)
306 return;
307
308 if (url.getURL() == null) {
309 File f = new File(PlatformRegistery.getConfDirectory() + File.separator
310 + System.currentTimeMillis() + ".rwf");
311 try {
312 url.setURL(f.toURL());
313 } catch (MalformedURLException e) {
314 log.error("invalid URL :" + e.getMessage());
315 }
316 }
317
318 try {
319 OutputStream os = new FileOutputStream(url.getURL().getFile());
320 WorkflowIO wfio = new WorkflowXMLIO(os);
321 wfio.write(getWorkflow());
322 log.info("save workflow url=" + url.getURL().getFile());
323 } catch (FileNotFoundException e) {
324 throw new DoelanException("Error while writing the file : "
325 + e.getMessage());
326 } catch (PlatformException e) {
327 throw new DoelanException("Error while writing the file : "
328 + e.getMessage());
329 }
330
331 }
332
333 /***
334 * Create and activate the demo test suite.
335 * @throws DoelanException if an error occurs while the initialization of the
336 * test suite.
337 */
338 public void createDemoWorkflow() throws DoelanException {
339
340 SimpleWorkflowBuilder swb = new SimpleWorkflowBuilder();
341 Workflow w = swb.addElement("DoelanLoadData", LOAD_ALGORITHM).addElement(
342 "EmptySpotTest", "algo1").addElement("SpotDiameterTest", "algo2")
343 .addElement(EXECUTE_GLOBAL_TESTS_ALGORITHM,
344 EXECUTE_GLOBAL_TESTS_ALGORITHM).addElement(
345 GENERATE_REPORT_ALGORITHM, GENERATE_REPORT_ALGORITHM).addElement(
346 SHOW_REPORT_ALGORITHM, SHOW_REPORT_ALGORITHM).getWorkflow();
347
348 try {
349 w.getElement("algo1").getParameters().setParameter("threshold", "10");
350
351 w.getElement("algo1").getParameters().setParameter("quorum", "10");
352
353 w.getElement("algo2").getParameters().setParameter("min", "10");
354 w.getElement("algo2").getParameters().setParameter("max", "50");
355 w.getElement("algo2").getParameters().setParameter("quorum", "10");
356
357 } catch (ParameterException e) {
358 throw new DoelanException("Unable to set parameters");
359 }
360
361 setWorkflow(w);
362 }
363
364 /***
365 * Create and activate the empty test suite.
366 * @throws DoelanException if an error occurs while the initialization of the
367 * test suite.
368 */
369 public void createEmptyWorkflow() throws DoelanException {
370
371 SimpleWorkflowBuilder swb = new SimpleWorkflowBuilder();
372 Workflow w = swb.addElement(LOAD_ALGORITHM, LOAD_ALGORITHM).addElement(
373 CONFIGURE_ALGORITHM, CONFIGURE_ALGORITHM).addElement(
374 EXECUTE_GLOBAL_TESTS_ALGORITHM, EXECUTE_GLOBAL_TESTS_ALGORITHM)
375 .addElement(GENERATE_REPORT_ALGORITHM, GENERATE_REPORT_ALGORITHM)
376 .addElement(SHOW_REPORT_ALGORITHM, SHOW_REPORT_ALGORITHM).getWorkflow();
377
378 w.setType(Defaults.DOELAN_WORKFLOW_TYPE);
379 w.setGenerator(DoelanRegistery.getAppName() + " "
380 + DoelanRegistery.getAppVersion());
381
382
383 w.getAnnotations().setProperty(
384 Defaults.DOELAN_WORKFLOW_VERSION_ANNOTATION_KEY,
385 Defaults.DOELAN_WORKFLOW_VERSION);
386
387
388
389
390
391
392
393
394 setWorkflow(w);
395 }
396
397 /***
398 * Load a workflow
399 * @param url Location of the test suite
400 * @throws DoelanException if an error occurs while reading the test suite
401 */
402 private void loadWorkflow(final QualityTestSuiteURL url)
403 throws DoelanException {
404
405 if (url == null || url.getURL() == null)
406 throw new DoelanException("Url is null");
407
408 try {
409 WorkflowIO wfio = new WorkflowXMLIO(url.getURL().openStream());
410
411 Workflow w = wfio.read();
412 setWorkflow(w);
413 setTestSuiteName(url.getName());
414
415 } catch (FileNotFoundException e) {
416 throw new DoelanException("Test suite file not found");
417 } catch (IOException e) {
418 throw new DoelanException("IO error while reading the test suite");
419 } catch (PlatformException e) {
420 throw new DoelanException("IO error while reading the test suite");
421 }
422 }
423
424 /***
425 * Test if a workflow is a valid testsuite.
426 * @param workflow Workflow to test
427 * @return true if the workflow is a valid workflow
428 */
429 private boolean isValidTestSuite(final Workflow workflow) {
430
431 if (workflow == null)
432 return false;
433
434 if (workflow.getType() == null
435 || !workflow.getType().equals(Defaults.DOELAN_WORKFLOW_TYPE)) {
436 log.error("Invalid test suite: Not a doelan workflow type");
437 return false;
438 }
439
440 WorkflowElement wfeLoad = workflow.getRootElement();
441
442
443 if (wfeLoad == null || wfeLoad.getAlgorithm() == null
444 || !(wfeLoad.getAlgorithm() instanceof DoelanLoadGenepixData)
445 || !wfeLoad.getId().equals(LOAD_ALGORITHM)) {
446 log
447 .error("Invalid test suite: load data algorithmn isn't the first element");
448 return false;
449 }
450
451 WorkflowElement wfeConfigure = wfeLoad.getNextElements()[0];
452 if (!(wfeConfigure.getAlgorithm() instanceof DoelanConfigure)
453 || !wfeConfigure.getId().equals(CONFIGURE_ALGORITHM)) {
454 log
455 .error("Invalid test suite: configure algorithm isn't the sedond element");
456 return false;
457 }
458
459
460 WorkflowElement[] endElements = new WorkflowGraph(workflow)
461 .getEndElementsOfTheGraph();
462
463 if (endElements == null || endElements.length != 1) {
464 log.error("Invalid test suite: no end element");
465 return false;
466 }
467
468 WorkflowElement wfeShowReport = endElements[0];
469 if (!(wfeShowReport.getAlgorithm() instanceof DoelanShowReport)
470 || !wfeShowReport.getId().equals(SHOW_REPORT_ALGORITHM)) {
471 log.error("Invalid test suite: show report isn't the last element");
472 return false;
473 }
474
475 WorkflowElement wfeGenerateReport = wfeShowReport.getPreviousElements()[0];
476 if (!(wfeGenerateReport.getAlgorithm() instanceof DoelanGenerateReport)
477 || !wfeGenerateReport.getId().equals(GENERATE_REPORT_ALGORITHM)) {
478 log.error("Invalid test suite: generate report isn't the n-1 element");
479 return false;
480 }
481
482 WorkflowElement wfeExecuteGlobalTests = wfeGenerateReport
483 .getPreviousElements()[0];
484 if (!(wfeExecuteGlobalTests.getAlgorithm() instanceof DoelanExecuteGlobalTests)
485 || !wfeExecuteGlobalTests.getId()
486 .equals(EXECUTE_GLOBAL_TESTS_ALGORITHM)) {
487 log
488 .error("Invalid test suite: execute global tests isn't the n-2 element");
489 return false;
490 }
491
492 return true;
493 }
494
495 /***
496 * Activate the test suite.
497 * @throws DoelanException if an error occurs while activate the workflow
498 */
499 private void activateWorflow() throws DoelanException {
500
501 final Workflow w = getWorkflow();
502
503 if (w == null)
504 return;
505
506 try {
507
508 w.activate();
509
510 if (!isValidTestSuite(w))
511 throw new DoelanException("invalid test suite");
512
513 WorkflowElement wfeLoad = workflow.getRootElement();
514 WorkflowElement wfeShowReport = new WorkflowGraph(workflow)
515 .getEndElementsOfTheGraph()[0];
516
517
518 if (isAppletMode()) {
519 DoelanLoadGenepixData mlgd = (DoelanLoadGenepixData) wfeLoad
520 .getAlgorithm();
521 mlgd.setApplet(getApplet());
522 }
523
524
525 DoelanShowReport mr = (DoelanShowReport) wfeShowReport.getAlgorithm();
526 mr.setReport(getReport());
527 mr.setStatus(getStatus());
528
529
530 getTable().getModel().setWorkflow(w);
531
532 } catch (PlatformException e) {
533 throw new DoelanException("Error while activate the test suite: "
534 + e.getMessage());
535 }
536
537 }
538
539 /***
540 * Start the workflow.
541 * @param chipTypeName Name of the selected chipType
542 * @param testSuiteName Name of the selected testSuite
543 * @param gprFilename Filename of the GPR data
544 * @param galFilename Filename of the GAL data
545 * @param description Description of the file
546 * @param applet applet used to load data
547 * @param listener workflow listener
548 * @throws DoelanException if an error occurs during the workflow
549 */
550 public void startWorkflow(final String chipTypeName,
551 final String testSuiteName, final String gprFilename,
552 final String galFilename, final String description, final Applet applet,
553 final WorkflowListener listener) throws DoelanException {
554
555 System.gc();
556
557
558 if (getWorkflow() != null) {
559
560 if (getWorkflow().size() < NUMBER_OF_DOELAN_ALGORITHM) {
561 throw new DoelanException("Warning: Your test suite contains no test.");
562 }
563
564
565 WorkflowElement wfe = getWorkflow().getRootElement();
566
567 try {
568
569 wfe.getParameters().setParameter("chipTypeName", chipTypeName);
570 wfe.getParameters().setParameter("testSuiteName", testSuiteName);
571 wfe.getParameters().setParameter("gprFilename",
572 gprFilename == null ? "" : gprFilename);
573 wfe.getParameters().setParameter("galFilename",
574 galFilename == null ? "" : galFilename);
575 wfe.getParameters().setParameter("description", description);
576 wfe.getParameters().setParameter("loadFromApplet",
577 applet == null ? "false" : "true");
578
579 } catch (ParameterException e) {
580 throw new DoelanException("Invalid parameters ; " + e.getMessage());
581 }
582
583
584 getReport().clear();
585 getTable().clearResults();
586
587
588 this.countAlgorithm = 0;
589
590 getWorkflow().addListener(listener);
591 getWorkflow().addListener(this);
592 setTestSuiteName(testSuiteName);
593 showProgressWorkflow();
594
595 new Thread(getWorkflow()).start();
596
597 }
598 }
599
600 /***
601 * Stop the workflow.
602 * @throws PlatformException if the workflow is not running
603 */
604 public void stopWorkflow() throws PlatformException {
605 getWorkflow().stop();
606 }
607
608
609
610
611
612 /***
613 * Throws an execption to a listener.
614 * @param e Exception to throw.
615 */
616 public void workflowNewException(final PlatformException e) {
617 }
618
619 /***
620 * Invoked when the target of the listener has changed its state.
621 * @param event a WorkflowEvent object
622 */
623 public void workflowStateChanged(final WorkflowEvent event) {
624
625 if (event == null)
626 return;
627
628 if (event.getId() == WorkflowEvent.END_ALGORITHM_EVENT)
629 showProgressWorkflow();
630
631 }
632
633 /***
634 * Show the progression of the workflow in the statusbar.
635 */
636 private void showProgressWorkflow() {
637
638 if (getStatusBar() == null)
639 return;
640
641 String msg = getTestSuiteName();
642
643
644
645
646
647 if (countAlgorithm == getWorkflow().size()) {
648 msg = msg + " - done";
649 this.countAlgorithm = 0;
650 } else {
651
652 int percent = (int) ((double) countAlgorithm
653 / (double) getWorkflow().size() * 100);
654 msg = msg + " - " + percent + "% done";
655 this.countAlgorithm++;
656 }
657
658 getStatusBar().setText(msg);
659 }
660
661 /***
662 * Return the unique instance of the Core object
663 * @return The instance of the core object
664 */
665 public static Core getCore() {
666
667 if (core == null)
668 core = new Core();
669 return core;
670 }
671
672
673
674
675
676 /***
677 * Private constructor.
678 */
679 private Core() {
680
681
682 Platform.start(Defaults.INTERNALS_MODULES, new String[] {PlatformRegistery
683 .getPluginsDirectory()});
684
685 }
686
687 }