|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object com.challengeandresponse.components.SoftwareUpdate
This modest little class assists with automatic retrieval of updates to an application. It mostly just calculates platform-specific paths to downloads and related files, and checks version numbers. Configuration data are retrieved from a server, so the application creator has a modest measure of control over the behavior of update clients even when they're out in the field. The class considers that versions for different platforms may not be released simultaneously. If there is a README file, it also retrieves it for display to a user, if you wish, before they approve/deny an update.
A quick overview of how you'd use this:
1. Add SoftwareUpdate jar to your application classpath and add software update code to the app
2. Create config file(s) on the software distribution web server. The config file provides the current version number, an optional hash, an optional readme file url, and an optional download URL for the latest release
If there are application-specific directories, a config file goes in each one. If there's no distinction made for different operating systems, then there's just one config file.
3. The application periodically checks for updates:
3a. instantiate the class, SoftwareUpdate su = new SoftwareUpdate();
3b. call loadConfig() to retrieve config data from the update server
3c. application compares its version serial number to the value returned from getCurrentVersionSerial()
3d. application may display the current version's README file, contents available from getCurrentReadme()
3e. if the app is out of date, it can do whatever is appropriate to get the upgrade from get CurrentDownloadURL()
3f. the application or download helper may do something to allow the downloaded file's hash to be compared to the config file's hash parameter, from getCurrentHash()
This class works well in conjunction with BrowserLauncher 2 available from: http://sourceforge.net/projects/browserlaunch2/
RELEASE NOTES
version 1.10
IMPORTANT!
After instantiating the class, call loadConfig() to fetch its config file (as in example program below).
Version 1.10 makes significant changes to the way update details are configured:
- Now uses a single configuration file (one per OS if you are separating downloads by OS) to hold all the settings that control the remote updater.
- This replaces the previous scheme in which separate "version" and "hash" file names were provided, that would be opened and read.
- This change has been made because it's a cleaner approach, and because it'll be desirable to add more server-control on the remote update clients in the future
- The download URL is now in the config file and is no longer specified in the class. This will allow implementors to alter the download URL at any time
or retrieve downloads from somewhere other than the baseURL. Also, because the download URL comes from the server
at check-time, installed copies in the field will pick up and use a changed URL immediately, creating flexibility for downloads and customer notification.
Configuration file format
Place one LABEL / VALUE pair per line, separated by white space
"#" at the start of a line comments-out the line
Labels are not case-sensitive. Case of values is preserved as written in the config file.
HTTP and HTTPS protocols are supported. No others
versionserial <the integer serial number of the latest version to compare against>
hash <hash of the latest version>
downloadurl <url to download the latest version from>
readmeurl <url of the readme file for the latest version>
Example configuration files
# My config for Macintosh
# Assumes:
# base URL is "http://my.host/product/download"
# addPlatform(OS_MAC,"mac/") was called to set up a Mac-specific handler.
#
versionserial 120
hash 341F2DE6
downloadurl http://my.host/product/download/mac/Product.dmg
readmeurl http://my.host/product/download/mac/README
SoftwareUpdate anticipates the software distribution web server will have a layout something like this:
a base url: http://host.tld.com/product/current/ --- the base URL
... and under that, if you're distinguishing downloads by operating system, one directory per OS that you support, each with a configuration file
eg: ./mac/configfile
eg: ./linux/configfile
eg: ./windows/configfile
... or if not distinguishing by OS, just one configuration file
eg: ./configfile
Version comparisons
Version comparisons are performed with a Version Serial Number. This is an integer value
that should be incremented with each new release. The value stored in the application at your
user's computer will be compared to the value stored in the configuration file's 'versionserial' parameter.
If the version serial number at the server is higher than the application's versionserial, an update is needed.
The configuration file only "requires" a version serial number... everything else can be optional.
If you don't provide the other params, the get...() methods that would return
their values will return null.
// example code
// this code assumes there will be three directories, /mac, /linux and /windows, for updates
// it presumes each platform directory will have a config file "CONFIGFILE" containing parameters as described above
//
// just to recap, this is the file and directory structure expected by the below example code:
// http://mysite.com/myproduct/ the base URL
// http://mysite.com/myproduct/mac/CONFIGFILE the config file for Macintosh updates
// http://mysite.com/myproduct/linux/CONFIGFILE the config file for Linux updates
// http://mysite.com/myproduct/windows/CONFIGFILE the config file for Windows updates
//
int thisVersion = 108; // the version of "This program" that will be checked for an available update
SoftwareUpdate su = new SoftwareUpdate("http://mysite.com/myproduct/","CONFIGFILE");
su.addPlatform(OS_MAC,"mac/");
su.addPlatform(OS_WINDOWS,"windows/");
su.addPlatform(OS_LINUX,"linux/");
// lazy exception catching. If caught separately, they tell more about what went wrong...
try {
su.loadConfig();
}
catch (Exception e) {
System.out.println("An exception occurred while loading the config file: "+e.getMessage());
}
System.out.println("Current version: "+su.getCurrentVersionSerial());
System.out.println("Current hash: "+su.getCurrentHash());
System.out.println("Current readme URL: "+su.getCurrentReadmeURL());
System.out.println("Current download URL: "+su.getCurrentDownloadURL());
System.out.println("Current readme file contents: "+su.getCurrentReadme());
// else compare the versions and download if not up to date
if (su.getCurrentVersionSerial() > thisVersion) {
System.out.println("Newer version "+su.getCurrentVersionSerial()+" available for download from: "+su.getCurrentDownloadURL());
}
else {
System.out.println("The current version "+thisVersion+" is up to date");
}
Field Summary | |
private java.lang.String |
baseURL
|
private static java.lang.String |
CONFIG_DOWNLOADURL
|
private static java.lang.String |
CONFIG_HASH
|
private static java.lang.String |
CONFIG_README
|
private static java.lang.String |
CONFIG_READMEURL
|
private static java.lang.String |
CONFIG_VERSIONSERIAL
|
private java.lang.String |
configFilename
|
private static java.util.Hashtable |
configParams
loadConfig() populates these configuration parameters from the config file. |
static java.lang.String |
COPYRIGHT
|
private java.lang.String |
os
|
static java.lang.String |
OS_LINUX
Can be used with 'addPlatform()' to ID a Linux operating system |
static java.lang.String |
OS_MAC
Can be used with 'addPlatform()' to ID a Mac operating system |
static java.lang.String |
OS_WINDOWS
Can be used with 'addPlatform()' to ID a Windows operating system |
private java.util.Hashtable |
platforms
Mapping a platform ID string to a URL path fragment |
static java.lang.String |
PRODUCT
|
static java.lang.String |
PRODUCT_SHORT
|
private java.lang.String |
userAgent
|
private static java.util.HashSet |
validConfigParams
a set of valid config parameters, used by loadParams() to keep the configParams table clean |
static java.lang.String |
VERSION
|
static java.lang.String |
VERSION_FULL
|
static int |
VERSIONSERIAL
|
Constructor Summary | |
private |
SoftwareUpdate()
no-arg constructor isn't available |
|
SoftwareUpdate(java.lang.String _baseURL,
java.lang.String _configFilename)
Basic constructor. |
Method Summary | |
void |
addPlatform(java.lang.String osIdentifier,
java.lang.String osSuffix)
Add a platform identifier (based on operating system), specifying the directory that will be appended to the path, and the path to the downloadable current release, for that platform. |
java.lang.String |
getCurrentDownloadPath()
Deprecated. badly named. Please use getCurrentDownloadURL |
java.net.URL |
getCurrentDownloadURL()
Return the download url as retrieved from the config file |
java.lang.String |
getCurrentHash()
|
java.lang.String |
getCurrentReadme()
Fetch and return the current README for the latest released version for this operating system |
java.net.URL |
getCurrentReadmeURL()
Return the readme URL |
int |
getCurrentVersion()
Deprecated. renamed to getCurrentVersionSerial(). getCurrentVersion() will be removed in a future release. |
int |
getCurrentVersionSerial()
|
java.lang.String |
getOS()
Get the current "OS" setting, which was initialized when the class is instantiated |
private java.lang.String |
getPlatformPath()
Return the URL path add-on for the current operating system, if any. |
java.lang.String |
getUserAgent()
Return the UserAgent identifier string that's sent to the host |
void |
loadConfig()
Call this method before trying to get...() anything from SoftwareUpdate. |
static void |
main(java.lang.String[] params)
Main method provided for testing and example... |
private java.net.HttpURLConnection |
openConnectionForURL(java.net.URL u,
boolean followRedirects)
Open a URL, and return a connection to it. |
void |
setOS(java.lang.String _os)
Set the current "OS" setting to override the auto-initialized OS value (at class instantiation, the OS string is set from System.getProperty("os.name") ) |
void |
setUserAgent(java.lang.String _newAgent)
Change the UserAgent identifier string that's sent to the host. |
Methods inherited from class java.lang.Object |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Field Detail |
public static final java.lang.String PRODUCT_SHORT
public static final java.lang.String PRODUCT
public static final java.lang.String VERSION
public static final int VERSIONSERIAL
public static final java.lang.String VERSION_FULL
public static final java.lang.String COPYRIGHT
private static final java.lang.String CONFIG_VERSIONSERIAL
private static final java.lang.String CONFIG_HASH
private static final java.lang.String CONFIG_DOWNLOADURL
private static final java.lang.String CONFIG_READMEURL
private static final java.lang.String CONFIG_README
private static final java.util.HashSet validConfigParams
private static java.util.Hashtable configParams
private java.util.Hashtable platforms
private java.lang.String baseURL
private java.lang.String configFilename
private java.lang.String os
private java.lang.String userAgent
public static final java.lang.String OS_MAC
public static final java.lang.String OS_WINDOWS
public static final java.lang.String OS_LINUX
Constructor Detail |
private SoftwareUpdate()
public SoftwareUpdate(java.lang.String _baseURL, java.lang.String _configFilename)
for example, new SoftwareUpdate("http://my.host/product/","configfile")
anticipates that http://my.host/product/configfile will be a config file if NOT distinguishing by OS
If distinguishing by OS, the the OS-specific directory is interposed in the path just before the file name, for example: http://my.host/product/mac/configfile
.
_baseURL
- The base URL under which config files(s) and optional per-os directories are found_configFilename
- The name (only) of the configuration file, to be appended to the baseURL (+OS version directory if any)Method Detail |
public int getCurrentVersion()
public int getCurrentVersionSerial()
public java.lang.String getCurrentHash()
public java.net.URL getCurrentDownloadURL()
for instructs about setting up different config files and paths for different platforms
public java.lang.String getCurrentDownloadPath()
public java.net.URL getCurrentReadmeURL()
public java.lang.String getCurrentReadme()
public java.lang.String getOS()
public void setOS(java.lang.String _os)
public void setUserAgent(java.lang.String _newAgent)
public java.lang.String getUserAgent()
public void addPlatform(java.lang.String osIdentifier, java.lang.String osSuffix)
The OS is determined via System.getProperty("os.name"). The first partial string match is used. Constants are provided in this class for the three mainstream operating systems (see the constant values OS_*).
Matching is not case sensitive
example: addPlatform(SoftwareUpdate.OS_MACOSX,"mac/");
osIdentifier
- a string that will match part of the System.getProperty("os.name") call for the desired OSosSuffix
- the string to append to the URL path, for this OS. This string will be appended to the baseURL that was set in the constructor. Provide trailing slashe as appropriatepublic void loadConfig() throws java.net.MalformedURLException, java.io.IOException, java.lang.NumberFormatException, java.lang.UnsupportedOperationException
java.net.MalformedURLException
- if a valid URL could not be constructed from baseURL,os-path and file name
java.io.IOException
- if an error occurred when opening and reading from the constructed URL
java.lang.NumberFormatException
- if an expected numeric parameter cannot be parsed as a number
java.lang.UnsupportedOperationException
- if a protocol other than HTTP or HTTPs is attemptedprivate java.lang.String getPlatformPath()
addPlatform(String, String)
private java.net.HttpURLConnection openConnectionForURL(java.net.URL u, boolean followRedirects) throws java.lang.UnsupportedOperationException, java.io.IOException
u
- The URL to open.followRedirects
- set 'true' to follow redirects coming back from the server (e.g. http://.../ -> http://.../index.html) false to just load the given page and stop even if there is a Location: header
java.lang.UnsupportedOperationException
- if an invalid protocol (neither HTTP nor HTTPS) is presented
java.io.IOException
- if an IO error occurred opening the URL or making the connectionpublic static void main(java.lang.String[] params)
Example config file that might be used with the program below:
# # Per the constructor below, this file would be located at http://myhost.tld/path/morepath/config # versionserial 110 hash 3F309A14 downloadurl http://myhost.tld/path/morepath/Program.sit readmeurl http://myhost.tld/path/morepath/README
|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |