1 package gov.nasa.pds.ltdt.gui;
2
3 import gov.nasa.pds.ltdt.gui.configuration.LTDTKeys;
4 import gov.nasa.pds.ltdt.gui.util.DictionaryUtility;
5 import gov.nasa.pds.ltdt.gui.util.ProcessWaitGlassPane;
6 import gov.nasa.pds.ltdt.gui.util.Utility;
7 import gov.nasa.pds.tools.dict.Dictionary;
8 import gov.nasa.pds.tools.label.parser.ParseException;
9
10 import java.awt.BorderLayout;
11 import java.awt.Color;
12 import java.awt.Container;
13 import java.awt.Dimension;
14 import java.awt.event.WindowAdapter;
15 import java.awt.event.WindowEvent;
16 import java.io.File;
17 import java.io.IOException;
18 import java.net.MalformedURLException;
19 import java.util.ArrayList;
20 import java.util.Enumeration;
21 import java.util.HashMap;
22 import java.util.Iterator;
23 import java.util.List;
24 import java.util.Map;
25 import java.util.Properties;
26 import java.util.Set;
27
28 import javax.swing.JFrame;
29 import javax.swing.JMenuBar;
30 import javax.swing.JOptionPane;
31 import javax.swing.JPanel;
32 import javax.swing.JSplitPane;
33 import javax.swing.JTextField;
34 import javax.swing.JToolBar;
35
36
37
38 public class MainWindow extends JFrame {
39
40 Container contp;
41 private MainWindowListener wListener;
42
43 public TemplateEditorPane editorPane=null;
44 public DictionaryListPane dictListPane=null;
45 public DictionaryDefinitionPane dictDefPane=null;
46 public StatusPane statusPane = null;
47
48 private JPanel leftPanel, rightPanel=null;
49
50 private JSplitPane mainSplitPane, leftSplitPane, rightSplitPane = null;
51 public JMenuBar bar=null;
52 public JToolBar jtb=null;
53 public Menu menu=null;
54 public ProjectCreateDialog jdlgCreateNewProject = null;
55 public ProjectCreateDialog jdlgSaveProjectAs = null;
56
57 public JTextField jtfTest = null;
58
59 // *** structure related to dictionary display and manipulation ***
60
61 // the dictionaryMap contains actual id to assist locate rest of the information at dictionaryMap
62 // the Shorten format holds identifiers only for displaying purpose
63
64 // Note: the long and short lists should be in sync, i.e. matching indexes
65 // because the id at the long list is the key to find the complete definition inside
66 // dictionaryMap
67
68 // complete mapping of keywords related to a project
69 public KeywordMap dictionaryMap = new KeywordMap();
70
71 // list of full treeEntryIDs, id only, in long format (with --)
72 // or short (without --) format
73 public String[] keywordFullLong = null;
74 public String[] keywordFullShort = null;
75
76 // list of treeEntryIDs as result of search in all types
77 public String[] keywordSubLong = null;
78 public String[] keywordSubShort = null;
79
80 // list of treeEntryIDs to be displayed based on the filter (object or element)
81 public String[] keywordDisplayLong = null; // the full version
82 public String[] keywordDisplayShort=null; // the shortened version without dictionary url
83
84 // tracking of the latest display type, default is Element type
85 public int requestedType = LTDTKeys.ELEMENT_TYPE;
86
87 // tracking of the latest selected keyword. This keyword should still be highlighted
88 // after search query is cleared.
89 // Note: this is the long id of the keyword to allow correctly
90 // identify it in case there are multiple resources of this keyword name in a project
91 public String lastSelectedKeyword = "";
92
93 // a structure to hold WDD
94 public Dictionary WDD = new Dictionary();
95
96 // merged of all dictionaries, including the ones already defined in a project,
97 // the newly imported ones, and WDD
98 // This variable is cleared before opening a new project, and it's altered in realtime
99 // whenever new keyword is created or a keyword defintion is altered.
100 public Dictionary mDictionary = new Dictionary();
101
102 // if all components in the frame has been created
103 // and the u/i is visible
104 // This flag is needed since some listener got triggered before
105 // the ui is displayed, which caused stack dump
106 public boolean windowVisible = false;
107
108 private HashMap commandLineParams;
109 private String dictCmdline="";
110 private Properties props;
111
112 public MainWindow (HashMap commandLineParams, Properties props) {
113
114 //public MainWindow (HashMap config, ArrayList dList) {
115 //this.config = config;
116 this.commandLineParams = commandLineParams;
117
118 this.props = props;
119 //this.dictionariesFromCommandArray = DictionaryUtility.getDictionaryNameList(props.getProperty(LTDTKeys.DICTIONARIESFROMCOMMAND));
120
121 setTitle ("LTDTool");
122
123 // initialization
124
125 getContentPane().setLayout(new BorderLayout());
126 setDefaultLookAndFeelDecorated(true);
127 // use JFrame.DO_NOTHING_ON_CLOSE here
128 // because there'll be extra handling when user quit the tool
129 this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
130
131 contp = this.getContentPane();
132 contp.setLayout(new BorderLayout());
133
134 wListener = new MainWindowListener(props, commandLineParams, this);
135 addWindowListener( wListener);
136
137 // left panel contains the editor pane for templates
138 // and a status pane. The status pane is not displayed during
139 // editing.
140 leftPanel = Utility.createVerticalBoxPanel();
141
142 editorPane = new TemplateEditorPane(props, this);
143 statusPane = new StatusPane();
144 statusPane.stPanel.setVisible(true);
145
146 leftSplitPane = new JSplitPane
147 (JSplitPane.VERTICAL_SPLIT, editorPane, statusPane.stPanel);
148
149 leftSplitPane.setOneTouchExpandable(true);
150 leftSplitPane.setResizeWeight(0.9);
151
152 leftPanel.add(leftSplitPane);
153
154 // right panel contains two sub panels: top and bottom panel.
155 // top panel displays the label objects/elements and a search box
156 // definition for any object/element selected on the top panel
157 // is displayed on the bottom panel.
158 rightPanel = Utility.createVerticalBoxPanel();
159
160 dictListPane = new DictionaryListPane(this);
161
162 dictDefPane = new DictionaryDefinitionPane(this);
163
164 // put the list and definition panels into a split pane
165 rightSplitPane = new JSplitPane
166 (JSplitPane.VERTICAL_SPLIT, dictListPane, dictDefPane);
167
168 rightSplitPane.setOneTouchExpandable(true);
169 rightSplitPane.setResizeWeight(0.7);
170 rightPanel.add(rightSplitPane);
171
172 // the main split pane consists of the editing area (left panel) and
173 // dictionary display area (right panel)
174 mainSplitPane = new JSplitPane
175 (JSplitPane.HORIZONTAL_SPLIT, leftPanel, rightPanel);
176 mainSplitPane.setOneTouchExpandable(true);
177
178 // put components together
179
180 contp.add(mainSplitPane);
181
182 // add menu bar and tool bar
183 menu = new Menu(props, this);
184 bar = menu.getMenuBar();
185 jtb = menu.getToolBar();
186
187
188 setJMenuBar(bar); // menu bar
189 contp.add(jtb, BorderLayout.NORTH); // tool bar
190
191 setContentPane(contp);
192
193 pack();
194 setVisible(true);
195 this.windowVisible = true;
196 }
197
198
199 private class MainWindowListener extends WindowAdapter {
200
201 private Properties props;
202 private MainWindow window;
203 private HashMap commandLineParams;
204 private String[] dictionariesFromCommandArray;
205
206
207 //private ArrayList dictList;
208
209
210 private int toolOpenStatus = 0;
211
212
213 public MainWindowListener (Properties props, HashMap commandLineParams, MainWindow window){
214
215 this.commandLineParams = commandLineParams;
216 this.window = window;
217 this.props = props;
218
219 dictionariesFromCommandArray =
220 DictionaryUtility.getDictionaryNameArray(props.getProperty(LTDTKeys.DICTIONARIESFROMCOMMAND));
221 }
222 /**
223 * windowClosing event handling
224 */
225 public void windowClosing (WindowEvent we) {
226 ToolExit.exitHandling(props, window);
227 }
228
229 /***
230 * windowOpen event handling
231 */
232 public void windowOpened (WindowEvent we) {
233
234 initializeSessionConfig();
235
236 if ("true".equals(props.getProperty("debug"))) {
237 System.err.println ("..........................................");
238 System.err.println ("LTDT Session has been initialized with ...");
239 for (Enumeration e= props.propertyNames(); e.hasMoreElements();) {
240 String key = e.nextElement().toString();
241 System.err.println (key+"="+props.getProperty(key));
242 }
243
244 System.err.println("open status is "+toolOpenStatus);
245 System.err.println (".........................................");
246
247 };
248
249 }
250
251 /***
252 * This is only called once when the tool is starting up.
253 * It gathering initial set of properties bases on user input and
254 * previous configuration data.
255 * The initial property values may be altered as the session progress
256 *
257 * Alternatively, project directory and data dictionaries can be entered through command line.
258 * @throws IOException
259 *
260 */
261 private void initializeSessionConfig () {
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296 String path = null;
297 Set mappings = commandLineParams.entrySet();
298 File fn = null;
299
300
301 if ("true".equals(props.getProperty("debug"))) {
302 System.err.println ("/////////////////////");
303 System.err.println ("\nParameters from command line:");
304 if (mappings.size() > 0) {
305 for (Iterator it=mappings.iterator(); it.hasNext(); ) {
306 Map.Entry me = (Map.Entry)it.next();
307 System.err.println (me);
308 }
309 }
310 else
311 System.err.println ("No parameters entered from command line.");
312
313 System.err.println ("Dictionary entered at command line was:");
314
315 if (dictionariesFromCommandArray != null)
316 for (int i=0; i<dictionariesFromCommandArray.length; i++) {
317 System.err.println(dictionariesFromCommandArray[i]);
318
319 }
320 System.err.println (">>>>>>>>>>>>");
321 }
322
323
324
325
326
327 try {
328 File toolPropertyFile = new File (LTDTKeys.LTDTPROPFILE);
329
330 if (!toolPropertyFile.exists()) {
331 new File(LTDTKeys.LTDTPROPFILE).createNewFile();
332 toolOpenStatus = LTDTKeys.NO_PROJECT_REGISTERED;
333 }
334 }
335 catch (IOException ie) {
336 JOptionPane.showMessageDialog(
337 window,
338 "Problem starting LTDTool. Cannot initialize tool profile information.");
339 System.exit(-1);
340 }
341
342
343
344
345
346
347 dictCmdline = (String)props.getProperty(LTDTKeys.DICTIONARIESFROMCOMMAND).trim();
348
349 if (dictCmdline.length()>0) {
350 props.setProperty(LTDTKeys.COMMANDLINEDICTIONARYADDED,"true");
351 }
352 else {
353 props.setProperty(LTDTKeys.COMMANDLINEDICTIONARYADDED,"false");
354
355 }
356
357 try {
358 if (commandLineParams.get(LTDTKeys.PROJECTDIR) == null) {
359
360 path = null;
361
362 if (Utility.getKeyList(LTDTKeys.LTDTPROPFILE).size()>0)
363 toolOpenStatus = LTDTKeys.NO_PROJECTDIR_INFO;
364 else toolOpenStatus = LTDTKeys.NO_PROJECT_REGISTERED;
365
366 props.setProperty(LTDTKeys.PROJECTNAME, LTDTKeys.UNTITLED);
367
368
369 }
370 else {
371 String commandLineProjectDir = (String)commandLineParams.get(LTDTKeys.PROJECTDIR);
372
373 fn = new File(commandLineProjectDir);
374
375
376
377 if (fn.exists()==false) {
378
379
380
381 path = commandLineProjectDir;
382 toolOpenStatus = LTDTKeys.PROJECTDIR_NOT_FOUND;
383 }
384 else {
385
386
387
388 path = fn.getCanonicalPath();
389
390 props.setProperty(LTDTKeys.PROJECTDIR, path );
391
392
393 if (new File(path+System.getProperty("file.separator")+LTDTKeys.PROPERTYFILENAME).exists() == false &&
394 Utility.dirRWAllowed(path)==false) {
395 toolOpenStatus = LTDTKeys.FOUND_PROJECTDIR_NO_PROPERTY_AND_NOT_READWRITEABLE;
396
397 }
398 else if (new File(path+System.getProperty("file.separator")+LTDTKeys.PROPERTYFILENAME).exists() == false) {
399 toolOpenStatus = LTDTKeys.FOUND_PROJECTDIR_NO_PROPERTY;
400 }
401
402 else if (Utility.dirRWAllowed(path)==false) {
403 toolOpenStatus = LTDTKeys.PROJECTDIR_NOT_READWRITEABLE;
404 }
405
406 else {
407 toolOpenStatus = LTDTKeys.PROJECTDIR_PROPERTY_FOUND;
408 props.setProperty(LTDTKeys.PROJECTNAME, Utility.getProjectName(props.getProperty(LTDTKeys.PROJECTDIR)));
409 }
410 }
411 }
412
413 }
414 catch (IOException ex) {
415
416 }
417
418
419
420 try {
421
422 if (toolOpenStatus == LTDTKeys.PROJECTDIR_PROPERTY_FOUND ) {
423
424 int openStatus = ProjectOpen.open(props, window, props.getProperty(LTDTKeys.PROJECTNAME), true);
425
426
427 if (openStatus==LTDTKeys.FOUND_PROJECTDIR_NO_PROPERTY) {
428 initializeNewWorkspace(window, openStatus);
429 if ("false".equals(props.getProperty(LTDTKeys.PROJECTALTERED)))
430 new ProjectGalleryDialog (props, window, LTDTKeys.PROJECTGALLERYTITLE, LTDTKeys.NEWFROMTEMPLATETABINDEX);
431 }
432 }
433
434 else {
435 warningCreateNewWorkspace (window, path);
436 initializeNewWorkspace (window, toolOpenStatus);
437 if ("false".equals(props.getProperty(LTDTKeys.PROJECTALTERED)))
438 new ProjectGalleryDialog (props, window, LTDTKeys.PROJECTGALLERYTITLE, LTDTKeys.NEWFROMTEMPLATETABINDEX);
439 }
440
441
442 }
443 catch (Exception ex) {
444
445 JOptionPane.showMessageDialog(window, "Error initiating LTDT Tool\n");
446
447 }
448
449 }
450
451 /***
452 * Initialize a session with generic property value set
453 * if user did not provide project info, or if project info is not valid.
454 */
455 private void initializeNewWorkspace(final MainWindow window, int initialStatus) {
456
457 Utility.initializeEmptyProject(props, window);
458
459 window.setTitle("LTDTool (Project Name: "+LTDTKeys.UNTITLED+")");
460
461
462
463 props.setProperty(LTDTKeys.PROJECTNAME, LTDTKeys.UNTITLED);
464
465 if (initialStatus == LTDTKeys.NO_PROJECTDIR_INFO ||
466 initialStatus == LTDTKeys.NO_PROJECT_REGISTERED ||
467 initialStatus == LTDTKeys.PROJECTDIR_NOT_READWRITEABLE ) {
468 props.setProperty(LTDTKeys.PROJECTDIR, System.getProperty("user.dir"));
469 }
470 else props.setProperty(LTDTKeys.PROJECTDIR, props.getProperty(LTDTKeys.PROJECTDIR));
471
472 props.setProperty(LTDTKeys.TEMPLATETYPE, "");
473 props.setProperty(LTDTKeys.TEMPLATEEXISTS, "false");
474 props.setProperty(LTDTKeys.WDDEXISTS, "false");
475
476
477
478
479
480 if ("true".equals(props.getProperty("debug")))
481 System.err.println ("Command line dictionary specification was: "+dictCmdline);
482
483 if (dictCmdline.length() >0 ) {
484
485
486
487 final ProcessWaitGlassPane pw4 = new ProcessWaitGlassPane();
488 window.setGlassPane(pw4);
489 pw4.setBackground( new Color(255, 255, 255, 255) );
490 pw4.setForeground( Color.LIGHT_GRAY);
491
492 pw4.activate("Opening project. Please wait ...");
493 Thread thread = new Thread()
494 {
495 public void run()
496 {
497
498 try {
499 window.mDictionary = DictionaryUtility.MergeDictionaryList(window.mDictionary, Utility.rowstring2urllist(dictCmdline) );
500 }
501 catch ( MalformedURLException me) {
502 JOptionPane.showMessageDialog(window, "Error when construction runtime merged dictionary. "+me.getMessage());
503 }
504 catch (ParseException pe) {
505 JOptionPane.showMessageDialog(window,"Error when construction runtime merged dictionary. "+pe.getMessage());
506 }
507 catch (IOException ie) {
508 JOptionPane.showMessageDialog(window, "Error when construction runtime merged dictionary. "+ie.getMessage());
509 }
510
511 ProjectOpen.populateKeywords(props, window, dictCmdline);
512 DictionaryUtility.populateDictionaryFullListingPane(window);
513
514 props.setProperty(LTDTKeys.DICTIONARIES, dictCmdline);
515 props.setProperty(LTDTKeys.COMMANDLINEDICTIONARYADDED, "true");
516 props.setProperty(LTDTKeys.PROJECTALTERED, "true");
517
518 DictionaryListPane.displaySingleTypeList(window, LTDTKeys.ELEMENTONLY);
519
520 pw4.deactivate();
521 }
522 };
523 thread.start();
524 }
525
526 else {
527 props.setProperty(LTDTKeys.DICTIONARIES, "");
528 props.setProperty(LTDTKeys.COMMANDLINEDICTIONARYADDED, "false");
529 props.setProperty(LTDTKeys.PROJECTALTERED, "false");
530
531 }
532
533 }
534
535 private void warningCreateNewWorkspace (MainWindow window, String path) {
536 String message=null;
537 boolean foundLTDTProfile = false;
538
539
540 try {
541 if (Utility.getKeyList(LTDTKeys.LTDTPROPFILE).size() > 0 )
542 foundLTDTProfile = true;
543
544 }
545 catch (IOException ex) {
546
547 }
548
549
550 switch (toolOpenStatus) {
551
552
553 case LTDTKeys.NO_PROJECT_REGISTERED:
554 case LTDTKeys.NO_PROJECTDIR_INFO:
555 break;
556
557 case LTDTKeys.PROJECTDIR_NOT_FOUND:
558 message = "Welcome to LTDTool. \nProject directory "+path+" can not be located. \nPlease create a new project ";
559 if (foundLTDTProfile==true)
560 message = message + " \nor open an existing project";
561 JOptionPane.showMessageDialog(window, message);
562 break;
563
564 case LTDTKeys.FOUND_PROJECTDIR_NO_PROPERTY_AND_NOT_READWRITEABLE:
565 message = "Welcome to LTDTool. \nProject information was not found at "+path+" \n and the directory is not readable or writable." +
566 "\nPlease create a new project ";
567 if (foundLTDTProfile==true)
568 message = message + " \nor open an existing project";
569 JOptionPane.showMessageDialog(window, message);
570 break;
571 case LTDTKeys.FOUND_PROJECTDIR_NO_PROPERTY:
572 message = "Welcome to LTDTool. \nProject information was not found at "+path+" \nPlease create a new project ";
573 if (foundLTDTProfile==true)
574 message = message + " \nor open an existing project";
575 JOptionPane.showMessageDialog(window, message);
576 break;
577 case LTDTKeys.PROJECTDIR_NOT_READWRITEABLE:
578 message = "Welcome to LTDTool. \nProject directory "+path+" is not readable or writable. \nPlease correct the file permission setting ";
579 if (foundLTDTProfile==true) {
580 message = message + " \nor open an existing project";
581
582 JOptionPane.showMessageDialog(window, message);
583 }
584 else {
585 JOptionPane.showMessageDialog(window, message);
586 }
587 default:;
588
589 }
590
591
592 }
593
594 }
595
596
597 public JFrame getWindow() {
598 return this;
599 }
600
601
602 MainWindowListener getListener() {
603 return wListener;
604 }
605 }