001/*
002 * This file is part of McIDAS-V
003 *
004 * Copyright 2007-2015
005 * Space Science and Engineering Center (SSEC)
006 * University of Wisconsin - Madison
007 * 1225 W. Dayton Street, Madison, WI 53706, USA
008 * https://www.ssec.wisc.edu/mcidas
009 * 
010 * All Rights Reserved
011 * 
012 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and
013 * some McIDAS-V source code is based on IDV and VisAD source code.  
014 * 
015 * McIDAS-V is free software; you can redistribute it and/or modify
016 * it under the terms of the GNU Lesser Public License as published by
017 * the Free Software Foundation; either version 3 of the License, or
018 * (at your option) any later version.
019 * 
020 * McIDAS-V is distributed in the hope that it will be useful,
021 * but WITHOUT ANY WARRANTY; without even the implied warranty of
022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
023 * GNU Lesser Public License for more details.
024 * 
025 * You should have received a copy of the GNU Lesser Public License
026 * along with this program.  If not, see http://www.gnu.org/licenses.
027 */
028
029package edu.wisc.ssec.mcidasv.chooser;
030
031import static javax.swing.GroupLayout.Alignment.BASELINE;
032import static javax.swing.GroupLayout.Alignment.LEADING;
033import static javax.swing.GroupLayout.Alignment.TRAILING;
034import static javax.swing.LayoutStyle.ComponentPlacement.RELATED;
035import static javax.swing.LayoutStyle.ComponentPlacement.UNRELATED;
036
037import java.awt.BorderLayout;
038import java.awt.FlowLayout;
039import java.awt.event.ActionEvent;
040import java.awt.event.ActionListener;
041import java.awt.event.KeyEvent;
042import java.awt.event.KeyListener;
043import java.io.File;
044import java.lang.reflect.Method;
045import java.util.ArrayList;
046import java.util.Hashtable;
047import java.util.List;
048import java.util.Map;
049
050import javax.swing.BorderFactory;
051import javax.swing.Box;
052import javax.swing.BoxLayout;
053import javax.swing.GroupLayout;
054import javax.swing.JButton;
055import javax.swing.JComboBox;
056import javax.swing.JComponent;
057import javax.swing.JLabel;
058import javax.swing.JList;
059import javax.swing.JOptionPane;
060import javax.swing.JPanel;
061import javax.swing.JRadioButton;
062import javax.swing.JTextField;
063import javax.swing.SwingUtilities;
064import javax.swing.plaf.FileChooserUI;
065
066import org.slf4j.Logger;
067import org.slf4j.LoggerFactory;
068import org.w3c.dom.Element;
069
070import ucar.unidata.idv.chooser.IdvChooser;
071import ucar.unidata.idv.chooser.IdvChooserManager;
072import ucar.unidata.util.GuiUtils;
073import ucar.unidata.util.PreferenceList;
074import edu.wisc.ssec.mcidasv.Constants;
075import edu.wisc.ssec.mcidasv.chooser.adde.AddeChooser;
076import edu.wisc.ssec.mcidasv.util.McVGuiUtils;
077import edu.wisc.ssec.mcidasv.util.McVGuiUtils.Width;
078import ucar.unidata.xml.XmlObjectStore;
079
080/**
081 * Polar Orbit Track Chooser
082 * Allows user to load TLE files for display in McIDAS-V via three methods:
083 * Remote: ADDE or URL
084 * Local: file
085 *
086 * @author Gail Dengel and Tommy Jasmin
087 */
088public class PolarOrbitTrackChooser extends AddeChooser implements Constants {
089
090    private static final long serialVersionUID = 1L;
091
092    private static final Logger logger = LoggerFactory.getLogger(PolarOrbitTrackChooser.class);
093
094    // chooser for local files
095    TLEFileChooser tlefc = null;
096
097    /** Connect button--we need to be able to disable this. */
098    JButton connectButton = McVGuiUtils.makeImageTextButton(ICON_CONNECT_SMALL, "Connect");
099
100    /** Manage button. */
101    JButton manageButton =
102        McVGuiUtils.makeImageButton("/edu/wisc/ssec/mcidasv/resources/icons/toolbar/preferences-system22.png",
103            this, "doManager", null, "Manage servers");
104
105    /** Public button--we need to draw a menu from this. */
106    JButton publicButton =
107        McVGuiUtils.makeImageButton("/edu/wisc/ssec/mcidasv/resources/icons/toolbar/show-layer-controls22.png",
108            this, "showGroups", null, "List public datasets");
109
110    private JComboBox serverSelector;
111    private JRadioButton localBtn;
112    private JRadioButton addeBtn;
113    private JRadioButton urlBtn;
114    private JLabel descLabel;
115    List<JComponent> addeList = new ArrayList<JComponent>();
116
117    /** Manages the pull down list of URLs. */
118    private PreferenceList prefList;
119
120    /** List of URLs. */
121    private JComboBox box;
122    private JTextField boxEditor;
123
124    private boolean propsOk = false;
125
126    /** Text type. */
127    private static final String TLE_TYPE = "text";
128
129    /** Property ID used to get the list or URLs. */
130    public static final String PREF_URLLIST = "idv.urllist";
131
132    /** Property ID used to determine the last {@literal "source"}. */
133    public static final String PROP_LAST_SOURCE = "mcidasv.chooser.tle.lastsource";
134
135    /** Property value that represents the {@literal "local"} button. */
136    public static final String FILE_SOURCE = "FILE";
137
138    /** Property value that represents the {@literal "ADDE"} button. */
139    public static final String ADDE_SOURCE = "ADDE";
140
141    /** Property value that represents the {@literal "URL"} button. */
142    public static final String URL_SOURCE = "URL";
143
144    /**
145     * Property for the tle server name key.
146     * @see #getServer()
147     */
148    public static String TLE_SERVER_NAME_KEY = "tle_server";
149    public static String URL_NAME_KEY = "url_name";
150    public static String LOCAL_FILE_KEY = "file_object";
151
152    /**
153     * Property for the TLE group name key.
154     * @see #getGroup()
155     */
156    public static String TLE_GROUP_NAME_KEY = "tle_group";
157
158    /** Property for the TLE user ID. */
159    public static String TLE_USER_ID_KEY = "tle_user";
160
161    /** Property for the TLE project number. */
162    public static String TLE_PROJECT_NUMBER_KEY = "tle_proj";
163
164    /** TLE data source identifier. */
165    public static final String TLE_DATA_SOURCE_ID = "TLE";
166
167    /** TLE display type. */
168    public static final String TLE_DISPLAY_TYPE = "tledisplay";
169
170    /** TLE data source type. */
171    public static final String TLE_DATA_TYPE = "TEXT";
172
173    /**
174     * Construct an Adde image selection widget
175     *
176     * @param mgr The chooser manager
177     * @param root The chooser.xml node
178     */
179    public PolarOrbitTrackChooser(IdvChooserManager mgr, Element root) {
180        super(mgr, root);
181        serverSelector = getServerSelector();
182        showServers();
183    }
184    
185    /**
186     * Return the data source ID.
187     *
188     * @return {@link #TLE_DATA_SOURCE_ID}
189     */
190    @Override protected String getDataSourceId() {
191        return TLE_DATA_SOURCE_ID;
192    }
193
194    /**
195     * Make the UI for this selector.
196     *
197     * @return The gui
198     */
199    @Override public JComponent doMakeContents() {
200        logger.debug("doMakeContents() in...");
201        JPanel outerPanel = new JPanel();
202        JPanel addePanel = new JPanel();
203        addePanel = (JPanel)makeAddePanel();
204
205        // retrieve our last visited directory
206        String path = (String)getIdv().getStateManager().getPreference(IdvChooser.PREF_DEFAULTDIR + getId());
207        String file = (String)getIdv().getStateManager().getPreference(IdvChooser.PREF_DEFAULTDIR + getId() + ".file");
208        tlefc = new TLEFileChooser(this, path, file);
209//        tlefc.setPotc(this);
210
211        JButton helpButton = McVGuiUtils.makeImageButton(ICON_HELP, "Show help");
212        helpButton.setActionCommand(GuiUtils.CMD_HELP);
213        helpButton.addActionListener(this);
214
215        JButton refreshButton = McVGuiUtils.makeImageButton(ICON_REFRESH, "Refresh");
216        refreshButton.setActionCommand(GuiUtils.CMD_UPDATE);
217        refreshButton.addActionListener(this);
218
219        McVGuiUtils.setComponentWidth(loadButton, Width.DOUBLE);
220        
221        outerPanel.setLayout(new BorderLayout());
222        JPanel choicePanel = new JPanel(new BorderLayout());
223        JPanel controlPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING));
224        
225        // load the local and remote choices in a Box in center panel
226        JPanel centerPanel = new JPanel();
227        centerPanel.setLayout(new BoxLayout(centerPanel, BoxLayout.PAGE_AXIS));
228        JPanel localPanel = new JPanel(new BorderLayout());
229        
230        // create border like the remote panel (titled) but include the
231        // gap that remote panel creates with various GroupLayout effects
232        localPanel.setBorder(BorderFactory.createCompoundBorder(
233            BorderFactory.createTitledBorder("Local"),
234            BorderFactory.createEmptyBorder(GAP_RELATED, GAP_RELATED, GAP_RELATED, GAP_RELATED)));
235        
236        JPanel remotePanel = new JPanel();
237        remotePanel.setBorder(BorderFactory.createTitledBorder("Remote"));
238        
239        // populate the local access panel
240        localPanel.add(localBtn, BorderLayout.NORTH);
241        localPanel.add(tlefc, BorderLayout.CENTER);
242        
243        // populate the remote access panel
244        remotePanel.add(addePanel);
245        
246        centerPanel.add(localPanel);
247        centerPanel.add(remotePanel);
248        choicePanel.add(centerPanel, BorderLayout.CENTER);
249        
250        outerPanel.add(choicePanel, BorderLayout.CENTER);
251        
252        // populate and add the control panel
253        controlPanel.add(helpButton);
254        controlPanel.add(Box.createHorizontalStrut(5));
255        controlPanel.add(refreshButton);
256        controlPanel.add(Box.createHorizontalStrut(5));
257        controlPanel.add(cancelButton);
258        controlPanel.add(Box.createHorizontalStrut(5));
259        controlPanel.add(loadButton);
260        outerPanel.add(controlPanel, BorderLayout.PAGE_END);
261
262        final XmlObjectStore store = getIdv().getStore();
263        String lastSource = store.get(PROP_LAST_SOURCE, FILE_SOURCE);
264        if (FILE_SOURCE.equals(lastSource)) {
265            localBtn.setSelected(true);
266            for (ActionListener a: localBtn.getActionListeners()) {
267                a.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, null) {
268                    // nothing to do in here
269                });
270            }
271        } else if (ADDE_SOURCE.equals(lastSource)) {
272            addeBtn.setSelected(true);
273            for (ActionListener a: addeBtn.getActionListeners()) {
274                a.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, null) {
275                    // nothing to do in here
276                });
277            }
278        } else if (URL_SOURCE.equals(lastSource)) {
279            urlBtn.setSelected(true);
280            for (ActionListener a: urlBtn.getActionListeners()) {
281                a.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, null) {
282                    // nothing to do in here
283                });
284            }
285        } else {
286            logger.trace("should not be able to arrive here; defaulting to file. (lastSource={})", lastSource);
287            localBtn.setSelected(true);
288        }
289
290        if (localBtn.isSelected()) {
291            File tmp = new File(path + File.separatorChar + file);
292//            logger.trace("attempting to select '{}'", tmp.getAbsolutePath());
293//            tlefc.setSelectedFile(tmp);
294            try {
295                FileChooserUI fcUi = tlefc.getUI();
296                tlefc.setSelectedFile(tmp);
297                Class<? extends FileChooserUI> fcClass = fcUi.getClass();
298//                logger.trace("classname={}", fcClass.getCanonicalName());
299                Method setFileName = fcClass.getMethod("setFileName", String.class);
300                setFileName.invoke(fcUi, tmp.getName());
301//                final JList list = McVGuiUtils.getDescendantOfType(JList.class, this, "Enabled", true);
302//                list.requestFocus();
303            } catch (Exception e) {
304                logger.warn("Could not dynamically invoke setFileName", e);
305            }
306//            logger.trace("selected='{}'", tlefc.getSelectedFile());
307
308
309        }
310        return outerPanel;
311    }
312    
313    /**
314     * Used by the local file chooser to make sure we are in Local Mode
315     * (the radio button is selected).  Helps to retain cleaner state.
316     *
317     * @return true if Local File Mode radio button is selected
318     */
319    public boolean localMode() {
320        if (localBtn.isSelected()) {
321            return true;
322        } else {
323            return false;
324        }
325    }
326
327    private JComponent makeAddePanel() {
328        JPanel outerPanel = new JPanel();
329
330        localBtn = new JRadioButton("File", false);
331        addeBtn = new JRadioButton("ADDE", true);
332        urlBtn = new JRadioButton("URL", false);
333        GuiUtils.buttonGroup(localBtn, addeBtn, urlBtn);
334
335        final XmlObjectStore store = getIdv().getStore();
336
337        localBtn.addActionListener(new ActionListener() {
338            public void actionPerformed(ActionEvent e) {
339                enableLoadFromFile(false);
340                // enable the file chooser
341                if (tlefc != null) {
342                    tlefc.setEnabled(true);
343                    tlefc.handleFileChanged();
344                }
345
346                // disable everything else? Just following pattern below
347                for (int i = 0; i < 5; i++) {
348                    JComponent comp = addeList.get(i);
349                    comp.setEnabled(false);
350                    enableDescriptors(false);
351                }
352                for (int i = 5; i < 7; i++) {
353                    JComponent comp = addeList.get(i);
354                    comp.setEnabled(false);
355                }
356                store.put(PROP_LAST_SOURCE, FILE_SOURCE);
357                store.save();
358            }
359        });
360        
361        // TJJ Nov 2013, I need to figure out what these 
362        // hardcoded component ids are!
363        addeBtn.addActionListener(new ActionListener() {
364            public void actionPerformed(ActionEvent e) {
365                // disable the file chooser
366                if (tlefc != null) {
367                    tlefc.setEnabled(false);
368                }
369                enableLoadFromAdde(true);
370                for (int i = 0; i < 5; i++) {
371                    JComponent comp = addeList.get(i);
372                    comp.setEnabled(true);
373                    enableDescriptors(true);
374                }
375                for (int i = 5; i < 7; i++) {
376                    JComponent comp = addeList.get(i);
377                    comp.setEnabled(false);
378                }
379                store.put(PROP_LAST_SOURCE, ADDE_SOURCE);
380                store.save();
381            }
382        });
383
384        final JLabel urlLabel = new JLabel("URL:");
385        // TJJ Nov 2013, I need to figure out what these 
386        // hardcoded component ids are!
387        urlBtn.addActionListener(new ActionListener() {
388            public void actionPerformed(ActionEvent e) {
389//                logger.trace("url button");
390                // disable the file chooser
391                if (tlefc != null) {
392                    tlefc.setEnabled(false);
393                }
394                for (int i = 5; i < 7; i++) {
395                    JComponent comp = addeList.get(i);
396                    comp.setEnabled(true);
397                }
398                enableLoadFromUrl(true);
399                for (int i = 0; i < 5; i++) {
400                    JComponent comp = addeList.get(i);
401                    comp.setEnabled(false);
402                    enableDescriptors(false);
403                }
404                urlLabel.setEnabled(true);
405                box.setEnabled(true);
406                store.put(PROP_LAST_SOURCE, URL_SOURCE);
407                store.save();
408            }
409        });
410        JLabel serverLabel = new JLabel("Server:");
411
412        descLabel = new JLabel("Descriptor:");
413        descLabel.setEnabled(false);
414        descriptorComboBox.setEnabled(false);
415
416        clearOnChange(serverSelector);
417        McVGuiUtils.setComponentWidth(serverSelector, Width.DOUBLE);
418
419        JLabel groupLabel = McVGuiUtils.makeLabelRight("Dataset:");
420
421        groupSelector.setEditable(isGroupEditable());
422        clearOnChange(groupSelector);
423        McVGuiUtils.setComponentWidth(groupSelector, Width.DOUBLE);
424
425        McVGuiUtils.setComponentWidth(connectButton, Width.DOUBLE);
426        connectButton.setActionCommand(CMD_CONNECT);
427        connectButton.addActionListener(this);
428
429        prefList = getPreferenceList(PREF_URLLIST);
430        box = prefList.createComboBox(CMD_LOAD, this);
431        boxEditor = (JTextField) box.getEditor().getEditorComponent();
432        boxEditor.addKeyListener(new KeyListener() {
433            public void keyPressed(KeyEvent e) {}
434            public void keyReleased(KeyEvent e) {}
435            public void keyTyped(KeyEvent e) {}
436        });
437        urlLabel.setEnabled(false);
438        box.setEnabled(false);
439
440        GroupLayout layout = new GroupLayout(outerPanel);
441        outerPanel.setLayout(layout);
442        layout.setHorizontalGroup(
443            layout.createParallelGroup(LEADING)
444            .addGroup(TRAILING, layout.createSequentialGroup()
445                .addGroup(layout.createParallelGroup(TRAILING)
446                        .addGroup(LEADING, layout.createSequentialGroup()
447                        .addGroup(layout.createParallelGroup(LEADING)
448                        .addComponent(addeBtn)
449                        .addGroup(layout.createSequentialGroup()
450                            .addComponent(serverLabel)
451                            .addGap(GAP_RELATED)
452                            .addComponent(serverSelector)
453                            .addGap(GAP_RELATED)
454                            .addComponent(manageButton)
455                            .addGap(GAP_RELATED)
456                            .addComponent(groupLabel)
457                            .addGap(GAP_RELATED)
458                            .addComponent(groupSelector)
459                            .addGap(GAP_RELATED)
460                            .addComponent(publicButton)
461                            .addPreferredGap(RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
462                            .addComponent(connectButton))
463                        .addGroup(layout.createSequentialGroup()
464                            .addComponent(descLabel)
465                            .addGap(GAP_RELATED)
466                            .addComponent(descriptorComboBox))
467                            .addGap(GAP_RELATED)
468                        .addComponent(urlBtn)
469                        .addGroup(layout.createSequentialGroup()
470                            .addComponent(urlLabel)
471                            .addGap(GAP_RELATED)
472                            .addComponent(box))))))
473        );
474
475        layout.setVerticalGroup(
476            layout.createParallelGroup(LEADING)
477            .addGroup(layout.createSequentialGroup()
478                .addComponent(addeBtn)
479                .addGroup(layout.createParallelGroup(BASELINE)
480                    .addComponent(serverLabel)
481                    .addComponent(serverSelector)
482                    .addComponent(manageButton)
483                    .addComponent(groupLabel)
484                    .addComponent(groupSelector)
485                    .addComponent(publicButton)
486                    .addComponent(connectButton))
487                .addPreferredGap(RELATED)
488                .addGroup(layout.createParallelGroup(BASELINE)
489                    .addComponent(descLabel)
490                    .addComponent(descriptorComboBox))
491                .addPreferredGap(UNRELATED)
492                .addComponent(urlBtn)
493                .addGroup(layout.createParallelGroup(BASELINE)
494                    .addComponent(urlLabel)
495                    .addComponent(box)))
496        );
497
498        addeList.add(serverLabel);
499        addeList.add(serverSelector);
500        addeList.add(groupLabel);
501        addeList.add(groupSelector);
502        addeList.add(connectButton);
503        McVGuiUtils.setComponentWidth(descriptorComboBox, Width.DOUBLEDOUBLE);
504        addeList.add(urlLabel);
505        addeList.add(box);
506
507//        String lastSource = store.get(PROP_LAST_SOURCE, FILE_SOURCE);
508//        if (FILE_SOURCE.equals(lastSource)) {
509//            localBtn.setSelected(true);
510//            for (ActionListener a: localBtn.getActionListeners()) {
511//                a.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, null) {
512//                    // nothing to do in here
513//                });
514//            }
515//        } else if (ADDE_SOURCE.equals(lastSource)) {
516//            addeBtn.setSelected(true);
517//            for (ActionListener a: addeBtn.getActionListeners()) {
518//                a.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, null) {
519//                    // nothing to do in here
520//                });
521//            }
522//        } else if (URL_SOURCE.equals(lastSource)) {
523//            urlBtn.setSelected(true);
524//            for (ActionListener a: urlBtn.getActionListeners()) {
525//                a.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, null) {
526//                    // nothing to do in here
527//                });
528//            }
529//        } else {
530//            logger.trace("should not be able to arrive here; defaulting to file. (lastSource={})", lastSource);
531//            localBtn.setSelected(true);
532//        }
533
534        return outerPanel;
535    }
536
537    public void enableLoadFromFile(boolean val) {
538//        logger.trace("val={}", val);
539        loadButton.setEnabled(val);
540        if (tlefc != null && tlefc.getSelectedFile() != null) {
541            setHaveData(val);
542        }
543    }
544
545    public void enableLoadFromAdde(boolean val) {
546//        logger.trace("val={}", val);
547        if (val && descriptorComboBox.isEnabled() && getSelectedDescriptor() != null) {
548            loadButton.setEnabled(val);
549        } else {
550            loadButton.setEnabled(val);
551        }
552    }
553
554    public void enableLoadFromUrl(boolean val) {
555//        logger.trace("val={}", val);
556        loadButton.setEnabled(val);
557        String url = (String)box.getSelectedItem();
558        if (val && url != null && !url.isEmpty()) {
559            setHaveData(true);
560        } else {
561            setHaveData(val);
562        }
563    }
564
565    public void enableFileLoad(boolean val) {
566//        logger.trace("loadButton={}", val);
567        loadButton.setEnabled(val);
568    }
569
570    private void enableDescriptors(boolean val) {
571//        logger.trace("descriptors={}", val);
572        if (val) {
573            boolean connected;
574            if (getState() == STATE_CONNECTED) {
575                connected = true;
576            } else {
577                connected = false;
578            }
579            if (connected) {
580                descLabel.setEnabled(true);
581                descriptorComboBox.setEnabled(true);
582            } else {
583                descLabel.setEnabled(false);
584                descriptorComboBox.setEnabled(false);
585            }
586        } else {
587            descLabel.setEnabled(false);
588            descriptorComboBox.setEnabled(false);
589        }
590    }
591
592    @Override protected boolean getGoodToGo() {
593        final XmlObjectStore store = getIdv().getStore();
594        String lastSource = store.get(PROP_LAST_SOURCE, FILE_SOURCE);
595        boolean goodToGo = false;
596        if (URL_SOURCE.equals(lastSource)) {
597            goodToGo = true;
598        }
599        return goodToGo;
600    }
601
602    /**
603     * Update labels, enable widgets, etc.
604     */
605    @Override protected void updateStatus() {
606//        if (localBtn != null && addeBtn != null && urlBtn != null) {
607//            logger.trace("updating status fromFile={} fromAdde={} fromUrl={}", localBtn.isSelected(), addeBtn.isSelected(), urlBtn.isSelected());
608//        }
609        super.updateStatus();
610        enableWidgets();
611        if ((addeBtn != null) && addeBtn.isSelected()) {
612            enableLoadFromAdde(true);
613        }
614    }
615
616    /**
617     * Get the data type ID.
618     *
619     * @return {@link #TLE_DATA_TYPE}
620     */
621    @Override public String getDataType() {
622        return TLE_DATA_TYPE;
623    }
624
625    /**
626     * Get the adde server group type to use.
627     *
628     * @return {@link #TLE_TYPE}
629     */
630    @Override protected String getGroupType() {
631        return TLE_TYPE;
632    }
633
634    /**
635     * User said go, we go. 
636     * Create the TLE DataSource
637     */
638    @Override public void doLoadInThread() {
639        prefList.saveState(box);
640        String dsName = TLE_DATA_SOURCE_ID;
641        if (tlefc.getSelectedFile() != null) {
642            dsName = tlefc.getSelectedFile().getName();
643        }
644        Hashtable ht = new Hashtable();
645        getDataSourceProperties(ht);
646        if (propsOk) {
647            makeDataSource(dsName, TLE_DATA_SOURCE_ID, ht);
648            saveServerState();
649        }
650    }
651
652    /**
653     * Get the DataSource properties
654     * 
655     * @param ht Hashtable of properties
656     */
657    @Override protected void getDataSourceProperties(Hashtable ht) {
658
659        // Local data
660        if (localBtn.isSelected()) {
661            if (tlefc.getSelectedFile() != null) {
662                // local file, set a new key...
663                ht.put(LOCAL_FILE_KEY, tlefc.getSelectedFile());
664                propsOk = true;
665            } else {
666                JOptionPane.showMessageDialog(this, "No file selected.");
667                propsOk = false;
668            }
669        }
670
671        // Remote data, ADDE
672        if (addeBtn.isSelected()) {
673            if (getState() == STATE_CONNECTED) {
674                super.getDataSourceProperties(ht);
675                ht.put(DATASET_NAME_KEY, getDatasetName());
676                String server = getServer();
677                ht.put(TLE_SERVER_NAME_KEY, server);
678                String group = getGroup();
679                ht.put(TLE_GROUP_NAME_KEY, group);
680                Map<String, String> acct = getAccounting(server, group);
681                String user = acct.get("user");
682                String proj = acct.get("proj");
683                ht.put(TLE_USER_ID_KEY, user);
684                ht.put(TLE_PROJECT_NUMBER_KEY, proj);
685                propsOk = true;
686            } else {
687                JOptionPane.showMessageDialog(this, "No ADDE server connection.");
688                propsOk = false;
689            }
690        }
691
692        // Remote or Local, URL
693        if (urlBtn.isSelected()) {
694            String s = (String) box.getSelectedItem();
695            if ((s != null) && !s.isEmpty()) {
696                ht.put(URL_NAME_KEY, box.getSelectedItem());
697                propsOk = true;
698            } else {
699                JOptionPane.showMessageDialog(this, "Please provide a valid URL.");
700                propsOk = false;
701            }
702        }
703    }
704
705    private String getDatasetName() {
706        return (String) descriptorComboBox.getSelectedItem();
707    }
708
709    @Override public void handleConnectFromThread() {
710        super.handleConnectFromThread();
711        enableDescriptors(true);
712    }
713
714    /**
715     * Get the default display type.
716     *
717     * @return {@link #TLE_DISPLAY_TYPE}
718     */
719    @Override protected String getDefaultDisplayType() {
720        return TLE_DISPLAY_TYPE;
721    }
722}