package de.blizzy.documentr.system;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import com.google.common.base.Charsets;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import de.blizzy.documentr.util.Util;
@Component
@Slf4j
public class UpdateChecker {
private static final String UPDATE_PROPERTIES_URL =
"http://documentr.org/attachment/documentr/1.x/home,download/latest-version.txt"; //$NON-NLS-1$
@Autowired
private SystemSettingsStore systemSettingsStore;
@Getter
private boolean updateAvailable;
@Getter
private String latestVersion;
private long lastCheckTime = -1;
@Scheduled(fixedRate=24 * 60 * 60 * 1000)
public void checkForUpdate() {
if (isCheckNecessary()) {
log.info("checking for documentr update"); //$NON-NLS-1$
lastCheckTime = System.currentTimeMillis();
Version currentVersion = getCurrentVersion();
if (currentVersion != null) {
log.debug("current version: {}", currentVersion); //$NON-NLS-1$
Version latestVersion = getLatestVersionFromServer();
if (latestVersion != null) {
log.debug("latest version: {}", latestVersion); //$NON-NLS-1$
if (latestVersion.compareTo(currentVersion) > 0) {
updateAvailable = true;
this.latestVersion = latestVersion.toString();
log.info("documentr update available: {}", latestVersion); //$NON-NLS-1$
} else {
log.info("documentr version is up to date"); //$NON-NLS-1$
}
} else {
log.debug("couldn't determine latest version"); //$NON-NLS-1$
}
} else {
log.debug("couldn't determine current version"); //$NON-NLS-1$
}
}
}
private boolean isCheckNecessary() {
String intervalStr = systemSettingsStore.getSetting(SystemSettingsStore.UPDATE_CHECK_INTERVAL);
boolean result = false;
if (!intervalStr.equals(SystemSettingsStore.UPDATE_CHECK_INTERVAL_NEVER)) {
long interval;
if (intervalStr.equals(SystemSettingsStore.UPDATE_CHECK_INTERVAL_WEEKLY)) {
interval = TimeUnit.MILLISECONDS.convert(7, TimeUnit.DAYS);
} else {
interval = TimeUnit.MILLISECONDS.convert(1, TimeUnit.DAYS);
}
long now = System.currentTimeMillis();
if ((lastCheckTime < 0) || ((now - lastCheckTime) >= interval)) {
result = true;
}
}
return result;
}
private Version getCurrentVersion() {
InputStreamReader in = null;
try {
InputStream stream = getResourceAsStream("/documentr-version.properties"); //$NON-NLS-1$
if (stream != null) {
in = new InputStreamReader(stream, Charsets.UTF_8);
Properties props = new Properties();
props.load(in);
String versionStr = (String) props.values().iterator().next();
if (!versionStr.startsWith("@")) { //$NON-NLS-1$
return Version.fromString(versionStr);
}
}
} catch (IOException e) {
log.error(StringUtils.EMPTY, e);
} finally {
Util.closeQuietly(in);
}
return null;
}
private InputStream getResourceAsStream(String name) {
return getClass().getClassLoader().getResourceAsStream(name);
}
private Version getLatestVersionFromServer() {
List<Version> versions = Lists.newArrayList(getLatestVersionsFromServer());
if (!versions.isEmpty()) {
Collections.sort(versions);
Collections.reverse(versions);
return versions.get(0);
}
return null;
}
private Set<Version> getLatestVersionsFromServer() {
String text = loadLatestVersionsFromServer();
Set<Version> versions = Sets.newHashSet();
if (StringUtils.isNotBlank(text)) {
try {
Properties props = new Properties();
props.load(new StringReader(text));
for (Object key : props.keySet()) {
versions.add(Version.fromString((String) key));
}
} catch (IOException e) {
log.error(StringUtils.EMPTY, e);
}
}
return versions;
}
private String loadLatestVersionsFromServer() {
try {
return new Downloader().getTextFromUrl(UPDATE_PROPERTIES_URL, Charsets.UTF_8);
} catch (UnknownHostException e) {
log.info("couldn't retrieve {}: unknown host", UPDATE_PROPERTIES_URL); //$NON-NLS-1$
} catch (SocketTimeoutException e) {
log.info("couldn't retrieve {}: connection timeout", UPDATE_PROPERTIES_URL); //$NON-NLS-1$
} catch (SocketException e) {
log.info("couldn't retrieve {}: {}", UPDATE_PROPERTIES_URL, e.getMessage()); //$NON-NLS-1$
} catch (IOException e) {
log.warn("error while checking for documentr update", e); //$NON-NLS-1$
}
return null;
}
}