Nuiton-utils-commits
Threads by month
- ----- 2026 -----
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
January 2013
- 3 participants
- 39 discussions
r2460 - in trunk: . nuiton-utils nuiton-utils/src/main/java/org/nuiton/util nuiton-utils/src/test/java/org/nuiton/util nuiton-utils/src/test/resources/properties
by bpoussin@users.nuiton.org 05 Jan '13
by bpoussin@users.nuiton.org 05 Jan '13
05 Jan '13
Author: bpoussin
Date: 2013-01-05 03:50:34 +0100 (Sat, 05 Jan 2013)
New Revision: 2460
Url: http://nuiton.org/projects/nuiton-utils/repository/revisions/2460
Log:
utilsation de commons-vfs2 pour l'acces au ressource ce qui permet
de supporter tout type de protocole et de format de compression
Modified:
trunk/nuiton-utils/pom.xml
trunk/nuiton-utils/src/main/java/org/nuiton/util/ApplicationUpdater.java
trunk/nuiton-utils/src/test/java/org/nuiton/util/ApplicationUpdaterTest.java
trunk/nuiton-utils/src/test/resources/properties/ApplicationUpdaterNetworkTest.properties
trunk/nuiton-utils/src/test/resources/properties/ApplicationUpdaterTest.properties
trunk/pom.xml
Modified: trunk/nuiton-utils/pom.xml
===================================================================
--- trunk/nuiton-utils/pom.xml 2013-01-04 15:51:26 UTC (rev 2459)
+++ trunk/nuiton-utils/pom.xml 2013-01-05 02:50:34 UTC (rev 2460)
@@ -44,6 +44,21 @@
</dependency>
<dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-compress</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>commons-httpclient</groupId>
+ <artifactId>commons-httpclient</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-vfs2</artifactId>
+ </dependency>
+
+ <dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</dependency>
Modified: trunk/nuiton-utils/src/main/java/org/nuiton/util/ApplicationUpdater.java
===================================================================
--- trunk/nuiton-utils/src/main/java/org/nuiton/util/ApplicationUpdater.java 2013-01-04 15:51:26 UTC (rev 2459)
+++ trunk/nuiton-utils/src/main/java/org/nuiton/util/ApplicationUpdater.java 2013-01-05 02:50:34 UTC (rev 2460)
@@ -5,11 +5,6 @@
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
-import java.net.InetSocketAddress;
-import java.net.MalformedURLException;
-import java.net.Proxy;
-import java.net.SocketAddress;
-import java.net.URL;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
@@ -21,6 +16,13 @@
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.commons.vfs2.AllFileSelector;
+import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.FileSystemException;
+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;
/**
* Permet de telecharger des mises a jour d'application.
@@ -29,7 +31,7 @@
* information necessaire pour la recuperation de l'application.
*
* Si une nouvelle version de l'application existe, elle est alors telechargee
- * et dezipper dans un repertoire specifique (elle ne remplace pas l'application
+ * et decompressee dans un repertoire specifique (elle ne remplace pas l'application
* courante).
*
* Il est alors a la charge d'un script de mettre en place cette nouvelle application
@@ -49,7 +51,8 @@
*
* <h3>format du fichier de properties</h3>
* [osName.][osArch.]appName.version=version de l'application
- * [osName.][osArch.]appName.url=url du zip de la nouvelle version
+ * [osName.][osArch.]appName.url=url du fichier compresse de la nouvelle version
+ * (format <a href="http://commons.apache.org/vfs/filesystems.html">commons-vfs2</a>)
*
* appName est a remplacer par le nom de l'application. Il est possible
* d'avoir plusieurs application dans le meme fichier ou plusieurs version
@@ -57,13 +60,13 @@
*
* osName et osArch sont toujours en minuscule
*
- * <h3>format des fichiers zip applicatif</h3>
+ * <h3>format des fichiers compresses</h3>
*
- * Le zip doit avec un repertoire racine qui contient l'ensemble de l'application
+ * Le fichier compresse doit avoir un repertoire racine qui contient l'ensemble de l'application
* c-a-d que les fichiers ne doivent pas etre directement a la racine lorsqu'on
- * dezippe le fichier.
+ * decompresse le fichier.
*
- * exemple de contenu de zip convenable
+ * exemple de contenu de fichier compresse convenable
* <pre>
* MonApp-0.3/Readme.txt
* MonApp-0.3/License.txt
@@ -150,8 +153,8 @@
* @param async if true, check is done in background mode
* @param callback callback used to interact with updater, can be null
*/
- public void update(URL propertiesURL, File currentDir, File destDir, boolean async, ApplicationUpdaterCallback callback) {
- Updater up = new Updater(config, propertiesURL, currentDir, destDir, callback);
+ public void update(String vfsPropertiesURL, File currentDir, File destDir, boolean async, ApplicationUpdaterCallback callback) {
+ Updater up = new Updater(config, vfsPropertiesURL, currentDir, destDir, callback);
if (async) {
Thread thread = new Thread(up, ApplicationUpdater.class.getSimpleName());
thread.start();
@@ -232,15 +235,15 @@
static public class Updater implements Runnable {
protected ApplicationConfig config;
- protected URL url;
+ protected String vfsPropertiesUrl;
protected File currentDir;
protected File destDir;
protected ApplicationUpdaterCallback callback;
- public Updater(ApplicationConfig config, URL url,
+ public Updater(ApplicationConfig config, String vfsPropertiesUrl,
File currentDir, File destDir, ApplicationUpdaterCallback callback) {
this.config = config;
- this.url = url;
+ this.vfsPropertiesUrl = vfsPropertiesUrl;
this.currentDir = currentDir;
this.destDir = destDir;
this.callback = callback;
@@ -255,8 +258,8 @@
*/
public void run() {
try {
- Proxy proxy = getProxy(config);
- ApplicationConfig releaseConfig = getUpdaterConfig(proxy);
+ FileSystemOptions vfsConfig = getVFSConfig(config);
+ ApplicationConfig releaseConfig = getUpdaterConfig(vfsConfig, vfsPropertiesUrl);
List<String> appNames = getApplicationName(releaseConfig);
Map<String, String> appVersions = getCurrentVersion(appNames, currentDir);
@@ -291,7 +294,7 @@
String app = appInfo.getKey();
ApplicationInfo info = appInfo.getValue();
try {
- doUpdate(proxy, appInfo.getValue());
+ doUpdate(vfsConfig, appInfo.getValue());
} catch (Exception eee) {
appUpdateError.put(app, eee);
try {
@@ -321,7 +324,7 @@
log.warn("Can't update");
log.info("Application update aborted because: ", eee);
if (callback != null) {
- callback.aborted(String.valueOf(url), eee);
+ callback.aborted(vfsPropertiesUrl, eee);
}
}
}
@@ -337,20 +340,13 @@
* @param info information sur l'application a mettre a jour
* @throws Exception
*/
- protected void doUpdate(Proxy proxy, ApplicationInfo info) throws Exception {
+ protected void doUpdate(FileSystemOptions vfsConfig, ApplicationInfo info) throws Exception {
if (info.destDir != null) {
- // suppression d'une ancienne version si elle existait
File dest = new File(info.destDir, info.name);
- if (dest.exists()) {
- log.warn(String.format("Remove destination directory for new data '%s'", dest));
- FileUtils.deleteDirectory(dest);
- }
+ deepCopy(vfsConfig, info.url, dest.getAbsolutePath());
- URL applicationURL = toURL(info.url);
- InputStream in = new BufferedInputStream(
- applicationURL.openConnection(proxy).getInputStream());
- ZipUtil.uncompressAndRename(in, info.destDir, "^[^/]+", info.name);
- File versionFile = new File(info.destDir, info.name + File.separator + VERSION_FILE);
+ // ajout du fichier de version
+ File versionFile = new File(dest, VERSION_FILE);
FileUtils.writeStringToFile(versionFile, info.newVersion);
log.info(String.format(
"Application '%s' is uptodate with version '%s' in '%s'",
@@ -361,21 +357,51 @@
}
/**
- * Converti le path en URL. Path doit etre une URL, mais pour les fichiers
+ * Recupere le contenu du repertoire de l'archive pour le mettre dans targetPath
+ * si targetPath existait deja, il est supprime au prealable.
+ *
+ * Si l'archive a plus d'un repertoire root, une exception est levee
+ *
+ * @param srcPath source path de la forme vfs2 ex:"zip:http://www.nuiton.org/attachments/download/830/nuiton-utils-2.6.5-deps.…"
+ * @param targetPath le path destination
+ * @throws FileSystemException
+ */
+ protected void deepCopy(FileSystemOptions vfsConfig,
+ String srcPath, String targetPath) throws FileSystemException {
+ FileSystemManager fsManager = VFS.getManager();
+ FileObject archive = fsManager.resolveFile(toVfsURL(srcPath), vfsConfig);
+
+ FileObject[] children = archive.getChildren();
+ if (children.length == 1) {
+ FileObject child = children[0];
+
+ FileObject target = fsManager.resolveFile(toVfsURL(targetPath), vfsConfig);
+ target.delete(new AllFileSelector());
+ target.copyFrom(child, new AllFileSelector());
+ } else {
+ throw new RuntimeException("must have only one root directory");
+ }
+ }
+
+ /**
+ * 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
+ * @return
*/
- protected URL toURL(String path) throws MalformedURLException {
- URL result;
- if (StringUtils.startsWith(path, "file:")) {
- File f = new File(StringUtils.substringAfter(path, "file:"));
- result = f.toURI().toURL();
- } else {
- result = new URL(path);
+ 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;
}
@@ -386,27 +412,35 @@
* @return
* @throws Exception
*/
- protected ApplicationConfig getUpdaterConfig(Proxy proxy) 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' with proxy '%s'",
- url, proxy));
+ log.debug(String.format("Try to load properties from '%s'", vfsPropertiesUrl));
}
-
- InputStream in = new BufferedInputStream(
- url.openConnection(proxy).getInputStream());
+
Properties prop = new Properties();
- prop.load(in);
+ 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",
- url, prop));
+ vfsPropertiesUrl, prop));
}
// load config with new properties as default
@@ -422,12 +456,12 @@
/**
* Recupere le proxy http a utiliser pour les connexions reseaux
- *
+ *
* @param config
* @return
*/
- protected Proxy getProxy(ApplicationConfig config) {
- Proxy result = Proxy.NO_PROXY;
+ protected FileSystemOptions getVFSConfig(ApplicationConfig config) {
+ FileSystemOptions result = new FileSystemOptions();
String proxyHost = config.getOption(HTTP_PROXY);
try {
proxyHost = StringUtils.substringAfter(proxyHost, "://");
@@ -435,9 +469,11 @@
String hostname = StringUtils.substringBefore(proxyHost, ":");
String port = StringUtils.substringAfter(proxyHost, ":");
if (StringUtils.isNumeric(port)) {
+
int portNumber = Integer.parseInt(port);
- SocketAddress socket = new InetSocketAddress(hostname, portNumber);
- result = new Proxy(Proxy.Type.HTTP, socket);
+
+ HttpFileSystemConfigBuilder.getInstance().setProxyHost(result, hostname);
+ HttpFileSystemConfigBuilder.getInstance().setProxyPort(result, portNumber);
} else {
log.warn(String.format("Invalide proxy port number '%s', not used proxy", port));
}
Modified: trunk/nuiton-utils/src/test/java/org/nuiton/util/ApplicationUpdaterTest.java
===================================================================
--- trunk/nuiton-utils/src/test/java/org/nuiton/util/ApplicationUpdaterTest.java 2013-01-04 15:51:26 UTC (rev 2459)
+++ trunk/nuiton-utils/src/test/java/org/nuiton/util/ApplicationUpdaterTest.java 2013-01-05 02:50:34 UTC (rev 2460)
@@ -47,7 +47,7 @@
@Test
public void testUpdate() throws Exception {
ApplicationUpdater up = new ApplicationUpdater();
- URL url = new File("src/test/resources/properties/ApplicationUpdaterTest.properties").toURI().toURL();
+ String url = "file:src/test/resources/properties/ApplicationUpdaterTest.properties";
File current = new File("src/test/resources/ApplicationUpdater");
File dest = new File("target/test/ApplicationUpdater/NEW");
up.update(url, current, dest, false, new Callback());
@@ -56,7 +56,7 @@
@Test
public void testUpdateNetwork() throws Exception {
ApplicationUpdater up = new ApplicationUpdater();
- URL url = new URL("http://svn.nuiton.org/svn/nuiton-utils/trunk/nuiton-utils/src/test/resource…");
+ String url = "http://svn.nuiton.org/svn/nuiton-utils/trunk/nuiton-utils/src/test/resource…";
File current = new File("src/test/resources/ApplicationUpdater");
File dest = new File("target/test/ApplicationUpdater/NEWNETWORK");
up.update(url, current, dest, false, new Callback());
Modified: trunk/nuiton-utils/src/test/resources/properties/ApplicationUpdaterNetworkTest.properties
===================================================================
--- trunk/nuiton-utils/src/test/resources/properties/ApplicationUpdaterNetworkTest.properties 2013-01-04 15:51:26 UTC (rev 2459)
+++ trunk/nuiton-utils/src/test/resources/properties/ApplicationUpdaterNetworkTest.properties 2013-01-05 02:50:34 UTC (rev 2460)
@@ -1,6 +1,6 @@
App1.version=0.3
-App1.url=http://svn.nuiton.org/svn/nuiton-utils/trunk/nuiton-utils/src/test/resources/ApplicationUpdater/zip/App1-0.3.zip
+App1.url=zip:http://svn.nuiton.org/svn/nuiton-utils/trunk/nuiton-utils/src/test/resources/ApplicationUpdater/zip/App1-0.3.zip
linux.App3.version=8
-linux.App3.url=http://svn.nuiton.org/svn/nuiton-utils/trunk/nuiton-utils/src/test/resources/ApplicationUpdater/zip/App3-7.zip
+linux.App3.url=zip:http://svn.nuiton.org/svn/nuiton-utils/trunk/nuiton-utils/src/test/resources/ApplicationUpdater/zip/App3-7.zip
linux.amd64.App2.version=7
-linux.amd64.App2.url=http://svn.nuiton.org/svn/nuiton-utils/trunk/nuiton-utils/src/test/resources/ApplicationUpdater/zip/App2-7.zip
+linux.amd64.App2.url=zip:http://svn.nuiton.org/svn/nuiton-utils/trunk/nuiton-utils/src/test/resources/ApplicationUpdater/zip/App2-7.zip
Modified: trunk/nuiton-utils/src/test/resources/properties/ApplicationUpdaterTest.properties
===================================================================
--- trunk/nuiton-utils/src/test/resources/properties/ApplicationUpdaterTest.properties 2013-01-04 15:51:26 UTC (rev 2459)
+++ trunk/nuiton-utils/src/test/resources/properties/ApplicationUpdaterTest.properties 2013-01-05 02:50:34 UTC (rev 2460)
@@ -1,6 +1,6 @@
App1.version=0.3
-App1.url=file:src/test/resources/ApplicationUpdater/zip/App1-0.3.zip
+App1.url=zip:file:src/test/resources/ApplicationUpdater/zip/App1-0.3.zip
linux.App3.version=8
-linux.App3.url=file:src/test/resources/ApplicationUpdater/zip/App3-7.zip
+linux.App3.url=zip:file:src/test/resources/ApplicationUpdater/zip/App3-7.zip
linux.amd64.App2.version=7
-linux.amd64.App2.url=file:src/test/resources/ApplicationUpdater/zip/App2-7.zip
+linux.amd64.App2.url=zip:file:src/test/resources/ApplicationUpdater/zip/App2-7.zip
Modified: trunk/pom.xml
===================================================================
--- trunk/pom.xml 2013-01-04 15:51:26 UTC (rev 2459)
+++ trunk/pom.xml 2013-01-05 02:50:34 UTC (rev 2460)
@@ -147,6 +147,24 @@
<dependencies>
<dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-compress</artifactId>
+ <version>1.4.1</version>
+ </dependency>
+
+ <dependency>
+ <groupId>commons-httpclient</groupId>
+ <artifactId>commons-httpclient</artifactId>
+ <version>3.1</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-vfs2</artifactId>
+ <version>2.0</version>
+ </dependency>
+
+ <dependency>
<groupId>org.nuiton.i18n</groupId>
<artifactId>nuiton-i18n</artifactId>
<version>${nuitonI18nVersion}</version>
1
0
r2459 - in trunk/nuiton-utils/src: main/java/org/nuiton/util test/resources/properties
by bpoussin@users.nuiton.org 04 Jan '13
by bpoussin@users.nuiton.org 04 Jan '13
04 Jan '13
Author: bpoussin
Date: 2013-01-04 16:51:26 +0100 (Fri, 04 Jan 2013)
New Revision: 2459
Url: http://nuiton.org/projects/nuiton-utils/repository/revisions/2459
Log:
mise a jour de la doc pour les Os et arch
modif properties de test pour tester sans arch
Modified:
trunk/nuiton-utils/src/main/java/org/nuiton/util/ApplicationUpdater.java
trunk/nuiton-utils/src/test/resources/properties/ApplicationUpdaterNetworkTest.properties
trunk/nuiton-utils/src/test/resources/properties/ApplicationUpdaterTest.properties
Modified: trunk/nuiton-utils/src/main/java/org/nuiton/util/ApplicationUpdater.java
===================================================================
--- trunk/nuiton-utils/src/main/java/org/nuiton/util/ApplicationUpdater.java 2013-01-04 15:14:41 UTC (rev 2458)
+++ trunk/nuiton-utils/src/main/java/org/nuiton/util/ApplicationUpdater.java 2013-01-04 15:51:26 UTC (rev 2459)
@@ -73,6 +73,22 @@
* donc si le repertoire racine n'existe pas ou qu'il y a plusieurs repertoires
* a la racine le resultat de l'operation n'est pas celui souhaite
*
+ * <h3>os.name and os.arch</h3>
+ * <table>
+ * <th><td>os.name</td><td>os.arch</td></th>
+ * <tr><td>linux</td><td>amd64</td></tr>
+ * <tr><td>linux</td><td>i386</td></tr>
+ * <tr><td>mac</td><td>ppc</td></tr>
+ * <tr><td>windows</td><td>x86</td></tr>
+ * <tr><td>solaris</td><td>sparc</td></tr>
+ * </table>
+ *
+ * os.name est tronque apres le 1er mot donc "windows 2000" et "windows 2003"
+ * deviennet tous les deux "windows". Si vous souhaitez gérer plus finement vos
+ * url de telechargement vous pouvez modifier les donnees via
+ * {@link ApplicationUpdaterCallback#updateToDo(java.util.Map) } en modifiant
+ * l'url avant de retourner la map
+ *
* @author poussin
* @version $Revision$
*
@@ -373,6 +389,8 @@
protected ApplicationConfig getUpdaterConfig(Proxy proxy) 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(
Modified: trunk/nuiton-utils/src/test/resources/properties/ApplicationUpdaterNetworkTest.properties
===================================================================
--- trunk/nuiton-utils/src/test/resources/properties/ApplicationUpdaterNetworkTest.properties 2013-01-04 15:14:41 UTC (rev 2458)
+++ trunk/nuiton-utils/src/test/resources/properties/ApplicationUpdaterNetworkTest.properties 2013-01-04 15:51:26 UTC (rev 2459)
@@ -1,6 +1,6 @@
App1.version=0.3
App1.url=http://svn.nuiton.org/svn/nuiton-utils/trunk/nuiton-utils/src/test…
+linux.App3.version=8
+linux.App3.url=http://svn.nuiton.org/svn/nuiton-utils/trunk/nuiton-utils/src/test/resources/ApplicationUpdater/zip/App3-7.zip
linux.amd64.App2.version=7
linux.amd64.App2.url=http://svn.nuiton.org/svn/nuiton-utils/trunk/nuiton-ut…
-linux.x86.App3.version=7
-linux.x86.App3.url=http://svn.nuiton.org/svn/nuiton-utils/trunk/nuiton-utils/src/test/resources/ApplicationUpdater/zip/App3-7.zip
Modified: trunk/nuiton-utils/src/test/resources/properties/ApplicationUpdaterTest.properties
===================================================================
--- trunk/nuiton-utils/src/test/resources/properties/ApplicationUpdaterTest.properties 2013-01-04 15:14:41 UTC (rev 2458)
+++ trunk/nuiton-utils/src/test/resources/properties/ApplicationUpdaterTest.properties 2013-01-04 15:51:26 UTC (rev 2459)
@@ -1,6 +1,6 @@
App1.version=0.3
App1.url=file:src/test/resources/ApplicationUpdater/zip/App1-0.3.zip
+linux.App3.version=8
+linux.App3.url=file:src/test/resources/ApplicationUpdater/zip/App3-7.zip
linux.amd64.App2.version=7
linux.amd64.App2.url=file:src/test/resources/ApplicationUpdater/zip/App2-7.zip
-linux.x86.App3.version=7
-linux.x86.App3.url=file:src/test/resources/ApplicationUpdater/zip/App3-7.zip
1
0
r2458 - in trunk/nuiton-utils/src: main/java/org/nuiton/util test/java/org/nuiton/util
by bpoussin@users.nuiton.org 04 Jan '13
by bpoussin@users.nuiton.org 04 Jan '13
04 Jan '13
Author: bpoussin
Date: 2013-01-04 16:14:41 +0100 (Fri, 04 Jan 2013)
New Revision: 2458
Url: http://nuiton.org/projects/nuiton-utils/repository/revisions/2458
Log:
mise a jour de la doc
mise a jour de test (Assert)
Modified:
trunk/nuiton-utils/src/main/java/org/nuiton/util/ApplicationUpdater.java
trunk/nuiton-utils/src/test/java/org/nuiton/util/ApplicationUpdaterTest.java
Modified: trunk/nuiton-utils/src/main/java/org/nuiton/util/ApplicationUpdater.java
===================================================================
--- trunk/nuiton-utils/src/main/java/org/nuiton/util/ApplicationUpdater.java 2013-01-04 15:05:56 UTC (rev 2457)
+++ trunk/nuiton-utils/src/main/java/org/nuiton/util/ApplicationUpdater.java 2013-01-04 15:14:41 UTC (rev 2458)
@@ -57,6 +57,22 @@
*
* osName et osArch sont toujours en minuscule
*
+ * <h3>format des fichiers zip applicatif</h3>
+ *
+ * Le zip doit avec un repertoire racine qui contient l'ensemble de l'application
+ * c-a-d que les fichiers ne doivent pas etre directement a la racine lorsqu'on
+ * dezippe le fichier.
+ *
+ * exemple de contenu de zip convenable
+ * <pre>
+ * MonApp-0.3/Readme.txt
+ * MonApp-0.3/License.txt
+ * </pre>
+ *
+ * Ceci est du au fait qu'on renomme le repertoire racine avec le nom de l'application,
+ * donc si le repertoire racine n'existe pas ou qu'il y a plusieurs repertoires
+ * a la racine le resultat de l'operation n'est pas celui souhaite
+ *
* @author poussin
* @version $Revision$
*
Modified: trunk/nuiton-utils/src/test/java/org/nuiton/util/ApplicationUpdaterTest.java
===================================================================
--- trunk/nuiton-utils/src/test/java/org/nuiton/util/ApplicationUpdaterTest.java 2013-01-04 15:05:56 UTC (rev 2457)
+++ trunk/nuiton-utils/src/test/java/org/nuiton/util/ApplicationUpdaterTest.java 2013-01-04 15:14:41 UTC (rev 2458)
@@ -6,6 +6,7 @@
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.junit.Assert;
import org.junit.Test;
import org.nuiton.util.ApplicationUpdater.ApplicationInfo;
@@ -33,10 +34,12 @@
for (Map.Entry<String, Exception> e : appUpdateError.entrySet()) {
log.info(String.format("Error during update for application '%s'", e.getKey()), e.getValue());
}
+ Assert.assertTrue(appUpdateError.isEmpty());
}
public void aborted(String propertiesURL, Exception eee) {
log.info(String.format("Update aborted for url '%s'", propertiesURL), eee);
+ Assert.assertTrue(false);
}
}
1
0
r2457 - in trunk/nuiton-utils/src: main/java/org/nuiton/util test/java/org/nuiton/util test/resources test/resources/ApplicationUpdater test/resources/ApplicationUpdater/App1 test/resources/ApplicationUpdater/App2 test/resources/ApplicationUpdater/App3 test/resources/ApplicationUpdater/zip test/resources/properties
by bpoussin@users.nuiton.org 04 Jan '13
by bpoussin@users.nuiton.org 04 Jan '13
04 Jan '13
Author: bpoussin
Date: 2013-01-04 16:05:56 +0100 (Fri, 04 Jan 2013)
New Revision: 2457
Url: http://nuiton.org/projects/nuiton-utils/repository/revisions/2457
Log:
Evolution #2502: Add class to check and download new application version
Added:
trunk/nuiton-utils/src/main/java/org/nuiton/util/ApplicationUpdater.java
trunk/nuiton-utils/src/test/java/org/nuiton/util/ApplicationUpdaterTest.java
trunk/nuiton-utils/src/test/resources/ApplicationUpdater/
trunk/nuiton-utils/src/test/resources/ApplicationUpdater/App1/
trunk/nuiton-utils/src/test/resources/ApplicationUpdater/App1/Readme.txt
trunk/nuiton-utils/src/test/resources/ApplicationUpdater/App1/version.appup
trunk/nuiton-utils/src/test/resources/ApplicationUpdater/App2/
trunk/nuiton-utils/src/test/resources/ApplicationUpdater/App2/Readme.txt
trunk/nuiton-utils/src/test/resources/ApplicationUpdater/App3/
trunk/nuiton-utils/src/test/resources/ApplicationUpdater/App3/Readme.txt
trunk/nuiton-utils/src/test/resources/ApplicationUpdater/App3/version.appup
trunk/nuiton-utils/src/test/resources/ApplicationUpdater/zip/
trunk/nuiton-utils/src/test/resources/ApplicationUpdater/zip/App1-0.3.zip
trunk/nuiton-utils/src/test/resources/ApplicationUpdater/zip/App2-7.zip
trunk/nuiton-utils/src/test/resources/ApplicationUpdater/zip/App3-7.zip
trunk/nuiton-utils/src/test/resources/properties/ApplicationUpdaterNetworkTest.properties
trunk/nuiton-utils/src/test/resources/properties/ApplicationUpdaterTest.properties
Added: trunk/nuiton-utils/src/main/java/org/nuiton/util/ApplicationUpdater.java
===================================================================
--- trunk/nuiton-utils/src/main/java/org/nuiton/util/ApplicationUpdater.java (rev 0)
+++ trunk/nuiton-utils/src/main/java/org/nuiton/util/ApplicationUpdater.java 2013-01-04 15:05:56 UTC (rev 2457)
@@ -0,0 +1,463 @@
+package org.nuiton.util;
+
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.InetSocketAddress;
+import java.net.MalformedURLException;
+import java.net.Proxy;
+import java.net.SocketAddress;
+import java.net.URL;
+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;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Permet de telecharger des mises a jour d'application.
+ *
+ * Le principe est qu'un fichier properties pointe par une URL indique les
+ * information necessaire pour la recuperation de l'application.
+ *
+ * Si une nouvelle version de l'application existe, elle est alors telechargee
+ * et dezipper dans un repertoire specifique (elle ne remplace pas l'application
+ * courante).
+ *
+ * Il est alors a la charge d'un script de mettre en place cette nouvelle application
+ * a la place de l'ancienne.
+ *
+ * Il est possible d'interagir avec ApplicationUpdater via l'implantation d'un
+ * {@link ApplicationUpdaterCallback} passer en parametre de la methode {@link #update}
+ *
+ * <h3>Configuration possible</h3>
+ * Vous pouvez passer un ApplicationConfig dans le constructeur ou utiliser
+ * la recherche du fichier de configuration par defaut (ApplicationUpdater.properties)
+ *
+ * Cette configuration permet de récupérer les informations suivantes:
+ * <li>http_proxy: le proxy a utiliser pour l'acces au reseau (ex: squid.chezmoi.fr:8080)
+ * <li>os.name: le nom du systeme d'exploitation sur lequel l'application fonctionne (ex: Linux)
+ * <li>os.arch: l'architecture du systeme d'exploitation sur lequel l'application fonctionne (ex: amd64)
+ *
+ * <h3>format du fichier de properties</h3>
+ * [osName.][osArch.]appName.version=version de l'application
+ * [osName.][osArch.]appName.url=url du zip de la nouvelle version
+ *
+ * appName est a remplacer par le nom de l'application. Il est possible
+ * d'avoir plusieurs application dans le meme fichier ou plusieurs version
+ * en fonction de l'os et de l'architecture.
+ *
+ * osName et osArch sont toujours en minuscule
+ *
+ * @author poussin
+ * @version $Revision$
+ *
+ * Last update: $Date$
+ * by : $Author$
+ *
+ * @since 2.7
+ */
+public class ApplicationUpdater {
+
+ /** to use log facility, just put in your code: log.info(\"...\"); */
+ static private Log log = LogFactory.getLog(ApplicationUpdater.class);
+
+ final static private String SEPARATOR_KEY = ".";
+
+ final static public String HTTP_PROXY = "http_proxy";
+
+ final static public String URL_KEY = "url";
+ final static public String VERSION_KEY = "version";
+ final static public String VERSION_FILE = "version.appup";
+
+ protected ApplicationConfig config;
+
+ /**
+ * Utilise le fichier de configuration par defaut: ApplicationUpdater.properties
+ */
+ public ApplicationUpdater() {
+ this(null);
+ }
+
+ /**
+ *
+ * @param config La configuration a utiliser pour rechercher le proxy (http_proxy)
+ * et os.name, os.arch
+ */
+ public ApplicationUpdater(ApplicationConfig config) {
+ if (config == null) {
+ try {
+ config = new ApplicationConfig(
+ ApplicationUpdater.class.getSimpleName() + ".properties");
+ config.parse();
+ config = config.getSubConfig(
+ ApplicationUpdater.class.getSimpleName() + SEPARATOR_KEY);
+ } catch (ArgumentsParserException eee) {
+ throw new RuntimeException(eee);
+ }
+ }
+ this.config = config;
+ }
+
+
+
+ /**
+ *
+ * @param url url where properties file is downloadable. This properties
+ * must contains information on application release
+ * @param currentDir directory where application is currently
+ * @param destDir default directory to put new application version, can be null if you used callback
+ * @param async if true, check is done in background mode
+ * @param callback callback used to interact with updater, can be null
+ */
+ public void update(URL propertiesURL, File currentDir, File destDir, boolean async, ApplicationUpdaterCallback callback) {
+ Updater up = new Updater(config, propertiesURL, currentDir, destDir, callback);
+ if (async) {
+ Thread thread = new Thread(up, ApplicationUpdater.class.getSimpleName());
+ thread.start();
+ } else {
+ up.run();
+ }
+ }
+
+ /**
+ * Permet d'interagir avec ApplicationUpdater
+ */
+ static public interface ApplicationUpdaterCallback {
+ /**
+ * Appeler avant la recuperation des nouvelles versions
+ *
+ * Permet de modifier le repertoire destination ou l'url du zip de
+ * l'application pour une application/version
+ * particuliere ou d'annuler la mise a jour en le supprimant de la map
+ * qui sera retourne
+ *
+ * @param appToUpdate liste des applications a mettre a jour
+ * @return null or empty map if we don't want update, otherwize list of
+ * app to update
+ *
+ */
+ Map<String, ApplicationInfo> updateToDo(Map<String, ApplicationInfo> appToUpdate);
+
+ /**
+ * Appeler une fois qu'une mise a jour a parfaitement fonctionne
+ *
+ * @param name le nom de l'application
+ * @param oldVersion l'ancienne version
+ * @param newVersion la nouvelle version
+ * @param applicationURL l'url d'ou provient le zip de l'application
+ * @param dest le repertoire ou se trouve la nouvelle version
+ */
+ void updateDone(
+ Map<String, ApplicationInfo> appToUpdate,
+ Map<String, Exception> appUpdateError);
+
+ /**
+ * Called when exception occur during process initialization
+ * @param propertiesURL url use to download properties release information
+ * @param eee exception throw during process
+ */
+ void aborted(String propertiesURL, Exception eee);
+ }
+
+ static public class ApplicationInfo {
+ public String name;
+ public String oldVersion;
+ public String newVersion;
+ public String url;
+ public File destDir;
+
+ public ApplicationInfo(String name, String oldVersion, String newVersion, String url, File destDir) {
+ this.name = name;
+ this.oldVersion = oldVersion;
+ this.newVersion = newVersion;
+ this.url = url;
+ this.destDir = destDir;
+ }
+
+ @Override
+ public String toString() {
+ String result = String.format(
+ "App: %s, oldVersion: %s, newVersion: %s, url: %s, destDir:%s",
+ name, oldVersion, newVersion, url, destDir);
+ return result;
+ }
+
+ }
+
+ /**
+ * La classe ou le travail est reellement fait, peut-etre appeler dans
+ * un thread si necessaire
+ */
+ static public class Updater implements Runnable {
+
+ protected ApplicationConfig config;
+ protected URL url;
+ protected File currentDir;
+ protected File destDir;
+ protected ApplicationUpdaterCallback callback;
+
+ public Updater(ApplicationConfig config, URL url,
+ File currentDir, File destDir, ApplicationUpdaterCallback callback) {
+ this.config = config;
+ this.url = url;
+ this.currentDir = currentDir;
+ this.destDir = destDir;
+ this.callback = callback;
+ }
+
+ /**
+ * <li>Recupere le fichier properties contenant les informations de mise a jour
+ * <li>liste les applications et leur version actuelle
+ * <li>pour chaque application a mettre a jour recupere le zip et le decompresse
+ *
+ * Si callback existe envoi les messages necessaire
+ */
+ public void run() {
+ try {
+ Proxy proxy = getProxy(config);
+ ApplicationConfig releaseConfig = getUpdaterConfig(proxy);
+
+ List<String> appNames = getApplicationName(releaseConfig);
+ Map<String, String> appVersions = getCurrentVersion(appNames, currentDir);
+
+ log.debug("application current version: " + appVersions);
+
+ // recherche des applications a mettre a jour
+ Map<String, ApplicationInfo> appToUpdate = new HashMap<String, ApplicationInfo>();
+ for (String app : appNames) {
+ String currentVersion = appVersions.get(app);
+ String newVersion = releaseConfig.getOption(app + 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));
+ if (greater) {
+ String urlString = releaseConfig.getOption(
+ app + SEPARATOR_KEY + URL_KEY);
+
+ appToUpdate.put(app, new ApplicationInfo(
+ app, currentVersion, newVersion, urlString, destDir));
+ }
+ }
+
+ // offre la possibilite a l'appelant de modifier les valeurs par defaut
+ if (callback != null) {
+ appToUpdate = callback.updateToDo(appToUpdate);
+ }
+
+ // mise a jour
+ Map<String, Exception> appUpdateError = new HashMap<String, Exception>();
+ for (Map.Entry<String, ApplicationInfo> appInfo : appToUpdate.entrySet()) {
+ String app = appInfo.getKey();
+ ApplicationInfo info = appInfo.getValue();
+ try {
+ doUpdate(proxy, appInfo.getValue());
+ } catch (Exception eee) {
+ appUpdateError.put(app, eee);
+ try {
+ // clear data if error occur during uncompress operation
+ File dest = new File(info.destDir, info.name);
+ if (dest.exists()) {
+ log.debug(String.format("Cleaning destination directory due to error '%s'", dest));
+ FileUtils.deleteDirectory(dest);
+ }
+ } catch(Exception doNothing) {
+ log.debug("Can't clean directory", doNothing);
+ }
+
+
+ log.warn(String.format(
+ "Can't update application '%s' with url '%s'",
+ app, info.url));
+ log.debug("Application update aborted because: ", eee);
+ }
+ }
+
+ // envoi le resultat a l'appelant s'il le souhaite
+ if (callback != null) {
+ callback.updateDone(appToUpdate, appUpdateError);
+ }
+ } catch(Exception eee) {
+ log.warn("Can't update");
+ log.info("Application update aborted because: ", eee);
+ if (callback != null) {
+ callback.aborted(String.valueOf(url), eee);
+ }
+ }
+ }
+
+ /**
+ * Decompresse le zip qui est pointer par l'url dans le repertoire
+ * specifie, et ajoute le fichier contenant la version de l'application.
+ * Le repertoire root du zip est renomme par le nom de l'application.
+ * Par exemple si un fichier se nomme "monApp-1.2/Readme.txt" il se
+ * nommera au final "monApp/Readme.txt"
+ *
+ * @param proxy le proxy a utiliser pour la connexion a l'url
+ * @param info information sur l'application a mettre a jour
+ * @throws Exception
+ */
+ protected void doUpdate(Proxy proxy, ApplicationInfo info) throws Exception {
+ if (info.destDir != null) {
+ // suppression d'une ancienne version si elle existait
+ File dest = new File(info.destDir, info.name);
+ if (dest.exists()) {
+ log.warn(String.format("Remove destination directory for new data '%s'", dest));
+ FileUtils.deleteDirectory(dest);
+ }
+
+ URL applicationURL = toURL(info.url);
+ InputStream in = new BufferedInputStream(
+ applicationURL.openConnection(proxy).getInputStream());
+ ZipUtil.uncompressAndRename(in, info.destDir, "^[^/]+", info.name);
+ File versionFile = new File(info.destDir, info.name + File.separator + VERSION_FILE);
+ FileUtils.writeStringToFile(versionFile, info.newVersion);
+ log.info(String.format(
+ "Application '%s' is uptodate with version '%s' in '%s'",
+ info.name, info.newVersion, info.destDir));
+ } else {
+ log.info(String.format("Update for '%s' aborted because destination dir is set to null", info.name));
+ }
+ }
+
+ /**
+ * Converti le path en URL. 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 URL toURL(String path) throws MalformedURLException {
+ URL result;
+ if (StringUtils.startsWith(path, "file:")) {
+ File f = new File(StringUtils.substringAfter(path, "file:"));
+ result = f.toURI().toURL();
+ } else {
+ result = new URL(path);
+ }
+ return result;
+ }
+
+ /**
+ * Return config prepared for os and arch
+ *
+ * @return
+ * @throws Exception
+ */
+ protected ApplicationConfig getUpdaterConfig(Proxy proxy) throws Exception {
+ String osName = StringUtils.lowerCase(config.getOsName());
+ String osArch = StringUtils.lowerCase(config.getOsArch());
+
+ if (log.isDebugEnabled()) {
+ log.debug(String.format(
+ "Try to load properties from '%s' with proxy '%s'",
+ url, proxy));
+ }
+
+ InputStream in = new BufferedInputStream(
+ url.openConnection(proxy).getInputStream());
+ Properties prop = new Properties();
+ prop.load(in);
+
+ if (log.isDebugEnabled()) {
+ log.debug(String.format(
+ "Properties loaded from '%s'\n%s",
+ url, 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() + SEPARATOR_KEY);
+
+ result = result.getSubConfig(osName + SEPARATOR_KEY);
+ result = result.getSubConfig(osArch + SEPARATOR_KEY);
+ return result;
+ }
+
+ /**
+ * Recupere le proxy http a utiliser pour les connexions reseaux
+ *
+ * @param config
+ * @return
+ */
+ protected Proxy getProxy(ApplicationConfig config) {
+ Proxy result = Proxy.NO_PROXY;
+ 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);
+ SocketAddress socket = new InetSocketAddress(hostname, portNumber);
+ result = new Proxy(Proxy.Type.HTTP, socket);
+ } 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<String, String> getCurrentVersion(List<String> apps, File dir) {
+ Map<String, String> result = new HashMap<String, String>();
+ for (String app : apps) {
+ File f = new File(dir, app + File.separator + VERSION_FILE);
+ String version = "0";
+ try {
+ version = FileUtils.readFileToString(f);
+ } catch (IOException ex) {
+ log.warn(String.format(
+ "Can't find file version '%s' for application '%s', this file should be '%s'",
+ VERSION_FILE, app, f));
+ }
+ version = StringUtils.trim(version);
+ result.put(app, version);
+ }
+ return result;
+ }
+
+ /**
+ * Retourne la liste des noms d'application se trouvant dans la
+ * configuration
+ *
+ * @param config
+ * @return
+ */
+ protected List<String> getApplicationName(ApplicationConfig config) {
+ Pattern p = Pattern.compile("([^.]+)\\.version");
+ List<String> result = new LinkedList<String>();
+ 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;
+ }
+
+ }
+
+}
Added: trunk/nuiton-utils/src/test/java/org/nuiton/util/ApplicationUpdaterTest.java
===================================================================
--- trunk/nuiton-utils/src/test/java/org/nuiton/util/ApplicationUpdaterTest.java (rev 0)
+++ trunk/nuiton-utils/src/test/java/org/nuiton/util/ApplicationUpdaterTest.java 2013-01-04 15:05:56 UTC (rev 2457)
@@ -0,0 +1,62 @@
+package org.nuiton.util;
+
+
+import java.io.File;
+import java.net.URL;
+import java.util.Map;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.junit.Test;
+import org.nuiton.util.ApplicationUpdater.ApplicationInfo;
+
+/**
+ *
+ * @author poussin
+ * @version $Revision$
+ *
+ * Last update: $Date$
+ * by : $Author$
+ */
+public class ApplicationUpdaterTest {
+
+ /** to use log facility, just put in your code: log.info(\"...\"); */
+ static private Log log = LogFactory.getLog(ApplicationUpdaterTest.class);
+
+ static private class Callback implements ApplicationUpdater.ApplicationUpdaterCallback {
+
+ public Map<String, ApplicationInfo> updateToDo(Map<String, ApplicationInfo> appToUpdate) {
+ log.info("Application to update\n" + appToUpdate);
+ return appToUpdate;
+ }
+
+ public void updateDone(Map<String, ApplicationInfo> appToUpdate, Map<String, Exception> appUpdateError) {
+ for (Map.Entry<String, Exception> e : appUpdateError.entrySet()) {
+ log.info(String.format("Error during update for application '%s'", e.getKey()), e.getValue());
+ }
+ }
+
+ public void aborted(String propertiesURL, Exception eee) {
+ log.info(String.format("Update aborted for url '%s'", propertiesURL), eee);
+ }
+
+ }
+
+ @Test
+ public void testUpdate() throws Exception {
+ ApplicationUpdater up = new ApplicationUpdater();
+ URL url = new File("src/test/resources/properties/ApplicationUpdaterTest.properties").toURI().toURL();
+ File current = new File("src/test/resources/ApplicationUpdater");
+ File dest = new File("target/test/ApplicationUpdater/NEW");
+ up.update(url, current, dest, false, new Callback());
+ }
+
+ @Test
+ public void testUpdateNetwork() throws Exception {
+ ApplicationUpdater up = new ApplicationUpdater();
+ URL url = new URL("http://svn.nuiton.org/svn/nuiton-utils/trunk/nuiton-utils/src/test/resource…");
+ File current = new File("src/test/resources/ApplicationUpdater");
+ File dest = new File("target/test/ApplicationUpdater/NEWNETWORK");
+ up.update(url, current, dest, false, new Callback());
+ }
+
+}
Added: trunk/nuiton-utils/src/test/resources/ApplicationUpdater/App1/Readme.txt
===================================================================
--- trunk/nuiton-utils/src/test/resources/ApplicationUpdater/App1/Readme.txt (rev 0)
+++ trunk/nuiton-utils/src/test/resources/ApplicationUpdater/App1/Readme.txt 2013-01-04 15:05:56 UTC (rev 2457)
@@ -0,0 +1,2 @@
+Application 1
+v0.1
Added: trunk/nuiton-utils/src/test/resources/ApplicationUpdater/App1/version.appup
===================================================================
--- trunk/nuiton-utils/src/test/resources/ApplicationUpdater/App1/version.appup (rev 0)
+++ trunk/nuiton-utils/src/test/resources/ApplicationUpdater/App1/version.appup 2013-01-04 15:05:56 UTC (rev 2457)
@@ -0,0 +1 @@
+0.1
\ No newline at end of file
Added: trunk/nuiton-utils/src/test/resources/ApplicationUpdater/App2/Readme.txt
===================================================================
--- trunk/nuiton-utils/src/test/resources/ApplicationUpdater/App2/Readme.txt (rev 0)
+++ trunk/nuiton-utils/src/test/resources/ApplicationUpdater/App2/Readme.txt 2013-01-04 15:05:56 UTC (rev 2457)
@@ -0,0 +1,2 @@
+Application 2
+v4
Added: trunk/nuiton-utils/src/test/resources/ApplicationUpdater/App3/Readme.txt
===================================================================
--- trunk/nuiton-utils/src/test/resources/ApplicationUpdater/App3/Readme.txt (rev 0)
+++ trunk/nuiton-utils/src/test/resources/ApplicationUpdater/App3/Readme.txt 2013-01-04 15:05:56 UTC (rev 2457)
@@ -0,0 +1,2 @@
+Application 3
+v7.1
Added: trunk/nuiton-utils/src/test/resources/ApplicationUpdater/App3/version.appup
===================================================================
--- trunk/nuiton-utils/src/test/resources/ApplicationUpdater/App3/version.appup (rev 0)
+++ trunk/nuiton-utils/src/test/resources/ApplicationUpdater/App3/version.appup 2013-01-04 15:05:56 UTC (rev 2457)
@@ -0,0 +1 @@
+7.1
\ No newline at end of file
Added: trunk/nuiton-utils/src/test/resources/ApplicationUpdater/zip/App1-0.3.zip
===================================================================
(Binary files differ)
Property changes on: trunk/nuiton-utils/src/test/resources/ApplicationUpdater/zip/App1-0.3.zip
___________________________________________________________________
Added: svn:mime-type
+ application/zip
Added: trunk/nuiton-utils/src/test/resources/ApplicationUpdater/zip/App2-7.zip
===================================================================
(Binary files differ)
Property changes on: trunk/nuiton-utils/src/test/resources/ApplicationUpdater/zip/App2-7.zip
___________________________________________________________________
Added: svn:mime-type
+ application/zip
Added: trunk/nuiton-utils/src/test/resources/ApplicationUpdater/zip/App3-7.zip
===================================================================
(Binary files differ)
Property changes on: trunk/nuiton-utils/src/test/resources/ApplicationUpdater/zip/App3-7.zip
___________________________________________________________________
Added: svn:mime-type
+ application/zip
Added: trunk/nuiton-utils/src/test/resources/properties/ApplicationUpdaterNetworkTest.properties
===================================================================
--- trunk/nuiton-utils/src/test/resources/properties/ApplicationUpdaterNetworkTest.properties (rev 0)
+++ trunk/nuiton-utils/src/test/resources/properties/ApplicationUpdaterNetworkTest.properties 2013-01-04 15:05:56 UTC (rev 2457)
@@ -0,0 +1,6 @@
+App1.version=0.3
+App1.url=http://svn.nuiton.org/svn/nuiton-utils/trunk/nuiton-utils/src/test/resources/ApplicationUpdater/zip/App1-0.3.zip
+linux.amd64.App2.version=7
+linux.amd64.App2.url=http://svn.nuiton.org/svn/nuiton-utils/trunk/nuiton-utils/src/test/resources/ApplicationUpdater/zip/App2-7.zip
+linux.x86.App3.version=7
+linux.x86.App3.url=http://svn.nuiton.org/svn/nuiton-utils/trunk/nuiton-utils/src/test/resources/ApplicationUpdater/zip/App3-7.zip
Added: trunk/nuiton-utils/src/test/resources/properties/ApplicationUpdaterTest.properties
===================================================================
--- trunk/nuiton-utils/src/test/resources/properties/ApplicationUpdaterTest.properties (rev 0)
+++ trunk/nuiton-utils/src/test/resources/properties/ApplicationUpdaterTest.properties 2013-01-04 15:05:56 UTC (rev 2457)
@@ -0,0 +1,6 @@
+App1.version=0.3
+App1.url=file:src/test/resources/ApplicationUpdater/zip/App1-0.3.zip
+linux.amd64.App2.version=7
+linux.amd64.App2.url=file:src/test/resources/ApplicationUpdater/zip/App2-7.zip
+linux.x86.App3.version=7
+linux.x86.App3.url=file:src/test/resources/ApplicationUpdater/zip/App3-7.zip
1
0
04 Jan '13
Author: bpoussin
Date: 2013-01-04 15:57:11 +0100 (Fri, 04 Jan 2013)
New Revision: 2456
Url: http://nuiton.org/projects/nuiton-utils/repository/revisions/2456
Log:
add new method to uncompress zip file from stream
Modified:
trunk/nuiton-utils/src/main/java/org/nuiton/util/ZipUtil.java
Modified: trunk/nuiton-utils/src/main/java/org/nuiton/util/ZipUtil.java
===================================================================
--- trunk/nuiton-utils/src/main/java/org/nuiton/util/ZipUtil.java 2013-01-04 14:56:12 UTC (rev 2455)
+++ trunk/nuiton-utils/src/main/java/org/nuiton/util/ZipUtil.java 2013-01-04 14:57:11 UTC (rev 2456)
@@ -97,6 +97,21 @@
}
/**
+ * Uncompress zipped stream in targetDir.
+ *
+ *
+ * @param stream the zip source stream, stream is closed before return
+ * @param targetDir the destination directory
+ * @return return last entry name
+ * @throws IOException if any problem while uncompressing
+ * @since 2.7
+ */
+ public static String uncompress(InputStream stream, File targetDir) throws IOException {
+ String result = uncompressAndRename(stream, targetDir, null, null);
+ return result;
+ }
+
+ /**
* Uncompress zipped file in targetDir, and rename uncompressed file if
* necessary. If renameFrom or renameTo is null no renaming is done
* <p/>
@@ -115,36 +130,63 @@
File targetDir,
String renameFrom,
String renameTo) throws IOException {
+ return uncompressAndRename(new FileInputStream(file), targetDir, renameFrom, renameTo);
+ }
+
+
+ /**
+ * Uncompress zipped stream in targetDir, and rename uncompressed file if
+ * necessary. If renameFrom or renameTo is null no renaming is done
+ * <p/>
+ * file in zip use / to separate directory and not begin with /
+ * each directory ended with /
+ *
+ * @param stream the zip source stream, stream is closed before return
+ * @param targetDir the destination directory
+ * @param renameFrom pattern to permit rename file before uncompress it
+ * @param renameTo new name for file if renameFrom is applicable to it
+ * you can use $1, $2, ... if you have '(' ')' in renameFrom
+ * @return return last entry name
+ * @throws IOException if any problem while uncompressing
+ * @since 2.7
+ */
+ public static String uncompressAndRename(InputStream stream,
+ File targetDir,
+ String renameFrom,
+ String renameTo) throws IOException {
String result = "";
- ZipInputStream in = new ZipInputStream(new FileInputStream(file));
- ZipEntry entry;
- while ((entry = in.getNextEntry()) != null) {
- String name = entry.getName();
- if (renameFrom != null && renameTo != null) {
- name = name.replaceAll(renameFrom, renameTo);
- if (log.isDebugEnabled()) {
- log.debug("rename " + entry.getName() + " -> " + name);
+ ZipInputStream in = new ZipInputStream(new BufferedInputStream(stream));
+ try {
+ ZipEntry entry;
+ while ((entry = in.getNextEntry()) != null) {
+ String name = entry.getName();
+ if (renameFrom != null && renameTo != null) {
+ name = name.replaceAll(renameFrom, renameTo);
+ if (log.isDebugEnabled()) {
+ log.debug("rename " + entry.getName() + " -> " + name);
+ }
}
- }
- result = name;
- File target = new File(targetDir, name);
- if (entry.isDirectory()) {
- FileUtil.createDirectoryIfNecessary(target);
- } else {
- FileUtil.createDirectoryIfNecessary(target.getParentFile());
- OutputStream out = new BufferedOutputStream(new FileOutputStream(target));
- try {
- byte[] buffer = new byte[BUFFER_SIZE];
- int len;
- while ((len = in.read(buffer, 0, BUFFER_SIZE)) != -1) {
- out.write(buffer, 0, len);
+ result = name;
+ File target = new File(targetDir, name);
+ if (entry.isDirectory()) {
+ FileUtil.createDirectoryIfNecessary(target);
+ } else {
+ FileUtil.createDirectoryIfNecessary(target.getParentFile());
+ OutputStream out = new BufferedOutputStream(new FileOutputStream(target));
+ try {
+ byte[] buffer = new byte[BUFFER_SIZE];
+ int len;
+ while ((len = in.read(buffer, 0, BUFFER_SIZE)) != -1) {
+ out.write(buffer, 0, len);
+ }
+ } finally {
+ out.close();
}
- } finally {
- out.close();
}
}
+ } finally {
+ in.close();
}
- in.close();
return result;
}
1
0
r2455 - in trunk/nuiton-utils/src: main/java/org/nuiton/util test/java/org/nuiton/util
by bpoussin@users.nuiton.org 04 Jan '13
by bpoussin@users.nuiton.org 04 Jan '13
04 Jan '13
Author: bpoussin
Date: 2013-01-04 15:56:12 +0100 (Fri, 04 Jan 2013)
New Revision: 2455
Url: http://nuiton.org/projects/nuiton-utils/repository/revisions/2455
Log:
add new methods:
- getOsName()
- getOsArch()
fix bad comportment in SubConfig (hasOption)
Modified:
trunk/nuiton-utils/src/main/java/org/nuiton/util/ApplicationConfig.java
trunk/nuiton-utils/src/test/java/org/nuiton/util/ApplicationConfigTest.java
Modified: trunk/nuiton-utils/src/main/java/org/nuiton/util/ApplicationConfig.java
===================================================================
--- trunk/nuiton-utils/src/main/java/org/nuiton/util/ApplicationConfig.java 2013-01-04 14:30:25 UTC (rev 2454)
+++ trunk/nuiton-utils/src/main/java/org/nuiton/util/ApplicationConfig.java 2013-01-04 14:56:12 UTC (rev 2455)
@@ -553,6 +553,28 @@
}
/**
+ * Get os name (system property {@code os.name}).
+ *
+ * @return os name
+ * @since 2.7
+ */
+ public String getOsName() {
+ String result = getOption("os.name");
+ return result;
+ }
+
+ /**
+ * Get os arch (system property {@code os.arch}).
+ *
+ * @return os arch
+ * @since 2.7
+ */
+ public String getOsArch() {
+ String result = getOption("os.arch");
+ return result;
+ }
+
+ /**
* Load default options of enum pass in param (enum must extend {@link OptionDef})
*
* @param optionClass to load
@@ -2311,7 +2333,8 @@
@Override
public boolean hasOption(String key) {
- return getParent().hasOption(getPrefix() + key);
+ boolean result = getOption(key) != null;
+ return result;
}
@Override
@@ -2330,10 +2353,8 @@
*/
@Override
public String getOption(String key) {
- String result;
- if (hasOption(key)) {
- result = getParent().getOption(getPrefix() + key);
- } else {
+ String result = getParent().getOption(getPrefix() + key);
+ if (result == null) {
result = getParent().getOption(key);
}
return result;
Modified: trunk/nuiton-utils/src/test/java/org/nuiton/util/ApplicationConfigTest.java
===================================================================
--- trunk/nuiton-utils/src/test/java/org/nuiton/util/ApplicationConfigTest.java 2013-01-04 14:30:25 UTC (rev 2454)
+++ trunk/nuiton-utils/src/test/java/org/nuiton/util/ApplicationConfigTest.java 2013-01-04 14:56:12 UTC (rev 2455)
@@ -53,6 +53,7 @@
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
+import org.apache.commons.lang3.StringUtils;
/** @author poussin */
public class ApplicationConfigTest {
@@ -666,4 +667,23 @@
Assert.assertEquals(expected, actual);
}
+
+ @Test
+ public void testGetOsName() throws Exception {
+ ApplicationConfig config = new ApplicationConfig();
+ config.parse();
+ String v = config.getOsName();
+ Assert.assertTrue(StringUtils.isNotBlank(v));
+ System.out.println("os.name: " + v);
+ }
+
+ @Test
+ public void testGetOsArch() throws Exception {
+ ApplicationConfig config = new ApplicationConfig();
+ config.parse();
+ String v = config.getOsArch();
+ Assert.assertTrue(StringUtils.isNotBlank(v));
+ System.out.println("os.arch: " + v);
+ }
+
}
1
0
04 Jan '13
Author: tchemit
Date: 2013-01-04 15:30:25 +0100 (Fri, 04 Jan 2013)
New Revision: 2454
Url: http://nuiton.org/projects/nuiton-utils/repository/revisions/2454
Log:
fix test
Modified:
trunk/nuiton-utils/src/test/java/org/nuiton/util/ApplicationConfigTest.java
Modified: trunk/nuiton-utils/src/test/java/org/nuiton/util/ApplicationConfigTest.java
===================================================================
--- trunk/nuiton-utils/src/test/java/org/nuiton/util/ApplicationConfigTest.java 2013-01-04 13:57:36 UTC (rev 2453)
+++ trunk/nuiton-utils/src/test/java/org/nuiton/util/ApplicationConfigTest.java 2013-01-04 14:30:25 UTC (rev 2454)
@@ -100,7 +100,7 @@
String path = testDirectory.getAbsolutePath();
try {
- System.setProperty(SystemUtils.USER_HOME, path);
+ System.setProperty("user.home", path);
ApplicationConfig config =
new ApplicationConfig(testName.getMethodName());
1
0
r2453 - in trunk: . nuiton-csv nuiton-profiling nuiton-utils nuiton-utils-maven-report-plugin nuiton-validator
by tchemit@users.nuiton.org 04 Jan '13
by tchemit@users.nuiton.org 04 Jan '13
04 Jan '13
Author: tchemit
Date: 2013-01-04 14:57:36 +0100 (Fri, 04 Jan 2013)
New Revision: 2453
Url: http://nuiton.org/projects/nuiton-utils/repository/revisions/2453
Log:
change to version 2.6.6
Modified:
trunk/nuiton-csv/pom.xml
trunk/nuiton-profiling/pom.xml
trunk/nuiton-utils-maven-report-plugin/pom.xml
trunk/nuiton-utils/pom.xml
trunk/nuiton-validator/pom.xml
trunk/pom.xml
Modified: trunk/nuiton-csv/pom.xml
===================================================================
--- trunk/nuiton-csv/pom.xml 2013-01-04 13:51:09 UTC (rev 2452)
+++ trunk/nuiton-csv/pom.xml 2013-01-04 13:57:36 UTC (rev 2453)
@@ -31,7 +31,7 @@
<parent>
<groupId>org.nuiton</groupId>
<artifactId>nuiton-utils-parent</artifactId>
- <version>2.7-SNAPSHOT</version>
+ <version>2.6.6-SNAPSHOT</version>
</parent>
<artifactId>nuiton-csv</artifactId>
Modified: trunk/nuiton-profiling/pom.xml
===================================================================
--- trunk/nuiton-profiling/pom.xml 2013-01-04 13:51:09 UTC (rev 2452)
+++ trunk/nuiton-profiling/pom.xml 2013-01-04 13:57:36 UTC (rev 2453)
@@ -31,7 +31,7 @@
<parent>
<groupId>org.nuiton</groupId>
<artifactId>nuiton-utils-parent</artifactId>
- <version>2.7-SNAPSHOT</version>
+ <version>2.6.6-SNAPSHOT</version>
</parent>
<artifactId>nuiton-profiling</artifactId>
Modified: trunk/nuiton-utils/pom.xml
===================================================================
--- trunk/nuiton-utils/pom.xml 2013-01-04 13:51:09 UTC (rev 2452)
+++ trunk/nuiton-utils/pom.xml 2013-01-04 13:57:36 UTC (rev 2453)
@@ -31,7 +31,7 @@
<parent>
<groupId>org.nuiton</groupId>
<artifactId>nuiton-utils-parent</artifactId>
- <version>2.7-SNAPSHOT</version>
+ <version>2.6.6-SNAPSHOT</version>
</parent>
<artifactId>nuiton-utils</artifactId>
Modified: trunk/nuiton-utils-maven-report-plugin/pom.xml
===================================================================
--- trunk/nuiton-utils-maven-report-plugin/pom.xml 2013-01-04 13:51:09 UTC (rev 2452)
+++ trunk/nuiton-utils-maven-report-plugin/pom.xml 2013-01-04 13:57:36 UTC (rev 2453)
@@ -31,7 +31,7 @@
<parent>
<groupId>org.nuiton</groupId>
<artifactId>nuiton-utils-parent</artifactId>
- <version>2.7-SNAPSHOT</version>
+ <version>2.6.6-SNAPSHOT</version>
</parent>
<artifactId>nuiton-utils-maven-report-plugin</artifactId>
Modified: trunk/nuiton-validator/pom.xml
===================================================================
--- trunk/nuiton-validator/pom.xml 2013-01-04 13:51:09 UTC (rev 2452)
+++ trunk/nuiton-validator/pom.xml 2013-01-04 13:57:36 UTC (rev 2453)
@@ -31,7 +31,7 @@
<parent>
<groupId>org.nuiton</groupId>
<artifactId>nuiton-utils-parent</artifactId>
- <version>2.7-SNAPSHOT</version>
+ <version>2.6.6-SNAPSHOT</version>
</parent>
<artifactId>nuiton-validator</artifactId>
Modified: trunk/pom.xml
===================================================================
--- trunk/pom.xml 2013-01-04 13:51:09 UTC (rev 2452)
+++ trunk/pom.xml 2013-01-04 13:57:36 UTC (rev 2453)
@@ -31,7 +31,7 @@
</parent>
<artifactId>nuiton-utils-parent</artifactId>
- <version>2.7-SNAPSHOT</version>
+ <version>2.6.6-SNAPSHOT</version>
<modules>
<module>nuiton-utils</module>
1
0
r2452 - in trunk/nuiton-utils/src: main/java/org/nuiton/util test/java/org/nuiton/util
by tchemit@users.nuiton.org 04 Jan '13
by tchemit@users.nuiton.org 04 Jan '13
04 Jan '13
Author: tchemit
Date: 2013-01-04 14:51:09 +0100 (Fri, 04 Jan 2013)
New Revision: 2452
Url: http://nuiton.org/projects/nuiton-utils/repository/revisions/2452
Log:
fixes #2500: [ApplicationConfig] Add a method to reset all options with *blank* values
Modified:
trunk/nuiton-utils/src/main/java/org/nuiton/util/ApplicationConfig.java
trunk/nuiton-utils/src/test/java/org/nuiton/util/ApplicationConfigTest.java
Modified: trunk/nuiton-utils/src/main/java/org/nuiton/util/ApplicationConfig.java
===================================================================
--- trunk/nuiton-utils/src/main/java/org/nuiton/util/ApplicationConfig.java 2012-12-29 11:29:25 UTC (rev 2451)
+++ trunk/nuiton-utils/src/main/java/org/nuiton/util/ApplicationConfig.java 2013-01-04 13:51:09 UTC (rev 2452)
@@ -69,6 +69,7 @@
import org.apache.commons.beanutils.ConstructorUtils;
import org.apache.commons.collections.EnumerationUtils;
import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuiton.util.converter.ConverterUtil;
@@ -708,6 +709,50 @@
}
/**
+ * Clean the user configuration file (The one in user home) and save it
+ * in user config file.
+ *
+ * All options with an empty value will be removed from this file.
+ *
+ * Moreover, like {@link #saveForUser(String...)} the given
+ * {@code excludeKeys} will never be saved.
+ *
+ * This method can be useful when migrating some configuration from a
+ * version to another one with deprecated options (otherwise they will stay
+ * for ever in the configuration file with an empty value which is not
+ * acceptable).
+ *
+ * <strong>Important note:</strong> Using this method can have some strange
+ * side effects, since it could then allow to reuse default configurations
+ * from other level (default, env, jvm,...). Use with care only!
+ *
+ * @param excludeKeys optional list of key to not treat in cleaning process,
+ * nor save in user user config file.
+ * @since 2.6.6
+ */
+ public void cleanUserConfig(String... excludeKeys) {
+
+ Set<String> keys = new HashSet<String>(homefile.stringPropertyNames());
+
+ List<String> toExclude = Arrays.asList(excludeKeys);
+
+ for (String key : keys) {
+ if (!toExclude.contains(key)) {
+ String property = homefile.getProperty(key);
+ if (StringUtils.isBlank(property)) {
+ if (log.isInfoEnabled()) {
+ log.info("Remove blank property: " + key);
+ }
+ homefile.remove(key);
+ }
+ }
+ }
+
+ // can now save cleaned user config
+ saveForUser(excludeKeys);
+ }
+
+ /**
* Obtain the system config file location.
*
* @return the system config file location
Modified: trunk/nuiton-utils/src/test/java/org/nuiton/util/ApplicationConfigTest.java
===================================================================
--- trunk/nuiton-utils/src/test/java/org/nuiton/util/ApplicationConfigTest.java 2012-12-29 11:29:25 UTC (rev 2451)
+++ trunk/nuiton-utils/src/test/java/org/nuiton/util/ApplicationConfigTest.java 2013-01-04 13:51:09 UTC (rev 2452)
@@ -25,15 +25,23 @@
package org.nuiton.util;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.SystemUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.Assert;
+import org.junit.Before;
import org.junit.BeforeClass;
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.TestName;
import org.nuiton.util.ApplicationConfig.Action;
import java.io.ByteArrayOutputStream;
import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
@@ -44,86 +52,205 @@
import java.util.ListIterator;
import java.util.Locale;
import java.util.Map;
+import java.util.Properties;
-/**
- *
- * @author poussin
- */
+/** @author poussin */
public class ApplicationConfigTest {
private static final Log log =
LogFactory.getLog(ApplicationConfigTest.class);
- /** main folder for tests data **/
+ /** main folder for tests data * */
protected static File DIR_TESTS_DATA;
- protected static final String SYSTEM_PROPERTY_USER_HOME = "user.home";
-
protected static int DUMMY_ACTION_CALL;
public static class DummyAction {
@Action.Step(1)
public void dummyAction(String s, int step) {
DUMMY_ACTION_CALL++;
- log.info(s + ":" + step);
+ log.info(s + ':' + step);
}
}
+ protected static String oldHome;
+
@BeforeClass
public static void setUpClass() {
// Initialize DIR_TESTS_DATA to target/surefire-data
- DIR_TESTS_DATA = TestHelper.createDefaultTestsDataDirectory();
+ DIR_TESTS_DATA = FileUtil.getFileFromFQN(TestHelper.createDefaultTestsDataDirectory(), ApplicationConfigTest.class.getName() + "." + System.nanoTime());
+
+ oldHome = SystemUtils.getUserHome().getAbsolutePath();
}
+ protected File testDirectory;
+
+ @Rule
+ public final TestName testName = new TestName();
+
+ @Before
+ public void before() {
+ testDirectory = new File(DIR_TESTS_DATA, testName.getMethodName());
+ }
+
@Test
- public void testSaveForUser() {
- log.info("testSaveForUser");
+ public void testSaveForUser() throws IOException {
- /** PREPARE DATA **/
+ // Initiliaze path and filename
+ String path = testDirectory.getAbsolutePath();
+ try {
+ System.setProperty(SystemUtils.USER_HOME, path);
+
+ ApplicationConfig config =
+ new ApplicationConfig(testName.getMethodName());
+
+ File userFile = config.getUserConfigFile();
+
+ userFile.delete();
+
+ config.setOption("key1", "toto");
+ config.setOption("key2", "tata");
+ config.setOption("key3", "tutu");
+
+ // Parent directory will be created
+ config.saveForUser();
+
+ // I like to test that file.create works :(
+ Assert.assertTrue(userFile.exists());
+
+ Properties p = loadPropertyFile(userFile);
+
+ Assert.assertEquals(3, p.size());
+
+ String property;
+
+ property = p.getProperty("key1");
+ Assert.assertEquals("toto", property);
+
+ property = p.getProperty("key2");
+ Assert.assertEquals("tata", property);
+
+ property = p.getProperty("key3");
+ Assert.assertEquals("tutu", property);
+
+ } finally {
+
+ if (oldHome != null) {
+ System.setProperty("user.home", oldHome);
+ }
+ }
+
+ }
+
+ @Test
+ public void cleanUserConfig() throws IOException, ArgumentsParserException {
+
// Initiliaze path and filename
- String path = new File(DIR_TESTS_DATA, "user").getAbsolutePath();
- String filename = "test-saveForUser.properties";
+ String path = testDirectory.getAbsolutePath();
- // Set path to USER_HOME (keep old value)
- String oldHome = System.getProperty(SYSTEM_PROPERTY_USER_HOME);
- System.setProperty(SYSTEM_PROPERTY_USER_HOME, path);
+ try {
+ System.setProperty("user.home", path);
- /** EXEC METHOD **/
+ ApplicationConfig config =
+ new ApplicationConfig(testName.getMethodName());
- ApplicationConfig config = new ApplicationConfig();
- config.setOption(ApplicationConfig.CONFIG_FILE_NAME, filename);
- File userFile = config.getUserConfigFile();
+ config.setOption("key1", "toto");
+ config.setOption("key2", "");
+ config.setOption("key3", "tutu");
- // If file exists, delete the file and his parent directory
- if (userFile.exists()) {
+ File userFile = config.getUserConfigFile();
+
+ Assert.assertTrue(userFile.getAbsolutePath().startsWith(path));
+
userFile.delete();
- userFile.getParentFile().delete();
- }
- Assert.assertFalse(userFile.exists());
- //FIXME-tchemit-2012-07-23 : why this should be false ? False test
- //Assert.assertFalse(userFile.getParentFile().exists());
+ config.saveForUser();
- log.info("execute saveForUser : path = " + path + " _ filename = " + filename);
- // Parent directory will be created
- config.saveForUser();
- Assert.assertTrue(userFile.exists());
+ Assert.assertTrue(userFile.exists());
- /** CLEAN **/
+ Properties p = loadPropertyFile(userFile);
- // Reset initial values
- System.setProperty(SYSTEM_PROPERTY_USER_HOME, oldHome);
+ Assert.assertEquals(3, p.size());
+
+ String property;
+
+ property = p.getProperty("key1");
+ Assert.assertEquals("toto", property);
+
+ property = p.getProperty("key2");
+ Assert.assertEquals("", property);
+
+ property = p.getProperty("key3");
+ Assert.assertEquals("tutu", property);
+
+ // reload config
+ config = new ApplicationConfig(testName.getMethodName());
+ config.parse();
+
+ config.cleanUserConfig();
+
+ Properties p2 = loadPropertyFile(userFile);
+
+ // key2 was removed
+ Assert.assertEquals(2, p2.size());
+
+ property = p2.getProperty("key1");
+ Assert.assertEquals("toto", property);
+
+ property = p2.getProperty("key2");
+ Assert.assertNull(property);
+
+ property = p2.getProperty("key3");
+ Assert.assertEquals("tutu", property);
+
+ // now key3 will be removed (even if not blank)
+ config.cleanUserConfig("key3");
+
+ // reload config
+ config = new ApplicationConfig(testName.getMethodName());
+ config.parse();
+
+ Properties p3 = loadPropertyFile(userFile);
+
+ // key3 was removed
+ Assert.assertEquals(1, p3.size());
+
+ property = p3.getProperty("key1");
+ Assert.assertEquals("toto", property);
+
+
+ } finally {
+
+ if (oldHome != null) {
+ System.setProperty("user.home", oldHome);
+ }
+ }
+
}
+ protected Properties loadPropertyFile(File file) throws IOException {
+ FileInputStream inStream;
+
+ inStream = FileUtils.openInputStream(file);
+ try {
+ Properties p = new Properties();
+ p.load(inStream);
+ inStream.close();
+ return p;
+ } finally {
+ IOUtils.closeQuietly(inStream);
+ }
+ }
+
/**
* Test of getUnparsed method, of class ApplicationConfig.
+ *
* @throws Exception
*/
@Test
public void testGetUnparsed() throws Exception {
- log.info("getUnparsed");
ApplicationConfig instance = new ApplicationConfig();
List<String> expResult = new ArrayList<String>();
List<String> result = instance.getUnparsed();
@@ -140,11 +267,11 @@
/**
* Test of addAction method, of class ApplicationConfig.
+ *
* @throws Exception
*/
@Test
public void testAddAction() throws Exception {
- log.info("addAction");
Action action = null;
ApplicationConfig instance = new ApplicationConfig();
@@ -157,11 +284,11 @@
/**
* Test of doAction method, of class ApplicationConfig.
+ *
* @throws Exception
*/
@Test
public void testDoAction() throws Exception {
- log.info("doAction");
ApplicationConfig instance = new ApplicationConfig();
Action action = new Action(1, new DummyAction(), DummyAction.class.getMethod("dummyAction", String.class, Integer.TYPE), "coucou", "12");
@@ -177,12 +304,9 @@
Assert.assertEquals(1, DUMMY_ACTION_CALL);
}
- /**
- * Test of setUseOnlyAliases method, of class ApplicationConfig.
- */
+ /** Test of setUseOnlyAliases method, of class ApplicationConfig. */
@Test
public void testSetUseOnlyAliases() {
- log.info("setUseOnlyAliases");
ApplicationConfig instance = new ApplicationConfig();
Assert.assertEquals(false, instance.isUseOnlyAliases());
instance.setUseOnlyAliases(false);
@@ -193,11 +317,11 @@
/**
* Test of addAlias method, of class ApplicationConfig.
+ *
* @throws Exception
*/
@Test
public void testAddAlias() throws Exception {
- log.info("addAlias");
ApplicationConfig instance = new ApplicationConfig();
instance.addAlias("toto", "totochange");
instance.addAlias("titi", "titichange");
@@ -215,23 +339,17 @@
Assert.assertEquals(expResult, result);
}
- /**
- * Test of setConfigFileName method, of class ApplicationConfig.
- */
+ /** Test of setConfigFileName method, of class ApplicationConfig. */
@Test
public void testSetConfigFileName() {
- log.info("setConfigFileName");
ApplicationConfig instance = new ApplicationConfig();
instance.setConfigFileName("bidulle");
Assert.assertEquals("bidulle", instance.getConfigFileName());
}
- /**
- * Test of setOption method, of class ApplicationConfig.
- */
+ /** Test of setOption method, of class ApplicationConfig. */
@Test
public void testSetOption() {
- log.info("setOption");
ApplicationConfig instance = new ApplicationConfig();
Assert.assertEquals(null, instance.getOption("truc"));
instance.setOption("truc", "bidulle");
@@ -260,9 +378,7 @@
// TODO ajouter d'autres tests pour des sub-(sub-(sub)) config
}
- /**
- * Test convertion to list
- */
+ /** Test convertion to list */
@Test
public void testGetAsList() {
List<String> asString = new ArrayList<String>();
@@ -278,18 +394,15 @@
Assert.assertEquals(Collections.EMPTY_LIST, instance.getOptionAsList("truc").getOption());
instance.setOption("truc", ApplicationConfig.class.getName()
- + "," + ApplicationConfigTest.class.getName());
+ + "," + ApplicationConfigTest.class.getName());
Assert.assertEquals(asString, instance.getOptionAsList("truc").getOption());
Assert.assertEquals(asClass, instance.getOptionAsList("truc").getOptionAsClass());
}
- /**
- * Test of getMethods method, of class ApplicationConfig.
- */
+ /** Test of getMethods method, of class ApplicationConfig. */
@Test
public void testGetMethods() {
- log.info("getMethods");
ApplicationConfig instance = new ApplicationConfig();
Map<String, Method> result = instance.getMethods();
Assert.assertTrue(result.containsKey("option"));
@@ -297,11 +410,11 @@
/**
* Test of getParams method, of class ApplicationConfig.
+ *
* @throws Exception
*/
@Test
public void testGetParams() throws Exception {
- log.info("getParams");
Method m = DummyAction.class.getMethod("dummyAction", String.class, Integer.TYPE);
List<String> list = new ArrayList<String>(Arrays.asList("toto", "10", "/tmp", "9"));
ListIterator<String> args = list.listIterator();
@@ -315,11 +428,11 @@
/**
* Test of createAction method, of class ApplicationConfig.
+ *
* @throws Exception
*/
@Test
public void testCreateAction() throws Exception {
- log.info("createAction");
List<String> list = new ArrayList<String>(Arrays.asList("dummy", "toto", "10", "/tmp", "9"));
ListIterator<String> args = list.listIterator();
args.next();
@@ -335,11 +448,11 @@
/**
* Test of parse method, of class ApplicationConfig.
+ *
* @throws Exception
*/
@Test
public void testParse() throws Exception {
- log.info("parse");
String[] args = "-f file -v -d -o /tmp/file -m coucou 10 others args".split(" ");
ApplicationConfig instance = new ApplicationConfig();
instance.addAlias("-f", "--option", "file");
@@ -363,6 +476,7 @@
/**
* Test that system properties such as ${user.home}, ${user.name} are
* replaced.
+ *
* @throws ArgumentsParserException
*/
@Test
@@ -378,7 +492,7 @@
instance.setOption("tempdir", "${java.io.tmpdir}" + File.separator + "blah");
File tempDir = instance.getOptionAsFile("tempdir");
- Assert.assertEquals(new File(System.getProperty("java.io.tmpdir") , "blah").getAbsolutePath(), tempDir.getAbsolutePath());
+ Assert.assertEquals(new File(System.getProperty("java.io.tmpdir"), "blah").getAbsolutePath(), tempDir.getAbsolutePath());
instance.setOption("system", "${os.name}");
instance.setOption("os", "${system}");
@@ -392,6 +506,7 @@
/**
* Test unparsed options
+ *
* @throws Exception
*/
@Test
@@ -410,6 +525,7 @@
/**
* Test get flat options method.
+ *
* @throws Exception
*/
@Test
@@ -427,17 +543,18 @@
// test replacement and non replacement
Assert.assertEquals("tutu toto",
- instance.getFlatOptions().getProperty("user.fullname"));
+ instance.getFlatOptions().getProperty("user.fullname"));
Assert.assertEquals("tutu toto",
- instance.getFlatOptions(true).getProperty("user.fullname"));
+ instance.getFlatOptions(true).getProperty("user.fullname"));
Assert.assertEquals("${user.lastname} ${user.firstname}",
- instance.getFlatOptions(false).getProperty("user.fullname"));
+ instance.getFlatOptions(false).getProperty("user.fullname"));
}
/**
* Test null options.
+ * <p/>
+ * TODO EC20100503 this test throw a huge exception
*
- * TODO EC20100503 this test throw a huge exception
* @throws Exception
*/
@Test
1
0