001/* 002 * This file is part of McIDAS-V 003 * 004 * Copyright 2007-2016 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; 030 031import java.awt.event.ActionEvent; 032import java.io.BufferedReader; 033import java.io.BufferedWriter; 034import java.io.File; 035import java.io.FileReader; 036import java.io.FileWriter; 037import java.util.Hashtable; 038import java.util.Map; 039import java.util.Objects; 040import java.util.Properties; 041 042import javax.swing.JEditorPane; 043import javax.swing.JLabel; 044import javax.swing.JOptionPane; 045import javax.swing.JPanel; 046import javax.swing.event.HyperlinkEvent; 047import javax.swing.event.HyperlinkListener; 048 049import ucar.unidata.idv.IdvObjectStore; 050import ucar.unidata.idv.IntegratedDataViewer; 051import ucar.unidata.util.FileManager; 052import ucar.unidata.util.IOUtil; 053import ucar.unidata.util.LogUtil; 054import ucar.unidata.util.Misc; 055import ucar.unidata.util.StringUtil; 056 057import edu.wisc.ssec.mcidasv.startupmanager.StartupManager; 058import edu.wisc.ssec.mcidasv.util.SystemState; 059 060public class StateManager extends ucar.unidata.idv.StateManager implements Constants, HyperlinkListener { 061 062 public static final String USERPATH_IS_BAD_MESSAGE = "<html>McIDAS-V is unable to create or write to the local user's directory.<br>Please select a directory.</html>"; 063 064 public static final String USERPATH_PICK = "Please select a directory to use as the McIDAS-V user path."; 065 066 /** Lazily-loaded VisAD build date. */ 067 private String visadDate; 068 069 /** Lazily-loaded VisAD SVN revision number. */ 070 private String visadVersion; 071 072 /** Lazily-loaded {@code ncIdv.jar} build timestamp. */ 073 private String netcdfDate; 074 075 /** Lazily-loaded {@code ncIdv.jar} version. */ 076 private String netcdfVersion; 077 078 private String version; 079 private String versionAbout; 080 081 public StateManager(IntegratedDataViewer idv) { 082 super(idv); 083 } 084 085 /** 086 * Override to set the right user directory. 087 * 088 * @return Newly created object store. 089 */ 090 @Override protected IdvObjectStore doMakeObjectStore() { 091 IdvObjectStore store = new IdvObjectStore(getIdv(), 092 getStoreSystemName(), getStoreName(), 093 getIdv().getEncoderForRead(), 094 StartupManager.getInstance().getPlatform().getUserDirectory()); 095 initObjectStore(store); 096 return store; 097 } 098 099 /** 100 * Initialize the given object store. This mostly initializes the user's 101 * {@literal "userpath"} directory when it is first created. 102 * 103 * @param store Object store to initialize. Cannot be {@code null}. 104 */ 105 @Override protected void initObjectStore(IdvObjectStore store) { 106 while (!store.userDirectoryOk()) { 107 LogUtil.userMessage(USERPATH_IS_BAD_MESSAGE); 108 File dir = FileManager.getDirectory(null, USERPATH_PICK); 109 if (dir != null) { 110 store.setOverrideDirectory(dir); 111 } else { 112 System.exit(0); 113 } 114 } 115 116 if (store.getMadeUserDirectory()) { 117 initNewUserDirectory(store.getUserDirectory()); 118 } 119 initUserDirectory(store.getUserDirectory()); 120 } 121 122 /** 123 * Handle a change to a link 124 * 125 * @param e the link's event 126 */ 127 @Override public void hyperlinkUpdate(HyperlinkEvent e) { 128 if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { 129 if (e.getURL() == null) { 130 click(e.getDescription()); 131 } else { 132 click(e.getURL().toString()); 133 } 134 } 135 } 136 137 /** 138 * Handle a click on a link 139 * 140 * @param url the link definition 141 */ 142 public void click(String url) { 143 getIdv().actionPerformed(new ActionEvent(this, 0, url)); 144 } 145 146 public String getOSName() { 147 String os = System.getProperty("os.name"); 148 os = os.replaceAll(" ", "_"); 149 return os; 150 } 151 152 public String getMcIdasVersionAbout() { 153 getMcIdasVersion(); 154 155 versionAbout = IOUtil.readContents((String) getProperty(Constants.PROP_ABOUTTEXT), ""); 156 versionAbout = StringUtil.replace(versionAbout, MACRO_VERSION, version); 157 Properties props = Misc.readProperties( 158 (String) getProperty(Constants.PROP_VERSIONFILE), 159 null, 160 getClass() 161 ); 162 163 String value = getIdvVersion(); 164 versionAbout = StringUtil.replace(versionAbout, Constants.MACRO_IDV_VERSION, value); 165 value = props.getProperty(PROP_COPYRIGHT_YEAR, ""); 166 versionAbout = StringUtil.replace(versionAbout, Constants.MACRO_COPYRIGHT_YEAR, value); 167 value = props.getProperty(PROP_BUILD_DATE, "Unknown"); 168 versionAbout = StringUtil.replace(versionAbout, Constants.MACRO_BUILDDATE, value); 169 versionAbout = StringUtil.replace(versionAbout, Constants.MACRO_VISAD_VERSION, getVisadVersion()); 170 171 return versionAbout; 172 } 173 174 public String getMcIdasVersion() { 175 if (version != null) { 176 return version; 177 } 178 179 Properties props = new Properties(); 180 props = Misc.readProperties((String) getProperty(Constants.PROP_VERSIONFILE), null, getClass()); 181 String maj = props.getProperty(PROP_VERSION_MAJOR, "0"); 182 String min = props.getProperty(PROP_VERSION_MINOR, "0"); 183 String rel = props.getProperty(PROP_VERSION_RELEASE, ""); 184 185 version = maj.concat(".").concat(min).concat(rel); 186 187 return version; 188 } 189 190 /** 191 * Returns the current Jython version. 192 * 193 * @return Jython's version information. 194 */ 195 @Override public String getJythonVersion() { 196 return org.python.Version.PY_VERSION; 197 } 198 199 /** 200 * Get a property. 201 * 202 * @param name Name of the property. Cannot be {@code null}. 203 * 204 * @return Value associated with {@code name} or {@code null}. 205 */ 206 @Override public Object getProperty(final String name) { 207 Object value = null; 208 if (McIDASV.isMac()) { 209 value = getProperties().get("mac."+name); 210 } 211 if (value == null) { 212 value = getProperties().get(name); 213 } 214 if (value == null) { 215 String fixedName = StateManager.fixIds(name); 216 if (!name.equals(fixedName)) { 217 return getProperties().get(fixedName); 218 } 219 } 220 return value; 221 } 222 223 /** 224 * Find the value associated with the given ID by checking the 225 * {@literal "properties"}, and if nothing was found, check the preferences. 226 * 227 * @param name Property or preference ID. Cannot be {@code null}. 228 * 229 * @return Either the value associated with {@code name} or {@code null}. 230 */ 231 public Object getPropertyOrPreference(String name) { 232 Object o = getProperty(name); 233 if (o == null) { 234 o = getPreference(name); 235 } 236 return o; 237 } 238 239 /** 240 * Find the {@link String} value associated with the given ID by checking 241 * the {@literal "properties"}, and if nothing was found, check the 242 * preferences. 243 * 244 * @param name Property or preference ID. Cannot be {@code null}. 245 * @param dflt Value to return if there is no property or preference 246 * associated with {@code name} 247 * 248 * @return Either the value associated with {@code name} or {@code dflt}. 249 */ 250 public String getPropertyOrPreference(String name, String dflt) { 251 String value = dflt; 252 Object o = getPropertyOrPreference(name); 253 if (o != null) { 254 value = o.toString(); 255 } 256 return value; 257 } 258 259 /** 260 * Find the {@link Integer} value associated with the given ID by checking 261 * the {@literal "properties"}, and if nothing was found, check the 262 * preferences. 263 * 264 * @param name Property or preference ID. Cannot be {@code null}. 265 * @param dflt Value to return if there is no property or preference 266 * associated with {@code name} 267 * 268 * @return Either the value associated with {@code name} or {@code dflt}. 269 */ 270 public int getPropertyOrPreference(String name, int dflt) { 271 int value = dflt; 272 Object o = getPropertyOrPreference(name); 273 if (o != null) { 274 value = Integer.valueOf(o.toString()); 275 } 276 return value; 277 } 278 279 /** 280 * Find the {@link Double} value associated with the given ID by checking 281 * the {@literal "properties"}, and if nothing was found, check the 282 * preferences. 283 * 284 * @param name Property or preference ID. Cannot be {@code null}. 285 * @param dflt Value to return if there is no property or preference 286 * associated with {@code name} 287 * 288 * @return Either the value associated with {@code name} or {@code dflt}. 289 */ 290 public double getPropertyOrPreference(String name, double dflt) { 291 double value = dflt; 292 Object o = getPropertyOrPreference(name); 293 if (o != null) { 294 value = Double.valueOf(o.toString()); 295 } 296 return value; 297 } 298 299 /** 300 * Find the {@link Boolean} value associated with the given ID by checking 301 * the {@literal "properties"}, and if nothing was found, check the 302 * preferences. 303 * 304 * @param name Property or preference ID. Cannot be {@code null}. 305 * @param dflt Value to return if there is no property or preference 306 * associated with {@code name} 307 * 308 * @return Either the value associated with {@code name} or {@code dflt}. 309 */ 310 public boolean getPropertyOrPreference(String name, boolean dflt) { 311 boolean value = dflt; 312 Object o = getPropertyOrPreference(name); 313 if (o != null) { 314 value = Boolean.valueOf(o.toString()); 315 } 316 return value; 317 } 318 319 /** 320 * Returns information about the current version of McIDAS-V and the IDV, 321 * along with their respective build dates. 322 * 323 * @return {@code Hashtable} containing versioning information. 324 */ 325 public Hashtable<String, String> getVersionInfo() { 326 String versionFile = (String)getProperty(Constants.PROP_VERSIONFILE); 327 Properties props = 328 Misc.readProperties(versionFile, null, getClass()); 329 330 String mcvBuild = props.getProperty(PROP_BUILD_DATE, "Unknown"); 331 332 Hashtable<String, String> table = new Hashtable<>(); 333 table.put("mcv.version.general", getMcIdasVersion()); 334 table.put("mcv.version.build", mcvBuild); 335 table.put("idv.version.general", getVersion()); 336 table.put("idv.version.build", getBuildDate()); 337 table.put("visad.version.general", getVisadVersion()); 338 table.put("visad.version.build", getVisadDate()); 339 table.put("netcdf.version.general", getNetcdfVersion()); 340 table.put("netcdf.version.build", getNetcdfDate()); 341 return table; 342 } 343 344 /** 345 * Return the timestamp from when {@code ncIdv.jar} was created. 346 * 347 * @return {@code String} representation of the creation timestamp. 348 */ 349 public String getNetcdfDate() { 350 if (netcdfDate == null) { 351 Map<String, String> props = SystemState.queryNcidvBuildProperties(); 352 netcdfDate = props.get("buildDate"); 353 netcdfVersion = props.get("version"); 354 } 355 return netcdfDate; 356 } 357 358 /** 359 * Return the version information within {@code ncIdv.jar}. 360 * 361 * @return Version of {@code ncIdv.jar} shipped by McIDAS-V. 362 */ 363 public String getNetcdfVersion() { 364 if (netcdfVersion == null) { 365 Map<String, String> props = SystemState.queryNcidvBuildProperties(); 366 netcdfDate = props.get("buildDate"); 367 netcdfVersion = props.get("version"); 368 } 369 return netcdfVersion; 370 } 371 372 /** 373 * Return the timestamp from when visad.jar was created. 374 * 375 * @return {@code String} representation of the creation timestamp. 376 * Likely to change formatting over time. 377 */ 378 public String getVisadDate() { 379 if (visadDate == null) { 380 Map<String, String> props = SystemState.queryVisadBuildProperties(); 381 visadDate = props.get(Constants.PROP_VISAD_DATE); 382 visadVersion = props.get(Constants.PROP_VISAD_REVISION); 383 } 384 return visadDate; 385 } 386 387 /** 388 * Return the {@literal "version"} of VisAD. 389 * 390 * @return Currently returns whatever the SVN revision number was when 391 * visad.jar was built. 392 */ 393 public String getVisadVersion() { 394 if (visadVersion == null) { 395 Map<String, String> props = SystemState.queryVisadBuildProperties(); 396 visadDate = props.get(Constants.PROP_VISAD_DATE); 397 visadVersion = props.get(Constants.PROP_VISAD_REVISION); 398 } 399 return visadVersion; 400 } 401 402 public String getIdvVersion() { 403 return getVersion(); 404 } 405 406 /** 407 * Overridden to set default of McIDAS-V 408 */ 409 @Override public String getStoreSystemName() { 410 return StartupManager.getInstance().getPlatform().getUserDirectory(); 411 } 412 413 /** 414 * Overridden to get dir of the unnecessary second level directory. 415 */ 416 @Override public String getStoreName() { 417 return ""; 418 } 419 420 /** 421 * Connect to McIDAS-V website and look for latest stable version. 422 * 423 * @return Latest stable version. 424 */ 425 public String getMcIdasVersionStable() { 426 String offscreen = "0"; 427 if (super.getIdv().getArgsManager().getIsOffScreen()) { 428 offscreen = "1"; 429 } 430 431 String version = ""; 432 try { 433 version = IOUtil.readContents(Constants.HOMEPAGE_URL+"/"+Constants.VERSION_HANDLER_URL+"?v="+getMcIdasVersion()+"&os="+getOSName()+"&off="+offscreen, ""); 434 } catch (Exception e) {} 435 return version.trim(); 436 } 437 438 /** 439 * Connect to McIDAS-V website and look for latest pre-release version. 440 * 441 * @return Latest pre-release version. 442 */ 443 public String getMcIdasVersionPrerelease() { 444 String version = ""; 445 try { 446 String htmlList = IOUtil.readContents(Constants.HOMEPAGE_URL+'/'+Constants.PRERELEASE_URL, ""); 447 String lines[] = htmlList.split("\n"); 448 for (int i=0; i<lines.length; i++) { 449 String line = lines[i].trim(); 450 if (line.matches(".*McIDAS-V_\\d+\\.\\d+.*")) { 451 line = line.substring(line.indexOf("McIDAS-V_")+9); 452 String aVersion = line.substring(0, line.indexOf("_")); 453 if (version.isEmpty()) { 454 version = aVersion; 455 } 456 else { 457 int comp = compareVersions(version, aVersion); 458 if (comp > 0) { 459 version = aVersion; 460 } 461 } 462 } 463 } 464 } catch (Exception e) {} 465 return version.trim(); 466 } 467 468 /** 469 * Connect to McIDAS website and look for latest notice. 470 * 471 * @return Contents of notice. String may be empty. 472 */ 473 public String getNoticeLatest() { 474 String notice = ""; 475 try { 476 notice = IOUtil.readContents(Constants.HOMEPAGE_URL+"/"+Constants.NOTICE_URL+"?requesting="+getMcIdasVersion()+"&os="+getOSName(), ""); 477 } catch (Exception e) {} 478 if (notice.indexOf("<notice>")<0) notice=""; 479 notice = notice.replaceAll("<[/?]notice>",""); 480 return notice.trim(); 481 } 482 483 /** 484 * Compare version strings. 485 * 486 * <p>The logic is as follows. 487 * <pre> 488 * 0: thisVersion and thatVersion are equal. 489 * <0: thisVersion is greater. 490 * >0: thatVersion is greater. 491 * </pre> 492 * 493 * @param thisVersion First version string to compare. 494 * @param thatVersion Second version string to compare. 495 * 496 * @return Value indicating which of {@code thisVersion} and 497 * {@code thatVersion} is {@literal "greater"}. 498 */ 499 public static int compareVersions(String thisVersion, String thatVersion) { 500 int thisInt = versionToInteger(thisVersion); 501 int thatInt = versionToInteger(thatVersion); 502 return thatInt - thisInt; 503 } 504 505 /** 506 * Turn version strings of the form {@code #.#(a#)}, where # is one or two 507 * digits, a is one of alpha or beta, and () is optional, into an integer 508 * value... (empty) > beta > alpha. 509 * 510 * @param version String representation of version number. 511 * 512 * @return Integer representation of {@code version}. 513 */ 514 public static int versionToInteger(String version) { 515 int value = 0; 516 int p; 517 String part; 518 Character one = null; 519 520 try { 521 522 // Major version 523 p = version.indexOf('.'); 524 if (p > 0) { 525 part = version.substring(0,p); 526 value += Integer.parseInt(part) * 1000000; 527 version = version.substring(p+1); 528 } 529 530 // Minor version 531 int minor = 0; 532 int i=0; 533 for (i=0; i<2 && i<version.length(); i++) { 534 one = version.charAt(i); 535 if (Character.isDigit(one)) { 536 if (i>0) minor *= 10; 537 minor += Character.digit(one, 10) * 10000; 538 } 539 else { 540 break; 541 } 542 } 543 value += minor; 544 if (one!=null) version = version.substring(i); 545 546 // Alpha/beta/update/release status 547 if (version.length() == 0) value += 300; 548 else if (version.charAt(0) == 'b') value += 200; 549 else if (version.charAt(0) == 'a') value += 100; 550 else if (version.charAt(0) == 'u') value += 400; 551 else if (version.charAt(0) == 'r') value += 400; 552 for (i=0; i<version.length(); i++) { 553 one = version.charAt(i); 554 if (Character.isDigit(one)) break; 555 } 556 if (one!=null) version = version.substring(i); 557 558 // Alpha/beta version 559 if (version.length() > 0) 560 value += Integer.parseInt(version); 561 562 } catch (Exception e) {} 563 564 return value; 565 } 566 567 public boolean getIsPrerelease() { 568 boolean isPrerelease = false; 569 String version = getMcIdasVersion(); 570 if (version.indexOf("a") >= 0 || version.indexOf("b") >= 0) { 571 isPrerelease = true; 572 } 573 return isPrerelease; 574 } 575 576 public void checkForNewerVersion(boolean notifyDialog) { 577 checkForNewerVersionStable(notifyDialog); 578 if (getStore().get(Constants.PREF_PRERELEASE_CHECK, getIsPrerelease())) { 579 checkForNewerVersionPrerelease(notifyDialog); 580 } 581 } 582 583 public void checkForNewerVersionStable(boolean notifyDialog) { 584 585 /** Get the stable version from the website (for statistics recording) */ 586 String thatVersion = getMcIdasVersionStable(); 587 588 /** Shortcut the rest of the process if we are processing offscreen */ 589 if (super.getIdv().getArgsManager().getIsOffScreen()) { 590 return; 591 } 592 593 String thisVersion = getMcIdasVersion(); 594 String titleText = "Version Check"; 595 596 if (thisVersion.equals("") || thatVersion.equals("")) { 597 if (notifyDialog) { 598 JOptionPane.showMessageDialog(null, "Version check failed", titleText, 599 JOptionPane.WARNING_MESSAGE); 600 } 601 } 602 else if (compareVersions(thisVersion, thatVersion) > 0) { 603 String labelText = "<html>Version <b>" + thatVersion + "</b> is available<br><br>"; 604 labelText += "Visit <a href=\"" + Constants.HOMEPAGE_URL + "\">"; 605 labelText += Constants.HOMEPAGE_URL + "</a> to download</html>"; 606 607 JPanel backgroundColorGetterPanel = new JPanel(); 608 JEditorPane messageText = new JEditorPane("text/html", labelText); 609 messageText.setBackground(backgroundColorGetterPanel.getBackground()); 610 messageText.setEditable(false); 611 messageText.addHyperlinkListener(this); 612 613// JLabel message = new JLabel(labelText, JLabel.CENTER); 614 JOptionPane.showMessageDialog(null, messageText, titleText, 615 JOptionPane.INFORMATION_MESSAGE); 616 } 617 else { 618 if (notifyDialog) { 619 String labelText = "<html>This version (<b>" + thisVersion + "</b>) is up to date</html>"; 620 JLabel message = new JLabel(labelText, JLabel.CENTER); 621 JOptionPane.showMessageDialog(null, message, titleText, 622 JOptionPane.INFORMATION_MESSAGE); 623 } 624 } 625 626 } 627 628 public void checkForNewerVersionPrerelease(boolean notifyDialog) { 629 630 /** Shortcut the rest of the process if we are processing offscreen */ 631 if (super.getIdv().getArgsManager().getIsOffScreen()) { 632 return; 633 } 634 635 String thisVersion = getMcIdasVersion(); 636 String thatVersion = getMcIdasVersionPrerelease(); 637 String titleText = "Prerelease Check"; 638 639 if (thisVersion.equals("") || thatVersion.equals("")) { 640 if (notifyDialog) { 641 JOptionPane.showMessageDialog(null, "No prerelease version available", titleText, 642 JOptionPane.WARNING_MESSAGE); 643 } 644 } 645 else if (compareVersions(thisVersion, thatVersion) > 0) { 646 String labelText = "<html>Prerelease <b>" + thatVersion + "</b> is available<br><br>"; 647 labelText += "Visit <a href=\"" + Constants.HOMEPAGE_URL+'/'+Constants.PRERELEASE_URL + "\">"; 648 labelText += Constants.HOMEPAGE_URL+'/'+Constants.PRERELEASE_URL + "</a> to download</html>"; 649 650 JPanel backgroundColorGetterPanel = new JPanel(); 651 JEditorPane messageText = new JEditorPane("text/html", labelText); 652 messageText.setBackground(backgroundColorGetterPanel.getBackground()); 653 messageText.setEditable(false); 654 messageText.addHyperlinkListener(this); 655 656// JLabel message = new JLabel(labelText, JLabel.CENTER); 657 JOptionPane.showMessageDialog(null, messageText, titleText, 658 JOptionPane.INFORMATION_MESSAGE); 659 } 660 else { 661 if (notifyDialog) { 662 String labelText = "<html>This version (<b>" + thisVersion + "</b>) is up to date</html>"; 663 JLabel message = new JLabel(labelText, JLabel.CENTER); 664 JOptionPane.showMessageDialog(null, message, titleText, 665 JOptionPane.INFORMATION_MESSAGE); 666 } 667 } 668 669 } 670 671 public void checkForNotice(boolean notifyDialog) { 672 673 // Shortcut this whole process if we are processing offscreen 674 if (super.getIdv().getArgsManager().getIsOffScreen()) { 675 return; 676 } 677 678 String thisNotice = getNoticeCached().trim(); 679 String thatNotice = getNoticeLatest().trim(); 680 String titleText = "New Notice"; 681 String labelText = thatNotice; 682 683 if (thatNotice.equals("")) { 684 setNoticeCached(thatNotice); 685 if (notifyDialog) { 686 titleText = "No Notice"; 687 JLabel message = new JLabel("There is no current notice", JLabel.CENTER); 688 JOptionPane.showMessageDialog(null, message, titleText, 689 JOptionPane.INFORMATION_MESSAGE); 690 } 691 return; 692 } else if (!thisNotice.equals(thatNotice)) { 693 setNoticeCached(thatNotice); 694 695 JPanel backgroundColorGetterPanel = new JPanel(); 696 JEditorPane messageText = new JEditorPane("text/html", labelText); 697 messageText.setBackground(backgroundColorGetterPanel.getBackground()); 698 messageText.setEditable(false); 699 messageText.addHyperlinkListener(this); 700 JOptionPane.showMessageDialog(null, messageText, titleText, 701 JOptionPane.INFORMATION_MESSAGE); 702 } else { 703 if (notifyDialog) { 704 titleText = "Previous Notice"; 705 JPanel bgPanel = new JPanel(); 706 JEditorPane messageText = 707 new JEditorPane("text/html", labelText); 708 messageText.setBackground(bgPanel.getBackground()); 709 messageText.setEditable(false); 710 messageText.addHyperlinkListener(this); 711 JOptionPane.showMessageDialog(null, messageText, titleText, 712 JOptionPane.INFORMATION_MESSAGE); 713 } 714 } 715 } 716 717 /** 718 * Debug a McIDAS-V {@literal "system notice"} before sending it to all 719 * users! 720 * 721 * @param noticeContents Contents of the notice. 722 * @param notifyDialog if {@code true}, show notice even if already seen. 723 * @param disableCache Whether or not {@code noticeContents} will be cached. 724 */ 725 public void debugNotice(String noticeContents, boolean notifyDialog, 726 boolean disableCache) 727 { 728 // Shortcut this whole process if we are processing offscreen 729 if (super.getIdv().getArgsManager().getIsOffScreen()) { 730 return; 731 } 732 733 String thisNotice; 734 thisNotice = disableCache ? "" : getNoticeCached().trim(); 735 String thatNotice = noticeContents.trim(); 736 String labelText = thatNotice; 737 738 if (thatNotice.isEmpty()) { 739 if (!disableCache) { 740 setNoticeCached(thatNotice); 741 } 742 if (notifyDialog) { 743 String titleText = "No Notice"; 744 JLabel message = new JLabel("There is no current notice", JLabel.CENTER); 745 JOptionPane.showMessageDialog(null, message, titleText, 746 JOptionPane.INFORMATION_MESSAGE); 747 } 748 } else if (!thisNotice.equals(thatNotice)) { 749 if (!disableCache) { 750 setNoticeCached(thatNotice); 751 } 752 String titleText = "New Notice"; 753 JPanel backgroundColorGetterPanel = new JPanel(); 754 JEditorPane messageText = new JEditorPane("text/html", labelText); 755 messageText.setBackground(backgroundColorGetterPanel.getBackground()); 756 messageText.setEditable(false); 757 messageText.addHyperlinkListener(this); 758 JOptionPane.showMessageDialog(null, messageText, titleText, 759 JOptionPane.INFORMATION_MESSAGE); 760 } else { 761 if (notifyDialog) { 762 String titleText = "Previous Notice"; 763 JPanel bgPanel = new JPanel(); 764 JEditorPane messageText = 765 new JEditorPane("text/html", labelText); 766 messageText.setBackground(bgPanel.getBackground()); 767 messageText.setEditable(false); 768 messageText.addHyperlinkListener(this); 769 JOptionPane.showMessageDialog(null, messageText, titleText, 770 JOptionPane.INFORMATION_MESSAGE); 771 } 772 } 773 } 774 775 private String getNoticePath() { 776 return StartupManager.getInstance().getPlatform().getUserFile("notice.txt"); 777 } 778 779 private String getNoticeCached() { 780 String notice = ""; 781 try{ 782 FileReader fstream = new FileReader(getNoticePath()); 783 BufferedReader in = new BufferedReader(fstream); 784 String line; 785 while ((line = in.readLine()) != null) { 786 notice += line + '\n'; 787 } 788 in.close(); 789 } catch (Exception e){ 790 System.err.println("Error: " + e.getMessage()); 791 } 792 return notice; 793 } 794 795 private void setNoticeCached(String notice) { 796 try{ 797 FileWriter fstream = new FileWriter(getNoticePath()); 798 BufferedWriter out = new BufferedWriter(fstream); 799 out.write(notice); 800 out.close(); 801 } catch (Exception e){ 802 System.err.println("Error: " + e.getMessage()); 803 } 804 } 805}