View Javadoc

1   /*
2    $Id: AceDialog.java,v 1.1.1.1 2003/08/25 18:36:04 mch Exp $
3   
4    Date         Author      Changes
5    1 Nov 2002   M Hill      Created
6   
7    (c) Copyright...
8    */
9   
10  package org.astrogrid.ace.client;
11  
12  import java.awt.*;
13  import java.awt.event.*;
14  import javax.swing.*;
15  
16  import org.astrogrid.log.*;
17  import org.astrogrid.ui.*;
18  import java.io.*;
19  import java.util.*;
20  import java.net.URL;
21  import org.astrogrid.tools.votable.*;
22  
23  import org.w3c.dom.Element;
24  import org.w3c.dom.Node;
25  import org.xml.sax.SAXException;
26  
27  import org.astrogrid.tools.xml.EasyDomLoader;
28  import org.astrogrid.common.myspace.*;
29  import org.astrogrid.common.client.*;
30  import org.astrogrid.ace.service.ServerSettings;
31  import org.astrogrid.ace.utils.NativeToXmlImpl;
32  
33  //import org.astrogrid.ui.help.*;
34  /***
35   * Offers the user an opportunity to edit the extraction criteria, select
36   * the ACE server, etc.
37   * This is a modal box - use wasCancelled() to test for whether the Cancel
38   * button was pressed (or the window was closed); if not, use
39   * getExtractionCriteria() and getAceServer() to retrieve what the use has
40   * selected.
41   *
42   *
43   * @author M Hill
44   */
45  
46  public class AceDialog extends JDialog implements ActionListener, AceConsumer
47  {
48  
49     JComboBox aceSelector = null;
50     private JButton installedConfigEditBtn = null;
51     private JButton serverListEditBtn = null;
52        //JComboBox spaceSelector = null;
53     JButton okButton = null;
54     JButton cancelButton = null;
55  
56     private JButton openButton = null;
57     private JButton saveButton = null;
58     private JButton saveAsButton = null;
59     private JButton editRawButton = null;
60     //private JHelpButton helpButton = null;
61     private JFileChooser configChooser = new JFileChooser();
62  
63     TemplateEditorPanel templateEditor = null;
64  
65     //MySpaceServers myspaceServers = new MySpaceServers();
66  
67     boolean isCancelled = true;
68  
69     Thread spawnedExtract = null;
70  
71     Element configDom = null;
72  
73     //name of config file being edited
74     String configFilename = "";
75  
76     //name of config file to use for extraction. This is used to store the actual
77     //entries in the field, which may have been edited since loading from/saving
78     //to configFilename
79     public static final String TEMP_CONFIG = "config.xml.$$$";
80  
81     /***
82      * Initializes the dialog.
83      */
84     public AceDialog(Frame owner, boolean modal)
85     {
86        super(owner, "Astronomy Catalogue Extractor", modal);
87  
88        getContentPane().setLayout(new BorderLayout());
89  
90        //put tabbed config editor in centre
91        templateEditor = new TemplateEditorPanel();
92        getContentPane().add(templateEditor, BorderLayout.CENTER);
93  
94        //toolbar at top
95        openButton = new JButton(IconFactory.getIcon("Open"));
96        if (openButton.getIcon() == null) openButton.setText("Open");
97        openButton.setToolTipText("Opens configuration file");
98        openButton.addActionListener(this);
99  
100       saveButton = new JButton(IconFactory.getIcon("Save"));
101       if (saveButton.getIcon() == null) saveButton.setText("Save");
102       saveButton.setToolTipText("Saves current configuration to file");
103       saveButton.addActionListener(this);
104 
105       saveAsButton = new JButton(IconFactory.getIcon("SaveAs"));
106       if (saveAsButton.getIcon() == null) saveAsButton.setText("SaveAs");
107       saveAsButton.setToolTipText("Saves current configuration to given file");
108       saveAsButton.addActionListener(this);
109 
110       editRawButton = new JButton(IconFactory.getIcon("Edit"));
111       if (editRawButton.getIcon() == null) editRawButton.setText("Edit");
112       editRawButton.setToolTipText("Edit configuration file in text editor");
113       editRawButton.addActionListener(this);
114 
115       /*
116       helpButton = new JHelpButton("sex",null); //IconFactory.getIcon("Help"));
117       helpButton.setToolTipText("Displays SExtractor manual");
118       helpButton.addActionListener(this);
119 
120       //set up help
121       if (!Help.mainBrowserSet())
122       {
123          Help.setMainBrowser(new JHelpBrowser());
124       }
125       Help.setRedirect("sex","http://www.eso.org/science/eis/eis_doc/sex2/sex2html/sex2_doc.html");
126        */
127 
128       JToolBar toolbar = new JToolBar();
129       toolbar.add(openButton);
130       toolbar.add(saveButton);
131       toolbar.add(saveAsButton);
132       toolbar.addSeparator();
133       toolbar.add(editRawButton);
134       toolbar.addSeparator();
135 //      toolbar.add(helpButton); not working yet
136       getContentPane().add(toolbar, BorderLayout.NORTH);
137 
138       // which ACE server to use - bottom left
139       JPanel aceServerPanel = new JPanel();
140       aceServerPanel.add(new JLabel("ACE Server", JLabel.RIGHT));
141       aceSelector = new JComboBox(AceServerList.getServers());
142       aceSelector.addActionListener(this);
143       aceServerPanel.add(aceSelector);
144 
145       serverListEditBtn = new JButton(IconFactory.getIcon("Edit List"));
146       if (serverListEditBtn.getIcon() == null) serverListEditBtn.setText("Edit List");
147       serverListEditBtn.setToolTipText("Edit list of ACE servers");
148       serverListEditBtn.addActionListener(this);
149       aceServerPanel.add(serverListEditBtn);
150 
151       installedConfigEditBtn = new JButton(IconFactory.getIcon("Edit"));
152       if (installedConfigEditBtn.getIcon() == null) installedConfigEditBtn.setText("Edit");
153       installedConfigEditBtn.setToolTipText("Edit installed extraction server");
154       installedConfigEditBtn.addActionListener(this);
155       aceServerPanel.add(installedConfigEditBtn);
156 
157       // buttons - bottom rightish
158       okButton = new JButton("Extract");
159       okButton.addActionListener(this);
160       cancelButton = new JButton("Cancel");
161       cancelButton.addActionListener(this);
162 
163       JPanel buttonPanel = new JPanel(new FlowLayout());
164       buttonPanel.add(okButton);
165       buttonPanel.add(cancelButton);
166 
167       //status bar
168 //      StatusBar statusBar = new StatusBar();
169 //      net.mchill.log.Log.addHandler(statusBar.getLogHandler());   //hmmm v dubious
170 
171       //assemble above
172       JPanel bottomPanel = new JPanel(new BorderLayout());
173       bottomPanel.add(aceServerPanel, BorderLayout.WEST);
174       bottomPanel.add(buttonPanel, BorderLayout.EAST);
175 //      bottomPanel.add(statusBar, BorderLayout.SOUTH);
176 
177       getContentPane().add(bottomPanel, BorderLayout.SOUTH);
178 
179       validate(); //relayout etc
180 
181       if (UserOptions.getDialogSize() != null)
182       {
183          setSize(UserOptions.getDialogSize());
184       }
185       else
186       {
187          setSize(800,400);
188       }
189       if (UserOptions.getDialogLocation() != null)
190       {
191          setLocation(UserOptions.getDialogLocation());
192       }
193 
194       configChooser.addChoosableFileFilter(new ExtensionFileFilter(
195          new String[] {"sex", "param"},  "SExtractor-native configuration files"
196       ));
197       configChooser.addChoosableFileFilter(new ExtensionFileFilter(
198          new String[] {"ace", "xml", "XML"},   "ACE xml configuration files"
199       ));
200 
201       //don't catch enter presses, as some input fields might want to use them,
202       // and this is quite a heavy event to kick off accidently
203       new org.astrogrid.ui.EscEnterListener(this, null, cancelButton);
204    }
205 
206 
207 
208    /***
209     * Sets the location, size, etc from the user options
210     */
211    public void loadUserOptions()
212    {
213       if ((UserOptions.getLastTemplateFilename() != null)
214           && (UserOptions.getLastTemplateFilename().length() >0))
215       {
216          //this is chuking exceptions for some reason: configChooser.setCurrentDirectory(new File(UserOptions.getLastTemplateFilename()));
217          loadConfig(UserOptions.getLastTemplateFilename());
218       }
219 
220       if (UserOptions.getLastAceServer() != null)
221       {
222          aceSelector.setSelectedItem(UserOptions.getLastAceServer());
223       }
224 
225    }
226 
227    /***
228     * Sets the user options to the location, size, field entries, etc
229     */
230    public void storeUserOptions()
231    {
232       UserOptions.setDialog(getSize(), getLocation());
233 
234       UserOptions.setLastTemplateFilename(configFilename);
235       UserOptions.setLastAceServer((String) aceSelector.getSelectedItem());
236    }
237 
238    /***
239     * Action perfromed - button pressed, etc
240     */
241    public void actionPerformed(ActionEvent e)
242    {
243       if (e.getSource() == okButton)
244       {
245          storeUserOptions();
246          if (isInputValid())
247          {
248             isCancelled = false;
249 
250             /*
251             //kick off extraction - dodgy check to see if we're running with
252             //Aladdin or not
253             if (!templateEditor.isImageFixed())
254             {
255                //standalone mode
256                Thread t = new StandaloneAce(
257                   getExtractionCriteria(),
258                   getAceServer()
259                );
260                t.start();
261             }
262             else
263             {
264                //aladin mode - just hide
265                setVisible(false);
266             }
267              */
268             setVisible(false);
269          }
270       }
271       else if (e.getSource() == cancelButton)
272       {
273          isCancelled = true;
274          setVisible(false);
275       }
276       else if (e.getSource() == openButton)
277       {
278          if (configChooser.showDialog(this, "Open") == JFileChooser.APPROVE_OPTION)
279          {
280             loadConfig(""+configChooser.getSelectedFile());
281          }
282       }
283       else if (e.getSource() == saveAsButton)
284       {
285          if (configChooser.showDialog(this, "Save") == JFileChooser.APPROVE_OPTION)
286          {
287             templateEditor.saveXmlFile(configChooser.getSelectedFile());
288             setConfigFilename(""+configChooser.getSelectedFile());
289          }
290       }
291       else if (e.getSource() == saveButton)
292       {
293          templateEditor.saveXmlFile(new File(configFilename));
294       }
295       else if (e.getSource() == editRawButton)
296       {
297          TextEditor textEditor = new TextEditor(this, "Editor");
298          textEditor.setModal(true);
299          textEditor.setText(templateEditor.toXmlString());
300          textEditor.show();
301          if (!textEditor.wasCancelled())
302          {
303             templateEditor.loadXmlString(textEditor.getText());
304          }
305       }
306       else if (e.getSource() == aceSelector)
307       {
308          installedConfigEditBtn.setEnabled(
309             AceServerList.isLocal( (String) aceSelector.getSelectedItem())
310          );
311       }
312       else if (e.getSource() == serverListEditBtn)
313       {
314          TextEditor textEditor = new TextEditor(this, "Editor");
315          textEditor.setModal(true);
316 
317          File f = new File(AceServerList.FILENAME);
318          if (!f.exists())
319          {
320             AceServerList.setSoftwiredDefaults();
321             AceServerList.store();
322          }
323 
324          textEditor.loadFile(new File(AceServerList.FILENAME));
325          textEditor.show();
326          if (!textEditor.wasCancelled())
327          {
328             textEditor.saveFile(new File(AceServerList.FILENAME));
329             try
330             {
331                AceServerList.load();
332             }
333             catch (IOException ioe)
334             {
335                Log.logError("Could not reload config", ioe);
336             }
337             aceSelector.setModel(new DefaultComboBoxModel(AceServerList.getServers()));
338          }
339       }
340       else if (e.getSource() == installedConfigEditBtn)
341       {
342          TextEditor textEditor = new TextEditor(this, "Editor");
343          textEditor.setModal(true);
344 
345          File f = new File(ServerSettings.FILE_NAME);
346          if (!f.exists())
347          {
348             ServerSettings.setDefaults();
349             ServerSettings.getInstance().store();
350          }
351 
352          textEditor.loadFile(new File(ServerSettings.FILE_NAME));
353          textEditor.show();
354          if (!textEditor.wasCancelled())
355          {
356             textEditor.saveFile(new File(ServerSettings.FILE_NAME));
357             try
358             {
359                ServerSettings.getInstance().load();
360             }
361             catch (IOException ioe)
362             {
363                Log.logError("Could not reload config", ioe);
364             }
365          }
366       }
367    }
368 
369    /***
370     * Set configuration file.  sets title.
371     */
372    public void setConfigFilename(String filename)
373    {
374       setTitle("ACE "+filename);
375 
376       configFilename = filename;
377    }
378 
379    /***
380     * load configuration file - Loads up fields, sets title, etc
381     */
382    public void loadConfig(String filename)
383    {
384       try
385       {
386          //look at type
387          if (filename.toLowerCase().endsWith(".sex"))
388          {
389             //file is native SExtractor configuration file
390             String xmlFilename = filename+".xml.$$$";
391             Log.trace("Converting native (sex) SExtractor '"+filename+"' to '"+xmlFilename+"'...");
392 
393             FileWriter xmlWriter = new FileWriter(xmlFilename);
394             NativeToXmlImpl.startXml(xmlWriter);
395             NativeToXmlImpl.makeSexXml(new FileReader(filename), xmlWriter);
396             NativeToXmlImpl.endXml(xmlWriter);
397 
398             Log.trace("...done convert");
399 
400             filename = xmlFilename;
401          }
402          else if (filename.toLowerCase().endsWith(".param"))
403          {
404             //file is native SExtractor param (output column) file
405             String xmlFilename = filename+".xml.$$$";
406             Log.trace("Converting native (param) SExtractor '"+filename+"' to '"+xmlFilename+"'...");
407 
408             NativeToXmlImpl.makeParamXml(new FileReader(filename), new FileWriter(xmlFilename));
409 
410             Log.trace("...done convert");
411 
412             filename = xmlFilename;
413          }
414 
415          // don't actually validate on reading as we may
416          //be loading parts of a file
417 
418 
419          //load into template editor
420          templateEditor.loadXmlFile(new File(filename));
421 
422       }
423       catch (IOException e)
424       {
425          Log.logWarning(null,"Could not load '"+filename+"' ",e);
426          return;
427       }
428 
429       //update UI
430       setConfigFilename(filename);
431    }
432 
433 
434    /***
435     * Was cancelled
436     */
437    public boolean wasCancelled()
438    {
439       return isCancelled;
440    }
441 
442    /***
443     * Is input valid.  Write out options and validate against schewa
444     */
445    protected boolean isInputValid()
446    {
447       try
448       {
449          createConfigDom();
450       }
451       catch (IOException ioe)
452       {
453          Log.logWarning(null,"Input Fields generate invalid extraction config file",ioe);
454          JOptionPane.showMessageDialog(
455             this,
456             "The XML file generated from these entries generates an error:\n"+ioe,
457             "Input Error",
458             JOptionPane.ERROR_MESSAGE
459          );
460          return false;
461       }
462 
463       //check that myspace/ace servers are compatible
464 
465 
466 
467       return true;
468    }
469 
470    /***
471     * Returns the results of all the editing - a DOM doc fitting the ACE input
472     * schema with the values set from the fields
473     */
474    public Element getExtractionCriteria()
475    {
476       try
477       {
478 //       if (configDom == null) do it anyway for the moment so we don't have to worry about changes resetting it
479          {
480             configDom = createConfigDom();
481          }
482       }
483       catch (IOException ioe)
484       {
485          Log.logError("Could not create criteria from entries",ioe);
486       }
487       return configDom;
488    }
489 
490 
491    /***
492     * Creates and returns the configuration that has been entered into the dialog as
493     * a Dom document.  All file locations are as given - no effort is made
494     * to check to see if they are visible to the service.  The file is
495     * validated against the schema
496     */
497    protected Element createConfigDom() throws IOException
498    {
499       /***
500       //for the moment, work off the template until Alan's save is OK
501       org.astrogrid.xmlutils.XmlValidatorIfc validator = new org.astrogrid.xmlutils.XmlValidatorXercesImpl();
502       try
503       {
504          validator.validate(""+configFilename);
505       }
506       catch (SAXException e)
507       {
508          IOException ioe = new IOException("Invalid temp config file '"+configFilename+": "+e);
509          ioe.setStackTrace(e.getStackTrace());
510          throw ioe;
511       }
512       return EasyDomLoader.loadElement(configFilename);
513        **/
514 
515       //need to validate it, so save it first to the temp location
516       File tempFile = new File(TEMP_CONFIG);
517       templateEditor.saveXmlFile(tempFile);
518 
519       //validate it
520       Log.trace("Validating '"+tempFile+"'...");
521       org.astrogrid.xmlutils.XmlValidatorXercesImpl validator = new org.astrogrid.xmlutils.XmlValidatorXercesImpl();
522       try
523       {
524          validator.validate(""+tempFile);
525       }
526       catch (SAXException e)
527       {
528          IOException ioe = new IOException("WebService document invalid '"+tempFile+": "+e);
529          ioe.setStackTrace(e.getStackTrace());  //java v1.4+
530          //ioe.fillInStackTrace(); //java v1.3
531          throw ioe;
532       }
533       Log.trace("...config file valid");
534 
535       //load template config file as dom
536       return EasyDomLoader.loadElement(""+tempFile);
537       /***/
538    }
539 
540 
541    /*** Returns the ace server string corresponding to the key in the server list
542     */
543    public String getAceServer()
544    {
545       return (String) aceSelector.getSelectedItem();
546    }
547 
548    /***
549     * Exposes the template editor panel
550     */
551    public TemplateEditorPanel getTemplateEditor()
552    {
553       return templateEditor;
554    }
555 
556    private static ImageIcon loadIcon(String icon)
557    {
558       //path is subdirectory of this package, called images
559       URL url = AceDialog.class.getResource("./images/"+icon+".gif");
560       if (url != null)
561          return new ImageIcon(Toolkit.getDefaultToolkit().getImage(url));
562 
563       return null;
564    }
565 
566    public void consumeAceResults(InputStream results)
567    {
568       try
569       {
570          JVotBox votBox = new JVotBox(null);
571          votBox.getVotController().loadVot(results);
572          votBox.show();
573       }
574       catch (IOException ioe)
575       {
576          Log.logError("Loading "+results, ioe);
577       }
578    }
579 
580 
581    /***
582     * Test harness and standalone client operation
583     */
584    public static void main(String [] args)
585    {
586       org.astrogrid.ui.Splash splash = new org.astrogrid.ui.Splash(
587          "ACE","Astronomy Catalogue Extractor", "v0.3",
588          Color.blue.darker().darker(), Color.yellow,
589          null, "MCH KEA AJWM");
590 
591       net.mchill.log.Log.addHandler(new net.mchill.log.Log2Console());
592       net.mchill.log.Log.addHandler(new net.mchill.log.Log2File("client.log"));
593       net.mchill.log.ui.Log2Popup popup = new net.mchill.log.ui.Log2Popup();
594 //      popup.setLocation(AceClientOptions.getDialogLocation().x- (AceClientOptions.getDialogSize().width/2),
595 //                        AceClientOptions.getDialogLocation().y- (AceClientOptions.getDialogSize().height/2));
596       Point p = UserOptions.getDialogLocation();
597       if (p != null)
598       {
599          popup.setLocation(p.x, p.y);
600       }
601 
602       popup.addFilter(new net.mchill.log.SeverityFilter(net.mchill.log.Severity.ERROR));
603       net.mchill.log.Log.addHandler(popup);
604 
605       AceDialog sd = new AceDialog(null, true);
606       sd.loadUserOptions();
607 
608       //      sd.fixImageUrl("http://aladin.u-strasbg.fr/java/alapre-test.pl?-c=name+cdfs&out=image&fmt=JPEG&resolution=STAND&qual=GOODS+WFI-B99+____");
609 
610       splash.dispose();
611 
612       sd.show();
613 
614       if (sd.wasCancelled())
615       {
616          Log.trace("...cancelled");
617       }
618       else
619       {
620         Log.trace("Spawning Extraction Thread...");
621 
622       //should set up a JVotBox as a consumer really...
623       Vot2InputPipe pipe = new org.astrogrid.ace.aladin.AladinPiper(sd, sd.getTemplateEditor().passbandPanel);
624 
625       //spawn a thread to run the extraction - auto starts
626       ClientExtractorThread extractorThread =
627          new ClientExtractorThread(
628             sd.getExtractionCriteria(),
629             sd.getAceServer(),
630             pipe
631          );
632 
633       extractorThread.start();
634       }
635    }
636 
637 
638 
639 }
640 
641 
642 
643 /*
644  $Log: AceDialog.java,v $
645  Revision 1.1.1.1  2003/08/25 18:36:04  mch
646  Reimported to fit It02 source structure
647 
648  Revision 1.20  2003/07/11 10:42:08  mch
649  Better trapping & reporting of invalid XML webdoc
650 
651  Revision 1.19  2003/07/02 19:18:49  mch
652  Fix for initial size being v small
653 
654  Revision 1.18  2003/06/26 19:14:04  mch
655  Passband stuff added
656 
657  Revision 1.17  2003/06/18 15:54:43  mch
658  Reintegrated with Aladin on JDK1.4, removed circular dependency
659 
660  Revision 1.16  2002/12/21 12:09:20  mch
661  Added button to edit server config
662 
663  Revision 1.15  2002/12/18 12:58:19  mch
664  Imported from MCHs laptop after Dec AVO Demo meeting in Cambridge
665 
666  Revision 1.14  2002/12/15 12:58:21  mch
667  Removed help
668 
669  Revision 1.13  2002/12/14 20:17:55  mch
670  Removed auto load of user options
671 
672  Revision 1.12  2002/12/13 16:35:07  mch
673  added help, more validation
674 
675  Revision 1.11  2002/12/09 22:49:08  mch
676  New threaded Aladin interface
677 
678  Revision 1.10  2002/12/06 16:33:32  mch
679  Testing Log keyword
680 
681  */
682 
683