001 /* 002 * $Id: AddeChooser.java,v 1.87 2012/02/19 17:35:35 davep Exp $ 003 * 004 * This file is part of McIDAS-V 005 * 006 * Copyright 2007-2012 007 * Space Science and Engineering Center (SSEC) 008 * University of Wisconsin - Madison 009 * 1225 W. Dayton Street, Madison, WI 53706, USA 010 * https://www.ssec.wisc.edu/mcidas 011 * 012 * All Rights Reserved 013 * 014 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and 015 * some McIDAS-V source code is based on IDV and VisAD source code. 016 * 017 * McIDAS-V is free software; you can redistribute it and/or modify 018 * it under the terms of the GNU Lesser Public License as published by 019 * the Free Software Foundation; either version 3 of the License, or 020 * (at your option) any later version. 021 * 022 * McIDAS-V is distributed in the hope that it will be useful, 023 * but WITHOUT ANY WARRANTY; without even the implied warranty of 024 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 025 * GNU Lesser Public License for more details. 026 * 027 * You should have received a copy of the GNU Lesser Public License 028 * along with this program. If not, see http://www.gnu.org/licenses. 029 */ 030 031 package edu.wisc.ssec.mcidasv.chooser.adde; 032 033 import static edu.wisc.ssec.mcidasv.servermanager.AddeEntry.DEFAULT_ACCOUNT; 034 import static edu.wisc.ssec.mcidasv.util.CollectionHelpers.arrList; 035 import static edu.wisc.ssec.mcidasv.McIDASV.isLoopback; 036 037 import static javax.swing.GroupLayout.DEFAULT_SIZE; 038 import static javax.swing.GroupLayout.Alignment.BASELINE; 039 import static javax.swing.GroupLayout.Alignment.LEADING; 040 import static javax.swing.GroupLayout.Alignment.TRAILING; 041 import static javax.swing.LayoutStyle.ComponentPlacement.RELATED; 042 import static javax.swing.LayoutStyle.ComponentPlacement.UNRELATED; 043 044 import java.awt.Component; 045 import java.awt.event.ActionEvent; 046 import java.awt.event.ActionListener; 047 import java.awt.event.ItemEvent; 048 import java.awt.event.ItemListener; 049 import java.awt.event.KeyEvent; 050 import java.awt.event.KeyListener; 051 import java.awt.event.MouseAdapter; 052 import java.awt.event.MouseEvent; 053 import java.io.EOFException; 054 import java.io.InputStream; 055 import java.net.ConnectException; 056 import java.net.URL; 057 import java.net.URLConnection; 058 import java.util.ArrayList; 059 import java.util.Arrays; 060 import java.util.Collections; 061 import java.util.Comparator; 062 import java.util.Enumeration; 063 import java.util.HashMap; 064 import java.util.Hashtable; 065 import java.util.LinkedHashMap; 066 import java.util.List; 067 import java.util.Map; 068 import java.util.Vector; 069 070 import javax.swing.GroupLayout; 071 import javax.swing.JButton; 072 import javax.swing.JCheckBox; 073 import javax.swing.JComboBox; 074 import javax.swing.JComponent; 075 import javax.swing.JLabel; 076 import javax.swing.JMenu; 077 import javax.swing.JMenuItem; 078 import javax.swing.JPanel; 079 import javax.swing.JPopupMenu; 080 import javax.swing.JTabbedPane; 081 import javax.swing.JTextField; 082 import javax.swing.SwingUtilities; 083 084 import org.bushe.swing.event.annotation.AnnotationProcessor; 085 import org.bushe.swing.event.annotation.EventSubscriber; 086 import org.slf4j.Logger; 087 import org.slf4j.LoggerFactory; 088 import org.w3c.dom.Element; 089 090 import edu.wisc.ssec.mcidas.adde.AddeURLException; 091 import edu.wisc.ssec.mcidas.adde.DataSetInfo; 092 093 import visad.DateTime; 094 095 import ucar.unidata.idv.chooser.IdvChooser; 096 import ucar.unidata.idv.chooser.IdvChooserManager; 097 import ucar.unidata.idv.chooser.adde.AddeServer; 098 import ucar.unidata.idv.chooser.adde.AddeServer.Group; 099 import ucar.unidata.util.DatedThing; 100 import ucar.unidata.util.GuiUtils; 101 import ucar.unidata.util.LogUtil; 102 import ucar.unidata.util.Misc; 103 import ucar.unidata.util.PreferenceList; 104 import ucar.unidata.util.StringUtil; 105 import ucar.unidata.xml.XmlObjectStore; 106 107 import edu.wisc.ssec.mcidasv.Constants; 108 import edu.wisc.ssec.mcidasv.McIDASV; 109 import edu.wisc.ssec.mcidasv.ParameterSet; 110 import edu.wisc.ssec.mcidasv.PersistenceManager; 111 import edu.wisc.ssec.mcidasv.servermanager.AddeAccount; 112 import edu.wisc.ssec.mcidasv.servermanager.AddeEntry; 113 import edu.wisc.ssec.mcidasv.servermanager.AddeEntry.EditorAction; 114 import edu.wisc.ssec.mcidasv.servermanager.AddeEntry.EntryType; 115 import edu.wisc.ssec.mcidasv.servermanager.EntryStore; 116 import edu.wisc.ssec.mcidasv.servermanager.EntryTransforms; 117 import edu.wisc.ssec.mcidasv.servermanager.LocalEntryEditor; 118 import edu.wisc.ssec.mcidasv.servermanager.RemoteAddeEntry; 119 import edu.wisc.ssec.mcidasv.servermanager.RemoteEntryEditor; 120 import edu.wisc.ssec.mcidasv.servermanager.TabbedAddeManager; 121 import edu.wisc.ssec.mcidasv.ui.ParameterTree; 122 import edu.wisc.ssec.mcidasv.ui.UIManager; 123 import edu.wisc.ssec.mcidasv.util.CollectionHelpers; 124 import edu.wisc.ssec.mcidasv.util.McVGuiUtils; 125 import edu.wisc.ssec.mcidasv.util.McVGuiUtils.Position; 126 import edu.wisc.ssec.mcidasv.util.McVGuiUtils.TextColor; 127 import edu.wisc.ssec.mcidasv.util.McVGuiUtils.Width; 128 129 /** 130 * 131 * @version $Revision: 1.87 $ 132 */ 133 public class AddeChooser extends ucar.unidata.idv.chooser.adde.AddeChooser implements Constants { 134 135 private static final Logger logger = LoggerFactory.getLogger(AddeChooser.class); 136 137 private JComboBox serverSelector; 138 139 /** List of descriptors */ 140 private PreferenceList descList; 141 142 /** Descriptor/name hashtable */ 143 protected Hashtable descriptorTable; 144 145 /** Property for the descriptor table */ 146 public static final String DESCRIPTOR_TABLE = "DESCRIPTOR_TABLE"; 147 148 /** Connect button--we need to be able to disable this */ 149 JButton connectButton = McVGuiUtils.makeImageTextButton(ICON_CONNECT_SMALL, "Connect"); 150 151 /** Parameter button--we need to be able to disable this */ 152 JButton parameterButton = 153 McVGuiUtils.makeImageButton("/edu/wisc/ssec/mcidasv/resources/icons/toolbar/document-open22.png", 154 this, "doParameters", null, "Load parameter set"); 155 156 /** Manage button */ 157 JButton manageButton = 158 McVGuiUtils.makeImageButton("/edu/wisc/ssec/mcidasv/resources/icons/toolbar/preferences-system22.png", 159 this, "doManager", null, "Manage servers"); 160 161 /** Public button--we need to draw a menu from this */ 162 JButton publicButton = 163 McVGuiUtils.makeImageButton("/edu/wisc/ssec/mcidasv/resources/icons/toolbar/show-layer-controls22.png", 164 this, "showGroups", null, "List public datasets"); 165 166 /** descriptor label */ 167 protected JLabel descriptorLabel = new JLabel(getDescriptorLabel()+":"); 168 169 /** A widget for the list of dataset descriptors */ 170 protected JComboBox descriptorComboBox = new JComboBox(); 171 172 /** The descriptor names */ 173 protected String[] descriptorNames; 174 175 /** Flag to keep from infinite looping */ 176 protected boolean ignoreDescriptorChange = false; 177 178 /** 179 * List of JComponent-s that depend on a descriptor being selected 180 * to be enabled 181 */ 182 protected ArrayList compsThatNeedDescriptor = new ArrayList(); 183 184 /** Selection label text */ 185 protected String LABEL_SELECT = " -- Select -- "; 186 187 /** Separator string */ 188 protected static String separator = "----------------"; 189 190 /** Name separator string */ 191 protected static String nameSeparator = " - "; 192 193 /** Reference back to the server manager */ 194 protected EntryStore serverManager; 195 196 public boolean allServersFlag; 197 198 /** Command for opening up the server manager */ 199 protected static final String CMD_MANAGER = "cmd.manager"; 200 201 private String lastBadServer = ""; 202 private String lastBadGroup = ""; 203 204 private String lastServerName = ""; 205 private String lastServerGroup = ""; 206 private String lastServerUser = ""; 207 private String lastServerProj = ""; 208 private AddeServer lastServer = new AddeServer(""); 209 210 private List<AddeServer> addeServers; 211 212 /** Used for parameter set restore */ 213 private static final String TAG_FOLDER = "folder"; 214 private static final String TAG_DEFAULT = "default"; 215 private static final String ATTR_NAME = "name"; 216 private static final String ATTR_SERVER = "server"; 217 private static final String ATTR_GROUP = "GROUP"; 218 private static final String ATTR_DESCRIPTOR = "DESCRIPTOR"; 219 private static final String ATTR_POS = "POS"; 220 private static final String ATTR_DAY = "DAY"; 221 private static final String ATTR_TIME = "TIME"; 222 private List restoreTimes = new ArrayList(); 223 public Element restoreElement; 224 private boolean shouldAddSource = false; 225 final JCheckBox cb = new JCheckBox("Add source",shouldAddSource); 226 227 /** Maps favorite type to the BundleTree that shows the Manage window for the type */ 228 private Hashtable parameterTrees = new Hashtable(); 229 230 /** 231 * Create an AddeChooser associated with an IdvChooser 232 * 233 * @param mgr The chooser manager 234 * @param root The chooser.xml node 235 */ 236 public AddeChooser(IdvChooserManager mgr, Element root) { 237 super(mgr, root); 238 AnnotationProcessor.process(this); 239 simpleMode = !getProperty(IdvChooser.ATTR_SHOWDETAILS, true); 240 241 loadButton = McVGuiUtils.makeImageTextButton(ICON_ACCEPT_SMALL, getLoadCommandName()); 242 loadButton.setActionCommand(getLoadCommandName()); 243 loadButton.addActionListener(this); 244 245 cancelButton = McVGuiUtils.makeImageButton(ICON_CANCEL, "Cancel"); 246 cancelButton.setActionCommand(GuiUtils.CMD_CANCEL); 247 cancelButton.addActionListener(this); 248 cancelButton.setEnabled(false); 249 250 serverSelector = getServerSelector(); 251 252 serverSelector.setToolTipText("Right click to manage servers"); 253 serverSelector.getEditor().getEditorComponent().addMouseListener( 254 new MouseAdapter() { 255 public void mouseReleased(MouseEvent e) { 256 if (!SwingUtilities.isRightMouseButton(e)) { 257 return; 258 } 259 260 AddeServer server = getAddeServer(); 261 if (server == null) { 262 return; 263 } 264 List<JMenuItem> items = new ArrayList<JMenuItem>(); 265 266 // Set the right-click behavior 267 if (isLocalServer()) { 268 items.add(GuiUtils.makeMenuItem("Manage local ADDE data", 269 AddeChooser.this, 270 "doManager", null)); 271 } 272 else { 273 items.add(GuiUtils.makeMenuItem("Manage ADDE servers", 274 AddeChooser.this, 275 "doManager", null)); 276 } 277 JPopupMenu popup = GuiUtils.makePopupMenu(items); 278 popup.show(serverSelector, e.getX(), e.getY()); 279 } 280 }); 281 serverSelector.setMaximumRowCount(16); 282 283 groupSelector.setToolTipText("Right click to manage servers"); 284 groupSelector.getEditor().getEditorComponent().addMouseListener( 285 new MouseAdapter() { 286 public void mouseReleased(MouseEvent e) { 287 if (!SwingUtilities.isRightMouseButton(e)) { 288 return; 289 } 290 291 AddeServer server = getAddeServer(); 292 if (server == null) { 293 return; 294 } 295 List<JMenuItem> items = new ArrayList<JMenuItem>(); 296 297 // Set the right-click behavior 298 if (isLocalServer()) { 299 items.add(GuiUtils.makeMenuItem("Manage local ADDE data", 300 AddeChooser.this, "doManager", null)); 301 } 302 else { 303 items.add(GuiUtils.makeMenuItem("Manage ADDE servers", 304 AddeChooser.this, "doManager", null)); 305 } 306 JPopupMenu popup = GuiUtils.makePopupMenu(items); 307 popup.show(groupSelector, e.getX(), e.getY()); 308 } 309 }); 310 groupSelector.setMaximumRowCount(16); 311 312 // serverManager = ((McIDASV)getIdv()).getServerManager(); 313 // serverManager.addManagedChooser(this); 314 addServerComp(descriptorLabel); 315 // addServerComp(descriptorComboBox); 316 317 descriptorComboBox.addItemListener(new ItemListener() { 318 public void itemStateChanged(ItemEvent e) { 319 if ( !ignoreDescriptorChange 320 && (e.getStateChange() == e.SELECTED)) { 321 descriptorChanged(); 322 } 323 } 324 }); 325 326 // Update the server list and load the saved state 327 updateServerList(); 328 loadServerState(); 329 330 // Default to no parameter button unless the overriding class wants one 331 hideParameterButton(); 332 } 333 334 /** 335 * Force a reload of the available servers and groups. 336 */ 337 public void updateServerList() { 338 updateServers(); 339 updateGroups(); 340 } 341 342 /** 343 * Returns a {@link java.util.Map Map} containing {@code user} and {@code proj} 344 * keys for the given {@code server/group} combination. 345 * 346 * <p>The values are either the specific ADDE account details for 347 * {@code server/group} or {@link edu.wisc.ssec.mcidasv.servermanager.AddeEntry#DEFAULT_ACCOUNT DEFAULT_ACCOUNT} 348 * values. 349 * 350 * @param server Server name. Should not be {@code null}. 351 * @param group Group name on {@code name}. Should not be {@code null}. 352 * 353 * @return {@code Map} containing the accounting details for {@code server/group}. 354 */ 355 protected Map<String, String> getAccounting(final String server, final String group) { 356 Map<String, String> acctInfo = new HashMap<String, String>(); 357 EntryStore entryStore = ((McIDASV)getIdv()).getServerManager(); 358 String strType = this.getDataType(); 359 EntryType type = EntryTransforms.strToEntryType(strType); 360 AddeAccount acct = entryStore.getAccountingFor(server, group, type); 361 acctInfo.put("user", acct.getUsername()); 362 acctInfo.put("proj", acct.getProject()); 363 return acctInfo; 364 } 365 366 /** 367 * Returns a {@link java.util.Map Map} containing {@code user} and {@code proj} 368 * keys for the given {@code server/group} combination. 369 * 370 * <p>The values are either the specific ADDE account details for 371 * {@code server/group} or {@link edu.wisc.ssec.mcidasv.servermanager.AddeEntry#DEFAULT_ACCOUNT DEFAULT_ACCOUNT} 372 * values. 373 * 374 * @param server Server name. Should not be {@code null}. 375 * @param group Group name on {@code name}. Should not be {@code null}. 376 * 377 * @return {@code Map} containing the accounting details for {@code server/group}. 378 */ 379 protected Map<String, String> getAccounting(final AddeServer server, final String group) { 380 return getAccounting(server.getName(), group); 381 } 382 383 private List<AddeServer> getManagedServers(final String type) { 384 EntryStore entryStore = ((McIDASV)getIdv()).getServerManager(); 385 return arrList(entryStore.getIdvStyleEntries(type)); 386 } 387 388 public void updateServers() { 389 Object selected = serverSelector.getSelectedItem(); 390 391 String type = getGroupType(); 392 List<AddeServer> managedServers = getManagedServers(type); 393 List<AddeServer> localList = arrList(); 394 List<AddeServer> remoteList = arrList(); 395 addeServers = CollectionHelpers.arrList(); 396 for (AddeServer server : managedServers) { 397 if (server.getIsLocal()) 398 localList.add(server); 399 else 400 remoteList.add(server); 401 } 402 403 logger.debug("{}: updateServers: local size={} contents={}", new Object[] { getDataType(), localList.size(), localList }); 404 logger.debug("{}: updateServers: remote size={} contents={}", new Object[] { getDataType(), remoteList.size(), remoteList }); 405 406 // server list doesn't need a separator if there's only remote servers 407 if (!localList.isEmpty()) { 408 addeServers.addAll(localList); 409 addeServers.add(new AddeServer(separator)); 410 } 411 Comparator<AddeServer> byServer = new ServerComparator(); 412 Collections.sort(remoteList, byServer); 413 addeServers.addAll(remoteList); 414 415 // always making this call helps to ensure the chooser stays up to date 416 // with the server manager. 417 GuiUtils.setListData(serverSelector, addeServers); 418 if (!addeServers.isEmpty()) { 419 if (selected == null || !containsServerName(addeServers, selected)) { 420 selected = serverSelector.getItemAt(0); 421 logger.debug("updateServers: selecting item at idx=0, item={} chooser={}", selected, this.getDataType()); 422 } 423 424 int index = getSelectorIndex(selected, serverSelector); 425 serverSelector.setSelectedIndex(index); 426 } 427 } 428 429 /** 430 * Searches the given {@link java.util.List List} of {@link ucar.unidata.idv.chooser.AddeServer AddeServers} 431 * for {@code server}. 432 * 433 * @param servers Servers to search. {@code null} is permitted. 434 * @param server Server to search for within {@code servers}. {@code null} is permitted. 435 * 436 * @return {@code true} if {@code servers} contains {@code server} or {@code false} otherwise. 437 */ 438 protected static boolean containsServerName(final List<AddeServer> servers, final Object server) { 439 if (servers == null || server == null) { 440 return false; 441 } 442 String serverName = (server instanceof AddeServer) ? ((AddeServer)server).getName() : server.toString(); 443 for (AddeServer tmp : servers) { 444 if (tmp.getName().equals(serverName)) { 445 return true; 446 } 447 } 448 return false; 449 } 450 451 /** 452 * Searches the given {@link java.util.List List} of {@link ucar.unidata.idv.chooser.AddeServer.Group Groups} 453 * for {@code group}. 454 * 455 * @param groups Groups to search. {@code null} is permitted. 456 * @param group Group to search for within {@code group}. {@code null} is permitted. 457 * 458 * @return {@code true} if {@code groups} contains {@code group} or {@code false} otherwise. 459 */ 460 protected static boolean containsGroupName(final List<Group> groups, final Object group) { 461 if (groups == null || group == null) { 462 return false; 463 } 464 String groupName = (group instanceof Group) ? ((Group)group).getName() : group.toString(); 465 for (Group tmp : groups) { 466 if (tmp.getName().equals(groupName)) { 467 return true; 468 } 469 } 470 return false; 471 } 472 473 /** 474 * Sort the groups alphabetically 475 */ 476 public void updateGroups() { 477 if (addingServer || groupSelector == null || getAddeServer() == null) 478 return; 479 480 Object selected = groupSelector.getSelectedItem(); 481 482 EntryStore servManager = ((McIDASV)getIdv()).getServerManager(); 483 484 List<Group> groups = CollectionHelpers.arrList(); 485 if (isLocalServer()) { 486 groups.addAll(servManager.getIdvStyleLocalGroups()); 487 } else { 488 String sel = null; 489 Object obj = serverSelector.getSelectedItem(); 490 if (obj instanceof String) { 491 sel = (String)obj; 492 logger.debug("updateGroups: string={} chooser={}", sel, this.getDataType()); 493 } else if (obj instanceof AddeServer) { 494 sel = ((AddeServer)obj).getName(); 495 logger.debug("updateGroups: server selection={} chooser={}", sel, this.getDataType()); 496 } else { 497 sel = obj.toString(); 498 logger.debug("updateGroups: unknown type={}; toString={}", sel.getClass().getName(), sel); 499 } 500 501 EntryType selType = EntryTransforms.strToEntryType(getGroupType()); 502 groups.addAll(servManager.getIdvStyleRemoteGroups(sel, selType)); 503 } 504 logger.trace("updateGroups: selected={} (type={}) chooser={} contents={}", new Object[] { serverSelector.getSelectedItem(), serverSelector.getSelectedItem().getClass().getName(), this.getDataType(), groups}); 505 Comparator<Group> byGroup = new GroupComparator(); 506 Collections.sort(groups, byGroup); 507 GuiUtils.setListData(groupSelector, groups); 508 if (!groups.isEmpty()) { 509 if (selected == null || !containsGroupName(groups, selected)) { 510 selected = groupSelector.getItemAt(0); 511 } 512 groupSelector.setSelectedItem(selected); 513 } 514 } 515 516 /** 517 * Load any saved server state 518 */ 519 //TODO: Make loadServerState protected in IDV, remove from here 520 private void loadServerState() { 521 if (addeServers == null) { 522 logger.debug("loadServerState: addeServers == null chooser={}", this.getDataType()); 523 return; 524 } 525 String id = getId(); 526 String[] serverState = 527 (String[]) getIdv().getStore().get(Constants.PREF_SERVERSTATE + '.' + id); 528 if (serverState == null) { 529 // serverState = Constants.DEFAULT_SERVERSTATE; 530 logger.debug("loadServerState: serverState == null chooser={}",this.getDataType()); 531 return; 532 } 533 AddeServer server = AddeServer.findServer(addeServers, serverState[0]); 534 if (server == null) { 535 logger.debug("loadServerState: server == null chooser={}",this.getDataType()); 536 return; 537 } 538 logger.debug("loadServerState: selecting server={} chooser={}", server, this.getDataType()); 539 serverSelector.setSelectedItem(server); 540 setGroups(); 541 updateGroups(); 542 if (serverState[1] != null) { 543 Group group = new Group(getDataType(), serverState[1], serverState[1]); 544 int index = getSelectorIndex(group, groupSelector); 545 if (index >= 0) { 546 logger.debug("loadServerState: selecting index={} group={} chooser={}", new Object[] { index, group, this.getDataType() }); 547 groupSelector.setSelectedIndex(index); 548 } else { 549 logger.debug("loadServerState: group == null chooser={}", this.getDataType()); 550 } 551 } else { 552 logger.debug("loadServerState: serverState[1] == null chooser={}", this.getDataType()); 553 } 554 } 555 556 /** 557 * Decide if the server you're asking about is actually a separator 558 */ 559 protected static boolean isSeparator(AddeServer checkServer) { 560 if (checkServer != null) { 561 if (checkServer.getName().equals(separator)) { 562 return true; 563 } 564 } 565 return false; 566 } 567 568 /** 569 * Decide if the server you're asking about is local 570 */ 571 protected boolean isLocalServer() { 572 return isLocalServer(getAddeServer()); 573 } 574 575 protected static boolean isLocalServer(AddeServer checkServer) { 576 if (checkServer != null) { 577 return checkServer.getIsLocal(); 578 } 579 return false; 580 } 581 582 private void setBadServer(String name, String group) { 583 if (name == null) { 584 name = ""; 585 } 586 if (group == null) { 587 group = ""; 588 } 589 590 lastBadServer = name; 591 lastBadGroup = group; 592 } 593 594 private boolean isBadServer(String name, String group) { 595 assert lastBadServer != null; 596 assert lastBadGroup != null; 597 return lastBadServer.equals(name) && lastBadGroup.equals(group); 598 } 599 600 private void setLastServer(String name, String group, AddeServer server) { 601 logger.trace("name='{}' group='{}' server='{}' old: name='{}' group='{}' server='{}'", new Object[] { name, group, server, lastServerName, lastServerGroup, lastServer }); 602 if (name == null) { 603 name = ""; 604 } 605 if (group == null) { 606 group = ""; 607 } 608 if (server == null) { 609 server = new AddeServer(name); 610 Group addeGroup = new Group(getDataType(), group, group); 611 server.addGroup(addeGroup); 612 } 613 lastServerName = name; 614 lastServerGroup = group; 615 lastServer = server; 616 } 617 618 private boolean isLastServer(String name, String group) { 619 assert lastServer != null; 620 assert lastServerName != null; 621 assert lastServerGroup != null; 622 return lastServerName.equals(name) && lastServerGroup.equals(group); 623 } 624 625 @EventSubscriber(eventClass=EntryStore.Event.class) 626 public void onServerManagerDataEvent(EntryStore.Event evt) { 627 EntryStore servManager = ((McIDASV)getIdv()).getServerManager(); 628 logger.debug("onServerManagerDataEvent: evt={} server={}", evt, servManager.getLastAdded()); 629 this.updateServerList(); 630 } 631 632 @EventSubscriber(eventClass=TabbedAddeManager.Event.class) 633 public void onServerManagerWindowEvent(TabbedAddeManager.Event evt) { 634 logger.debug("onServerManagerWindowEvent: caught event bus obj"); 635 } 636 637 private boolean addingServer = false; 638 639 /** 640 * Search a given {@link JComboBox} for the index of a given object. Mostly 641 * useful for searching {@link #serverSelector} or {@link #groupSelector}. 642 * 643 * @param needle An object. {@code null} values are permitted. 644 * @param haystack {@code JComboBox} to search. {@code null} values are 645 * permitted, but return {@code -1}. 646 * 647 * @return Either the index of {@code needle} within {@code haystack}, or 648 * {@code -1} if {@code needle} could not be found (or {@code haystack} is 649 * {@code null}). 650 */ 651 protected static int getSelectorIndex(final Object needle, 652 final JComboBox haystack) 653 { 654 if (haystack == null) { 655 return -1; 656 } 657 658 String name = null; 659 if (needle instanceof AddeServer) { 660 name = ((AddeServer)needle).getName(); 661 } else if (needle instanceof Group) { 662 name = ((Group)needle).getName(); 663 } else if (needle instanceof AddeEntry) { 664 name = ((AddeEntry)needle).getAddress(); 665 } else { 666 name = needle.toString(); 667 } 668 669 if (isLoopback(name)) { 670 return 0; 671 } 672 673 for (int i = 0; i < haystack.getItemCount(); i++) { 674 Object item = haystack.getItemAt(i); 675 String tmpName; 676 if (item instanceof AddeServer) { 677 tmpName = ((AddeServer)item).getName(); 678 } else { 679 tmpName = item.toString(); 680 } 681 682 if (name.equals(tmpName)) { 683 return i; 684 } 685 } 686 return -1; 687 } 688 689 /** 690 * Get the selected AddeServer 691 * 692 * @return the server or null 693 */ 694 protected AddeServer getAddeServer() { 695 if (lastServerName != null && lastServerName.equals("unset")) { 696 return null; 697 } 698 699 Object selected = serverSelector.getSelectedItem(); 700 if ((selected != null) && (selected instanceof AddeServer)) { 701 AddeServer server = (AddeServer)selected; 702 String group = getGroup(true); 703 Map<String, String> accounting = getAccounting(server, group); 704 logger.trace("accounting: new: u='{}' p='{}' old: u='{}' p='{}'", new Object[] { accounting.get("user"), accounting.get("proj"), lastServerUser, lastServerProj }); 705 lastServerUser = accounting.get("user"); 706 lastServerProj = accounting.get("proj"); 707 setLastServer(server.getName(), group, server); 708 return (AddeServer)selected; 709 } else if ((selected != null) && (selected instanceof String)) { 710 711 EntryStore servManager = ((McIDASV)getIdv()).getServerManager(); 712 String server = (String)selected; 713 String group = getGroup(true); 714 715 if (isBadServer(server, group)) { 716 logger.trace("getAddeServer: returning null; known bad server; server={} group={}", server, group); 717 return null; 718 } 719 720 if (isLastServer(server, group)) { 721 logger.trace("getAddeServer: returning last server name; server={} group={}", server, group); 722 return lastServer; 723 } 724 725 EditorAction editorAction = EditorAction.INVALID; 726 if (!isLoopback(server)) { 727 RemoteEntryEditor editor = new RemoteEntryEditor(servManager, server, ""); 728 editor.setVisible(true); 729 editorAction = editor.getEditorAction(); 730 } else { 731 LocalEntryEditor editor = new LocalEntryEditor(servManager, group); 732 editor.setVisible(true); 733 editorAction = editor.getEditorAction(); 734 } 735 736 int servIndex = 0; 737 int groupIndex = 0; 738 739 if (editorAction != EditorAction.CANCELLED && editorAction != EditorAction.INVALID) { 740 741 List<AddeServer> added = arrList(EntryTransforms.convertMcvServers(servManager.getLastAddedByType(EntryTransforms.strToEntryType(getDataType())))); 742 AddeServer first = null; 743 if (!added.isEmpty()) { 744 first = added.get(0); 745 servIndex = getSelectorIndex(first, serverSelector); 746 setLastServer(server, group, first); 747 } 748 749 serverSelector.setSelectedIndex(servIndex); 750 groupSelector.setSelectedIndex(groupIndex); 751 logger.trace("getAddeServer: serverIdx={} groupIdx={}", servIndex, groupIndex); 752 753 return first; 754 } else { 755 logger.trace("getAddeServer: returning null due to cancel request"); 756 setBadServer(server, group); 757 return null; 758 } 759 760 761 762 } else if (selected == null) { 763 logger.trace("getAddeServer: null object in selector; returning null"); 764 } else { 765 logger.debug("getAddeServer: unknown obj type={}; toString={}", selected.getClass().getName(), selected.toString()); 766 } 767 return null; 768 } 769 770 /** 771 * A utility to add a component to the list of components that 772 * need the descriptor 773 * 774 * @param comp The component 775 * @return The component 776 */ 777 protected JComponent addDescComp(JComponent comp) { 778 compsThatNeedDescriptor.add(comp); 779 return comp; 780 } 781 782 /** 783 * Set LABEL_SELECT from elsewhere 784 */ 785 protected void setSelectString(String string) { 786 LABEL_SELECT = string; 787 } 788 789 /** 790 * Reset the descriptor stuff 791 */ 792 protected void resetDescriptorBox() { 793 ignoreDescriptorChange = true; 794 descriptorComboBox.setSelectedItem(LABEL_SELECT); 795 ignoreDescriptorChange = false; 796 } 797 798 /** 799 * Handle when the user presses the connect button 800 * 801 * @throws Exception On badness 802 */ 803 public void handleConnect() throws Exception { 804 AddeServer server = getAddeServer(); 805 if (server == null) { 806 return; 807 } 808 setState(STATE_CONNECTING); 809 connectToServer(); 810 handleUpdate(); 811 } 812 813 @Override protected void handleConnectionError(Exception e) { 814 if (e != null && e.getMessage() != null) { 815 String msg = e.getMessage(); 816 int msgPos = msg.indexOf("AddeURLException:"); 817 if (msgPos >= 0 && msg.length() > 18) { 818 msg = msg.substring(msgPos + 18); 819 setState(STATE_UNCONNECTED); 820 setHaveData(false); 821 resetDescriptorBox(); 822 GuiUtils.showDialog("ADDE Error", new JLabel(msg)); 823 return; 824 } 825 if (msg.indexOf("Connecting to server:localhost:") >= 0) { 826 setState(STATE_UNCONNECTED); 827 setHaveData(false); 828 resetDescriptorBox(); 829 GuiUtils.showDialog("ADDE Error", new JLabel("Local server is not responding")); 830 return; 831 } 832 } 833 super.handleConnectionError(e); 834 } 835 836 /** 837 * Handle unknown data set error 838 */ 839 @Override protected void handleUnknownDataSetError() { 840 String server = getServer(); 841 String group = getGroup(); 842 Map<String, String> acct = getAccounting(server, group); 843 String user = acct.get("user"); 844 String proj = acct.get("proj"); 845 846 StringBuilder msg = new StringBuilder("Could not connect to dataset \""); 847 msg.append(getGroup()).append("\" on server \"").append(getServer()).append("\"."); 848 if (DEFAULT_ACCOUNT.getUsername().equals(user) && DEFAULT_ACCOUNT.getProject().equals(proj)) { 849 msg.append("\n\nDataset may require ADDE accounting information."); 850 } else { 851 msg.append("\n\nAccounting information:\nusername: \"") 852 .append(user).append("\"\nproject: \"").append(proj).append('"'); 853 } 854 LogUtil.userErrorMessage(msg.toString()); 855 setState(STATE_UNCONNECTED); 856 } 857 858 /** 859 * Handle the event 860 * 861 * @param ae The event 862 */ 863 public void actionPerformed(ActionEvent ae) { 864 String cmd = ae.getActionCommand(); 865 if (cmd.equals(CMD_MANAGER)) { 866 doManager(); 867 } 868 else { 869 super.actionPerformed(ae); 870 } 871 } 872 873 /** 874 * Go directly to the Server Manager 875 */ 876 public void doManager() { 877 // if (isLocalServer()) { 878 // ((McIDASV)getIdv()).showAddeManager(); 879 // return; 880 // } 881 getIdv().getPreferenceManager().showTab(Constants.PREF_LIST_ADDE_SERVERS); 882 } 883 884 /** 885 * Show the parameter restore tree 886 */ 887 public void doParameters() { 888 JPopupMenu popup = new JPopupMenu(); 889 JMenuItem mi = new JMenuItem("Manage..."); 890 mi.addActionListener(new ActionListener() { 891 public void actionPerformed(ActionEvent ae) { 892 System.out.println(ae); 893 showParameterSetDialog(getParameterSetType()); 894 } 895 }); 896 popup.add(mi); 897 898 // Add the checkbox to automatically create a data source 899 cb.addActionListener(new ActionListener() { 900 public void actionPerformed(ActionEvent ae) { 901 shouldAddSource = cb.isSelected(); 902 } 903 }); 904 popup.addSeparator(); 905 popup.add(cb); 906 907 final PersistenceManager pm = (PersistenceManager)getIdv().getPersistenceManager(); 908 List<ParameterSet> parameterSets = pm.getAllParameterSets(getParameterSetType()); 909 910 for (int i=0; i<parameterSets.size(); i++) { 911 if (i==0) popup.addSeparator(); 912 final ParameterSet ps = parameterSets.get(i); 913 914 // Parameter set at root 915 if (ps.getCategories().size() == 0) { 916 mi = new JMenuItem(ps.getName()); 917 mi.addActionListener(new ActionListener() { 918 public void actionPerformed(ActionEvent ae) { 919 restoreParameterSet(ps.getElement()); 920 } 921 }); 922 popup.add(mi); 923 } 924 925 // Recurse into folders 926 else { 927 // Find or make the menu for the given parameter set 928 JMenu m = getPopupSubMenuForParameterSet(popup, ps); 929 // Create parameter set entry 930 mi = new JMenuItem(ps.getName()); 931 mi.addActionListener(new ActionListener() { 932 public void actionPerformed(ActionEvent ae) { 933 restoreParameterSet(ps.getElement()); 934 } 935 }); 936 m.add(mi); 937 } 938 939 } 940 941 popup.show(parameterButton, 0, (int) parameterButton.getBounds().getHeight()); 942 } 943 944 private JMenu getPopupSubMenuForParameterSet(JPopupMenu popup, final ParameterSet ps) { 945 List<String> menuNames = ps.getCategories(); 946 if (menuNames.size() < 1) return null; 947 948 // Build the complete menu 949 String menuName = menuNames.get(0); 950 menuNames.remove(0); 951 JMenu theMenu = new JMenu(); 952 953 // Look for the menu in popup 954 boolean found = false; 955 for (int i=0; i<popup.getComponentCount(); i++) { 956 Component thisComponent = popup.getComponent(i); 957 if (thisComponent instanceof JMenu && ((JMenu)thisComponent).getText().equals(menuName)) { 958 theMenu = mergeMenuNames((JMenu)thisComponent, menuNames); 959 found = true; 960 } 961 } 962 963 // Make a new menu, add the root, return the leaf 964 if (!found) { 965 JMenu theRoot = new JMenu(menuName); 966 theMenu = makeMenuRecursive(theRoot, menuNames); 967 popup.add(theRoot); 968 } 969 970 return theMenu; 971 } 972 973 /** 974 * Make a new recursive menu 975 * 976 * @param rootMenu The root menu to add items to 977 * @param menuNames List of string names for submenus 978 * @return A new JMenu representing the leaf 979 */ 980 private JMenu makeMenuRecursive(JMenu rootMenu, List<String> menuNames) { 981 if (menuNames.size() < 1) return rootMenu; 982 JMenu newMenu = new JMenu(menuNames.get(0)); 983 rootMenu.add(newMenu); 984 menuNames.remove(0); 985 return makeMenuRecursive(newMenu, menuNames); 986 } 987 988 /** 989 * Recurse into a menu, returning either a pointer to the designated names path 990 * or a pointer to the leaf menu added by merging new names 991 * 992 * @param thisMenu The root menu to merge 993 * @param menuNames List of string names to look for 994 * @return A new JMenu representing the leaf matched by menuNames 995 */ 996 private JMenu mergeMenuNames(JMenu thisMenu, List<String> menuNames) { 997 if (menuNames.size() < 1) return thisMenu; 998 boolean found = false; 999 String menuName = menuNames.get(0); 1000 for (int i=0; i<thisMenu.getItemCount(); i++) { 1001 JMenuItem mi = thisMenu.getItem(i); 1002 if (!(mi instanceof JMenu)) continue; 1003 if (mi.getText().equals(menuName)) { 1004 menuNames.remove(0); 1005 thisMenu = mergeMenuNames((JMenu)mi, menuNames); 1006 found = true; 1007 } 1008 } 1009 if (!found) { 1010 thisMenu = makeMenuRecursive(thisMenu, menuNames); 1011 } 1012 return thisMenu; 1013 } 1014 1015 /** 1016 * Return the parameter type associated with this chooser. Override! 1017 */ 1018 protected String getParameterSetType() { 1019 return "adde"; 1020 } 1021 1022 /** 1023 * Show the parameter set manager 1024 */ 1025 private void showParameterSetDialog(final String parameterSetType) { 1026 ParameterTree tree = (ParameterTree) parameterTrees.get(parameterSetType); 1027 if (tree == null) { 1028 tree = new ParameterTree((UIManager)getIdv().getIdvUIManager() , parameterSetType); 1029 parameterTrees.put(parameterSetType, tree); 1030 } 1031 else { 1032 //DAVEP 1033 System.out.println("Should refresh the parameter tree here"); 1034 } 1035 tree.setVisible(true); 1036 } 1037 1038 /** 1039 * Clear the selected parameter set 1040 */ 1041 protected void clearParameterSet() { 1042 restoreElement = null; 1043 restoreTimes = new ArrayList(); 1044 shouldAddSource = false; 1045 } 1046 1047 /** 1048 * Restore the selected parameter set using element attributes 1049 * 1050 * @param restoreElement 1051 * @return 1052 */ 1053 protected boolean restoreParameterSet(Element restoreElement) { 1054 if (restoreElement == null) return false; 1055 if (!restoreElement.getTagName().equals("default")) return false; 1056 1057 this.restoreElement = restoreElement; 1058 1059 boolean oldISCE = ignoreStateChangedEvents; 1060 ignoreStateChangedEvents = true; 1061 1062 // Restore server 1063 String server = restoreElement.getAttribute(ATTR_SERVER); 1064 if (server != null) serverSelector.setSelectedItem(new AddeServer(server)); 1065 1066 // Restore group 1067 String group = restoreElement.getAttribute(ATTR_GROUP); 1068 if (group != null) groupSelector.setSelectedItem(group); 1069 1070 // Act as though the user hit "connect" 1071 readFromServer(); 1072 1073 // Restore descriptor 1074 String descriptor = restoreElement.getAttribute(ATTR_DESCRIPTOR); 1075 if (descriptor != null) { 1076 Enumeration enumeration = descriptorTable.keys(); 1077 for (int i = 0; enumeration.hasMoreElements(); i++) { 1078 String key = enumeration.nextElement().toString(); 1079 Object val = descriptorTable.get(key); 1080 if (descriptor.equals(val)) { 1081 descriptorComboBox.setSelectedItem(val + nameSeparator + key); 1082 descriptorChanged(); 1083 break; 1084 } 1085 } 1086 } 1087 1088 // Restore date/time 1089 if (restoreElement.hasAttribute(ATTR_POS)) { 1090 setDoAbsoluteTimes(false); 1091 Integer pos = new Integer(restoreElement.getAttribute(ATTR_POS)); 1092 if (pos.intValue() >= 0) { 1093 getRelativeTimesList().setSelectedIndex(pos); 1094 } 1095 restoreTimes = new ArrayList(); 1096 } 1097 else if ((restoreElement.hasAttribute(ATTR_DAY)) && (restoreElement.hasAttribute(ATTR_TIME))) { 1098 setDoAbsoluteTimes(true); 1099 String dateStr = restoreElement.getAttribute(ATTR_DAY); 1100 String timeStr = restoreElement.getAttribute(ATTR_TIME); 1101 List dateS = StringUtil.split(dateStr, ","); 1102 List timeS = StringUtil.split(timeStr, ","); 1103 int numImages = timeS.size(); 1104 restoreTimes = new ArrayList(); 1105 try { 1106 DateTime dt = new DateTime(); 1107 dt.resetFormat(); 1108 String dtformat = dt.getFormatPattern(); 1109 for (int ix=0; ix<numImages; ix++) { 1110 DateTime restoreTime = dt.createDateTime((String)dateS.get(ix) + " " + (String)timeS.get(ix)); 1111 restoreTimes.add(restoreTime); 1112 } 1113 } catch (Exception e) { 1114 System.out.println("Exception e=" + e); 1115 return false; 1116 } 1117 } 1118 1119 System.out.println("Returning from AddeChooser.restoreParameterSet()"); 1120 1121 ignoreStateChangedEvents = oldISCE; 1122 return true; 1123 } 1124 1125 /** 1126 * Set the absolute times list. The times list can contain any of the object types 1127 * that makeDatedObjects knows how to handle, i.e., Date, visad.DateTime, DatedThing, AddeImageDescriptor, etc. 1128 * 1129 * @param times List of thinggs to put into absolute times list 1130 */ 1131 protected void setAbsoluteTimes(List times) { 1132 super.setAbsoluteTimes(times); 1133 restoreAbsoluteTimes(); 1134 } 1135 1136 protected void restoreAbsoluteTimes() { 1137 List allTimes = makeDatedObjects(super.getAbsoluteTimes()); 1138 if (restoreTimes.size() > 0 && allTimes.size() > 0) { 1139 int[] indices = new int[restoreTimes.size()]; 1140 try { 1141 DateTime rtdt; 1142 DateTime atdt; 1143 DatedThing at; 1144 for (int i = 0; i < restoreTimes.size(); i++) { 1145 rtdt = (DateTime)restoreTimes.get(i); 1146 for (int j = 0; j < allTimes.size(); j++) { 1147 at = (DatedThing)allTimes.get(j); 1148 atdt = new DateTime(at.getDate()); 1149 if (atdt.equals(rtdt)) { 1150 indices[i] = j; 1151 } 1152 } 1153 } 1154 } catch (Exception e) { 1155 System.out.println("Exception e=" + e); 1156 } 1157 setSelectedAbsoluteTimes(indices); 1158 } 1159 } 1160 1161 /** 1162 * show/hide the parameter restore button 1163 */ 1164 public void showParameterButton() { 1165 parameterButton.setVisible(true); 1166 } 1167 1168 public void hideParameterButton() { 1169 parameterButton.setVisible(false); 1170 } 1171 1172 /** 1173 * Override and simulate clicking Add Source if requested 1174 */ 1175 public void setHaveData(boolean have) { 1176 super.setHaveData(have); 1177 if (have && shouldAddSource) { 1178 System.out.println("Adding source at setHaveData"); 1179 // Even though setHaveData should mean we can go, we can't... wait a few jiffies 1180 Misc.runInABit(100, AddeChooser.this, "doClickLoad", null); 1181 } 1182 } 1183 1184 public void doClickLoad() { 1185 loadButton.doClick(); 1186 } 1187 1188 public void showServers() { 1189 allServersFlag = !allServersFlag; 1190 XmlObjectStore store = getIdv().getStore(); 1191 store.put(Constants.PREF_SYSTEMSERVERSIMG, allServersFlag); 1192 store.save(); 1193 updateServers(); 1194 updateGroups(); 1195 } 1196 1197 protected String getStateString() { 1198 int state = getState(); 1199 switch (state) { 1200 case STATE_CONNECTED: return "Connected to server"; 1201 case STATE_UNCONNECTED: return "Not connected to server"; 1202 case STATE_CONNECTING: return "Connecting to server"; 1203 default: return "Unknown state: " + state; 1204 } 1205 } 1206 1207 /** 1208 * Disable/enable any components that depend on the server. 1209 * Try to update the status label with what we know here. 1210 */ 1211 protected void updateStatus() { 1212 super.updateStatus(); 1213 if (getState() == STATE_CONNECTED) { 1214 lastServer = new AddeServer(""); 1215 lastServerGroup = ""; 1216 lastServerName = ""; 1217 lastServerProj = ""; 1218 lastServerUser = ""; 1219 1220 if (!haveDescriptorSelected()) { 1221 if (!usingStations() || haveStationSelected()) { 1222 // String name = getDataName().toLowerCase(); 1223 String name = getDescriptorLabel().toLowerCase(); 1224 if (StringUtil.startsWithVowel(name)) { 1225 setStatus("Please select an " + name); 1226 } else { 1227 setStatus("Please select a " + name); 1228 } 1229 } 1230 } 1231 } 1232 1233 GuiUtils.enableTree(connectButton, getState() != STATE_CONNECTING); 1234 } 1235 1236 /** 1237 * Get the data type ID 1238 * 1239 * @return the data type 1240 */ 1241 public String getDataType() { 1242 return "ANY"; 1243 } 1244 1245 /** 1246 * Check if the server is ok 1247 * 1248 * @return status code 1249 */ 1250 protected int checkIfServerIsOk() { 1251 try { 1252 StringBuffer buff = getUrl(REQ_TEXT); 1253 appendKeyValue(buff, PROP_FILE, FILE_PUBLICSRV); 1254 URL url = new URL(buff.toString()); 1255 URLConnection urlc = url.openConnection(); 1256 InputStream is = urlc.getInputStream(); 1257 is.close(); 1258 return STATUS_OK; 1259 } catch (AddeURLException ae) { 1260 String aes = ae.toString(); 1261 if (aes.indexOf("Invalid project number") >= 0) { 1262 LogUtil.userErrorMessage("Invalid project number"); 1263 return STATUS_NEEDSLOGIN; 1264 } 1265 if (aes.indexOf("Invalid user id") >= 0) { 1266 LogUtil.userErrorMessage("Invalid user ID"); 1267 return STATUS_NEEDSLOGIN; 1268 } 1269 if (aes.indexOf("Accounting data") >= 0) { 1270 return STATUS_NEEDSLOGIN; 1271 } 1272 if (aes.indexOf("cannot run server 'txtgserv'") >= 0) { 1273 return STATUS_OK; 1274 } 1275 LogUtil.userErrorMessage("Error connecting to server " + getServer() + ":\n" 1276 + ae.getMessage()); 1277 return STATUS_ERROR; 1278 } catch (ConnectException exc) { 1279 setState(STATE_UNCONNECTED); 1280 setHaveData(false); 1281 resetDescriptorBox(); 1282 String message = "Error connecting to server " + getServer(); 1283 if (isLocalServer()) 1284 message += "\n\nLocal servers can be restarted from the\n'Local ADDE Data Manager' in the 'Tools' menu"; 1285 LogUtil.userErrorMessage(message); 1286 return STATUS_ERROR; 1287 } catch (EOFException exc) { 1288 setState(STATE_UNCONNECTED); 1289 setHaveData(false); 1290 resetDescriptorBox(); 1291 LogUtil.userErrorMessage("Server " + getServer() + " is not responding"); 1292 return STATUS_ERROR; 1293 } catch (Exception exc) { 1294 logException("Connecting to server: " + getServer(), exc); 1295 return STATUS_ERROR; 1296 } 1297 } 1298 1299 public boolean canAccessServer() { 1300 // Set<Types> defaultTypes = EnumSet.of(ServerPropertyDialog.convertDataType(getDataType())); 1301 // while (true) { 1302 // int status = checkIfServerIsOk(); 1303 // if (status == STATUS_OK) { 1304 // break; 1305 // } 1306 // if (status == STATUS_ERROR) { 1307 // setState(STATE_UNCONNECTED); 1308 // return false; 1309 // } 1310 // 1311 //// AddeServer server = getAddeServer(); 1312 // AddeServer server = getAddeServer2(serverSelector, groupSelector); 1313 // Map<String, String> accounting = serverManager.getAccountingFor(server, type) 1314 // 1315 // String name = server.getName(); 1316 // String group = getGroup(); 1317 // String user = accounting.get("user"); 1318 // String proj = accounting.get("proj"); 1319 // 1320 // ServerPropertyDialog dialog = new ServerPropertyDialog(null, true, serverManager); 1321 // dialog.setTitle("Edit Server Information"); 1322 // dialog.showDialog(name, group, user, proj, defaultTypes); 1323 // 1324 // if (!dialog.getAddedDatasetDescriptors().isEmpty()) { 1325 // System.err.println("verified info: " + dialog.getAddedDatasetDescriptors()); 1326 // break; 1327 // } 1328 // } 1329 return true; 1330 } 1331 1332 public Map<String, String> getAccountingInfo() { 1333 AddeServer server = getAddeServer(); 1334 Map<String, String> map = new LinkedHashMap<String, String>(); 1335 if (server != null) { 1336 List<AddeServer.Group> groups = server.getGroups(); 1337 Map<String, String>acctInfo = getAccounting(server, groups.get(0).toString()); 1338 map.put("user", acctInfo.get("user")); 1339 map.put("proj", acctInfo.get("proj")); 1340 map.put("server", server.getName()); 1341 map.put("group", getGroup()); 1342 } else { 1343 map.put("user", RemoteAddeEntry.DEFAULT_ACCOUNT.getUsername()); 1344 map.put("proj", RemoteAddeEntry.DEFAULT_ACCOUNT.getUsername()); 1345 map.put("server", ""); 1346 map.put("group", ""); 1347 } 1348 return map; 1349 } 1350 1351 /** 1352 * Saves the currently selected server and group to a chooser-specific 1353 * preference. Preference ID is {@code PREF_SERVERSTATE+'.'+getId()}. 1354 */ 1355 @Override public void saveServerState() { 1356 String[] serverState = { getServer(), getGroup() }; 1357 getIdv().getStore().put(PREF_SERVERSTATE+'.'+getId(), serverState); 1358 getIdv().getStore().save(); 1359 } 1360 1361 /** 1362 * Connect to the server. 1363 */ 1364 protected void connectToServer() { 1365 clearParameterSet(); 1366 setDescriptors(null); 1367 setDoAbsoluteTimes(false); 1368 if (!canAccessServer()) { 1369 logger.debug("couldn't connect! shucks! golly!"); 1370 return; 1371 } else { 1372 logger.debug("you have successfully used the server manager! it is a miracle!"); 1373 } 1374 readFromServer(); 1375 saveServerState(); 1376 ignoreStateChangedEvents = true; 1377 if (descList != null) { 1378 descList.saveState(groupSelector); 1379 } 1380 ignoreStateChangedEvents = false; 1381 } 1382 1383 /** 1384 * Do server connection stuff... override this with type-specific methods 1385 */ 1386 protected void readFromServer() { 1387 readDescriptors(); 1388 readTimes(); 1389 } 1390 1391 // what the request needs to look like: 1392 // adde://localhost:8112/imagedata?&PORT=112&COMPRES S=gzip&USER=idv&PROJ=0 1393 // &VERSION=1&DEBUG=false&TRAC E=0&GROUP=MYDATA&DESCRIPTOR=ENTRY4&BAND=1 1394 // &LATLON= 30.37139 71.74912&PLACE=CENTER&SIZE=1000 1000&UNI T=BRIT 1395 // &MAG=1 1&SPAC=1&NAV=X&AUX=YES&DOC=X&POS=0 1396 1397 /** 1398 * Generate a list of image descriptors for the descriptor list. 1399 */ 1400 protected void readDescriptors() { 1401 try { 1402 StringBuffer buff = getGroupUrl(REQ_DATASETINFO, getGroup()); 1403 buff.append("&type=").append(getDataType()); 1404 logger.debug("readDesc: buff={}", buff.toString()); 1405 DataSetInfo dsinfo = new DataSetInfo(buff.toString()); 1406 descriptorTable = dsinfo.getDescriptionTable(); 1407 String[] names = new String[descriptorTable.size()]; 1408 Enumeration enumeration = descriptorTable.keys(); 1409 for (int i = 0; enumeration.hasMoreElements(); i++) { 1410 Object thisElement = enumeration.nextElement(); 1411 if (!isLocalServer()) 1412 names[i] = descriptorTable.get(thisElement).toString() + nameSeparator + thisElement.toString(); 1413 else 1414 names[i] = thisElement.toString(); 1415 } 1416 logger.debug("readDesc: names={}", names); 1417 Arrays.sort(names); 1418 setDescriptors(names); 1419 setState(STATE_CONNECTED); 1420 } catch (Exception e) { 1421 handleConnectionError(e); 1422 } 1423 } 1424 1425 /** 1426 * Initialize the descriptor list from a list of names 1427 * 1428 * @param names list of names 1429 */ 1430 protected void setDescriptors(String[] names) { 1431 synchronized (WIDGET_MUTEX) { 1432 ignoreDescriptorChange = true; 1433 descriptorComboBox.removeAllItems(); 1434 descriptorNames = names; 1435 if ((names == null) || (names.length == 0)) { 1436 return; 1437 } 1438 descriptorComboBox.addItem(LABEL_SELECT); 1439 for (int j = 0; j < names.length; j++) { 1440 descriptorComboBox.addItem(names[j]); 1441 } 1442 ignoreDescriptorChange = false; 1443 } 1444 } 1445 1446 /** 1447 * Respond to a change in the descriptor list. 1448 */ 1449 protected void descriptorChanged() { 1450 readTimes(); 1451 updateStatus(); 1452 } 1453 1454 /** 1455 * Check if a descriptor (image type) has been chosen 1456 * 1457 * @return true if an image type has been chosen 1458 */ 1459 protected boolean haveDescriptorSelected() { 1460 if ( !GuiUtils.anySelected(descriptorComboBox)) { 1461 return false; 1462 } 1463 return (getDescriptor() != null); 1464 } 1465 1466 /** 1467 * Get the selected descriptor. 1468 * 1469 * @return the currently selected descriptor. 1470 */ 1471 protected String getDescriptor() { 1472 return getDescriptorFromSelection(getSelectedDescriptor()); 1473 } 1474 1475 /** 1476 * Get the descriptor relating to the selection. 1477 * 1478 * @param selection String name from the widget 1479 * 1480 * @return the descriptor 1481 */ 1482 protected String getDescriptorFromSelection(String selection) { 1483 if (descriptorTable == null) { 1484 return null; 1485 } 1486 if (selection == null) { 1487 return null; 1488 } 1489 1490 if (!selection.contains(nameSeparator)) { 1491 return (String)descriptorTable.get(selection); 1492 } 1493 else { 1494 String[] toks = selection.split(nameSeparator, 2); 1495 String key = toks[1].trim(); 1496 return (String)descriptorTable.get(key); 1497 } 1498 } 1499 1500 /** 1501 * Get the selected descriptor. 1502 * 1503 * @return the selected descriptor 1504 */ 1505 public String getSelectedDescriptor() { 1506 String selection = (String) descriptorComboBox.getSelectedItem(); 1507 if (selection == null) { 1508 return null; 1509 } 1510 if (selection.equals(LABEL_SELECT)) { 1511 return null; 1512 } 1513 return selection; 1514 } 1515 1516 /** 1517 * Get the descriptor table for this chooser 1518 * 1519 * @return a Hashtable of descriptors and names 1520 */ 1521 public Hashtable getDescriptorTable() { 1522 return descriptorTable; 1523 } 1524 1525 /** 1526 * Get any extra key=value pairs that are appended to all requests. 1527 * 1528 * @param buff The buffer to append onto 1529 */ 1530 protected void appendMiscKeyValues(StringBuffer buff) { 1531 appendKeyValue(buff, PROP_COMPRESS, DEFAULT_COMPRESS); 1532 appendKeyValue(buff, PROP_PORT, DEFAULT_PORT); 1533 // appendKeyValue(buff, PROP_DEBUG, DEFAULT_DEBUG); 1534 appendKeyValue(buff, PROP_DEBUG, Boolean.toString(EntryStore.isAddeDebugEnabled(false))); 1535 appendKeyValue(buff, PROP_VERSION, DEFAULT_VERSION); 1536 appendKeyValue(buff, PROP_USER, getLastAddedUser()); 1537 appendKeyValue(buff, PROP_PROJ, getLastAddedProj()); 1538 } 1539 1540 public String getLastAddedUser() { 1541 if (lastServerUser != null && lastServerUser.length() > 0) { 1542 logger.debug("getLastAddedUser: using non-default {}", lastServerUser); 1543 return lastServerUser; 1544 } 1545 else { 1546 logger.debug("getLastAddedUser: using default {}", DEFAULT_USER); 1547 return DEFAULT_USER; 1548 } 1549 } 1550 1551 public String getLastAddedProj() { 1552 if (lastServerProj != null && lastServerProj.length() > 0) { 1553 logger.debug("getLastAddedProj: using non-default {}", lastServerProj); 1554 return lastServerProj; 1555 } 1556 else { 1557 logger.debug("getLastAddedProj: using default {}", DEFAULT_PROJ); 1558 return DEFAULT_PROJ; 1559 } 1560 } 1561 1562 /** 1563 * Show the groups dialog. This method is not meant to be called 1564 * but is public by reason of implementation (or insanity). 1565 */ 1566 public void showGroups() { 1567 JPopupMenu popup = new JPopupMenu(); 1568 popup.add(new JMenuItem("Reading public datasets...")); 1569 popup.show(publicButton, 0, (int) publicButton.getBounds().getHeight()); 1570 1571 List groups = readGroups(); 1572 popup.removeAll(); 1573 if ((groups == null) || (groups.size() == 0)) { 1574 popup.add(new JMenuItem("No public datasets available")); 1575 popup.setVisible(false); 1576 popup.setVisible(true); 1577 return; 1578 } 1579 1580 JMenuItem mi; 1581 for (int i = 0; i < groups.size(); i++) { 1582 final String group = groups.get(i).toString(); 1583 mi = new JMenuItem(group); 1584 mi.addActionListener(new ActionListener() { 1585 public void actionPerformed(ActionEvent ae) { 1586 groupSelector.setSelectedItem(group); 1587 doConnect(); 1588 } 1589 }); 1590 popup.add(mi); 1591 } 1592 popup.setVisible(false); 1593 popup.setVisible(true); 1594 } 1595 1596 /** 1597 * return the String id of the chosen server name 1598 * 1599 * @return the server name 1600 */ 1601 public String getServer() { 1602 AddeServer server = getAddeServer(); 1603 if (server!=null) 1604 return server.getName(); 1605 else 1606 return ""; 1607 } 1608 1609 protected String getGroup() { 1610 return getGroup(false); 1611 } 1612 1613 /** 1614 * Is the group selector editable? Override if ya want. 1615 * @return 1616 */ 1617 protected boolean isGroupEditable() { 1618 return true; 1619 } 1620 1621 /** 1622 * Get the image group from the GUI. 1623 * 1624 * @return The image group. 1625 */ 1626 protected String getGroup(final boolean fromGetServer) { 1627 Object selected = groupSelector.getSelectedItem(); 1628 if (selected == null) { 1629 return null; 1630 } 1631 1632 if (selected instanceof AddeServer.Group) { 1633 AddeServer.Group group = (AddeServer.Group) selected; 1634 return group.getName(); 1635 } 1636 1637 if (selected instanceof String) { 1638 return (String)selected; 1639 } 1640 1641 String groupName = selected.toString().trim(); 1642 if (!fromGetServer && (groupName.length() > 0)) { 1643 //Force the get in case they typed a server name 1644 getServer(); 1645 1646 AddeServer server = getAddeServer(); 1647 if (server != null) { 1648 AddeServer.Group group = 1649 getIdv().getIdvChooserManager().addAddeServerGroup( 1650 server, groupName, getGroupType()); 1651 if (!group.getActive()) { 1652 getIdv().getIdvChooserManager().activateAddeServerGroup( 1653 server, group); 1654 } 1655 //Now put the list of groups back in to the selector 1656 setGroups(); 1657 groupSelector.setSelectedItem(group); 1658 } 1659 } 1660 return groupName; 1661 } 1662 1663 /** 1664 * Get the server selector 1665 * @return The server selector 1666 */ 1667 public JComboBox getServerSelector() { 1668 if (serverSelector == null) 1669 serverSelector = super.getServerSelector(); 1670 1671 ItemListener[] ell = serverSelector.getItemListeners(); 1672 for (int i=0; i<ell.length; i++) { 1673 serverSelector.removeItemListener((ItemListener)ell[i]); 1674 } 1675 updateServers(); 1676 updateGroups(); 1677 serverSelector.addItemListener(new ItemListener() { 1678 public void itemStateChanged(ItemEvent e) { 1679 if ( !ignoreStateChangedEvents) { 1680 Object selected = serverSelector.getSelectedItem(); 1681 if (selected instanceof AddeServer) { 1682 AddeServer selectedServer = (AddeServer)selected; 1683 if (selectedServer != null) { 1684 if (isSeparator(selectedServer)) { 1685 connectButton.setEnabled(false); 1686 return; 1687 } 1688 } 1689 } 1690 setState(STATE_UNCONNECTED); 1691 connectButton.setEnabled(true); 1692 // setGroups(); 1693 resetDescriptorBox(); 1694 updateGroups(); 1695 // System.err.println("itemStateChanged"); 1696 } 1697 // else { 1698 // System.out.println("Ignoring state change here..."); 1699 // } 1700 } 1701 }); 1702 1703 serverSelector.getEditor().getEditorComponent().addKeyListener(new KeyListener() { 1704 public void keyTyped(final KeyEvent e) {} 1705 public void keyPressed(final KeyEvent e) {} 1706 public void keyReleased(final KeyEvent e) { 1707 JTextField field = (JTextField)serverSelector.getEditor().getEditorComponent(); 1708 boolean partialMatch = false; 1709 for (int i = 0; i < serverSelector.getItemCount(); i++) { 1710 String entry = serverSelector.getItemAt(i).toString(); 1711 if (entry.toLowerCase().startsWith(field.getText().toLowerCase())) 1712 partialMatch = true; 1713 } 1714 1715 if (!partialMatch && groupSelector != null) { 1716 logger.debug("aha! chooser=", getDataType()); 1717 ((JTextField)groupSelector.getEditor().getEditorComponent()).setText(""); 1718 } 1719 } 1720 }); 1721 1722 return serverSelector; 1723 } 1724 1725 /** 1726 * Enable or disable the GUI widgets based on what has been 1727 * selected. 1728 */ 1729 protected void enableWidgets() { 1730 synchronized (WIDGET_MUTEX) { 1731 boolean newEnabledState = (getState() == STATE_CONNECTED); 1732 for (int i = 0; i < compsThatNeedDescriptor.size(); i++) { 1733 JComponent comp = (JComponent) compsThatNeedDescriptor.get(i); 1734 if (comp.isEnabled() != newEnabledState) { 1735 GuiUtils.enableTree(comp, newEnabledState); 1736 } 1737 } 1738 } 1739 } 1740 1741 /** 1742 * Add a listener to the given combobox that will set the 1743 * state to unconnected 1744 * 1745 * @param box The box to listen to. 1746 */ 1747 protected void clearOnChange(final JComboBox box) { 1748 box.addItemListener(new ItemListener() { 1749 public void itemStateChanged(ItemEvent e) { 1750 if ( !ignoreStateChangedEvents) { 1751 setState(STATE_UNCONNECTED); 1752 GuiUtils.setListData(descriptorComboBox, new Vector()); 1753 // System.err.println("clearOnChange"); 1754 } 1755 // else { 1756 // System.out.println("Ignoring state change in clearOnChange for: " + box.toString()); 1757 // } 1758 } 1759 }); 1760 } 1761 1762 /** 1763 * Get the descriptor widget label 1764 * 1765 * @return label for the descriptor widget 1766 */ 1767 public String getDescriptorLabel() { 1768 return "Descriptor"; 1769 } 1770 1771 protected int getNumTimesToSelect() { 1772 return 5; 1773 } 1774 1775 /** 1776 * Get the default selected index for the relative times list. 1777 * 1778 * @return default index 1779 */ 1780 protected int getDefaultRelativeTimeIndex() { 1781 return 4; 1782 } 1783 1784 /** 1785 * Check the times lists 1786 */ 1787 protected void checkTimesLists() { 1788 super.checkTimesLists(); 1789 if (timesCardPanelExtra == null) { 1790 return; 1791 } 1792 if (getDoAbsoluteTimes()) { 1793 timesCardPanelExtra.show("absolute"); 1794 } else { 1795 timesCardPanelExtra.show("relative"); 1796 } 1797 } 1798 1799 /** Card panel to hold extra relative and absolute time components */ 1800 private GuiUtils.CardLayoutPanel timesCardPanelExtra; 1801 1802 /** 1803 * Set the relative and absolute extra components 1804 */ 1805 protected JPanel makeTimesPanel(JComponent relativeCard, JComponent absoluteCard) { 1806 JPanel timesPanel = super.makeTimesPanel(false,true); 1807 1808 // Make a new timesPanel that has extra components tacked on the bottom, inside the tabs 1809 Component[] comps = timesPanel.getComponents(); 1810 1811 if (comps.length==1 && comps[0] instanceof JTabbedPane) { 1812 timesCardPanelExtra = new GuiUtils.CardLayoutPanel(); 1813 if (relativeCard == null) relativeCard = new JPanel(); 1814 if (absoluteCard == null) absoluteCard = new JPanel(); 1815 timesCardPanelExtra.add(relativeCard, "relative"); 1816 timesCardPanelExtra.add(absoluteCard, "absolute"); 1817 timesPanel = GuiUtils.centerBottom(comps[0], timesCardPanelExtra); 1818 } 1819 1820 return timesPanel; 1821 } 1822 1823 /** 1824 * Make the UI for this selector. 1825 * 1826 * Thank you NetBeans for helping with the layout! 1827 * 1828 * @return The gui 1829 */ 1830 private JPanel innerPanel = new JPanel(); 1831 1832 private JLabel statusLabel = new JLabel("Status"); 1833 1834 /** 1835 * Super setStatus() takes a second string to enable "simple" mode 1836 * which highlights the required component. We don't really care 1837 * about that feature, and we don't want getStatusLabel() to 1838 * change the label background color. 1839 */ 1840 @Override 1841 public void setStatus(String statusString, String foo) { 1842 if (statusString == null) 1843 statusString = ""; 1844 statusLabel.setText(statusString); 1845 } 1846 1847 protected void setInnerPanel(JPanel newInnerPanel) { 1848 innerPanel = newInnerPanel; 1849 } 1850 1851 /** 1852 * Create the basic layout 1853 */ 1854 protected JComponent doMakeContents() { 1855 JPanel outerPanel = new JPanel(); 1856 1857 JLabel serverLabelInner = new JLabel("Server:"); 1858 McVGuiUtils.setLabelPosition(serverLabelInner, Position.RIGHT); 1859 JPanel serverLabel = GuiUtils.leftRight(parameterButton, serverLabelInner); 1860 McVGuiUtils.setComponentWidth(serverLabel); 1861 1862 clearOnChange(serverSelector); 1863 McVGuiUtils.setComponentWidth(serverSelector, Width.DOUBLE); 1864 1865 JLabel groupLabel = McVGuiUtils.makeLabelRight("Dataset:"); 1866 1867 groupSelector.setEditable(isGroupEditable()); 1868 clearOnChange(groupSelector); 1869 McVGuiUtils.setComponentWidth(groupSelector, Width.DOUBLE); 1870 1871 McVGuiUtils.setComponentWidth(connectButton, Width.DOUBLE); 1872 connectButton.setActionCommand(CMD_CONNECT); 1873 connectButton.addActionListener(this); 1874 1875 /** Set the attributes for the descriptor label and combo box, even though 1876 * they are not used here. Extending classes can add them to the panel if 1877 * necessary. 1878 */ 1879 McVGuiUtils.setComponentWidth(descriptorLabel); 1880 McVGuiUtils.setLabelPosition(descriptorLabel, Position.RIGHT); 1881 1882 McVGuiUtils.setComponentWidth(descriptorComboBox, Width.DOUBLEDOUBLE); 1883 1884 if (descriptorComboBox.getMinimumSize().getWidth() < ELEMENT_DOUBLE_WIDTH) { 1885 McVGuiUtils.setComponentWidth(descriptorComboBox, Width.DOUBLE); 1886 } 1887 1888 JLabel statusLabelLabel = McVGuiUtils.makeLabelRight(""); 1889 1890 statusLabel.setText("Status"); 1891 McVGuiUtils.setLabelPosition(statusLabel, Position.RIGHT); 1892 McVGuiUtils.setComponentColor(statusLabel, TextColor.STATUS); 1893 1894 JButton helpButton = McVGuiUtils.makeImageButton(ICON_HELP, "Show help"); 1895 helpButton.setActionCommand(GuiUtils.CMD_HELP); 1896 helpButton.addActionListener(this); 1897 1898 JButton refreshButton = McVGuiUtils.makeImageButton(ICON_REFRESH, "Refresh"); 1899 refreshButton.setActionCommand(GuiUtils.CMD_UPDATE); 1900 refreshButton.addActionListener(this); 1901 1902 McVGuiUtils.setComponentWidth(loadButton, Width.DOUBLE); 1903 1904 GroupLayout layout = new GroupLayout(outerPanel); 1905 outerPanel.setLayout(layout); 1906 layout.setHorizontalGroup( 1907 layout.createParallelGroup(LEADING) 1908 .addGroup(TRAILING, layout.createSequentialGroup() 1909 .addGroup(layout.createParallelGroup(TRAILING) 1910 .addGroup(layout.createSequentialGroup() 1911 .addContainerGap() 1912 .addComponent(helpButton) 1913 .addGap(GAP_RELATED) 1914 .addComponent(refreshButton) 1915 .addGap(GAP_RELATED) 1916 .addComponent(cancelButton) 1917 .addPreferredGap(RELATED) 1918 .addComponent(loadButton)) 1919 .addGroup(LEADING, layout.createSequentialGroup() 1920 .addContainerGap() 1921 .addGroup(layout.createParallelGroup(LEADING) 1922 .addComponent(innerPanel, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) 1923 .addGroup(layout.createSequentialGroup() 1924 .addComponent(serverLabel) 1925 .addGap(GAP_RELATED) 1926 .addComponent(serverSelector) 1927 .addGap(GAP_RELATED) 1928 .addComponent(manageButton) 1929 .addGap(GAP_RELATED) 1930 .addComponent(groupLabel) 1931 .addGap(GAP_RELATED) 1932 .addComponent(groupSelector) 1933 .addGap(GAP_RELATED) 1934 .addComponent(publicButton) 1935 .addPreferredGap(RELATED, DEFAULT_SIZE, Short.MAX_VALUE) 1936 .addComponent(connectButton)) 1937 .addGroup(layout.createSequentialGroup() 1938 .addComponent(statusLabelLabel) 1939 .addGap(GAP_RELATED) 1940 .addComponent(statusLabel, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE))))) 1941 .addContainerGap()) 1942 ); 1943 layout.setVerticalGroup( 1944 layout.createParallelGroup(LEADING) 1945 .addGroup(layout.createSequentialGroup() 1946 .addContainerGap() 1947 .addGroup(layout.createParallelGroup(BASELINE) 1948 .addComponent(serverLabel) 1949 .addComponent(serverSelector) 1950 .addComponent(manageButton) 1951 .addComponent(groupLabel) 1952 .addComponent(groupSelector) 1953 .addComponent(publicButton) 1954 .addComponent(connectButton)) 1955 .addPreferredGap(UNRELATED) 1956 .addComponent(innerPanel, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) 1957 .addPreferredGap(UNRELATED) 1958 .addGroup(layout.createParallelGroup(BASELINE) 1959 .addComponent(statusLabelLabel) 1960 .addComponent(statusLabel)) 1961 .addPreferredGap(UNRELATED) 1962 .addGroup(layout.createParallelGroup(BASELINE) 1963 .addComponent(loadButton) 1964 .addComponent(cancelButton) 1965 .addComponent(refreshButton) 1966 .addComponent(helpButton)) 1967 .addContainerGap()) 1968 ); 1969 1970 return outerPanel; 1971 1972 } 1973 1974 public class ServerComparator implements Comparator<AddeServer> { 1975 public int compare(AddeServer server1, AddeServer server2) { 1976 return server1.getName().compareTo(server2.getName()); 1977 } 1978 } 1979 1980 public class GroupComparator implements Comparator<Group> { 1981 public int compare(Group group1, Group group2) { 1982 return group1.getName().compareTo(group2.getName()); 1983 } 1984 } 1985 } 1986