001 /* 002 * $Id: StateManager.java,v 1.30 2012/04/30 15:57: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; 032 033 import java.awt.event.ActionEvent; 034 import java.io.BufferedReader; 035 import java.io.BufferedWriter; 036 import java.io.FileReader; 037 import java.io.FileWriter; 038 import java.util.Hashtable; 039 import java.util.Properties; 040 041 import javax.swing.JEditorPane; 042 import javax.swing.JLabel; 043 import javax.swing.JOptionPane; 044 import javax.swing.JPanel; 045 import javax.swing.event.HyperlinkEvent; 046 import javax.swing.event.HyperlinkListener; 047 048 import ucar.unidata.idv.IdvObjectStore; 049 import ucar.unidata.idv.IntegratedDataViewer; 050 import ucar.unidata.util.IOUtil; 051 import ucar.unidata.util.Misc; 052 import ucar.unidata.util.StringUtil; 053 import edu.wisc.ssec.mcidasv.startupmanager.StartupManager; 054 055 public class StateManager extends ucar.unidata.idv.StateManager implements Constants, HyperlinkListener { 056 057 private String version; 058 private String versionAbout; 059 060 public StateManager(IntegratedDataViewer idv) { 061 super(idv); 062 } 063 064 /** 065 * Override to set the right user directory 066 */ 067 protected IdvObjectStore doMakeObjectStore() { 068 IdvObjectStore store = new IdvObjectStore(getIdv(), 069 getStoreSystemName(), getStoreName(), 070 getIdv().getEncoderForRead(), 071 StartupManager.INSTANCE.getPlatform().getUserDirectory()); 072 initObjectStore(store); 073 return store; 074 } 075 076 /** 077 * Handle a change to a link 078 * 079 * @param e the link's event 080 */ 081 public void hyperlinkUpdate(HyperlinkEvent e) { 082 if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { 083 if (e.getURL() == null) { 084 click(e.getDescription()); 085 } else { 086 click(e.getURL().toString()); 087 } 088 } 089 } 090 091 /** 092 * Handle a click on a link 093 * 094 * @param url the link definition 095 */ 096 public void click(String url) { 097 getIdv().actionPerformed(new ActionEvent(this, 0, url)); 098 } 099 100 public String getOSName() { 101 String os = System.getProperty("os.name"); 102 os = os.replaceAll(" ", "_"); 103 return os; 104 } 105 106 public String getMcIdasVersionAbout() { 107 getMcIdasVersion(); 108 109 versionAbout = IOUtil.readContents((String) getProperty(Constants.PROP_ABOUTTEXT), ""); 110 versionAbout = StringUtil.replace(versionAbout, MACRO_VERSION, version); 111 Properties props = Misc.readProperties( 112 (String) getProperty(Constants.PROP_VERSIONFILE), 113 null, 114 getClass() 115 ); 116 117 String value = getIdvVersion(); 118 versionAbout = StringUtil.replace(versionAbout, Constants.MACRO_IDV_VERSION, value); 119 value = props.getProperty(PROP_COPYRIGHT_YEAR, ""); 120 versionAbout = StringUtil.replace(versionAbout, Constants.MACRO_COPYRIGHT_YEAR, value); 121 value = props.getProperty(PROP_BUILD_DATE, "Unknown"); 122 versionAbout = StringUtil.replace(versionAbout, Constants.MACRO_BUILDDATE, value); 123 124 return versionAbout; 125 } 126 127 public String getMcIdasVersion() { 128 if (version != null) { 129 return version; 130 } 131 132 Properties props = new Properties(); 133 props = Misc.readProperties((String) getProperty(Constants.PROP_VERSIONFILE), null, getClass()); 134 String maj = props.getProperty(PROP_VERSION_MAJOR, "0"); 135 String min = props.getProperty(PROP_VERSION_MINOR, "0"); 136 String rel = props.getProperty(PROP_VERSION_RELEASE, ""); 137 138 version = maj.concat(".").concat(min).concat(rel); 139 140 return version; 141 } 142 143 /** 144 * Get a property 145 * 146 * @param name name of the property 147 * 148 * @return the property or null 149 */ 150 @Override public Object getProperty(final String name) { 151 Object value = null; 152 if (McIDASV.isMac()) 153 value = getProperties().get("mac."+name); 154 155 if (value == null) 156 value = getProperties().get(name); 157 158 if (value == null) { 159 String fixedName = StateManager.fixIds(name); 160 if (!name.equals(fixedName)) 161 return getProperties().get(fixedName); 162 } 163 return value; 164 } 165 166 /** 167 * Returns information about the current version of McIDAS-V and the IDV, 168 * along with their respective build dates. 169 * 170 * @return Hashtable containing versioning information. 171 */ 172 public Hashtable<String, String> getVersionInfo() { 173 Properties props = new Properties(); 174 props = Misc.readProperties((String) getProperty(Constants.PROP_VERSIONFILE), null, getClass()); 175 176 String mcvBuild = props.getProperty(PROP_BUILD_DATE, "Unknown"); 177 178 Hashtable<String, String> table = new Hashtable<String, String>(); 179 table.put("mcv.version.general", getMcIdasVersion()); 180 table.put("mcv.version.build", mcvBuild); 181 table.put("idv.version.general", getVersion()); 182 table.put("idv.version.build", getBuildDate()); 183 return table; 184 } 185 186 public String getIdvVersion() { 187 return getVersion(); 188 } 189 190 /** 191 * Overridden to set default of McIDAS-V 192 */ 193 public String getStoreSystemName() { 194 return StartupManager.INSTANCE.getPlatform().getUserDirectory(); 195 } 196 197 /** 198 * Overridden to get dir of the unnecessary second level directory. 199 * 200 * @see ucar.unidata.idv.StateManager#getStoreName() 201 */ 202 public String getStoreName() { 203 return ""; 204 } 205 206 /** 207 * Connect to McIDAS website and look for latest stable version 208 */ 209 public String getMcIdasVersionStable() { 210 String version = ""; 211 try { 212 version = IOUtil.readContents(Constants.HOMEPAGE_URL+'/'+Constants.VERSION_URL+"?requesting="+getMcIdasVersion()+"&os="+getOSName(), ""); 213 } catch (Exception e) {} 214 return version.trim(); 215 } 216 217 /** 218 * Connect to McIDAS website and look for latest prerelease version 219 */ 220 public String getMcIdasVersionPrerelease() { 221 String version = ""; 222 try { 223 String htmlList = IOUtil.readContents(Constants.HOMEPAGE_URL+'/'+Constants.PRERELEASE_URL, ""); 224 String lines[] = htmlList.split("\n"); 225 for (int i=0; i<lines.length; i++) { 226 String line = lines[i].trim(); 227 if (line.matches(".*McIDAS-V_\\d+\\.\\d+.*")) { 228 line = line.substring(line.indexOf("McIDAS-V_")+9); 229 String aVersion = line.substring(0, line.indexOf("_")); 230 if (version == "") { 231 version = aVersion; 232 } 233 else { 234 int comp = compareVersions(version, aVersion); 235 if (comp > 0) { 236 version = aVersion; 237 } 238 } 239 } 240 } 241 } catch (Exception e) {} 242 return version.trim(); 243 } 244 245 /** 246 * Connect to McIDAS website and look for latest notice 247 */ 248 public String getNoticeLatest() { 249 String notice = ""; 250 try { 251 notice = IOUtil.readContents(Constants.HOMEPAGE_URL+"/"+Constants.NOTICE_URL+"?requesting="+getMcIdasVersion()+"&os="+getOSName(), ""); 252 } catch (Exception e) {} 253 if (notice.indexOf("<notice>")<0) notice=""; 254 notice = notice.replaceAll("<[/?]notice>",""); 255 return notice.trim(); 256 } 257 258 /** 259 * Compare version strings 260 * 0: equal 261 * <0: this version is greater 262 * >0: that version is greater 263 */ 264 private int compareVersions(String thisVersion, String thatVersion) { 265 int thisInt = versionToInteger(thisVersion); 266 int thatInt = versionToInteger(thatVersion); 267 return (thatInt - thisInt); 268 } 269 270 /** 271 * Turn version strings of the form #.#(a#) 272 * where # is one or two digits, a is one of alpha or beta, and () is optional 273 * Into an integer... (empty) > beta > alpha 274 */ 275 private int versionToInteger(String version) { 276 int value = 0; 277 int p; 278 String part; 279 Character one = null; 280 281 try { 282 283 // Major version 284 p = version.indexOf('.'); 285 if (p > 0) { 286 part = version.substring(0,p); 287 value += Integer.parseInt(part) * 1000000; 288 version = version.substring(p+1); 289 } 290 291 // Minor version 292 int minor = 0; 293 int i=0; 294 for (i=0; i<2 && i<version.length(); i++) { 295 one = version.charAt(i); 296 if (Character.isDigit(one)) { 297 if (i>0) minor *= 10; 298 minor += Character.digit(one, 10) * 10000; 299 } 300 else { 301 break; 302 } 303 } 304 value += minor; 305 if (one!=null) version = version.substring(i); 306 307 // Alpha/beta/update/release status 308 if (version.length() == 0) value += 300; 309 else if (version.charAt(0) == 'b') value += 200; 310 else if (version.charAt(0) == 'a') value += 100; 311 else if (version.charAt(0) == 'u') value += 400; 312 else if (version.charAt(0) == 'r') value += 400; 313 for (i=0; i<version.length(); i++) { 314 one = version.charAt(i); 315 if (Character.isDigit(one)) break; 316 } 317 if (one!=null) version = version.substring(i); 318 319 // Alpha/beta version 320 if (version.length() > 0) 321 value += Integer.parseInt(version); 322 323 } catch (Exception e) {} 324 325 return value; 326 } 327 328 public boolean getIsPrerelease() { 329 boolean isPrerelease = false; 330 String version = getMcIdasVersion(); 331 if (version.indexOf("a") >= 0 || version.indexOf("b") >= 0) { 332 isPrerelease = true; 333 } 334 return isPrerelease; 335 } 336 337 public void checkForNewerVersion(boolean notifyDialog) { 338 checkForNewerVersionStable(notifyDialog); 339 if (getStore().get(Constants.PREF_PRERELEASE_CHECK, getIsPrerelease())) { 340 checkForNewerVersionPrerelease(notifyDialog); 341 } 342 } 343 344 public void checkForNewerVersionStable(boolean notifyDialog) { 345 346 /** Shortcut this whole process if we are processing offscreen */ 347 if (super.getIdv().getArgsManager().getIsOffScreen()) 348 return; 349 350 String thisVersion = getMcIdasVersion(); 351 String thatVersion = getMcIdasVersionStable(); 352 String titleText = "Version Check"; 353 354 if (thisVersion.equals("") || thatVersion.equals("")) { 355 if (notifyDialog) { 356 JOptionPane.showMessageDialog(null, "Version check failed", titleText, 357 JOptionPane.WARNING_MESSAGE); 358 } 359 } 360 else if (compareVersions(thisVersion, thatVersion) > 0) { 361 String labelText = "<html>Version <b>" + thatVersion + "</b> is available<br><br>"; 362 labelText += "Visit <a href=\"" + Constants.HOMEPAGE_URL + "\">"; 363 labelText += Constants.HOMEPAGE_URL + "</a> to download</html>"; 364 365 JPanel backgroundColorGetterPanel = new JPanel(); 366 JEditorPane messageText = new JEditorPane("text/html", labelText); 367 messageText.setBackground(backgroundColorGetterPanel.getBackground()); 368 messageText.setEditable(false); 369 messageText.addHyperlinkListener(this); 370 371 // JLabel message = new JLabel(labelText, JLabel.CENTER); 372 JOptionPane.showMessageDialog(null, messageText, titleText, 373 JOptionPane.INFORMATION_MESSAGE); 374 } 375 else { 376 if (notifyDialog) { 377 String labelText = "<html>This version (<b>" + thisVersion + "</b>) is up to date</html>"; 378 JLabel message = new JLabel(labelText, JLabel.CENTER); 379 JOptionPane.showMessageDialog(null, message, titleText, 380 JOptionPane.INFORMATION_MESSAGE); 381 } 382 } 383 384 } 385 386 public void checkForNewerVersionPrerelease(boolean notifyDialog) { 387 388 /** Shortcut this whole process if we are processing offscreen */ 389 if (super.getIdv().getArgsManager().getIsOffScreen()) 390 return; 391 392 String thisVersion = getMcIdasVersion(); 393 String thatVersion = getMcIdasVersionPrerelease(); 394 String titleText = "Prerelease Check"; 395 396 if (thisVersion.equals("") || thatVersion.equals("")) { 397 if (notifyDialog) { 398 JOptionPane.showMessageDialog(null, "No prerelease version available", titleText, 399 JOptionPane.WARNING_MESSAGE); 400 } 401 } 402 else if (compareVersions(thisVersion, thatVersion) > 0) { 403 String labelText = "<html>Prerelease <b>" + thatVersion + "</b> is available<br><br>"; 404 labelText += "Visit <a href=\"" + Constants.HOMEPAGE_URL+'/'+Constants.PRERELEASE_URL + "\">"; 405 labelText += Constants.HOMEPAGE_URL+'/'+Constants.PRERELEASE_URL + "</a> to download</html>"; 406 407 JPanel backgroundColorGetterPanel = new JPanel(); 408 JEditorPane messageText = new JEditorPane("text/html", labelText); 409 messageText.setBackground(backgroundColorGetterPanel.getBackground()); 410 messageText.setEditable(false); 411 messageText.addHyperlinkListener(this); 412 413 // JLabel message = new JLabel(labelText, JLabel.CENTER); 414 JOptionPane.showMessageDialog(null, messageText, titleText, 415 JOptionPane.INFORMATION_MESSAGE); 416 } 417 else { 418 if (notifyDialog) { 419 String labelText = "<html>This version (<b>" + thisVersion + "</b>) is up to date</html>"; 420 JLabel message = new JLabel(labelText, JLabel.CENTER); 421 JOptionPane.showMessageDialog(null, message, titleText, 422 JOptionPane.INFORMATION_MESSAGE); 423 } 424 } 425 426 } 427 428 public void checkForNotice(boolean notifyDialog) { 429 430 /** Shortcut this whole process if we are processing offscreen */ 431 if (super.getIdv().getArgsManager().getIsOffScreen()) 432 return; 433 434 String thisNotice = getNoticeCached().trim(); 435 String thatNotice = getNoticeLatest().trim(); 436 String titleText = "New Notice"; 437 String labelText = thatNotice; 438 439 if (thatNotice.equals("")) { 440 setNoticeCached(thatNotice); 441 if (notifyDialog) { 442 titleText = "No Notice"; 443 JLabel message = new JLabel("There is no current notice", JLabel.CENTER); 444 JOptionPane.showMessageDialog(null, message, titleText, 445 JOptionPane.INFORMATION_MESSAGE); 446 } 447 return; 448 } 449 else if (!thisNotice.equals(thatNotice)) { 450 setNoticeCached(thatNotice); 451 452 JPanel backgroundColorGetterPanel = new JPanel(); 453 JEditorPane messageText = new JEditorPane("text/html", labelText); 454 messageText.setBackground(backgroundColorGetterPanel.getBackground()); 455 messageText.setEditable(false); 456 messageText.addHyperlinkListener(this); 457 458 // JLabel message = new JLabel(labelText, JLabel.CENTER); 459 JOptionPane.showMessageDialog(null, messageText, titleText, 460 JOptionPane.INFORMATION_MESSAGE); 461 } 462 else { 463 if (notifyDialog) { 464 titleText = "Previous Notice"; 465 JLabel message = new JLabel(labelText, JLabel.CENTER); 466 JOptionPane.showMessageDialog(null, message, titleText, 467 JOptionPane.INFORMATION_MESSAGE); 468 } 469 } 470 471 } 472 473 private String getNoticePath() { 474 return StartupManager.INSTANCE.getPlatform().getUserFile("notice.txt"); 475 } 476 477 private String getNoticeCached() { 478 String notice = ""; 479 try{ 480 FileReader fstream = new FileReader(getNoticePath()); 481 BufferedReader in = new BufferedReader(fstream); 482 String line; 483 while ((line = in.readLine()) != null) { 484 notice += line + '\n'; 485 } 486 in.close(); 487 } catch (Exception e){ 488 System.err.println("Error: " + e.getMessage()); 489 } 490 return notice; 491 } 492 493 private void setNoticeCached(String notice) { 494 try{ 495 FileWriter fstream = new FileWriter(getNoticePath()); 496 BufferedWriter out = new BufferedWriter(fstream); 497 out.write(notice); 498 out.close(); 499 } catch (Exception e){ 500 System.err.println("Error: " + e.getMessage()); 501 } 502 } 503 504 }