Source code: fzi/injectj/config/panel/ScriptOrderPanel.java
1 // This file is part of the Inject/J project
2 // (C) 1999-2001 Forschungszentrum Informatik (FZI) Karlsruhe
3 // Please visit our website at http://injectj.fzi.de
4
5 package fzi.injectj.config.panel;
6
7 import java.awt.*;
8 import java.awt.event.*;
9 import javax.swing.*;
10 import java.io.File;
11 import java.util.*;
12 import fzi.injectj.Main;
13 import fzi.injectj.config.*;
14 import fzi.injectj.language.*;
15 import fzi.injectj.node.ScriptDeclaration;
16 import fzi.injectj.util.StringUtil;
17
18 /** Panel to choose the execution order of parsed scripts. If user hits the
19 * "Next"-Button, the dependencies between scripts are checked.
20 *
21 * @author Volker Kuttruff
22 */
23 public class ScriptOrderPanel extends JPanel implements InjectJPanel
24 {
25
26 protected MainWindow mainWindow;
27
28 JButton nextButton = new JButton();
29 JButton helpButton = new JButton();
30 JButton prevButton = new JButton();
31 JButton addScriptButton = new JButton();
32 JButton quitButton = new JButton();
33 JScrollPane scriptListScrollPane = new JScrollPane();
34 JList scriptOrderList = new JList();
35 JLabel scriptOrderLabel = new JLabel();
36 JButton upButton = new JButton();
37 JButton downButton = new JButton();
38 JButton removeButton = new JButton();
39 JComboBox scriptChooseComboBox = new JComboBox();
40 JLabel addScriptLabel = new JLabel();
41
42 protected Vector execOrder = null;
43 protected Vector allScriptNames = new Vector();
44
45 public void newProjectCreated() {
46 if (scriptOrderList.getModel()!=null) scriptOrderList.setListData(new Object[0]);
47 if (scriptChooseComboBox.getItemCount()>0) scriptChooseComboBox.removeAllItems();
48 if (execOrder!=null) execOrder.removeAllElements();
49 if (allScriptNames!=null) allScriptNames.removeAllElements();
50 }
51
52 public ScriptOrderPanel(MainWindow mainWindow)
53 {
54 try
55 {
56 this.mainWindow = mainWindow;
57 execOrder = null;
58 jbInit();
59 }
60 catch(Exception ex)
61 {
62 ex.printStackTrace();
63 }
64 }
65
66 public ScriptOrderPanel()
67 {
68 this(null);
69 }
70
71 public void setMainWindow(MainWindow mainWindow) {
72 this.mainWindow = mainWindow;
73 }
74
75 private void jbInit() throws Exception
76 {
77 this.setLayout(null);
78 this.setPreferredSize(new Dimension(600, 400));
79
80 prevButton.setText("<<Previous");
81 prevButton.setBounds(new Rectangle(270 ,360, 100, 30));
82 prevButton.addActionListener(new java.awt.event.ActionListener()
83 {
84
85 public void actionPerformed(ActionEvent e)
86 {
87 prevButton_actionPerformed(e);
88 }
89 });
90
91 nextButton.setText("Next >>");
92 nextButton.setBounds(new Rectangle(385, 360, 100, 30));
93 nextButton.addActionListener(new java.awt.event.ActionListener()
94 {
95
96 public void actionPerformed(ActionEvent e)
97 {
98 nextButton_actionPerformed(e);
99 }
100 });
101
102 helpButton.setText("Help");
103 helpButton.setBounds(new Rectangle(500, 360, 75, 30));
104 helpButton.addActionListener(new java.awt.event.ActionListener()
105 {
106
107 public void actionPerformed(ActionEvent e)
108 {
109 helpButton_actionPerformed(e);
110 }
111 });
112
113 addScriptLabel.setText("Please choose script to add to execution order");
114 addScriptLabel.setBounds(new Rectangle(25, 285, 450, 25));
115 scriptChooseComboBox.setBounds(new Rectangle(25, 310, 425, 25));
116
117 addScriptButton.setText("Add");
118 addScriptButton.setBounds(new Rectangle(475, 310, 100, 25));
119 addScriptButton.addActionListener(new java.awt.event.ActionListener()
120 {
121
122 public void actionPerformed(ActionEvent e)
123 {
124 addScriptButton_actionPerformed(e);
125 }
126 });
127
128 scriptOrderLabel.setText("Script execution order");
129 scriptOrderLabel.setBounds(new Rectangle(25, 15, 450, 25));
130 scriptListScrollPane.setBounds(new Rectangle(25, 40, 425, 230));
131 scriptOrderList.addKeyListener(new java.awt.event.KeyListener() {
132 public void keyPressed(KeyEvent e) {}
133 public void keyTyped(KeyEvent e) {}
134 public void keyReleased(KeyEvent e) {
135 if (e.getKeyChar()=='+') {
136 downButton_actionPerformed(null);
137 }
138 if (e.getKeyChar()=='-') {
139 upButton_actionPerformed(null);
140 }
141 }
142 });
143
144 upButton.setText("Up");
145 upButton.setBounds(new Rectangle(475, 40, 100, 25));
146 upButton.addActionListener(new java.awt.event.ActionListener()
147 {
148
149 public void actionPerformed(ActionEvent e)
150 {
151 upButton_actionPerformed(e);
152 }
153 });
154 downButton.setText("Down");
155 downButton.setBounds(new Rectangle(475, 80, 100, 25));
156 downButton.addActionListener(new java.awt.event.ActionListener()
157 {
158
159 public void actionPerformed(ActionEvent e)
160 {
161 downButton_actionPerformed(e);
162 }
163 });
164
165 removeButton.setText("Remove");
166 removeButton.setBounds(new Rectangle(475, 245, 100, 25));
167 removeButton.addActionListener(new java.awt.event.ActionListener()
168 {
169
170 public void actionPerformed(ActionEvent e)
171 {
172 removeButton_actionPerformed(e);
173 }
174 });
175
176 quitButton.setText("Quit");
177 quitButton.setBounds(new Rectangle(25, 360, 150, 30));
178 quitButton.addActionListener(new java.awt.event.ActionListener()
179 {
180
181 public void actionPerformed(ActionEvent e)
182 {
183 quitButton_actionPerformed(e);
184 }
185 });
186
187 this.add(prevButton, null);
188 this.add(nextButton, null);
189 this.add(helpButton, null);
190 this.add(quitButton, null);
191 this.add(scriptListScrollPane, null);
192 this.add(addScriptButton, null);
193 this.add(scriptOrderLabel, null);
194 this.add(upButton, null);
195 this.add(downButton, null);
196 this.add(removeButton, null);
197 this.add(scriptChooseComboBox, null);
198 this.add(addScriptLabel, null);
199 scriptListScrollPane.getViewport().add(scriptOrderList, null);
200 }
201
202 /** Updates the look&feel of the given component. Subcomponents are
203 * recursively updated.
204 *
205 * @param component the component to update its look&feel
206 */
207 protected void updateComponentUI(JComponent component) {
208 component.updateUI();
209 Component[] components = component.getComponents();
210 for (int i=0; i<components.length; i++) {
211 if(components[i] instanceof JComponent) {
212 updateComponentUI((JComponent) components[i]);
213 }
214 }
215 }
216
217 /** Updates labels of all buttons */
218 protected void updateLabels() {
219 quitButton.setText(CodeMapper.getText(LabelCode.QUIT_BUTTON));
220 helpButton.setText(CodeMapper.getText(LabelCode.HELP_BUTTON));
221 prevButton.setText(CodeMapper.getText(LabelCode.PREVIOUS_BUTTON));
222 nextButton.setText(CodeMapper.getText(LabelCode.NEXT_BUTTON));
223 upButton.setText(CodeMapper.getText(LabelCode.UP_BUTTON));
224 downButton.setText(CodeMapper.getText(LabelCode.DOWN_BUTTON));
225 removeButton.setText(CodeMapper.getText(LabelCode.REMOVE_BUTTON));
226 addScriptButton.setText(CodeMapper.getText(LabelCode.ADD_BUTTON));
227 addScriptLabel.setText(CodeMapper.getText(LabelCode.ADDSCRIPTTOORDER_LABEL));
228 scriptOrderLabel.setText(CodeMapper.getText(LabelCode.ORDERLIST_LABEL));
229 }
230
231 public void updateAll() {
232 updateLabels();
233 updateComponentUI(this);
234 }
235
236 public void setWindowTitle() {
237 if(mainWindow!=null) mainWindow.setTitle(CodeMapper.getText(LabelCode.SCRIPTEXECORDER_TITLE));
238 }
239
240 public boolean panelActivated(boolean fromPreviousPanel) {
241 setWindowTitle();
242 if (fromPreviousPanel) {
243 boolean veto = updateList();
244 if (veto) return true;
245 }
246 return false;
247 }
248
249 public boolean panelDeactivated(boolean toNextPanel) {
250
251 ProjectConfig config = mainWindow.getCurrentProject();
252 if (config==null) {
253 Main.err.println("No config object available!");
254 return false;
255 }
256 config.setExecOrder(execOrder);
257 return false;
258 }
259
260 /** Updates script oder list and script combo box according to the settings
261 * of the current project.
262 *
263 * @return true, if no error occured, false otherwise
264 */
265 protected boolean updateList() {
266
267 ProjectConfig config = mainWindow.getCurrentProject();
268 if (config==null) {
269 Main.err.println("No config object available!");
270 return false;
271 }
272
273 allScriptNames.removeAllElements();
274 if (scriptChooseComboBox.getItemCount()>0) {
275 scriptChooseComboBox.removeAllItems();
276 }
277 Vector temp = config.getExecOrder();
278 if (temp!=null) execOrder = temp;
279 Enumeration scriptNameEnum = config.getScriptNameEnumeration();
280 while (scriptNameEnum.hasMoreElements()) {
281 String scriptName = (String) scriptNameEnum.nextElement();
282 ScriptDeclaration tempScript = config.getScript(scriptName);
283 if (tempScript==null) continue;
284 if (!tempScript.isInterface()) {
285 allScriptNames.addElement(scriptName);
286 scriptChooseComboBox.addItem(scriptName);
287 }
288 if (temp==null) {
289 if (execOrder==null) execOrder = new Vector();
290 if (!tempScript.isInterface()) execOrder.addElement(scriptName);
291 }
292 }
293
294 if(execOrder==null) return false;
295 scriptNameEnum = execOrder.elements();
296 while (scriptNameEnum.hasMoreElements()) {
297 String scriptName = (String) scriptNameEnum.nextElement();
298 Object tempScript = config.getScript(scriptName);
299 if (tempScript==null) execOrder.removeElement(scriptName);
300 }
301
302 scriptOrderList.setListData(execOrder);
303 return false;
304 }
305
306 void prevButton_actionPerformed(ActionEvent e)
307 {
308 mainWindow.switchToPrevious();
309 }
310
311 void nextButton_actionPerformed(ActionEvent e)
312 {
313 if (execOrder!=null && !checkScriptDependencies()) return;
314 mainWindow.switchToNext();
315 }
316
317 void upButton_actionPerformed(ActionEvent e)
318 {
319 boolean canMove = true;
320 int lastIndex = 0;
321 int indices[] = scriptOrderList.getSelectedIndices();
322 int toBeSelected[] = new int[indices.length];
323 for (int i=0; i<indices.length; i++) {
324 int index = indices[i];
325 if (index==0) {
326 canMove = false;
327 lastIndex = index;
328 toBeSelected[i] = index;
329 continue;
330 }
331 if (!canMove && ((lastIndex+1)==index) ) {
332 lastIndex = index;
333 toBeSelected[i] = index;
334 continue;
335 }
336 canMove = true;
337 Object temp = execOrder.elementAt(index-1);
338 execOrder.setElementAt(execOrder.elementAt(index), index-1);
339 execOrder.setElementAt(temp, index);
340 toBeSelected[i] = index-1;
341 }
342 scriptOrderList.setListData(execOrder);
343 scriptOrderList.setSelectedIndices(toBeSelected);
344 mainWindow.getCurrentProject().setChanged();
345 }
346
347 void downButton_actionPerformed(ActionEvent e)
348 {
349 boolean canMove = true;
350 int lastIndex = execOrder.size();
351 int indices[] = scriptOrderList.getSelectedIndices();
352 int toBeSelected[] = new int[indices.length];
353 for (int i=indices.length-1; i>=0; i--) {
354 int index = indices[i];
355 if (index>=execOrder.size()-1) {
356 canMove=false;
357 lastIndex = index;
358 toBeSelected[i] = index;
359 continue;
360 }
361 if (!canMove && ((lastIndex-1) == index)) {
362 lastIndex = index;
363 toBeSelected[i] = index;
364 continue;
365 }
366
367 canMove = true;
368 Object temp = execOrder.elementAt(index+1);
369 execOrder.setElementAt(execOrder.elementAt(index), index+1);
370 execOrder.setElementAt(temp, index);
371 toBeSelected[i] = index+1;
372 }
373
374 scriptOrderList.setListData(execOrder);
375 scriptOrderList.setSelectedIndices(toBeSelected);
376 mainWindow.getCurrentProject().setChanged();
377 }
378
379 void removeButton_actionPerformed(ActionEvent e)
380 {
381 //$$$ TODO: Warning if script is needed by another one $$$
382 Object selectedValues[] = scriptOrderList.getSelectedValues();
383 for (int i=0; i<selectedValues.length; i++) {
384 execOrder.removeElement(selectedValues[i]);
385 }
386 scriptOrderList.setListData(execOrder);
387 mainWindow.getCurrentProject().setChanged();
388 }
389
390 void addScriptButton_actionPerformed(ActionEvent e)
391 {
392 Object selectedItem = scriptChooseComboBox.getSelectedItem();
393 if (selectedItem==null) return;
394 String scriptName = selectedItem.toString();
395 if (execOrder.contains(scriptName)) return;
396 execOrder.addElement(scriptName);
397 scriptOrderList.setListData(execOrder);
398 mainWindow.getCurrentProject().setChanged();
399 }
400
401 /** Checks the dependencies between scripts.
402 *
403 * @return true, if all dependencies are okay, false otherwise
404 */
405 protected boolean checkScriptDependencies() {
406
407 ProjectConfig config = mainWindow.getCurrentProject();
408 if (config==null) {
409 Main.err.println("No config object available!");
410 return false;
411 }
412
413 Main.messages.println("Checking script dependencies...");
414
415 mainWindow.setWaitCursor();
416 Enumeration scriptNameEnumeration = execOrder.elements();
417
418 while (scriptNameEnumeration.hasMoreElements()) {
419
420 ScriptDeclaration script = config.getScript((String)scriptNameEnumeration.nextElement());
421
422 Enumeration needsEnumeration = script.getNeedsEnumeration();
423 while (needsEnumeration.hasMoreElements()) {
424 String scriptName = (String) needsEnumeration.nextElement();
425 ScriptDeclaration needsScript = config.getScript(scriptName);
426 if (needsScript==null) {
427 mainWindow.setDefaultCursor();
428 String msg = CodeMapper.getText(ErrorCode.SCRIPTNOTFOUND_TEXT);
429 String errorMessage = StringUtil.replace(msg,"%1",scriptName);
430 msg = CodeMapper.getText(ErrorCode.SCRIPTNEEDEDBY_TEXT);
431 msg = StringUtil.replace(msg,"%1",script.getName());
432 errorMessage = errorMessage + "\n"+msg;
433 String errorTitle = CodeMapper.getText(LabelCode.ERROR_LABEL);
434 MessageDialog dlg = new MessageDialog(mainWindow,errorTitle,true);
435 dlg.setMessage(errorMessage, false);
436 dlg.show();
437 return false;
438 }
439 if (needsScript.isInterface()) {
440 if (!hasImplementation(config, needsScript)) {
441 mainWindow.setDefaultCursor();
442 String msg = CodeMapper.getText(ErrorCode.NOIMPLFOUND_TEXT);
443 String errorMessage = StringUtil.replace(msg,"%1",needsScript.getName());
444 msg = CodeMapper.getText(ErrorCode.SCRIPTNEEDEDBY_TEXT);
445 msg = StringUtil.replace(msg,"%1",script.getName());
446 errorMessage = errorMessage + "\n"+msg;
447 String errorTitle = CodeMapper.getText(LabelCode.ERROR_LABEL);
448 MessageDialog dlg = new MessageDialog(mainWindow,errorTitle,true);
449 dlg.setMessage(errorMessage, false);
450 dlg.show();
451 return false;
452 }
453 }
454 }
455
456 Enumeration extendsEnumeration = script.getExtendsEnumeration();
457 while (extendsEnumeration.hasMoreElements()) {
458 String scriptName = (String) extendsEnumeration.nextElement();
459 ScriptDeclaration extendsScript = config.getScript(scriptName);
460 if (extendsScript==null) {
461 mainWindow.setDefaultCursor();
462 String msg = CodeMapper.getText(ErrorCode.SCRIPTNOTFOUND_TEXT);
463 String errorMessage = StringUtil.replace(msg,"%1",scriptName);
464 msg = CodeMapper.getText(ErrorCode.SCRIPTEXTENDEDBY_TEXT);
465 msg = StringUtil.replace(msg,"%1",script.getName());
466 errorMessage = errorMessage + "\n"+msg;
467 String errorTitle = CodeMapper.getText(LabelCode.ERROR_LABEL);
468 MessageDialog dlg = new MessageDialog(mainWindow,errorTitle,true);
469 dlg.setMessage(errorMessage, false);
470 dlg.show();
471 return false;
472 }
473 if (!extendsScript.isInterface()) {
474 mainWindow.setDefaultCursor();
475 String msg = CodeMapper.getText(ErrorCode.SCRIPTNOTANINTERFACE_TEXT);
476 String errorMessage = StringUtil.replace(msg,"%1",scriptName);
477 msg = CodeMapper.getText(ErrorCode.SCRIPTEXTENDEDBY_TEXT);
478 msg = StringUtil.replace(msg,"%1",script.getName());
479 errorMessage = errorMessage + "\n"+msg;
480 String errorTitle = CodeMapper.getText(LabelCode.ERROR_LABEL);
481 MessageDialog dlg = new MessageDialog(mainWindow,errorTitle,true);
482 dlg.setMessage(errorMessage, false);
483 dlg.show();
484 return false;
485 }
486 }
487
488 Enumeration implementsEnumeration = script.getImplementsEnumeration();
489 while (implementsEnumeration.hasMoreElements()) {
490 String scriptName = (String) implementsEnumeration.nextElement();
491 ScriptDeclaration implementsScript = config.getScript(scriptName);
492 if (implementsScript==null) {
493 mainWindow.setDefaultCursor();
494 String msg = CodeMapper.getText(ErrorCode.SCRIPTNOTFOUND_TEXT);
495 String errorMessage = StringUtil.replace(msg,"%1",scriptName);
496 msg = CodeMapper.getText(ErrorCode.SCRIPTIMPLBY_TEXT);
497 msg = StringUtil.replace(msg,"%1",script.getName());
498 errorMessage = errorMessage + "\n"+msg;
499 String errorTitle = CodeMapper.getText(LabelCode.ERROR_LABEL);
500 MessageDialog dlg = new MessageDialog(mainWindow,errorTitle,true);
501 dlg.setMessage(errorMessage, false);
502 dlg.show();
503 return false;
504 }
505 if (!implementsScript.isInterface()) {
506 mainWindow.setDefaultCursor();
507 String msg = CodeMapper.getText(ErrorCode.SCRIPTNOTANINTERFACE_TEXT);
508 String errorMessage = StringUtil.replace(msg,"%1",scriptName);
509 msg = CodeMapper.getText(ErrorCode.SCRIPTIMPLBY_TEXT);
510 msg = StringUtil.replace(msg,"%1",script.getName());
511 errorMessage = errorMessage + "\n"+msg;
512 String errorTitle = CodeMapper.getText(LabelCode.ERROR_LABEL);
513 MessageDialog dlg = new MessageDialog(mainWindow,errorTitle,true);
514 dlg.setMessage(errorMessage, false);
515 dlg.show();
516 return false;
517 }
518 }
519 }
520 mainWindow.setDefaultCursor();
521 return true;
522 }
523
524 /** Checks if a given script has an implementation.
525 *
526 * @param config the current project
527 * @param script the script to check if it has an implementation
528 * @return true, if script has an implenentation or if script is an interface,
529 * false is script has no implementation
530 */
531 protected boolean hasImplementation(ProjectConfig config, ScriptDeclaration script) {
532
533 if (!script.isInterface()) return true;
534
535 Enumeration implementations = config.getScriptNameEnumeration();
536 while (implementations!=null && implementations.hasMoreElements()) {
537 String scriptName = (String) implementations.nextElement();
538 ScriptDeclaration aScript = config.getScript(scriptName);
539 if (!execOrder.contains(aScript.getName())) continue;
540 if (!aScript.isInterface()) {
541 if (aScript.isImplementing(script.getName()) && execOrder.contains(aScript.getName())) {
542 return true;
543 }
544 Enumeration implementsEnum = aScript.getImplementsEnumeration();
545 while (implementsEnum!=null && implementsEnum.hasMoreElements()) {
546 ScriptDeclaration implementedScript = config.getScript((String) implementsEnum.nextElement());
547 if (implementedScript!=null && isExtension(config, implementedScript, script.getName())) return true;
548 }
549 }
550 }
551 return false;
552 }
553
554 /** Checks if a script is an extension of a possible parent. Only valid for
555 * interfaces.
556 *
557 * @param config the current project
558 * @param extension the script to check if it is an extension of a parent
559 * @param parent name of parent to check if script is extension
560 * @return true, if script is extension of parent, false if not or if script isn't
561 * an interface
562 */
563 protected boolean isExtension(ProjectConfig config, ScriptDeclaration extension, String parent) {
564
565 if (!extension.isInterface()) return false;
566 Enumeration extendsEnum = extension.getExtendsEnumeration();
567 while (extendsEnum!=null && extendsEnum.hasMoreElements()) {
568 ScriptDeclaration aParent = config.getScript((String) extendsEnum.nextElement());
569 if (aParent!=null && aParent.getName().equals(parent)) return true;
570 if (aParent!=null && isExtension(config, aParent, parent)) return true;
571 }
572 return false;
573 }
574
575 void helpButton_actionPerformed(ActionEvent e)
576 {
577 mainWindow.showHelp();
578 }
579
580 void quitButton_actionPerformed(ActionEvent e)
581 {
582 if(mainWindow!=null) mainWindow.dispose();
583 mainWindow.exit();
584 }
585
586 public String helpFilename() {
587 return "scriptorder.html";
588 }
589
590 }