org.nuiton.updater.AbstractApplicationUpdaterAction Maven / Gradle / Ivy
package org.nuiton.updater;
/*
* #%L
* Nuiton Application Updater
* $Id: AbstractApplicationUpdaterAction.java 2588 2013-07-20 14:25:42Z tchemit $
* $HeadURL: https://nuiton.org/svn/nuiton-updater/tags/nuiton-updater-3.0-alpha-2/src/main/java/org/nuiton/updater/AbstractApplicationUpdaterAction.java $
* %%
* Copyright (C) 2013 CodeLutin, Tony Chemit
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* .
* #L%
*/
import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.vfs2.FileObject;
import org.apache.commons.vfs2.FileSystemManager;
import org.apache.commons.vfs2.FileSystemOptions;
import org.apache.commons.vfs2.VFS;
import org.apache.commons.vfs2.provider.http.HttpFileSystemConfigBuilder;
import org.nuiton.util.VersionUtil;
import org.nuiton.config.ApplicationConfig;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.InputStream;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Abstract updater action.
*
* @author tchemit
* @since 2.6.12
*/
public abstract class AbstractApplicationUpdaterAction implements Runnable {
/** Logger. */
private static final Log log =
LogFactory.getLog(AbstractApplicationUpdaterAction.class);
public static final String HTTP_PROXY = "http_proxy";
public static final String URL_KEY = "url";
public static final String AUTHENTICATION_KEY = "auth";
public static final String VERSION_KEY = "version";
protected ApplicationConfig config;
protected String vfsPropertiesUrl;
protected File currentDir;
public AbstractApplicationUpdaterAction(ApplicationConfig config,
String vfsPropertiesUrl,
File currentDir) {
this.config = config;
this.vfsPropertiesUrl = vfsPropertiesUrl;
this.currentDir = currentDir;
}
protected Map getVersions(ApplicationConfig releaseConfig,
boolean allVersion,
File destDir) {
List appNames = getApplicationName(releaseConfig);
Map appVersions = getCurrentVersion(appNames, currentDir);
log.debug("application current version: " + appVersions);
// recherche des applications a mettre a jour
Map appToUpdate = new HashMap();
for (String app : appNames) {
String currentVersion = appVersions.get(app);
String newVersion = releaseConfig.getOption(app + ApplicationUpdater.SEPARATOR_KEY + VERSION_KEY);
boolean greater = VersionUtil.greaterThan(newVersion, currentVersion);
log.debug(String.format("for %s Current(%s) < newVersion(%s) ? %s",
app, currentVersion, newVersion, greater));
boolean add = allVersion || greater;
if (add) {
String urlString = releaseConfig.getOption(
app + ApplicationUpdater.SEPARATOR_KEY + URL_KEY);
boolean needAuthentication = releaseConfig.getOptionAsBoolean(
app + ApplicationUpdater.SEPARATOR_KEY + AUTHENTICATION_KEY);
if (allVersion && !greater) {
newVersion = null;
}
appToUpdate.put(app, new ApplicationInfo(
app, currentVersion, newVersion, urlString, destDir, needAuthentication));
}
}
return appToUpdate;
}
/**
* Converti le path en URL vfs2. Path doit etre une URL, mais pour les fichiers
* au lieu d'etre absolue ils peuvent etre relatif, un traitement special
* est donc fait pour ce cas. Cela est necessaire pour facilement faire
* des tests unitaires independant de la machine ou il sont fait
*
* @param path
* @return
*/
protected String toVfsURL(String path) {
String result = path;
Pattern p = Pattern.compile("(.*?file:)([^/][^!]*)(.*)");
Matcher m = p.matcher(path);
if (m.matches()) {
String filepath = m.group(2);
File f = new File(filepath);
result = path.replaceAll(
"(.*?file:)([^/][^!]*)(.*)",
"$1" + f.getAbsolutePath() + "$3");
}
return result;
}
/**
* Return config prepared for os and arch
*
* @return
* @throws Exception
*/
protected ApplicationConfig getUpdaterConfig(FileSystemOptions vfsConfig,
String vfsPropertiesUrl) throws Exception {
String osName = StringUtils.lowerCase(config.getOsName());
String osArch = StringUtils.lowerCase(config.getOsArch());
// take only first part for osName (windows 2000 or windows 2003 -> windows)
osName = StringUtils.substringBefore(osName, " ");
if (log.isDebugEnabled()) {
log.debug(String.format("Try to load properties from '%s'", vfsPropertiesUrl));
}
Properties prop = new Properties();
FileSystemManager fsManager = VFS.getManager();
FileObject properties = fsManager.resolveFile(toVfsURL(vfsPropertiesUrl), vfsConfig);
try {
InputStream in = new BufferedInputStream(properties.getContent().getInputStream());
prop.load(in);
} finally {
try {
properties.close();
} catch (Exception doNothing) {
log.debug("Can't close vfs file", doNothing);
}
}
if (log.isDebugEnabled()) {
log.debug(String.format(
"Properties loaded from '%s'\n%s",
vfsPropertiesUrl, prop));
}
// load config with new properties as default
ApplicationConfig result = new ApplicationConfig(prop);
// don't parse. We want only prop in applicationConfig
result = result.getSubConfig(
ApplicationUpdater.class.getSimpleName() + ApplicationUpdater.SEPARATOR_KEY);
result = result.getSubConfig(osName + ApplicationUpdater.SEPARATOR_KEY);
result = result.getSubConfig(osArch + ApplicationUpdater.SEPARATOR_KEY);
return result;
}
/**
* Recupere le proxy http a utiliser pour les connexions reseaux
*
* @param config
* @return
*/
protected FileSystemOptions getVFSConfig(ApplicationConfig config) {
FileSystemOptions result = new FileSystemOptions();
String proxyHost = config.getOption(HTTP_PROXY);
try {
proxyHost = StringUtils.substringAfter(proxyHost, "://");
if (StringUtils.isNotBlank(proxyHost)) {
String hostname = StringUtils.substringBefore(proxyHost, ":");
String port = StringUtils.substringAfter(proxyHost, ":");
if (StringUtils.isNumeric(port)) {
int portNumber = Integer.parseInt(port);
HttpFileSystemConfigBuilder.getInstance().setProxyHost(result, hostname);
HttpFileSystemConfigBuilder.getInstance().setProxyPort(result, portNumber);
} else {
log.warn(String.format("Invalide proxy port number '%s', not used proxy", port));
}
}
} catch (Exception eee) {
log.warn(String.format("Can't use proxy '%s'", proxyHost), eee);
}
return result;
}
/**
* Recherche pour chaque application la version courante
*
* @param apps la liste des applications a rechercher
* @return
*/
protected Map getCurrentVersion(List apps, File dir) {
Map result = Maps.newTreeMap();
for (String app : apps) {
File applicationDirectory = new File(dir, app);
String version = ApplicationUpdater.loadVersionFile(
app,
applicationDirectory);
result.put(app, version);
}
return result;
}
/**
* Retourne la liste des noms d'application se trouvant dans la
* configuration
*
* @param config
* @return
*/
protected List getApplicationName(ApplicationConfig config) {
Pattern p = Pattern.compile("([^.]+)\\.version");
List result = new LinkedList();
for (String v : config.getFlatOptions().stringPropertyNames()) {
Matcher match = p.matcher(v);
if (match.matches()) {
result.add(match.group(1));
} else if (StringUtils.endsWith(v, ".version")) {
log.debug(String.format("value is not valid application version '%s'", v));
}
}
return result;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy