dynamic_link: new function ilib_build_jar (SEP #117) 44/13044/9
Simon Marchetto [Wed, 20 Nov 2013 15:48:38 +0000 (16:48 +0100)]
Change-Id: Id5575093352373915a6d1ba884e116fd6860f67b

21 files changed:
SEP/INDEX
SEP/SEP_114_jcreatejar.odt
SEP/SEP_117_ilib_build_jar.odt [new file with mode: 0644]
scilab/CHANGES_5.5.X
scilab/contrib/Makefile.am
scilab/contrib/Makefile.in
scilab/contrib/toolbox_skeleton.iss
scilab/contrib/toolbox_skeleton/DESCRIPTION-FUNCTIONS
scilab/contrib/toolbox_skeleton/etc/toolbox_skeleton.start
scilab/contrib/toolbox_skeleton/src/builder_src.sce
scilab/contrib/toolbox_skeleton/src/java/builder_java.sce [new file with mode: 0644]
scilab/contrib/toolbox_skeleton/src/java/org/scilab/contrib/toolboxskeleton/Sum.java [new file with mode: 0644]
scilab/contrib/toolbox_skeleton/tests/unit_tests/java_sum.dia.ref [new file with mode: 0644]
scilab/contrib/toolbox_skeleton/tests/unit_tests/java_sum.tst [new file with mode: 0644]
scilab/modules/dynamic_link/help/en_US/ilib_build_jar.xml [new file with mode: 0644]
scilab/modules/dynamic_link/help/fr_FR/ilib_build_jar.xml [new file with mode: 0644]
scilab/modules/dynamic_link/macros/ilib_build_jar.sci [new file with mode: 0644]
scilab/modules/dynamic_link/tests/unit_tests/ilib_build_jar.dia.ref [new file with mode: 0644]
scilab/modules/dynamic_link/tests/unit_tests/ilib_build_jar.tst [new file with mode: 0644]
scilab/modules/modules_manager/tests/unit_tests/toolbox_skeleton.unix.dia.ref
scilab/modules/modules_manager/tests/unit_tests/toolbox_skeleton.win.dia.ref

index cef2c09..38a9a2b 100644 (file)
--- a/SEP/INDEX
+++ b/SEP/INDEX
@@ -112,3 +112,4 @@ SEP #113: resize_matrix hypermatrices support.
 SEP #114: New function jcreatejar.
 SEP #115: New function bode_asymp.
 SEP #116: conjgrad function, to regroup the Conjugate Gradient solvers. pcg obsolete as it is.
+SEP #117: New function ilib_build_jar
index e3654f8..aa76a42 100644 (file)
Binary files a/SEP/SEP_114_jcreatejar.odt and b/SEP/SEP_114_jcreatejar.odt differ
diff --git a/SEP/SEP_117_ilib_build_jar.odt b/SEP/SEP_117_ilib_build_jar.odt
new file mode 100644 (file)
index 0000000..f869808
Binary files /dev/null and b/SEP/SEP_117_ilib_build_jar.odt differ
index 7576cc7..0b31576 100644 (file)
@@ -9,6 +9,7 @@ New Features
 
 * New functions introduced:
  - jcreatejar - Creates a Java archive (JAR) from a set of files / directories
+ - ilib_build_jar - Builds Java packages from sources into a JAR file
 
 * modulo() and pmodulo() now support integers & hypermatrices (See bug #13002).
 
index ca4cff5..a345191 100644 (file)
@@ -14,6 +14,8 @@ toolbox_skeleton/src/c/csub.c \
 toolbox_skeleton/src/c/multiplybypi.h \
 toolbox_skeleton/src/c/csub.h \
 toolbox_skeleton/src/c/csum.h \
+toolbox_skeleton/src/java/org/scilab/contrib/toolboxskeleton/Sum.java \
+toolbox_skeleton/src/java/builder_java.sce \
 toolbox_skeleton/src/cleaner_src.sce \
 toolbox_skeleton/src/builder_src.sce \
 toolbox_skeleton/etc/toolbox_skeleton.quit \
@@ -48,6 +50,8 @@ toolbox_skeleton/tests/unit_tests/scilab_sum.dia.ref \
 toolbox_skeleton/tests/unit_tests/fortran_sum.dia.ref \
 toolbox_skeleton/tests/unit_tests/c_sum.dia.ref \
 toolbox_skeleton/tests/unit_tests/scilab_sum.tst \
+toolbox_skeleton/tests/unit_tests/java_sum.tst \
+toolbox_skeleton/tests/unit_tests/java_sum.dia.ref \
 toolbox_skeleton/sci_gateway/fortran/builder_gateway_fortran.sce \
 toolbox_skeleton/sci_gateway/fortran/sci_fsum.c \
 toolbox_skeleton/sci_gateway/c/sci_csub.c \
index 4c3efd1..f417244 100644 (file)
@@ -410,6 +410,8 @@ toolbox_skeleton/src/c/csub.c \
 toolbox_skeleton/src/c/multiplybypi.h \
 toolbox_skeleton/src/c/csub.h \
 toolbox_skeleton/src/c/csum.h \
+toolbox_skeleton/src/java/org/scilab/contrib/toolboxskeleton/Sum.java \
+toolbox_skeleton/src/java/builder_java.sce \
 toolbox_skeleton/src/cleaner_src.sce \
 toolbox_skeleton/src/builder_src.sce \
 toolbox_skeleton/etc/toolbox_skeleton.quit \
@@ -444,6 +446,8 @@ toolbox_skeleton/tests/unit_tests/scilab_sum.dia.ref \
 toolbox_skeleton/tests/unit_tests/fortran_sum.dia.ref \
 toolbox_skeleton/tests/unit_tests/c_sum.dia.ref \
 toolbox_skeleton/tests/unit_tests/scilab_sum.tst \
+toolbox_skeleton/tests/unit_tests/java_sum.tst \
+toolbox_skeleton/tests/unit_tests/java_sum.dia.ref \
 toolbox_skeleton/sci_gateway/fortran/builder_gateway_fortran.sce \
 toolbox_skeleton/sci_gateway/fortran/sci_fsum.c \
 toolbox_skeleton/sci_gateway/c/sci_csub.c \
index da6b23c..79be267 100644 (file)
@@ -54,6 +54,8 @@ Source: contrib\{#TOOLBOX_SKELETON}\src\fortran\builder_fortran.sce; DestDir: {a
 Source: contrib\{#TOOLBOX_SKELETON}\src\fortran\fsum.f; DestDir: {app}\contrib\{#TOOLBOX_SKELETON}\src\fortran; Components: {#COMPN_TOOLBOX_SKELETON}
 Source: contrib\{#TOOLBOX_SKELETON}\tests\*.*; DestDir: {app}\contrib\{#TOOLBOX_SKELETON}\tests; Flags: recursesubdirs; Components: {#COMPN_TOOLBOX_SKELETON}
 Source: contrib\{#TOOLBOX_SKELETON}\locales\*.*; DestDir: {app}\contrib\{#TOOLBOX_SKELETON}\locales; Flags: recursesubdirs; Components: {#COMPN_TOOLBOX_SKELETON}
+Source: contrib\{#TOOLBOX_SKELETON}\src\java\builder_java.sce; DestDir: {app}\contrib\{#TOOLBOX_SKELETON}\src\java; Components: {#COMPN_TOOLBOX_SKELETON}
+Source: contrib\{#TOOLBOX_SKELETON}\src\java\org\scilab\contrib\toolboxskeleton\Sum.java; DestDir: {app}\contrib\{#TOOLBOX_SKELETON}\src\java\org\scilab\contrib\toolboxskeleton; Components: {#COMPN_TOOLBOX_SKELETON}
 
 ;--------------------------------------------------------------------------------------------------------------
 #define XCOS_TOOLBOX_SKELETON "xcos_toolbox_skeleton"
index d87fe47..f66ea45 100644 (file)
@@ -2,3 +2,4 @@ scilab_sum - scilab_sum from scilab
 fortran_sum - sum from fortran
 c_sum - sum from C
 c_sub - subtraction from C
+org.scilab.contrib.toolboxskeleton.Sum - Sum from Java
index 4500b70..6ad227b 100644 (file)
@@ -4,7 +4,7 @@
 // This file is released under the 3-clause BSD license. See COPYING-BSD.
 
 function toolbox_skeletonlib = startModule()
-   
+
     TOOLBOX_NAME  = "toolbox_skeleton";
     TOOLBOX_TITLE = "Toolbox Skeleton";
 
@@ -24,17 +24,19 @@ function toolbox_skeletonlib = startModule()
   mprintf("\tLoad macros\n");
   pathmacros = pathconvert( root_tlbx ) + "macros" + filesep();
   toolbox_skeletonlib = lib(pathmacros);
-  
-// load gateways
+
+// load gateways and Java libraries
 // =============================================================================
-  mprintf("\tLoad gateways\n");
   verboseMode = ilib_verbose();
   ilib_verbose(0);
+  mprintf("\tLoad gateways\n");
   exec(pathconvert(root_tlbx+"/sci_gateway/loader_gateway.sce",%f));
+  mprintf("\tLoad Java libraries\n");
+  exec(pathconvert(root_tlbx+"/src/java/loader.sce",%f));
   ilib_verbose(verboseMode);
 
 // load localization
-    addlocalizationdomain(TOOLBOX_NAME, root_tlbx + "/locales");
+  addlocalizationdomain(TOOLBOX_NAME, root_tlbx + "/locales");
 
 // Load and add help chapter
 // =============================================================================
index 9bd10ff..db7ff7f 100644 (file)
@@ -1,7 +1,7 @@
 // This file is released under the 3-clause BSD license. See COPYING-BSD.
 
 function builder_src()
-    langage_src = ["fortran" "c"];
+    langage_src = ["fortran" "c" "java"];
     path_src = get_absolute_file_path("builder_src.sce");
     tbx_builder_src_lang(langage_src, path_src);
 endfunction
diff --git a/scilab/contrib/toolbox_skeleton/src/java/builder_java.sce b/scilab/contrib/toolbox_skeleton/src/java/builder_java.sce
new file mode 100644 (file)
index 0000000..f089090
--- /dev/null
@@ -0,0 +1,25 @@
+// This file is released under the 3-clause BSD license. See COPYING-BSD.
+
+// This macro compiles JAR from Java files
+
+function builder_java()
+    src_java_dir = get_absolute_file_path("builder_java.sce");
+
+    curdir = pwd();
+    cd(src_java_dir);
+
+    jar_dir = fullpath(fullfile(src_java_dir, "../../jar"));
+    if ~isdir(jar_dir)
+        mkdir(jar_dir);
+    end
+
+    package_name = "org.scilab.contrib.toolboxskeleton";
+    jar_file_path = fullfile(jar_dir, package_name + ".jar");
+    ilib_build_jar(jar_file_path, package_name, src_java_dir);
+
+    cd(curdir);
+endfunction
+
+builder_java();
+clear builder_java;
+
diff --git a/scilab/contrib/toolbox_skeleton/src/java/org/scilab/contrib/toolboxskeleton/Sum.java b/scilab/contrib/toolbox_skeleton/src/java/org/scilab/contrib/toolboxskeleton/Sum.java
new file mode 100644 (file)
index 0000000..aa7a7c3
--- /dev/null
@@ -0,0 +1,12 @@
+/* ====================================================================== */
+/* Template toolbox_skeleton */
+/* This file is released under the 3-clause BSD license. See COPYING-BSD. */
+/* ====================================================================== */
+
+package org.scilab.contrib.toolboxskeleton;
+
+public class Sum {
+    public static double sum(double a, double b) {
+        return a + b;
+    }
+}
diff --git a/scilab/contrib/toolbox_skeleton/tests/unit_tests/java_sum.dia.ref b/scilab/contrib/toolbox_skeleton/tests/unit_tests/java_sum.dia.ref
new file mode 100644 (file)
index 0000000..fac83d2
--- /dev/null
@@ -0,0 +1,5 @@
+// This file is released under the 3-clause BSD license. See COPYING-BSD.
+//=================================
+jimport org.scilab.contrib.toolboxskeleton.Sum;
+assert_checkequal(Sum.sum(7.0, 5.0), 12.0);
+//=================================
diff --git a/scilab/contrib/toolbox_skeleton/tests/unit_tests/java_sum.tst b/scilab/contrib/toolbox_skeleton/tests/unit_tests/java_sum.tst
new file mode 100644 (file)
index 0000000..fac83d2
--- /dev/null
@@ -0,0 +1,5 @@
+// This file is released under the 3-clause BSD license. See COPYING-BSD.
+//=================================
+jimport org.scilab.contrib.toolboxskeleton.Sum;
+assert_checkequal(Sum.sum(7.0, 5.0), 12.0);
+//=================================
diff --git a/scilab/modules/dynamic_link/help/en_US/ilib_build_jar.xml b/scilab/modules/dynamic_link/help/en_US/ilib_build_jar.xml
new file mode 100644 (file)
index 0000000..b495ed1
--- /dev/null
@@ -0,0 +1,146 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*
+*  ======================================================================
+*  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+*  Copyright (C) 2013 - Scilab Enterprises - Simon MARCHETTO
+*
+*  This file is distributed under the same license as the Scilab package.
+* =======================================================================
+*
+-->
+<refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:db="http://docbook.org/ns/docbook" version="5.0-subset Scilab" xml:lang="en" xml:id="ilib_build_jar">
+    <refnamediv>
+        <refname>ilib_build_jar</refname>
+        <refpurpose>Build Java packages from sources into a JAR file</refpurpose>
+    </refnamediv>
+    <refsynopsisdiv>
+        <title>Calling Sequence</title>
+        <synopsis>
+            ilib_build_jar(jarFilePath, packageNames[, sourcePath[, classPath, [, manifestFilePath]]])
+        </synopsis>
+    </refsynopsisdiv>
+    <refsection>
+        <title>Parameters</title>
+        <variablelist>
+            <varlistentry>
+                <term>jarFilePath</term>
+                <listitem>
+                    <para>A string, sets the destination file path of the JAR.</para>
+                </listitem>
+            </varlistentry>
+            <varlistentry>
+                <term>packageNames</term>
+                <listitem>
+                    <para>A string matrix, contains the names of packages that will be built and stored the JAR.</para>
+                </listitem>
+            </varlistentry>
+            <varlistentry>
+                <term>sourcePaths</term>
+                <listitem>
+                    <para>A string matrix, sets the paths to the packages Java source directories.</para>
+                </listitem>
+            </varlistentry>
+            <varlistentry>
+                <term>classPaths</term>
+                <listitem>
+                    <para>A string matrix (optional), sets the class paths of the dependencies needed for the build.</para>
+                </listitem>
+            </varlistentry>
+            <varlistentry>
+                <term>manifestFilePath</term>
+                <listitem>
+                    <para>A string (optional), sets the file path of the manifest data to include in the JAR.</para>
+                </listitem>
+            </varlistentry>
+        </variablelist>
+    </refsection>
+    <refsection>
+        <title>Description</title>
+        <para>
+            <literal>ilib_build_jar</literal> extends <link linkend="ilib_build">ilib_build</link>, which purpose is to build C/C++/Fortran libraries, to Java. In other words, <literal>ilib_build_jar</literal> allows to build Java libraries from a set of Java sources. A library in Java is a JAR file (Java archive, extension is <literal>.jar</literal>), which contains Java compiled packages (a Java package contains a set of classes sharing the same purpose), and a manifest file (to describe its content).
+        </para>
+        <para>
+            <literal>ilib_build_jar</literal> works like following. All the Java sources found in the given source directory paths <literal>sourcePaths</literal> are compiled. Then the JAR file specified in <literal>jarFilePath</literal> is created from all the compiled classes of all the packages declared in <literal>packageNames</literal>. <literal>ilib_build_jar</literal> relies on the <link linkend="jcompile">jcompile</link> function for compilation, and <link linkend="jcreatejar">jcreatejar</link> for JAR creation, no external tool is needed.
+        </para>
+        <para>
+            The following Java conventions should be followed when using <literal>ilib_build_jar</literal>.
+            A JAR file usually contains one package only, and its file name is often the same as the package. The Java package is usually organized in a class directory tree, and has a hierarchical naming pattern something like <literal>org.company.software.package</literal>, which the class directory tree follows. Each class location in the tree corresponds to its <literal>package</literal> declaration in the source.
+        </para>
+        <para>
+            <literal>ilib_build_jar</literal> can be used to create a JAR file with several packages, with any desired file name. The only requirement is that one package name at least must be declared, and each of the Java classes should belong to a package.
+        </para>
+        <para>
+            The build dependencies can be specified by setting the <literal>classPaths</literal> argument. It can be paths to JAR files or paths to directories containing Java compiled classes.
+        </para>
+        <para>
+            The file path to a manifest can be given, this one will be stored in the JAR, in the MANIFEST.MF file in META-INF folder. If the manifest file is not specified or does not exist, a default manifest will be created in the JAR. Note: if a manifest is given, it must contain a version attribute, otherwise the manifest in the JAR will be empty.
+        </para>
+    </refsection>
+    <refsection>
+        <title>Examples</title>
+        <programlisting role="example"><![CDATA[
+// Example of ilib_build_jar
+
+// Create org.scilab.test.mypackage package sources in TMPDIR
+packageName = 'org.scilab.test.mypackage';
+packageSrcPath = fullfile(TMPDIR, packageName);
+
+// Create a source file in the package (in org/scilab/test/mypackage folder)
+function addJavaSourceToPackage(className, packageName)
+    packagePath = strsubst(packageName, '.', filesep());
+    packagePath = fullfile(packageSrcPath, packagePath);
+    mkdir(packagePath);
+    filePath = fullfile(packagePath, className + '.java');
+
+    sourceCode = [msprintf('package %s;', packageName); ..
+        msprintf('public class %s {}\n', className);
+        ];
+    fd = mopen(filePath, 'wt');
+    mputl(sourceCode, fd);
+    mclose(fd);
+endfunction
+
+// Add 'Foo' and 'bar.Bar' classes to the package
+addJavaSourceToPackage('Foo', packageName);
+addJavaSourceToPackage('Bar', packageName + '.bar');
+
+// Build the package
+jarFilePath = fullfile(TMPDIR, packageName + '.jar');
+ilib_build_jar(jarFilePath, packageName, packageSrcPath);
+
+// Import and test the package
+javaclasspath(jarFilePath);
+jimport org.scilab.test.mypackage.Foo;
+foo = Foo.new();
+jimport org.scilab.test.mypackage.bar.Bar;
+bar = Bar.new();
+      ]]></programlisting>
+    </refsection>
+    <refsection role="see also">
+        <title>See Also</title>
+        <simplelist type="inline">
+            <member>
+                <link linkend="jcompile">jcompile</link>
+            </member>
+            <member>
+                <link linkend="jcreatejar">jcreatejar</link>
+            </member>
+            <member>
+                <link linkend="javaclasspath">javaclasspath</link>
+            </member>
+        </simplelist>
+    </refsection>
+    <refsection>
+        <title>History</title>
+        <revhistory>
+            <revision>
+                <revnumber>5.5.0</revnumber>
+                <revremark>
+                    Function introduced.
+                </revremark>
+            </revision>
+        </revhistory>
+    </refsection>
+</refentry>
+
diff --git a/scilab/modules/dynamic_link/help/fr_FR/ilib_build_jar.xml b/scilab/modules/dynamic_link/help/fr_FR/ilib_build_jar.xml
new file mode 100644 (file)
index 0000000..ec88238
--- /dev/null
@@ -0,0 +1,145 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*
+*  ======================================================================
+*  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+*  Copyright (C) 2013 - Scilab Enterprises - Simon MARCHETTO
+*
+*  This file is distributed under the same license as the Scilab package.
+* =======================================================================
+*
+-->
+<refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:db="http://docbook.org/ns/docbook" version="5.0-subset Scilab" xml:lang="fr" xml:id="ilib_build_jar">
+    <refnamediv>
+        <refname>ilib_build_jar</refname>
+        <refpurpose>Construit une archive JAR de packages Java</refpurpose>
+    </refnamediv>
+    <refsynopsisdiv>
+        <title>Séquence d'appel</title>
+        <synopsis>
+            ilib_build_jar(jarFilePath, packageNames[, sourcePath[, classPath, [, manifestFilePath]]])
+        </synopsis>
+    </refsynopsisdiv>
+    <refsection>
+        <title>Paramètres</title>
+        <variablelist>
+            <varlistentry>
+                <term>jarFilePath</term>
+                <listitem>
+                    <para>Une chaine de caractères, contenant le chemin d'accès complet du fichier JAR destination.</para>
+                </listitem>
+            </varlistentry>
+            <varlistentry>
+                <term>packageNames</term>
+                <listitem>
+                    <para>Une matrice de chaines de caractères, définissant les noms des packages Java à construire et à stocker dans le fichier JAR.</para>
+                </listitem>
+            </varlistentry>
+            <varlistentry>
+                <term>sourcePaths</term>
+                <listitem>
+                    <para>Une matrice de chaines de caractères, contenant les chemins d'accès des répertoires contenant les sources Java.</para>
+                </listitem>
+            </varlistentry>
+            <varlistentry>
+                <term>classPaths</term>
+                <listitem>
+                    <para>Une matrice de chaines de caractères (optionelle), qui contient les chemins d'accès des dépendences de compilation.</para>
+                </listitem>
+            </varlistentry>
+            <varlistentry>
+                <term>manifestFilePath</term>
+                <listitem>
+                    <para>Une chaine de caractères, (optionelle), contenant le chemin d'accès complet d'un fichier manifeste à inclure dans le fichier JAR.</para>
+                </listitem>
+            </varlistentry>
+        </variablelist>
+    </refsection>
+    <refsection>
+        <title>Description</title>
+        <para>
+            <literal>ilib_build_jar</literal> étend au language Java la fonction <link linkend="ilib_build">ilib_build</link>, qui sert à construire des libraries C/C++/Fortran. En d'autres termes, <literal>ilib_build_jar</literal> permet de construire des librairies Java à partir de sources Java. En Java, une librairie est un fichier JAR (archive Java, dont l'extension est <literal>.jar</literal>), qui contient des packages Java compilés (un package Java regroupe un ensemble de classes) et un fichier manifeste, qui décrit le contenu du fichier JAR.
+        </para>
+        <para>
+            <literal>ilib_build_jar</literal> fonctionne comme suit. Tous les fichiers sources Java trouvés dans les chemins de répertoires donnés par l'argument <literal>sourcePaths</literal> sont compilés. Ensuite le fichier JAR cible dont le chemin est donné par l'argument <literal>jarFilePath</literal> est créé à partir de toutes les classes compilées correspondant aux packages déclarés dans l'argument <literal>packageNames</literal>. <literal>ilib_build_jar</literal> se base sur la fonction <link linkend="jcompile">jcompile</link> pour la compilation et sur <link linkend="jcreatejar">jcreatejar</link> pour la création d'archive JAR. Aucun autre outil externe supplémentaire n'est requis.
+        </para>
+        <para>
+            Rappelons quelques informations à propos des packages Java, essentielles pour utiliser <literal>ilib_build_jar</literal>.
+            Les pakages Java sont structurés de façon hiérarchique, et Java impose que l'emplacement des fichiers sources correspond à la hiérarchie des packages, par exemple un package portant le nom monpackage doit être stocké dans un répertoire du même nom.
+            La convention est qu'un fichier JAR contient habituellement une seule hiérarchie de packages Java, et son nom de fichier correspond au nom de package racine, qui sera de type <literal>org.company.software.package</literal>.
+            <literal>ilib_build_jar</literal> peut être utilisée pour créer un fichier JAR contenant plusieurs hiérarchies de packages Java, avec un nom de fichier arbitraire. Les seules obligations sont qu'un nom de package au moins doit être déclaré à <literal>ilib_build_jar</literal>, et que chacune des classes Java doit appartenir à un package.
+        </para>
+        <para>
+            Les dépendances nécessaires pour la compilation peuvent être déclarées dans l'argument <literal>classPaths</literal>. Cela peut être des chemins complets à des fichiers JAR contenant des packages Java, ou à des répertoires contenant des classes Java compilées.
+        </para>
+        <para>
+            On peut aussi spécifier un chemin d'accès à un fichier manifeste, via l'argument <literal>manifestFilePath</literal>, dont les données seront stockées dans le fichier JAR, dans le fichier <literal>MANIFEST.MF</literal>, dans le sous-répertoire <literal>META-INF</literal>. Si le fichier manifeste n'est pas spécifié ou n'existe pas, un manifeste sera créé par défaut. Note: si on spécifie un manifeste, celui doit contenir un attribut de version, autrement le manifeste dans le fichier JAR risque d'être vide.
+        </para>
+    </refsection>
+    <refsection>
+        <title>Exemples</title>
+        <programlisting role="example"><![CDATA[
+// Exemple pour ilib_build_jar
+
+// Crée les sources du package org.scilab.test.mypackage package dans TMPDIR
+packageName = 'org.scilab.test.mypackage';
+packageSrcPath = fullfile(TMPDIR, packageName);
+
+// Crée un fichier source du package (dans le répertoire org/scilab/test/mypackage)
+function addJavaSourceToPackage(className, packageName)
+    packagePath = strsubst(packageName, '.', filesep());
+    packagePath = fullfile(packageSrcPath, packagePath);
+    mkdir(packagePath);
+    filePath = fullfile(packagePath, className + '.java');
+
+    sourceCode = [msprintf('package %s;', packageName); ..
+        msprintf('public class %s {}\n', className);
+        ];
+    fd = mopen(filePath, 'wt');
+    mputl(sourceCode, fd);
+    mclose(fd);
+endfunction
+
+// Ajoute les classes 'Foo' and 'bar.Bar' au package
+addJavaSourceToPackage('Foo', packageName);
+addJavaSourceToPackage('Bar', packageName + '.bar');
+
+// Construit le package
+jarFilePath = fullfile(TMPDIR, packageName + '.jar');
+ilib_build_jar(jarFilePath, packageName, packageSrcPath);
+
+// Import et teste la package
+javaclasspath(jarFilePath);
+jimport org.scilab.test.mypackage.Foo;
+foo = Foo.new();
+jimport org.scilab.test.mypackage.bar.Bar;
+bar = Bar.new();
+      ]]></programlisting>
+    </refsection>
+    <refsection role="see also">
+        <title>Voir aussi</title>
+        <simplelist type="inline">
+            <member>
+                <link linkend="jcompile">jcompile</link>
+            </member>
+            <member>
+                <link linkend="jcreatejar">jcreatejar</link>
+            </member>
+            <member>
+                <link linkend="javaclasspath">javaclasspath</link>
+            </member>
+        </simplelist>
+    </refsection>
+    <refsection>
+        <title>Historique</title>
+        <revhistory>
+            <revision>
+                <revnumber>5.5.0</revnumber>
+                <revremark>
+                    Fonction introduite.
+                </revremark>
+            </revision>
+        </revhistory>
+    </refsection>
+</refentry>
+
diff --git a/scilab/modules/dynamic_link/macros/ilib_build_jar.sci b/scilab/modules/dynamic_link/macros/ilib_build_jar.sci
new file mode 100644 (file)
index 0000000..a91bc1d
--- /dev/null
@@ -0,0 +1,286 @@
+// ====================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2013 - Scilab Enterprises
+//
+// This file must be used under the terms of the CeCILL.
+// This source file is licensed as described in the file COPYING, which
+// you should have received as part of this distribution.  The terms
+// are also available at
+// http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
+// =====================================================================
+
+// Builds a Java package (JAR) from a set of Java sources (see SEP #116)
+// - jarFilePath: is the JAR target file path
+// - packageNames: names of packages to archive in the JAR
+// - sourcePaths: paths to directories containing Java sources
+// - classPaths (optional): paths to dependencies (JARs or directories)
+// - manifestFilePath (optional) : file path to manifest
+function ilib_build_jar(jarFilePath, packageNames, sourcePaths, classPaths, manifestFilePath)
+
+    // Returns all the java source files contained in a path tree
+    function javaFilePaths = findJavaFiles(path, javaFilePaths)
+        fileNames = listfiles(path)';
+        filePaths = fullfile(path, fileNames);
+
+        // First, explore sub directories
+        dirPaths = filePaths(find(isdir(filePaths)));
+        for i = 1:size(dirPaths, '*')
+            javaFilePaths = [javaFilePaths; findJavaFiles(dirPaths(i), [])];
+        end
+
+        // Then add Java files of that directory
+        dirJavaFilePaths = filePaths(find(fileext(filePaths) == '.java'));
+        javaFilePaths = [javaFilePaths; dirJavaFilePaths'];
+    endfunction
+
+    // Returns the JIMS build root path
+    // It is the JIMS/bin folder in TMPDIR
+    function jimsBuildPath = getJimsBuildPath()
+        jimsBuildPath = fullfile(TMPDIR, "JIMS/bin");
+    endfunction
+
+    // Returns the package compilation path
+    // It is the 'deepest' directory containing the built classes
+    // if package is 'com.foo.package' the returned path will be:
+    //   TMPDIR/JIMS/bin/com/foo/package
+    function packageCompilePath = getPackageCompilePath(packageName)
+        packageSubPath = strsubst(packageName, '.', filesep());
+        packageCompilePath = fullfile(getJimsBuildPath(), packageSubPath);
+    endfunction
+
+    // Returns the jar root input path
+    // It is the directory that will be jar-ed
+    // if jar is 'com.foo.package' the returned path will be:
+    //   TMPDIR/JIMS/bin/com.foo.package
+    function jarInputRootPath = getJarInputRootPath(jarName)
+        jarInputRootPath = fullfile(getJimsBuildPath(), '_jar_' + jarName);
+        if isdir(jarInputRootPath) then
+            removedir(jarInputRootPath);
+        end
+        mkdir(jarInputRootPath);
+    endfunction
+
+    // Returns the package path in the jar input path
+    // It is the directory where the classes will be copied
+    // if package is 'com.foo.package' the returned path will be:
+    //   TMPDIR/JIMS/com.foo.package/bin/com/foo/package
+    function jarInputPackagePath = getJarPackagePath(jarInputRootPath, packageName)
+        if ~isempty(packageName) then
+            packagePath = strsubst(packageName, '.', filesep());
+            jarInputPackagePath = fullfile(jarInputRootPath, packagePath);
+            mkdir(jarInputPackagePath);
+        else
+            jarInputPackagePath = jarInputRootPath;
+        end
+    endfunction
+
+    // Add header instructions for loader and cleaner script (license info, change dir, etc..)
+    function addHeaderToScript(scriptName, fd)
+        mputl('// This file is released under the 3-clause BSD license. See COPYING-BSD.', fd);
+        mputl('// Generated by builder.sce: Please, do not edit this file.', fd);
+        mputl('// ------------------------------------------------------', fd);
+        mputl('curdir = pwd();', fd);
+        mputl(msprintf('scriptdir = get_file_path(''%s'');', scriptName), fd);
+        mputl(msprintf('chdir(scriptdir);'), fd);
+        mputl('// ------------------------------------------------------', fd);
+    endfunction
+
+    // Add footer instructions for loader and cleaner script (restore dir, etc..)
+    function addFooterToScript(fd)
+        mputl('// ------------------------------------------------------', fd);
+        mputl('chdir(curdir);', fd);
+        mputl('clear curdir;', fd);
+    endfunction
+
+    // Creates a loader script (loader.sce)
+    // Does the javaclasspath on the created jar file
+    function createLoaderScript(loaderScriptName, jarFilePath)
+        fd = mopen(loaderScriptName, 'wt');
+        addHeaderToScript(loaderScriptName, fd);
+        mputl(msprintf('jarFilePath = fullfile(scriptdir, ''%s'');', jarFilePath), fd);
+        mputl('javaclasspath(fullpath(jarFilePath));', fd);
+        addFooterToScript(fd);
+        mclose(fd);
+    endfunction
+
+    // Creates a cleaner script (cleaner.sce)
+    // Deletes the loader script and jar file
+    function createCleanerScript(cleanerScriptName, loaderScriptName, jarFilePath)
+        fd = mopen(cleanerScriptName, 'wt');
+        addHeaderToScript(cleanerScriptName, fd);
+        mputl(msprintf('if fileinfo(''%s'') <> [] then', loaderScriptName), fd');
+        mputl(msprintf('    mdelete(''%s'');', loaderScriptName), fd);
+        mputl('end', fd);
+        mputl('// ------------------------------------------------------', fd);
+        mputl(msprintf('jarFilePath = fullfile(scriptdir, ''%s'');', jarFilePath), fd);
+        mputl('if fileinfo(jarFilePath) <> [] then', fd);
+        mputl('    mdelete(jarFilePath);', fd);
+        mputl('end', fd);
+        addFooterToScript(fd);
+        mclose(fd);
+    endfunction
+
+
+    // ilib_build_jar body
+
+    // ilib_build_jar needs Java, it is not usable in NWNI mode
+    if (getscilabmode() == "NWNI")
+        error(msprintf(_("%s: function not available in NWNI mode.\n"), "ilib_build_jar"));
+        return;
+    end
+
+    // Check input arguments
+    [lhs, rhs] = argn(0);
+    if rhs < 3 then
+        error(msprintf(_("%s: Wrong number of input argument(s): 3 to 5 expected.\n"), "ilib_build_jar"));
+        return;
+    end
+
+    // Input argument 1: jar file path
+    if type(jarFilePath) <> 10 then
+        error(999, msprintf(_("%s: Wrong type for input argument #%d: A string expected.\n"), "ilib_build_jar", 1));
+    end
+    if size(jarFilePath, "*") <> 1 then
+        error(999, msprintf(_("%s: Wrong size for input argument #%d: A string expected.\n"), "ilib_build_jar", 1));
+        return;
+    end
+
+    // Input argument 2: package names
+    if rhs > 2 then
+        if type(packageNames) <> 10 then
+            error(999, msprintf(_("%s: Wrong type for input argument #%d: A matrix of strings expected.\n"), "ilib_build_jar", 2));
+            return;
+        end
+    end
+
+    // Input argument 3: source paths
+    if type(sourcePaths) <> 10 then
+        error(999, msprintf(_("%s: Wrong type for input argument #%d: A matrix of strings expected.\n"), "ilib_build_jar", 3));
+        return;
+    end
+
+    // Input argument 4 (optional): class paths
+    if rhs > 3 then
+        if type(classPaths) <> 10 then
+            error(999, msprintf(_("%s: Wrong type for input argument #%d: A matrix of strings expected.\n"), "ilib_build_jar", 4));
+            return;
+        end
+    else
+        classPaths = '';
+    end
+
+    // Input argument 5 (optional): manifest file path
+    if rhs > 4 then
+        if type(manifestFilePath) <> 10 then
+            error(999, msprintf(_("%s: Wrong type for input argument #%d: A matrix of strings expected.\n"), "ilib_build_jar", 5));
+            return;
+        end
+    else
+        manifestFilePath = '';
+    end
+
+    [jarDir, jarName] = fileparts(jarFilePath);
+
+    if (ilib_verbose() <> 0) then
+        mprintf(_("   Building JAR library %s\n"), jarName + '.jar');
+    end
+
+    // Create a directory for jar creation
+    jarInputRootPath = getJarInputRootPath(jarName);
+    if ~isdir(jarInputRootPath) then
+        error(msprintf(_("Cannot create jar build dir %s"), jarInputRootPath));
+        return;
+    end
+
+    // Dependencies
+    if ~isempty(classPaths) then
+        if (ilib_verbose() == 2) then
+            mprintf(_("   Add dependency class paths:\n%s\n"), classPaths);
+        end
+        javaclasspath(classPaths);
+    end
+
+    nbPackages = size(packageNames, '*');
+    for i = 1:nbPackages
+        packageName = packageNames(i);
+        if (ilib_verbose() == 2) then
+            mprintf(_("   Build package %s\n"), packageName);
+        end
+
+        // Delete each package compilation directory if exists
+        packageCompilePath = getPackageCompilePath(packageName);
+        if isdir(packageCompilePath) then
+            removedir(packageCompilePath);
+        end
+
+        // Find all Java sources for that package and compile
+        sourcePath = sourcePaths(i);
+        javaFilePaths = findJavaFiles(sourcePath, []);
+        if javaFilePaths <> [] then
+            if (ilib_verbose() == 2) then
+                mprintf(_("   Compiling source files:\n"));
+                disp(javaFilePaths);
+            elseif (ilib_verbose() == 1) then
+                mprintf(_("   Compiling Java sources in %s\n"), sourcePath);
+            end
+            jcompile(javaFilePaths);
+        else
+            if (ilib_verbose() <> 0) then
+                warning(msprintf(_("No Java sources in %s to compile for package %s"), sourcePath, packageName));
+            end
+        end
+
+        // Copy package compiled classes ...
+        packageCompilePath = getPackageCompilePath(packageName);
+        if isdir(packageCompilePath) then
+            // ... to its location in JAR
+            jarInputPackagePath = getJarPackagePath(jarInputRootPath, packageName);
+            if ~isdir(jarInputPackagePath) then
+                error(msprintf(_("Cannot create jar package directory %s"), jarInputRootPath));
+            end
+
+            if (ilib_verbose() == 2) then
+                mprintf(_("   Copying compiled package from %s to %s\n"), packageCompilePath, jarInputPackagePath);
+            end
+            copyfile(packageCompilePath, jarInputPackagePath);
+        else
+            if (ilib_verbose() <> 0) then
+                warning(msprintf(_("Cannot find compilation directory %s for package %s"), packageCompilePath, packageName));
+            end
+        end
+    end
+
+    // Delete target jar if already exists
+    if isfile(jarFilePath) then
+        deletefile(jarFilePath);
+    end
+
+    // Create jar
+    if (ilib_verbose() <> 0) then
+        mprintf(_("   Creating JAR archive %s\n"), jarFilePath);
+    end
+    jcreatejar(jarFilePath, jarInputRootPath, '', manifestFilePath);
+    if ~isfile(jarFilePath) then
+        error(msprintf(_("Cannot create JAR file %s"), jarFilePath));
+    end
+
+    // Creates script
+    jarFileRelativePath = getrelativefilename(pwd(), jarFilePath);
+    if (ilib_verbose() == 2) then
+        mprintf(_("   Creating scripts for JAR relative path %s\n"), jarFileRelativePath);
+    end
+
+    // Creates loader script
+    loaderScriptName = 'loader.sce';
+    if (ilib_verbose() <> 0) then
+        mprintf(_("   Create loader script for Java %s\n"), loaderScriptName);
+    end
+    createLoaderScript(loaderScriptName, jarFileRelativePath);
+
+    // Creates cleaner script
+    cleanerScriptName = 'cleaner.sce';
+    if (ilib_verbose() <> 0) then
+        mprintf(_("   Create cleaner script for Java %s\n"), cleanerScriptName);
+    end
+    createCleanerScript(cleanerScriptName, loaderScriptName, jarFileRelativePath);
+endfunction
diff --git a/scilab/modules/dynamic_link/tests/unit_tests/ilib_build_jar.dia.ref b/scilab/modules/dynamic_link/tests/unit_tests/ilib_build_jar.dia.ref
new file mode 100644 (file)
index 0000000..784feca
--- /dev/null
@@ -0,0 +1,220 @@
+// ======================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2013 - Scilab Enterprises - Simon MARCHETTO
+//
+//  This file is distributed under the same license as the Scilab package.
+// =======================================================================
+// Save original env
+origDir = pwd();
+verbose = ilib_verbose();
+testRootDir = fullfile(TMPDIR, "ilib_build_jar");
+mkdir(testRootDir);
+cd(testRootDir);
+ilib_verbose(0);
+// Creates a sub directory of a parent dir, cleans it if exist
+function path = createSubDir(parentDir, subDir, removeExistingDir)
+    path = fullfile(parentDir, subDir);
+    if isdir(path) & removeExistingDir then
+        removedir(path);
+    end
+    mkdir(path);
+endfunction
+// Create a Java class source code for a specified package, eventually containing an import directive
+function sourceCode = createSourceCode(className, packageName, importPackageName)
+    sourceCode = msprintf('package %s;\n', packageName);
+    if ~isempty(importPackageName) then
+        sourceCode = [sourceCode; msprintf('import %s.*;\n', importPackageName)]
+    end
+    sourceCode = [sourceCode; msprintf('public class %s {}\n', className)];
+endfunction
+// Adds a Java class source file in a specified package source tree
+function filePath = addSourceToPackage(className, packageName, packageSrcPath, sourceCode)
+    if ~isempty(packageName) then
+        packagePath = strsubst(packageName, '.', filesep());
+        path = createSubDir(packageSrcPath, packagePath, %F);
+    else
+        path = packageSrcPath;
+    end
+    filePath = fullfile(path, className + '.java');
+    fd = mopen(filePath, 'wt');
+    if isempty(sourceCode) then
+        sourceCode = createSourceCode(className, packageName, '');
+    end
+    mputl(sourceCode, fd);
+    mclose(fd);
+endfunction
+// Checks the import of a specified class
+function checkImportClass(expectedClassName)
+    classobj = jimport(expectedClassName, %f);
+    aclass = classobj.class;
+    className = aclass.getName(jvoid);
+    assert_checkequal(className, expectedClassName);
+endfunction
+// Checks the specified JAR package contains the expected classes (with an import)
+function checkJar(jarFilePath, packageNames, expectedClassNames)
+    javaclasspath(jarFilePath);
+    for i = 1:size(packageNames, 'r')
+        for j = 1:size(expectedClassNames, 'c')
+            checkImportClass(packageNames(i, 1) + '.' + expectedClassNames(i, j));
+        end
+    end
+endfunction
+// Checks the specified JAR build command provokes an error
+function checkCompileError(buildJarCmd)
+    compileError = msprintf(_('jcompile: An error occured: Cannot compile the code'));
+    execstr(buildJarCmd, 'errcatch');
+    errMsg = lasterror();
+    assert_checktrue(errMsg <> []);
+    assert_checktrue(strstr(errMsg, compileError) <> []);
+endfunction
+// Creates a small JAR containing 1 package and 1 class
+function jarFilePath = buildJar1Package1Class(packageName, className, rootPath, sourceCode)
+    packageSrcPath = createSubDir(testRootDir, packageName, %T);
+    jarFilePath = fullfile(testRootDir, packageName + '.jar');
+    addSourceToPackage(className, packageName, packageSrcPath, '');
+    ilib_build_jar(jarFilePath, packageName, packageSrcPath);
+endfunction
+// Chekcs content and execution of loader script loader.sce
+function checkLoaderScript(loaderScriptName, jarFilePath, expectedClassName)
+    loaderScriptPath = fullpath(loaderScriptName);
+    // Check code
+    expectedLoaderCode = [ ..
+        '// This file is released under the 3-clause BSD license. See COPYING-BSD.'; ..
+        '// Generated by builder.sce: Please, do not edit this file.'; ..
+        '// ------------------------------------------------------'; ..
+        'curdir = pwd();'; ..
+        msprintf('scriptdir = get_file_path(''%s'');', loaderScriptName); ..
+        'chdir(scriptdir);'; ..
+        '// ------------------------------------------------------'; ..
+        msprintf('jarFilePath = fullfile(scriptdir, ''%s'');', jarFilePath); ..
+        'javaclasspath(fullpath(jarFilePath));'; ..
+        '// ------------------------------------------------------'; ..
+        'chdir(curdir);'; ..
+        'clear curdir;' ..
+        ];
+    loaderCode = mgetl(loaderScriptPath);
+    assert_checkequal(loaderCode, expectedLoaderCode);
+    // Check execution result
+    res = exec(loaderScriptPath, 'errcatch');
+    assert_checkequal(res, 0);
+    checkImportClass(expectedClassName);
+endfunction
+// Checks content and execution of cleaner script cleaner.sce
+function checkCleanerScript(cleanerScriptName, loaderScriptName, jarFilePath)
+    cleanerScriptPath = fullpath(cleanerScriptName);
+    loaderScriptPath = fullpath(loaderScriptName);
+    // Check code
+    expectedCleanerCode = [ ..
+        '// This file is released under the 3-clause BSD license. See COPYING-BSD.'; ..
+        '// Generated by builder.sce: Please, do not edit this file.'; ..
+        '// ------------------------------------------------------'; ..
+        'curdir = pwd();'; ..
+        msprintf('scriptdir = get_file_path(''%s'');', cleanerScriptName); ..
+        'chdir(scriptdir);'; ..
+        '// ------------------------------------------------------'; ..
+        msprintf('if fileinfo(''%s'') <> [] then', loaderScriptName); ..
+        msprintf('    mdelete(''%s'');', loaderScriptName); ..
+        'end'; ..
+        '// ------------------------------------------------------'; ..
+        msprintf('jarFilePath = fullfile(scriptdir, ''%s'');', jarFilePath); ..
+        'if fileinfo(jarFilePath) <> [] then'; ..
+        '    mdelete(jarFilePath);'; ..
+        'end'; ..
+        '// ------------------------------------------------------'; ..
+        'chdir(curdir);'; ..
+        'clear curdir;' ..
+        ];
+    cleanerCode = mgetl(cleanerScriptPath);
+    assert_checkequal(cleanerCode, expectedCleanerCode);
+    // Check execution result
+    res = exec(cleanerScriptPath, 'errcatch');
+    assert_checkequal(res, 0);
+    assert_checkfalse(isfile(loaderScriptPath));
+    // A loaded JAR file is locked by the JVM and cannot be deleted (Java 6 issue).
+    //assert_checkfalse(isfile(jarFilePath));
+endfunction
+// TEST JAR BUILD
+// Test build a JAR of a simple package with one class
+packageName = 'testpackage';
+className = 'Foo';
+jarFilePath = buildJar1Package1Class(packageName, className, testRootDir, '');
+checkJar(jarFilePath, packageName, className);
+// Test build a JAR of a package with two classes
+packageName = 'testpackage2';
+packageSrcPath = createSubDir(testRootDir, packageName, %T);
+jarFilePath = fullfile(testRootDir, packageName + '.jar');
+addSourceToPackage('Foo1', packageName, packageSrcPath, '');
+addSourceToPackage('Foo2', packageName, packageSrcPath, '');
+ilib_build_jar(jarFilePath, packageName, packageSrcPath);
+checkJar(jarFilePath, packageName, ['Foo1', 'Foo2']);
+// Test build a JAR of one 'standard' package
+packageName = 'org.scilab.test.mypackage';
+packageSrcPath = createSubDir(testRootDir, packageName, %T);
+jarFilePath = fullfile(testRootDir, packageName + '.jar');
+addSourceToPackage('Foo1', packageName, packageSrcPath, '');
+addSourceToPackage('Foo2', packageName + '.folder', packageSrcPath, '');
+ilib_build_jar(jarFilePath, packageName, packageSrcPath);
+checkJar(jarFilePath, packageName, ['Foo1', 'folder.Foo2']);
+// Test build a JAR of two packages
+jarFilePath = fullfile(testRootDir, 'testmultipackages.jar');
+// package1
+packageName1 = 'org.scilab.test.package1';
+package1SrcPath = createSubDir(testRootDir, packageName1, %T);
+addSourceToPackage('Foo1', packageName1, package1SrcPath, '');
+addSourceToPackage('Foo2', packageName1 + '.folder', package1SrcPath, '');
+// package2
+packageName2 = 'org.scilab.test.package2';
+package2SrcPath = createSubDir(testRootDir, packageName2, %T);
+addSourceToPackage('FooA', packageName2, package2SrcPath, '');
+addSourceToPackage('FooB', packageName2 + '.folder', package2SrcPath, '');
+// build
+ilib_build_jar(jarFilePath, [packageName1, packageName2], [package1SrcPath, package2SrcPath]);
+checkJar(jarFilePath, [packageName1; packageName2], ['Foo1', 'folder.Foo2'; 'FooA', 'folder.FooB']);
+// Test compilation errors
+packageName = 'testpackagecompileerrors';
+packageSrcPath = createSubDir(testRootDir, packageName, %T);
+jarFilePath = fullfile(testRootDir, packageName + '.jar');
+className = '1234';
+sourceCode = createSourceCode(className, packageName, '');
+javaFilePath = addSourceToPackage(className, packageName, packageSrcPath);
+checkCompileError("ilib_build_jar(jarFilePath, packageName, packageSrcPath)");
+// TEST LOADER AND CLEANER SCRIPTS
+packageName = 'dummypackage';
+className = 'Foo';
+jarFilePath = buildJar1Package1Class(packageName, className, testRootDir, '');
+checkLoaderScript('loader.sce', 'dummypackage.jar', 'dummypackage.Foo');
+checkCleanerScript('cleaner.sce', 'loader.sce', 'dummypackage.jar');
+// TEST OPTIONAL ARGUMENTS
+// Test dependency packages argument
+// create dependency package (in another directory, so that it is not in classpath)
+dependencyPackageName = 'dependencypackage';
+dependencyJarFilePath = buildJar1Package1Class(dependencyPackageName, 'Dummy', '');
+// remove dependency package class directory, because it is in class path
+jimsBinPath = fullfile(TMPDIR, 'JIMS/bin');
+removedir(fullfile(jimsBinPath, dependencyPackageName));
+// create package that uses the dependency
+packageName = 'testpackagedependencies';
+packageSrcPath = createSubDir(testRootDir, packageName, %T);
+jarFilePath = fullfile(testRootDir, packageName + '.jar');
+className = 'Bar';
+sourceCode = createSourceCode(className, packageName, dependencyPackageName);
+// check compile error without specifying dependency
+addSourceToPackage(className, packageName, packageSrcPath, sourceCode);
+checkCompileError("ilib_build_jar(jarFilePath, packageName, packageSrcPath)");
+// check it is ok with specifying dependency
+ilib_build_jar(jarFilePath, packageName, packageSrcPath, dependencyJarFilePath);
+checkJar(jarFilePath, packageName, className);
+// TEST TOOLBOX SKELETON
+// Build toolbox skeleton java code and run unit test
+toolboxSkeletonSrcPath = fullfile(SCI, "contrib", "toolbox_skeleton");
+toolboxSkeletonPath = fullfile(testRootDir, "toolbox_skeleton");
+copyfile(toolboxSkeletonSrcPath, toolboxSkeletonPath);
+javaBuilderPath = fullfile(toolboxSkeletonPath, "src", "java", "builder_java.sce");
+exec(javaBuilderPath);
+javaLoaderPath = fullfile(toolboxSkeletonPath, "src", "java", "loader.sce");
+exec(javaLoaderPath);
+javaTestPath = fullfile(toolboxSkeletonPath, "tests", "unit_tests", "java_sum.tst");
+exec(javaTestPath);
+// Restore original env
+cd(origDir);
+ilib_verbose(verbose);
diff --git a/scilab/modules/dynamic_link/tests/unit_tests/ilib_build_jar.tst b/scilab/modules/dynamic_link/tests/unit_tests/ilib_build_jar.tst
new file mode 100644 (file)
index 0000000..8e03b33
--- /dev/null
@@ -0,0 +1,257 @@
+// ======================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2013 - Scilab Enterprises - Simon MARCHETTO
+//
+//  This file is distributed under the same license as the Scilab package.
+// =======================================================================
+
+// Save original env
+origDir = pwd();
+verbose = ilib_verbose();
+
+testRootDir = fullfile(TMPDIR, "ilib_build_jar");
+mkdir(testRootDir);
+cd(testRootDir);
+
+ilib_verbose(0);
+
+// Creates a sub directory of a parent dir, cleans it if exist
+function path = createSubDir(parentDir, subDir, removeExistingDir)
+    path = fullfile(parentDir, subDir);
+    if isdir(path) & removeExistingDir then
+        removedir(path);
+    end
+    mkdir(path);
+endfunction
+
+// Create a Java class source code for a specified package, eventually containing an import directive
+function sourceCode = createSourceCode(className, packageName, importPackageName)
+    sourceCode = msprintf('package %s;\n', packageName);
+    if ~isempty(importPackageName) then
+        sourceCode = [sourceCode; msprintf('import %s.*;\n', importPackageName)]
+    end
+    sourceCode = [sourceCode; msprintf('public class %s {}\n', className)];
+endfunction
+
+// Adds a Java class source file in a specified package source tree
+function filePath = addSourceToPackage(className, packageName, packageSrcPath, sourceCode)
+    if ~isempty(packageName) then
+        packagePath = strsubst(packageName, '.', filesep());
+        path = createSubDir(packageSrcPath, packagePath, %F);
+    else
+        path = packageSrcPath;
+    end
+
+    filePath = fullfile(path, className + '.java');
+
+    fd = mopen(filePath, 'wt');
+    if isempty(sourceCode) then
+        sourceCode = createSourceCode(className, packageName, '');
+    end
+    mputl(sourceCode, fd);
+    mclose(fd);
+endfunction
+
+// Checks the import of a specified class
+function checkImportClass(expectedClassName)
+    classobj = jimport(expectedClassName, %f);
+    aclass = classobj.class;
+    className = aclass.getName(jvoid);
+    assert_checkequal(className, expectedClassName);
+endfunction
+
+// Checks the specified JAR package contains the expected classes (with an import)
+function checkJar(jarFilePath, packageNames, expectedClassNames)
+    javaclasspath(jarFilePath);
+    for i = 1:size(packageNames, 'r')
+        for j = 1:size(expectedClassNames, 'c')
+            checkImportClass(packageNames(i, 1) + '.' + expectedClassNames(i, j));
+        end
+    end
+endfunction
+
+// Checks the specified JAR build command provokes an error
+function checkCompileError(buildJarCmd)
+    compileError = msprintf(_('jcompile: An error occured: Cannot compile the code'));
+    execstr(buildJarCmd, 'errcatch');
+    errMsg = lasterror();
+    assert_checktrue(errMsg <> []);
+    assert_checktrue(strstr(errMsg, compileError) <> []);
+endfunction
+
+// Creates a small JAR containing 1 package and 1 class
+function jarFilePath = buildJar1Package1Class(packageName, className, rootPath, sourceCode)
+    packageSrcPath = createSubDir(testRootDir, packageName, %T);
+    jarFilePath = fullfile(testRootDir, packageName + '.jar');
+    addSourceToPackage(className, packageName, packageSrcPath, '');
+    ilib_build_jar(jarFilePath, packageName, packageSrcPath);
+endfunction
+
+// Chekcs content and execution of loader script loader.sce
+function checkLoaderScript(loaderScriptName, jarFilePath, expectedClassName)
+    loaderScriptPath = fullpath(loaderScriptName);
+
+    // Check code
+    expectedLoaderCode = [ ..
+        '// This file is released under the 3-clause BSD license. See COPYING-BSD.'; ..
+        '// Generated by builder.sce: Please, do not edit this file.'; ..
+        '// ------------------------------------------------------'; ..
+        'curdir = pwd();'; ..
+        msprintf('scriptdir = get_file_path(''%s'');', loaderScriptName); ..
+        'chdir(scriptdir);'; ..
+        '// ------------------------------------------------------'; ..
+        msprintf('jarFilePath = fullfile(scriptdir, ''%s'');', jarFilePath); ..
+        'javaclasspath(fullpath(jarFilePath));'; ..
+        '// ------------------------------------------------------'; ..
+        'chdir(curdir);'; ..
+        'clear curdir;' ..
+        ];
+    loaderCode = mgetl(loaderScriptPath);
+    assert_checkequal(loaderCode, expectedLoaderCode);
+
+    // Check execution result
+    res = exec(loaderScriptPath, 'errcatch');
+    assert_checkequal(res, 0);
+    checkImportClass(expectedClassName);
+endfunction
+
+// Checks content and execution of cleaner script cleaner.sce
+function checkCleanerScript(cleanerScriptName, loaderScriptName, jarFilePath)
+    cleanerScriptPath = fullpath(cleanerScriptName);
+    loaderScriptPath = fullpath(loaderScriptName);
+
+    // Check code
+    expectedCleanerCode = [ ..
+        '// This file is released under the 3-clause BSD license. See COPYING-BSD.'; ..
+        '// Generated by builder.sce: Please, do not edit this file.'; ..
+        '// ------------------------------------------------------'; ..
+        'curdir = pwd();'; ..
+        msprintf('scriptdir = get_file_path(''%s'');', cleanerScriptName); ..
+        'chdir(scriptdir);'; ..
+        '// ------------------------------------------------------'; ..
+        msprintf('if fileinfo(''%s'') <> [] then', loaderScriptName); ..
+        msprintf('    mdelete(''%s'');', loaderScriptName); ..
+        'end'; ..
+        '// ------------------------------------------------------'; ..
+        msprintf('jarFilePath = fullfile(scriptdir, ''%s'');', jarFilePath); ..
+        'if fileinfo(jarFilePath) <> [] then'; ..
+        '    mdelete(jarFilePath);'; ..
+        'end'; ..
+        '// ------------------------------------------------------'; ..
+        'chdir(curdir);'; ..
+        'clear curdir;' ..
+        ];
+    cleanerCode = mgetl(cleanerScriptPath);
+
+    assert_checkequal(cleanerCode, expectedCleanerCode);
+
+    // Check execution result
+    res = exec(cleanerScriptPath, 'errcatch');
+    assert_checkequal(res, 0);
+    assert_checkfalse(isfile(loaderScriptPath));
+    // A loaded JAR file is locked by the JVM and cannot be deleted (Java 6 issue).
+    //assert_checkfalse(isfile(jarFilePath));
+endfunction
+
+
+// TEST JAR BUILD
+
+// Test build a JAR of a simple package with one class
+packageName = 'testpackage';
+className = 'Foo';
+jarFilePath = buildJar1Package1Class(packageName, className, testRootDir, '');
+checkJar(jarFilePath, packageName, className);
+
+// Test build a JAR of a package with two classes
+packageName = 'testpackage2';
+packageSrcPath = createSubDir(testRootDir, packageName, %T);
+jarFilePath = fullfile(testRootDir, packageName + '.jar');
+addSourceToPackage('Foo1', packageName, packageSrcPath, '');
+addSourceToPackage('Foo2', packageName, packageSrcPath, '');
+ilib_build_jar(jarFilePath, packageName, packageSrcPath);
+checkJar(jarFilePath, packageName, ['Foo1', 'Foo2']);
+
+// Test build a JAR of one 'standard' package
+packageName = 'org.scilab.test.mypackage';
+packageSrcPath = createSubDir(testRootDir, packageName, %T);
+jarFilePath = fullfile(testRootDir, packageName + '.jar');
+addSourceToPackage('Foo1', packageName, packageSrcPath, '');
+addSourceToPackage('Foo2', packageName + '.folder', packageSrcPath, '');
+ilib_build_jar(jarFilePath, packageName, packageSrcPath);
+checkJar(jarFilePath, packageName, ['Foo1', 'folder.Foo2']);
+
+// Test build a JAR of two packages
+jarFilePath = fullfile(testRootDir, 'testmultipackages.jar');
+// package1
+packageName1 = 'org.scilab.test.package1';
+package1SrcPath = createSubDir(testRootDir, packageName1, %T);
+addSourceToPackage('Foo1', packageName1, package1SrcPath, '');
+addSourceToPackage('Foo2', packageName1 + '.folder', package1SrcPath, '');
+// package2
+packageName2 = 'org.scilab.test.package2';
+package2SrcPath = createSubDir(testRootDir, packageName2, %T);
+addSourceToPackage('FooA', packageName2, package2SrcPath, '');
+addSourceToPackage('FooB', packageName2 + '.folder', package2SrcPath, '');
+// build
+ilib_build_jar(jarFilePath, [packageName1, packageName2], [package1SrcPath, package2SrcPath]);
+checkJar(jarFilePath, [packageName1; packageName2], ['Foo1', 'folder.Foo2'; 'FooA', 'folder.FooB']);
+
+// Test compilation errors
+packageName = 'testpackagecompileerrors';
+packageSrcPath = createSubDir(testRootDir, packageName, %T);
+jarFilePath = fullfile(testRootDir, packageName + '.jar');
+className = '1234';
+sourceCode = createSourceCode(className, packageName, '');
+javaFilePath = addSourceToPackage(className, packageName, packageSrcPath);
+checkCompileError("ilib_build_jar(jarFilePath, packageName, packageSrcPath)");
+
+
+// TEST LOADER AND CLEANER SCRIPTS
+
+packageName = 'dummypackage';
+className = 'Foo';
+jarFilePath = buildJar1Package1Class(packageName, className, testRootDir, '');
+checkLoaderScript('loader.sce', 'dummypackage.jar', 'dummypackage.Foo');
+checkCleanerScript('cleaner.sce', 'loader.sce', 'dummypackage.jar');
+
+
+// TEST OPTIONAL ARGUMENTS
+
+// Test dependency packages argument
+// create dependency package (in another directory, so that it is not in classpath)
+dependencyPackageName = 'dependencypackage';
+dependencyJarFilePath = buildJar1Package1Class(dependencyPackageName, 'Dummy', '');
+// remove dependency package class directory, because it is in class path
+jimsBinPath = fullfile(TMPDIR, 'JIMS/bin');
+removedir(fullfile(jimsBinPath, dependencyPackageName));
+// create package that uses the dependency
+packageName = 'testpackagedependencies';
+packageSrcPath = createSubDir(testRootDir, packageName, %T);
+jarFilePath = fullfile(testRootDir, packageName + '.jar');
+className = 'Bar';
+sourceCode = createSourceCode(className, packageName, dependencyPackageName);
+// check compile error without specifying dependency
+addSourceToPackage(className, packageName, packageSrcPath, sourceCode);
+checkCompileError("ilib_build_jar(jarFilePath, packageName, packageSrcPath)");
+// check it is ok with specifying dependency
+ilib_build_jar(jarFilePath, packageName, packageSrcPath, dependencyJarFilePath);
+checkJar(jarFilePath, packageName, className);
+
+
+// TEST TOOLBOX SKELETON
+
+// Build toolbox skeleton java code and run unit test
+toolboxSkeletonSrcPath = fullfile(SCI, "contrib", "toolbox_skeleton");
+toolboxSkeletonPath = fullfile(testRootDir, "toolbox_skeleton");
+copyfile(toolboxSkeletonSrcPath, toolboxSkeletonPath);
+javaBuilderPath = fullfile(toolboxSkeletonPath, "src", "java", "builder_java.sce");
+exec(javaBuilderPath);
+javaLoaderPath = fullfile(toolboxSkeletonPath, "src", "java", "loader.sce");
+exec(javaLoaderPath);
+javaTestPath = fullfile(toolboxSkeletonPath, "tests", "unit_tests", "java_sum.tst");
+exec(javaTestPath);
+
+
+// Restore original env
+cd(origDir);
+ilib_verbose(verbose);
index 5e397d8..e3f458c 100644 (file)
@@ -37,6 +37,11 @@ Building sources...
    ilib_gen_Make: Modification of the Makefile in TMPDIR.
    Running the Makefile
    Generate a cleaner file
+   Building JAR library org.scilab.contrib.toolboxskeleton.jar
+   Compiling Java sources in TMPDIR/toolbox_skeleton/src/java/
+   Creating JAR archive TMPDIR/toolbox_skeleton/jar/org.scilab.contrib.toolboxskeleton.jar
+   Create loader script for Java loader.sce
+   Create cleaner script for Java cleaner.sce
 Building gateway...
    Generate a gateway file
    Generate a loader file
@@ -103,16 +108,18 @@ exec("TMPDIR/toolbox_skeleton/loader.sce");
 Start Toolbox Skeleton
        Load macros
        Load gateways
+       Load Java libraries
        Load help
        Load demos
 test_run("TMPDIR/toolbox_skeleton/", [], "short_summary");
    001/001 - [TMPDIR/toolbox_skeleton/] : 
 
-   001/003 - [TMPDIR/toolbox_skeleton/] c_sum...................passed
-   002/003 - [TMPDIR/toolbox_skeleton/] fortran_sum.............passed
-   003/003 - [TMPDIR/toolbox_skeleton/] scilab_sum..............passed
+   001/004 - [TMPDIR/toolbox_skeleton/] c_sum...................passed
+   002/004 - [TMPDIR/toolbox_skeleton/] fortran_sum.............passed
+   003/004 - [TMPDIR/toolbox_skeleton/] java_sum................passed
+   004/004 - [TMPDIR/toolbox_skeleton/] scilab_sum..............passed
 
 
    --------------------------------------------------------------------------
-   Tests:    3,    Passed:    3,    Failed:    0,    Skipped:    0
+   Tests:    4,    Passed:    4,    Failed:    0,    Skipped:    0
    --------------------------------------------------------------------------
index 6080d56..c9baca1 100644 (file)
@@ -96,16 +96,18 @@ exec("TMPDIR/toolbox_skeleton/loader.sce");
 Start Toolbox Skeleton
        Load macros
        Load gateways
+       Load Java libraries
        Load help
        Load demos
 test_run("TMPDIR/toolbox_skeleton/", [], "short_summary");
    001/001 - [TMPDIR/toolbox_skeleton/] : 
 
-   001/003 - [TMPDIR/toolbox_skeleton/] c_sum...................passed
-   002/003 - [TMPDIR/toolbox_skeleton/] fortran_sum.............passed
-   003/003 - [TMPDIR/toolbox_skeleton/] scilab_sum..............passed
+   001/004 - [TMPDIR/toolbox_skeleton/] c_sum...................passed
+   002/004 - [TMPDIR/toolbox_skeleton/] fortran_sum.............passed
+   003/004 - [TMPDIR/toolbox_skeleton/] java_sum................passed
+   004/004 - [TMPDIR/toolbox_skeleton/] scilab_sum..............passed
 
 
    --------------------------------------------------------------------------
-   Tests:    3,    Passed:    3,    Failed:    0,    Skipped:    0
+   Tests:    4,    Passed:    4,    Failed:    0,    Skipped:    0
    --------------------------------------------------------------------------