external_objects_java: new function jcreatejar (SEP #114) 42/13042/5
Simon Marchetto [Wed, 6 Nov 2013 17:26:58 +0000 (18:26 +0100)]
Change-Id: Id852b5fa2d10bd5b9ff963ec696b3962274cdcad

19 files changed:
SEP/SEP_114_jcreatejar.odt [new file with mode: 0644]
scilab/CHANGES_5.5.X
scilab/modules/external_objects_java/Makefile.am
scilab/modules/external_objects_java/Makefile.in
scilab/modules/external_objects_java/external_objects_java.vcxproj
scilab/modules/external_objects_java/external_objects_java.vcxproj.filters
scilab/modules/external_objects_java/help/en_US/jcreatejar.xml [new file with mode: 0644]
scilab/modules/external_objects_java/includes/gw_external_objects_java.h
scilab/modules/external_objects_java/sci_gateway/c/gw_external_objects_java.c
scilab/modules/external_objects_java/sci_gateway/cpp/sci_jcreatejar.cpp [new file with mode: 0644]
scilab/modules/external_objects_java/sci_gateway/external_objects_java_gateway.xml
scilab/modules/external_objects_java/src/cpp/ScilabJavaEnvironment.cpp
scilab/modules/external_objects_java/src/cpp/ScilabJavaEnvironment.hxx
scilab/modules/external_objects_java/src/java/org/scilab/modules/external_objects_java/ScilabJarCreator.java [new file with mode: 0644]
scilab/modules/external_objects_java/src/jni/ScilabJarCreator.cpp [new file with mode: 0644]
scilab/modules/external_objects_java/src/jni/ScilabJarCreator.hxx [new file with mode: 0644]
scilab/modules/external_objects_java/src/jni/ScilabObjects.giws.xml
scilab/modules/external_objects_java/tests/unit_tests/jcreatejar.dia.ref [new file with mode: 0644]
scilab/modules/external_objects_java/tests/unit_tests/jcreatejar.tst [new file with mode: 0644]

diff --git a/SEP/SEP_114_jcreatejar.odt b/SEP/SEP_114_jcreatejar.odt
new file mode 100644 (file)
index 0000000..e3654f8
Binary files /dev/null and b/SEP/SEP_114_jcreatejar.odt differ
index 0a96559..e7af7f8 100644 (file)
@@ -7,6 +7,9 @@ New Features
 * The figures "visible" property now also applies to uicontrols.
   In previous releases, only axes were managed by this property setting.
 
+* New functions introduced:
+ - jcreatejar - Creates a Java archive (JAR) from a set of files / directories
+
 
 Scilab Bug Fixes
 ================
index 8360e90..1a5893c 100644 (file)
@@ -25,9 +25,9 @@ libsciexternal_objects_java_la_etc_DATA = etc/external_objects_java.quit \
 
 include $(top_srcdir)/Makefile.incl.am
 
-EXTERNAL_OBJECTS_JAVA_JNI_SOURCES = 
+EXTERNAL_OBJECTS_JAVA_JNI_SOURCES =
 
-EXTERNAL_OBJECTS_JAVA_C_SOURCES = 
+EXTERNAL_OBJECTS_JAVA_C_SOURCES =
 
 EXTERNAL_OBJECTS_JAVA_CPP_SOURCES = src/cpp/ScilabJavaEnvironment.cpp \
 src/cpp/NoMoreScilabMemoryException.cpp \
@@ -35,6 +35,7 @@ src/cpp/JavaOptionsSetter.cpp \
 src/cpp/ScilabJavaEnvironmentWrapper.cpp \
 src/jni/ScilabJavaArray.cpp \
 src/jni/ScilabJavaCompiler.cpp \
+src/jni/ScilabJarCreator.cpp \
 src/jni/ScilabJavaClass.cpp \
 src/jni/ScilabJavaObject.cpp \
 src/jni/ScilabClassLoader.cpp \
@@ -50,6 +51,7 @@ sci_gateway/cpp/sci_jgetmethods.cpp \
 sci_gateway/cpp/sci_jgetfields.cpp \
 sci_gateway/cpp/sci_jgetfield.cpp \
 sci_gateway/cpp/sci_jcompile.cpp \
+sci_gateway/cpp/sci_jcreatejar.cpp \
 sci_gateway/cpp/sci_jnewInstance.cpp \
 sci_gateway/cpp/sci_jremove.cpp \
 sci_gateway/cpp/sci_jexists.cpp \
@@ -103,13 +105,13 @@ libsciexternal_objects_java_la_CPPFLAGS = -I$(srcdir)/includes/ \
     $(JAVA_JNI_INCLUDE)
 
 
-pkglib_LTLIBRARIES = libsciexternal_objects_java.la 
-noinst_LTLIBRARIES = libsciexternal_objects_java-algo.la 
+pkglib_LTLIBRARIES = libsciexternal_objects_java.la
+noinst_LTLIBRARIES = libsciexternal_objects_java-algo.la
 
 libsciexternal_objects_java_la_LDFLAGS = -version-number $(SCILAB_LIBRARY_VERSION) $(LD_FLAGS)  $(X_LIBS) $(X_EXTRA_LIBS)
 
 libsciexternal_objects_java_algo_la_SOURCES = $(EXTERNAL_OBJECTS_JAVA_C_SOURCES) $(EXTERNAL_OBJECTS_JAVA_JNI_SOURCES) $(EXTERNAL_OBJECTS_JAVA_CPP_SOURCES)
-libsciexternal_objects_java_la_SOURCES = $(GATEWAY_C_SOURCES) $(GATEWAY_CPP_SOURCES) 
+libsciexternal_objects_java_la_SOURCES = $(GATEWAY_C_SOURCES) $(GATEWAY_CPP_SOURCES)
 libsciexternal_objects_java_algo_la_CFLAGS = $(libsciexternal_objects_java_la_CFLAGS)
 libsciexternal_objects_java_algo_la_CPPFLAGS = $(libsciexternal_objects_java_la_CPPFLAGS)
 
@@ -135,3 +137,4 @@ tests/libintl.jar
 if GUI
 USEANT=1
 endif
+
index 4f0d492..59187a9 100644 (file)
@@ -180,6 +180,7 @@ am__objects_2 =  \
        libsciexternal_objects_java_algo_la-ScilabJavaEnvironmentWrapper.lo \
        libsciexternal_objects_java_algo_la-ScilabJavaArray.lo \
        libsciexternal_objects_java_algo_la-ScilabJavaCompiler.lo \
+       libsciexternal_objects_java_algo_la-ScilabJarCreator.lo \
        libsciexternal_objects_java_algo_la-ScilabJavaClass.lo \
        libsciexternal_objects_java_algo_la-ScilabJavaObject.lo \
        libsciexternal_objects_java_algo_la-ScilabClassLoader.lo \
@@ -205,6 +206,7 @@ am__objects_3 =  \
        libsciexternal_objects_java_la-sci_jgetfields.lo \
        libsciexternal_objects_java_la-sci_jgetfield.lo \
        libsciexternal_objects_java_la-sci_jcompile.lo \
+       libsciexternal_objects_java_la-sci_jcreatejar.lo \
        libsciexternal_objects_java_la-sci_jnewInstance.lo \
        libsciexternal_objects_java_la-sci_jremove.lo \
        libsciexternal_objects_java_la-sci_jexists.lo \
@@ -681,6 +683,7 @@ src/cpp/JavaOptionsSetter.cpp \
 src/cpp/ScilabJavaEnvironmentWrapper.cpp \
 src/jni/ScilabJavaArray.cpp \
 src/jni/ScilabJavaCompiler.cpp \
+src/jni/ScilabJarCreator.cpp \
 src/jni/ScilabJavaClass.cpp \
 src/jni/ScilabJavaObject.cpp \
 src/jni/ScilabClassLoader.cpp \
@@ -697,6 +700,7 @@ sci_gateway/cpp/sci_jgetmethods.cpp \
 sci_gateway/cpp/sci_jgetfields.cpp \
 sci_gateway/cpp/sci_jgetfield.cpp \
 sci_gateway/cpp/sci_jcompile.cpp \
+sci_gateway/cpp/sci_jcreatejar.cpp \
 sci_gateway/cpp/sci_jnewInstance.cpp \
 sci_gateway/cpp/sci_jremove.cpp \
 sci_gateway/cpp/sci_jexists.cpp \
@@ -744,11 +748,11 @@ libsciexternal_objects_java_la_CPPFLAGS = -I$(srcdir)/includes/ \
        -I$(top_srcdir)/modules/commons/src/jni/ \
     $(JAVA_JNI_INCLUDE)
 
-pkglib_LTLIBRARIES = libsciexternal_objects_java.la 
-noinst_LTLIBRARIES = libsciexternal_objects_java-algo.la 
+pkglib_LTLIBRARIES = libsciexternal_objects_java.la
+noinst_LTLIBRARIES = libsciexternal_objects_java-algo.la
 libsciexternal_objects_java_la_LDFLAGS = -version-number $(SCILAB_LIBRARY_VERSION) $(LD_FLAGS)  $(X_LIBS) $(X_EXTRA_LIBS)
 libsciexternal_objects_java_algo_la_SOURCES = $(EXTERNAL_OBJECTS_JAVA_C_SOURCES) $(EXTERNAL_OBJECTS_JAVA_JNI_SOURCES) $(EXTERNAL_OBJECTS_JAVA_CPP_SOURCES)
-libsciexternal_objects_java_la_SOURCES = $(GATEWAY_C_SOURCES) $(GATEWAY_CPP_SOURCES) 
+libsciexternal_objects_java_la_SOURCES = $(GATEWAY_C_SOURCES) $(GATEWAY_CPP_SOURCES)
 libsciexternal_objects_java_algo_la_CFLAGS = $(libsciexternal_objects_java_la_CFLAGS)
 libsciexternal_objects_java_algo_la_CPPFLAGS = $(libsciexternal_objects_java_la_CPPFLAGS)
 libsciexternal_objects_java_la_LIBADD = libsciexternal_objects_java-algo.la $(top_builddir)/modules/commons/libscicommons.la $(top_builddir)/modules/jvm/libscijvm.la
@@ -869,6 +873,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsciexternal_objects_java_algo_la-JavaOptionsSetter.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsciexternal_objects_java_algo_la-NoMoreScilabMemoryException.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsciexternal_objects_java_algo_la-ScilabClassLoader.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsciexternal_objects_java_algo_la-ScilabJarCreator.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsciexternal_objects_java_algo_la-ScilabJavaArray.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsciexternal_objects_java_algo_la-ScilabJavaClass.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsciexternal_objects_java_algo_la-ScilabJavaCompiler.Plo@am__quote@
@@ -884,6 +889,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsciexternal_objects_java_la-sci_jcast.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsciexternal_objects_java_la-sci_jcompile.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsciexternal_objects_java_la-sci_jconvMatrixMethod.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsciexternal_objects_java_la-sci_jcreatejar.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsciexternal_objects_java_la-sci_jdeff.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsciexternal_objects_java_la-sci_jdisableTrace.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsciexternal_objects_java_la-sci_jenableTrace.Plo@am__quote@
@@ -995,6 +1001,13 @@ libsciexternal_objects_java_algo_la-ScilabJavaCompiler.lo: src/jni/ScilabJavaCom
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsciexternal_objects_java_algo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libsciexternal_objects_java_algo_la-ScilabJavaCompiler.lo `test -f 'src/jni/ScilabJavaCompiler.cpp' || echo '$(srcdir)/'`src/jni/ScilabJavaCompiler.cpp
 
+libsciexternal_objects_java_algo_la-ScilabJarCreator.lo: src/jni/ScilabJarCreator.cpp
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsciexternal_objects_java_algo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libsciexternal_objects_java_algo_la-ScilabJarCreator.lo -MD -MP -MF $(DEPDIR)/libsciexternal_objects_java_algo_la-ScilabJarCreator.Tpo -c -o libsciexternal_objects_java_algo_la-ScilabJarCreator.lo `test -f 'src/jni/ScilabJarCreator.cpp' || echo '$(srcdir)/'`src/jni/ScilabJarCreator.cpp
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libsciexternal_objects_java_algo_la-ScilabJarCreator.Tpo $(DEPDIR)/libsciexternal_objects_java_algo_la-ScilabJarCreator.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='src/jni/ScilabJarCreator.cpp' object='libsciexternal_objects_java_algo_la-ScilabJarCreator.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsciexternal_objects_java_algo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libsciexternal_objects_java_algo_la-ScilabJarCreator.lo `test -f 'src/jni/ScilabJarCreator.cpp' || echo '$(srcdir)/'`src/jni/ScilabJarCreator.cpp
+
 libsciexternal_objects_java_algo_la-ScilabJavaClass.lo: src/jni/ScilabJavaClass.cpp
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsciexternal_objects_java_algo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libsciexternal_objects_java_algo_la-ScilabJavaClass.lo -MD -MP -MF $(DEPDIR)/libsciexternal_objects_java_algo_la-ScilabJavaClass.Tpo -c -o libsciexternal_objects_java_algo_la-ScilabJavaClass.lo `test -f 'src/jni/ScilabJavaClass.cpp' || echo '$(srcdir)/'`src/jni/ScilabJavaClass.cpp
 @am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libsciexternal_objects_java_algo_la-ScilabJavaClass.Tpo $(DEPDIR)/libsciexternal_objects_java_algo_la-ScilabJavaClass.Plo
@@ -1072,6 +1085,13 @@ libsciexternal_objects_java_la-sci_jcompile.lo: sci_gateway/cpp/sci_jcompile.cpp
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsciexternal_objects_java_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libsciexternal_objects_java_la-sci_jcompile.lo `test -f 'sci_gateway/cpp/sci_jcompile.cpp' || echo '$(srcdir)/'`sci_gateway/cpp/sci_jcompile.cpp
 
+libsciexternal_objects_java_la-sci_jcreatejar.lo: sci_gateway/cpp/sci_jcreatejar.cpp
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsciexternal_objects_java_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libsciexternal_objects_java_la-sci_jcreatejar.lo -MD -MP -MF $(DEPDIR)/libsciexternal_objects_java_la-sci_jcreatejar.Tpo -c -o libsciexternal_objects_java_la-sci_jcreatejar.lo `test -f 'sci_gateway/cpp/sci_jcreatejar.cpp' || echo '$(srcdir)/'`sci_gateway/cpp/sci_jcreatejar.cpp
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libsciexternal_objects_java_la-sci_jcreatejar.Tpo $(DEPDIR)/libsciexternal_objects_java_la-sci_jcreatejar.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='sci_gateway/cpp/sci_jcreatejar.cpp' object='libsciexternal_objects_java_la-sci_jcreatejar.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsciexternal_objects_java_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libsciexternal_objects_java_la-sci_jcreatejar.lo `test -f 'sci_gateway/cpp/sci_jcreatejar.cpp' || echo '$(srcdir)/'`sci_gateway/cpp/sci_jcreatejar.cpp
+
 libsciexternal_objects_java_la-sci_jnewInstance.lo: sci_gateway/cpp/sci_jnewInstance.cpp
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsciexternal_objects_java_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libsciexternal_objects_java_la-sci_jnewInstance.lo -MD -MP -MF $(DEPDIR)/libsciexternal_objects_java_la-sci_jnewInstance.Tpo -c -o libsciexternal_objects_java_la-sci_jnewInstance.lo `test -f 'sci_gateway/cpp/sci_jnewInstance.cpp' || echo '$(srcdir)/'`sci_gateway/cpp/sci_jnewInstance.cpp
 @am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libsciexternal_objects_java_la-sci_jnewInstance.Tpo $(DEPDIR)/libsciexternal_objects_java_la-sci_jnewInstance.Plo
index df0ec52..0672d2c 100644 (file)
     <ClCompile Include="sci_gateway\cpp\sci_jcast.cpp" />
     <ClCompile Include="sci_gateway\cpp\sci_jcompile.cpp" />
     <ClCompile Include="sci_gateway\cpp\sci_jconvMatrixMethod.cpp" />
+    <ClCompile Include="sci_gateway\cpp\sci_jcreatejar.cpp" />
     <ClCompile Include="sci_gateway\cpp\sci_jdeff.cpp" />
     <ClCompile Include="sci_gateway\cpp\sci_jdisableTrace.cpp" />
     <ClCompile Include="sci_gateway\cpp\sci_jenableTrace.cpp" />
     <ClCompile Include="src\cpp\ScilabJavaEnvironment.cpp" />
     <ClCompile Include="src\cpp\ScilabJavaEnvironmentWrapper.cpp" />
     <ClCompile Include="src\jni\ScilabClassLoader.cpp" />
+    <ClCompile Include="src\jni\ScilabJarCreator.cpp" />
     <ClCompile Include="src\jni\ScilabJavaArray.cpp" />
     <ClCompile Include="src\jni\ScilabJavaClass.cpp" />
     <ClCompile Include="src\jni\ScilabJavaCompiler.cpp" />
     <ClInclude Include="src\cpp\wrap.hpp" />
     <ClInclude Include="src\cpp\WrapAsDirectBufferTemplate.hpp" />
     <ClInclude Include="src\jni\ScilabClassLoader.hxx" />
+    <ClInclude Include="src\jni\ScilabJarCreator.hxx" />
     <ClInclude Include="src\jni\ScilabJavaArray.hxx" />
     <ClInclude Include="src\jni\ScilabJavaClass.hxx" />
     <ClInclude Include="src\jni\ScilabJavaCompiler.hxx" />
index 85d8c82..e6400a0 100644 (file)
     <ClCompile Include="src\jni\ScilabOperations.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="sci_gateway\cpp\sci_jcreatejar.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="src\jni\ScilabJarCreator.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="src\cpp\JavaOptionsHelper.hxx">
     <ClInclude Include="src\jni\ScilabOperations.hxx">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="src\jni\ScilabJarCreator.hxx">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
 </Project>
\ No newline at end of file
diff --git a/scilab/modules/external_objects_java/help/en_US/jcreatejar.xml b/scilab/modules/external_objects_java/help/en_US/jcreatejar.xml
new file mode 100644 (file)
index 0000000..a4f196e
--- /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="en" xml:id="jcreatejar">
+    <refnamediv>
+        <refname>jcreatejar</refname>
+        <refpurpose>Creates a Java Archive (JAR) from a set of files / directories</refpurpose>
+    </refnamediv>
+    <refsynopsisdiv>
+        <title>Calling Sequence</title>
+        <synopsis>
+            jcreatejar(jarFilePath, filePaths[, rootPath, [, manifestFilePath]])
+        </synopsis>
+    </refsynopsisdiv>
+    <refsection>
+        <title>Parameters</title>
+        <variablelist>
+            <varlistentry>
+                <term>jarFilePath</term>
+                <listitem>
+                    <para>A string containing the destination file path of the JAR.</para>
+                </listitem>
+            </varlistentry>
+            <varlistentry>
+                <term>filePaths</term>
+                <listitem>
+                    <para>A row / column string matrix containing the paths of the input files/directories to include in the JAR.</para>
+                </listitem>
+            </varlistentry>
+            <varlistentry>
+                <term>rootPath</term>
+                <listitem>
+                    <para>An optional string setting the path from which the relative paths in the JAR of all the input files/directories will be computed.</para>
+                </listitem>
+            </varlistentry>
+            <varlistentry>
+                <term>manifestFilePath</term>
+                <listitem>
+                    <para>An optional string setting the file path of the manifest data to include in the JAR.</para>
+                </listitem>
+            </varlistentry>
+        </variablelist>
+    </refsection>
+    <refsection>
+        <title>Description</title>
+        <para>
+            Creates a JAR (Java Archive) file from a set of input files / directories. A common use is to a create Java packages (which contain Java class files).
+            For example, the function <link linkend="ilib_build_jar">ilib_build_jar</link> uses <literal>jcreatejar</literal> to build toolboxes containing Java sources.
+            But <literal>jcreatejar</literal> can also be used to compress files of any type (for example to send them over a network).
+        </para>
+        <para>
+            Most of times, a JAR file is created from a single tree of files, and the path tree in the JAR file is the same as the input path tree. So when <literal>jcreatejar</literal> is given a set of files and directories, it automatically computes the root path of all that files / directories, and set the paths in the JAR relative to that root path. This one can also be explicitly specified in the <literal>rootPath</literal> argument.
+        </para>
+        <para>
+            A JAR file contains a manifest, which contains data to describe the content of the JAR. In the JAR, this manifest is the file <literal>MANIFEST.MF</literal> in the <literal>META-INF</literal> folder.
+            The manifest file can be automatically found at that location in the input tree, or the file path to the manifest can be given in the <literal>manifestFilePath</literal> argument. If the manifest file cannot be found, 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>
+        <para>
+            The JAR destination file path, stored in the argument <literal>jarFilePath</literal>, should have the extension <literal>.jar</literal>. The destination JAR file, if it already exists, is overwriten.
+        </para>
+    </refsection>
+    <refsection>
+        <title>Examples</title>
+        <programlisting role="example"><![CDATA[
+// Example of jcreatejar: create a Java package (of classes)
+
+// Create a directory for package sources
+jar_src_path = fullfile(TMPDIR, 'jarPackageExample');
+mkdir(jar_src_path);
+
+// Create a Java source and compiles it to a Java class
+function createJavaClass(class_name, code)
+    class_src_path = fullfile(jar_src_path, class_name + '.java');
+    fd = mopen(class_src_path, 'wt');
+    mputl(code, fd);
+    mclose(fd);
+    jcompile(class_src_path);
+endfunction
+
+// Create a class in the root of the package
+createJavaClass('Class1', msprintf( ..
+    'package jarPackageExample;\n' + ..
+    'public class Class1 {}'));
+
+// Create another class in a folder of the package
+mkdir(fullfile(jar_src_path, 'folder'));
+createJavaClass('folder/Class2', msprintf( ..
+    'package jarPackageExample.folder;\n' + ..
+    'public class Class2 {}'));
+
+// The compiled package is in TMPDIR in JIMS folder
+jar_tmp_path = fullfile(TMPDIR, 'JIMS/bin/jarPackageExample');
+
+// Create the package JAR
+jar_dest_path = fullfile(TMPDIR, 'jarPackageExample.jar');
+jcreatejar(jar_dest_path, jar_tmp_path);
+      ]]></programlisting>
+        <programlisting role="example"><![CDATA[
+// Example of jcreatejar: create a JAR containing images, and add a manifest
+
+// Create the manifest file
+manifest_path = fullfile(TMPDIR, 'MANIFEST.MF');
+manifest = msprintf('Manifest-Version: 1.0\nName: Scilab images');
+fd = mopen(manifest_path, 'wt');
+mputl(manifest, fd);
+mclose(fd);
+
+// Create the JAR
+jar_src_path = fullfile(SCI, 'desktop/images');
+jar_dest_path = fullfile(TMPDIR, 'jarImagesExample.jar');
+jcreatejar(jar_dest_path, jar_src_path, '', manifest_path);
+      ]]></programlisting>
+    </refsection>
+    <refsection role="see also">
+        <title>See Also</title>
+        <simplelist type="inline">
+            <member>
+                <link linkend="jcompile">jcompile</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>
+
index 0d8ec03..c846aa2 100644 (file)
@@ -43,6 +43,7 @@ EXTERNAL_OBJECTS_JAVA_SCILAB_IMPEXP int sci_jinvoke(char *fname, unsigned long f
 EXTERNAL_OBJECTS_JAVA_SCILAB_IMPEXP int sci_jconvMatrixMethod(char *fname, unsigned long fname_len);
 EXTERNAL_OBJECTS_JAVA_SCILAB_IMPEXP int sci_jgetinfo(char *fname, unsigned long fname_len);
 EXTERNAL_OBJECTS_JAVA_SCILAB_IMPEXP int sci_jinvoke_db(char *fname, unsigned long fname_len);
+EXTERNAL_OBJECTS_JAVA_SCILAB_IMPEXP int sci_jcreatejar(char *fname, unsigned long fname_len);
 /*--------------------------------------------------------------------------*/
 #endif /* __GW_EXTERNAL_OBJECTS_H__ */
 /*--------------------------------------------------------------------------*/
index 50d9614..72b68bb 100644 (file)
@@ -45,7 +45,8 @@ static gw_generic_table Tab[] =
     {sci_jinvoke, "jinvoke"},
     {sci_jconvMatrixMethod, "jconvMatrixMethod"},
     {sci_jgetinfo, "jgetinfo"},
-    {sci_jinvoke_db, "jinvoke_db"}
+    {sci_jinvoke_db, "jinvoke_db"},
+    {sci_jcreatejar, "jcreatejar"}
 };
 
 /*--------------------------------------------------------------------------*/
diff --git a/scilab/modules/external_objects_java/sci_gateway/cpp/sci_jcreatejar.cpp b/scilab/modules/external_objects_java/sci_gateway/cpp/sci_jcreatejar.cpp
new file mode 100644 (file)
index 0000000..cbe8574
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ * 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
+ *
+ */
+
+extern "C" {
+#include "Scierror.h"
+#include "gw_external_objects_java.h"
+#include "MALLOC.h"
+}
+
+#include "ScilabJavaEnvironment.hxx"
+
+using namespace org_scilab_modules_external_objects_java;
+using namespace org_modules_external_objects;
+
+int sci_jcreatejar(char *fname, unsigned long fname_len)
+{
+    SciErr sciErr;
+    int res = 1;
+
+    CheckInputArgument(pvApiCtx, 2, 4);
+    CheckOutputArgument(pvApiCtx, 0, 1);
+
+    // Input argument 1: jar file path
+    int* addr1 = NULL;
+    getVarAddressFromPosition(pvApiCtx, 1, &addr1);
+
+    char *jarFilePath = NULL;
+    if (getAllocatedSingleString(pvApiCtx, addr1, &jarFilePath))
+    {
+        Scierror(202, _("%s: Wrong type for argument #%d: A string expected.\n"), fname, 1);
+        return 1;
+    }
+
+    // Input argument 2: paths of files to be jar-red
+    int* addr2 = NULL;
+    sciErr = getVarAddressFromPosition(pvApiCtx, 2, &addr2);
+    if (sciErr.iErr)
+    {
+        freeAllocatedSingleString(jarFilePath);
+        printError(&sciErr, 0);
+        return 1;
+    }
+
+    if (!isStringType(pvApiCtx, addr2))
+    {
+        freeAllocatedSingleString(jarFilePath);
+        Scierror(202, _("%s: Wrong type for input argument #%d: String array expected.\n"), fname, 2);
+        return 1;
+    }
+
+    int nbRow = 0;
+    int nbCol = 0;
+    sciErr = getVarDimension(pvApiCtx, addr2, &nbRow, &nbCol);
+    if (sciErr.iErr)
+    {
+        freeAllocatedSingleString(jarFilePath);
+        printError(&sciErr, 0);
+        return 1;
+    }
+
+    if ((nbRow < 1 || nbCol != 1) && (nbCol < 1 || nbRow != 1))
+    {
+        freeAllocatedSingleString(jarFilePath);
+        throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid dimension for argument #%d: A row or a column expected."), 2);
+    }
+    int nbFilePaths = nbRow * nbCol;
+
+    char **filePaths = NULL;
+    if (getAllocatedMatrixOfString(pvApiCtx, addr2, &nbRow, &nbCol, &filePaths))
+    {
+        freeAllocatedSingleString(jarFilePath);
+        printError(&sciErr, 0);
+        return 1;
+    }
+
+    char *filesRootPath = NULL;
+    if (nbInputArgument(pvApiCtx) > 2)
+    {
+        // Input argument 3: files root path
+        int* addr3 = NULL;
+        getVarAddressFromPosition(pvApiCtx, 3, &addr3);
+
+        if (getAllocatedSingleString(pvApiCtx, addr3, &filesRootPath))
+        {
+            freeAllocatedSingleString(jarFilePath);
+            freeAllocatedMatrixOfString(nbRow, nbCol, filePaths);
+            Scierror(202, _("%s: Wrong type for argument #%d: A string expected.\n"), fname, 3);
+            return 1;
+        }
+    }
+
+    char *manifestFilePath = NULL;
+    if (nbInputArgument(pvApiCtx) > 3)
+    {
+        // Input argument 4: manifest file path
+        int* addr4 = NULL;
+        getVarAddressFromPosition(pvApiCtx, 4, &addr4);
+
+        if (getAllocatedSingleString(pvApiCtx, addr4, &manifestFilePath))
+        {
+            freeAllocatedSingleString(jarFilePath);
+            freeAllocatedMatrixOfString(nbRow, nbCol, filePaths);
+            freeAllocatedSingleString(filesRootPath);
+            Scierror(202, _("%s: Wrong type for argument #%d: A string expected.\n"), fname, 4);
+            return 1;
+        }
+    }
+
+    try
+    {
+        ScilabJavaEnvironment::start();
+        ScilabJavaEnvironment *javaEnvironment = ScilabJavaEnvironment::getInstance();
+        if (javaEnvironment)
+        {
+            res = javaEnvironment->createJarArchive(jarFilePath, filePaths, nbFilePaths, filesRootPath, manifestFilePath);
+
+            // Create boolean return value
+            int *ret = NULL;
+            sciErr = allocMatrixOfBoolean(pvApiCtx, nbInputArgument(pvApiCtx) + 1, 1, 1, &ret);
+            if (sciErr.iErr)
+            {
+                printError(&sciErr, 0);
+                return 1;
+            }
+            ret[0] = (res == 0) ? 1 : 0;
+            AssignOutputVariable(pvApiCtx, 1) = nbInputArgument(pvApiCtx) + 1;
+            ReturnArguments(pvApiCtx);
+        }
+        else
+        {
+            Scierror(999, "%s: No Java environment available (instance is null).", fname);
+        }
+    }
+    catch (std::exception &e)
+    {
+        Scierror(999, "%s: An error occured: %s", fname, e.what());
+    }
+
+    freeAllocatedSingleString(jarFilePath);
+    freeAllocatedMatrixOfString(nbRow, nbCol, filePaths);
+    freeAllocatedSingleString(filesRootPath);
+    freeAllocatedSingleString(manifestFilePath);
+
+    return 0;
+}
index c89746b..6fa4c6e 100644 (file)
@@ -2,7 +2,7 @@
 <!--
  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
  * Copyright (C) 2012 - Scilab Enterprises - Calixte Denizet
- * 
+ *
  * 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
@@ -55,4 +55,5 @@
     <PRIMITIVE gatewayId="72" primitiveId="24" primitiveName="jconvMatrixMethod" />
     <PRIMITIVE gatewayId="72" primitiveId="25" primitiveName="jgetinfo" />
     <PRIMITIVE gatewayId="72" primitiveId="26" primitiveName="jinvoke_db" />
+    <PRIMITIVE gatewayId="72" primitiveId="27" primitiveName="jcreatejar" />
 </GATEWAY>
index 3a10739..b905175 100644 (file)
@@ -26,6 +26,7 @@
 #include "ScilabOperations.hxx"
 #include "NoMoreScilabMemoryException.hxx"
 #include "ScilabAutoCleaner.hxx"
+#include "ScilabJarCreator.hxx"
 
 //#include "ScilabJavaObjectHelper.hxx"
 extern "C" {
@@ -522,4 +523,19 @@ void ScilabJavaEnvironment::getMethodResult(JavaVM * jvm_, const char * const me
         throw GiwsException::JniCallMethodException(curEnv);
     }
 };
+
+int ScilabJavaEnvironment::createJarArchive(char *jarFilePath, char **filePaths, int filePathsSize, char *filesRootPath,
+        char *manifestFilePath)
+{
+    JavaVM *vm = getScilabJavaVM();
+    try
+    {
+        return ScilabJarCreator::createJarArchive(vm, jarFilePath, filePaths, filePathsSize, filesRootPath, manifestFilePath, false);
+    }
+    catch (const GiwsException::JniException & e)
+    {
+        throw ScilabJavaException(__LINE__, __FILE__, gettext("Cannot create jar:\n%s"), e.getJavaDescription().c_str());
+    }
+}
+
 }
index 5cfcc8f..be290f0 100644 (file)
@@ -171,6 +171,8 @@ public :
         return traceEnabled;
     }
 
+    int createJarArchive(char *jarFilePath, char **filePaths, int filePathsSize, char *filesRootPath, char *manifestFilePath);
+
 private:
     ScilabJavaEnvironment();
 
diff --git a/scilab/modules/external_objects_java/src/java/org/scilab/modules/external_objects_java/ScilabJarCreator.java b/scilab/modules/external_objects_java/src/java/org/scilab/modules/external_objects_java/ScilabJarCreator.java
new file mode 100644 (file)
index 0000000..43a635e
--- /dev/null
@@ -0,0 +1,261 @@
+/*
+ * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ * Copyright (C) 2013 - Scilab Enterprises - Simon MARCHETTO
+ *
+ * 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
+ *
+ */
+
+package org.scilab.modules.external_objects_java;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.jar.JarEntry;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+
+
+/**
+ * Class to create JAR files (for JIMS)
+ */
+public class ScilabJarCreator {
+    /**
+     * Create a Jar archive from a set of files
+     * @param jarFilePath the destination jar path
+     * @param filePaths the set of file paths to be jar-ed
+     * @param filesRootPath the root path of files from which the relative paths in jar will be computed
+     * @param manifestFilePath the path of manifest file
+     * @param keepAbsolutePaths keep absolute paths of files in jar
+     */
+    public static int createJarArchive(String jarFilePath, String[] filePaths, String filesRootPath,
+                                       String manifestFilePath, boolean keepAbsolutePaths) throws ScilabJavaException {
+        JarOutputStream jarOutputStream = null;
+        try {
+            // Normalize path (Windows short path => long path, remove '..')
+            String[] normalizedFilePaths = new String[filePaths.length];
+            int i = 0;
+            for (String filePath : filePaths) {
+                normalizedFilePaths[i++] = new File(filePath).getCanonicalPath();
+            }
+
+            // Use the given root path or compute it
+            String commonPath = null;
+            if ((filesRootPath == null) || (filesRootPath.isEmpty())) {
+                if (!keepAbsolutePaths) {
+                    commonPath = getCommonPath(normalizedFilePaths);
+                }
+            } else {
+                // Normalize root path
+                commonPath = new File(filesRootPath).getCanonicalPath();
+            }
+
+            // Finds all the list of all the files in the directory trees
+            List<String> expandedFilePaths = expandPaths(normalizedFilePaths);
+
+            // Manifest
+            // if specified take the one given in argument, otherwise take META-INF/MANIFEST.MF
+            // if does not exist, create a manifest
+            Manifest manifest = null;
+            if ((manifestFilePath == null) || (manifestFilePath.isEmpty())) {
+                manifestFilePath = commonPath + File.separator + "META-INF" + File.separator + "MANIFEST.MF";
+            }
+            if (new File(manifestFilePath).exists()) {
+                manifest = new Manifest(new FileInputStream(manifestFilePath));
+            } else {
+                manifest = new Manifest();
+            }
+
+            // Now create the jar with all the files
+            FileOutputStream stream = new FileOutputStream(jarFilePath);
+            jarOutputStream = new JarOutputStream(stream, manifest);
+
+            for (String filePath : expandedFilePaths) {
+                File file = new File(filePath);
+                String pathInJar;
+                if ((commonPath != null) && (!commonPath.isEmpty())) {
+                    pathInJar = getRelativePath(commonPath, filePath);
+                } else {
+                    if (keepAbsolutePaths) {
+                        pathInJar = file.getPath();
+                    } else {
+                        pathInJar = file.getName();
+                    }
+                }
+
+                // Skip manifest file, it will be created automatically
+                if (pathInJar.equals("META-INF/MANIFEST.MF")) {
+                    continue;
+                }
+
+                addFileToJarArchive(file, pathInJar, jarOutputStream);
+            }
+
+            closeJarArchive(jarOutputStream);
+            jarOutputStream = null;
+            return 0;
+        } catch (Exception e) {
+            try {
+                closeJarArchive(jarOutputStream);
+                deleteJarArchive(jarFilePath);
+            } catch (Exception e2) {}
+            e.printStackTrace();
+            throw new ScilabJavaException(String.format("Cannot create jar archive %s : %s\n", jarFilePath, e.getMessage()));
+        }
+    }
+
+    /**
+     * Recursively list all chidren file paths contained in a list of paths
+     * @param paths the paths to expand
+     */
+    private static List<String> expandPaths(String... paths) throws IOException {
+        ArrayList<String> expandedPaths = new ArrayList<String>();
+        for (String filePath : paths) {
+            File file = new File(filePath);
+            if (file.isDirectory()) {
+                for (File childFile: file.listFiles()) {
+                    expandedPaths.addAll(expandPaths(childFile.getPath()));
+                }
+            } else {
+                expandedPaths.add(filePath);
+            }
+        }
+        return expandedPaths;
+    }
+
+    /**
+     * Adds a file to an opened Jar archive
+     * @param file the file to add
+     * @param pathInJar the path of file in jar
+     * @param jar the opened Jar in which the file is added
+     */
+    private static void addFileToJarArchive(File file, String pathInJar, JarOutputStream jar) throws IOException {
+        BufferedInputStream in = null;
+        try {
+            pathInJar.replace("\\", "/");
+
+            JarEntry entry = new JarEntry(pathInJar);
+            entry.setTime(file.lastModified());
+            jar.putNextEntry(entry);
+            in = new BufferedInputStream(new FileInputStream(file));
+
+            byte[] buffer = new byte[4096];
+            while (true) {
+                int count = in.read(buffer);
+                if (count == -1) {
+                    break;
+                }
+                jar.write(buffer, 0, count);
+            }
+            jar.closeEntry();
+        } finally {
+            if (in != null) {
+                in.close();
+            }
+        }
+    }
+
+    /**
+    * Returns the common path of a set of paths
+    * ex: /tmp/dummy/foo and /tmp/dummy/bar/foo have /tmp/dummy as common path
+    * @param paths the input paths
+    */
+    private static String getCommonPath(String[] paths) throws IOException {
+        int nbPaths = paths.length;
+        if (nbPaths == 0) {
+            return "";
+        } else if (nbPaths == 1) {
+            File path = new File(paths[0]);
+            if (path.isDirectory()) {
+                return path.getAbsolutePath();
+            } else {
+                return path.getParentFile().getAbsolutePath();
+            }
+        }
+
+        // Escape because Windows backslash crashes split (regexp)
+        String fileSep = java.util.regex.Pattern.quote(System.getProperty("file.separator"));
+
+        String commonPath = "";
+        String[][] folders = new String[nbPaths][];
+
+        // Split each path in all its folders
+        int k = 0;
+        for (String path : paths) {
+            folders[k++] = path.split(fileSep);
+        }
+
+        // For each folder of first path
+        for (int j = 0; j < folders[0].length; j++) {
+            String folderToMatch = folders[0][j];
+
+            // Compare with the folder at same position in all the other paths
+            boolean allMatched = true;
+            for (int i = 1; i < folders.length && allMatched; i++) {
+                if (j >= folders[i].length) {
+                    return commonPath;
+                }
+                allMatched &= (new File(folders[i][j]).compareTo(new File(folderToMatch)) == 0);
+            }
+
+            // Update common path
+            if (allMatched) {
+                commonPath += folderToMatch + File.separator;
+            } else {
+                return commonPath;
+            }
+        }
+
+        return commonPath;
+    }
+
+    /**
+    * Returns the relative path of a path given a base path
+    * @param base the base path
+    * @param path the path for which we want the relative path
+    */
+    private static String getRelativePath(String base, String path) {
+        return new File(base).toURI().relativize(new File(path).toURI()).getPath();
+    }
+
+    /**
+    * Closes a jar
+    * @param jarOutputStream the jar output stream
+    */
+    private static void closeJarArchive(JarOutputStream jarOutputStream) throws ScilabJavaException {
+        try {
+            if (jarOutputStream != null) {
+                jarOutputStream.close();
+            }
+        } catch (IOException e) {
+            throw new ScilabJavaException(String.format("Cannot close jar stream : %s\n", e.getMessage()));
+        }
+    }
+
+    /**
+    * Deletes a jar
+    * @param jarFilePath the file path of jar to be deleted
+    */
+    private static void deleteJarArchive(String jarFilePath) throws ScilabJavaException {
+        File f = new File(jarFilePath);
+        if (f.exists()) {
+            if (f.canWrite()) {
+                if (!f.delete()) {
+                    throw new ScilabJavaException(String.format("Cannot delete jar archive %s.\n", jarFilePath));
+                }
+            } else {
+                throw new ScilabJavaException(String.format("Cannot delete jar archive %s : File is write protected.\n", jarFilePath));
+            }
+        } else {
+            throw new ScilabJavaException(String.format("Cannot delete jar archive %s : No such file.\n", jarFilePath));
+        }
+    }
+}
diff --git a/scilab/modules/external_objects_java/src/jni/ScilabJarCreator.cpp b/scilab/modules/external_objects_java/src/jni/ScilabJarCreator.cpp
new file mode 100644 (file)
index 0000000..c577799
--- /dev/null
@@ -0,0 +1,241 @@
+#include "ScilabJarCreator.hxx"
+/* Generated by GIWS (version 2.0.1) with command:
+giws -e -f ScilabObjects.giws.xml
+*/
+/*
+
+This is generated code.
+
+This software is a computer program whose purpose is to hide the complexity
+of accessing Java objects/methods from C++ code.
+
+This software is governed by the CeCILL-B license under French law and
+abiding by the rules of distribution of free software.  You can  use,
+modify and/ or redistribute the software under the terms of the CeCILL-B
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info".
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability.
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or
+data to be ensured and,  more generally, to use and operate it in the
+same conditions as regards security.
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL-B license and that you accept its terms.
+*/
+
+namespace org_scilab_modules_external_objects_java
+{
+
+// Static declarations (if any)
+
+// Returns the current env
+
+JNIEnv * ScilabJarCreator::getCurrentEnv()
+{
+    JNIEnv * curEnv = NULL;
+    jint res = this->jvm->AttachCurrentThread(reinterpret_cast<void **>(&curEnv), NULL);
+    if (res != JNI_OK)
+    {
+        throw GiwsException::JniException(getCurrentEnv());
+    }
+    return curEnv;
+}
+// Destructor
+
+ScilabJarCreator::~ScilabJarCreator()
+{
+    JNIEnv * curEnv = NULL;
+    this->jvm->AttachCurrentThread(reinterpret_cast<void **>(&curEnv), NULL);
+
+    curEnv->DeleteGlobalRef(this->instance);
+    curEnv->DeleteGlobalRef(this->instanceClass);
+    curEnv->DeleteGlobalRef(this->stringArrayClass);
+}
+// Constructors
+ScilabJarCreator::ScilabJarCreator(JavaVM * jvm_)
+{
+    jmethodID constructObject = NULL ;
+    jobject localInstance ;
+    jclass localClass ;
+
+    const std::string construct = "<init>";
+    const std::string param = "()V";
+    jvm = jvm_;
+
+    JNIEnv * curEnv = getCurrentEnv();
+
+    localClass = curEnv->FindClass( this->className().c_str() ) ;
+    if (localClass == NULL)
+    {
+        throw GiwsException::JniClassNotFoundException(curEnv, this->className());
+    }
+
+    this->instanceClass = static_cast<jclass>(curEnv->NewGlobalRef(localClass));
+
+    /* localClass is not needed anymore */
+    curEnv->DeleteLocalRef(localClass);
+
+    if (this->instanceClass == NULL)
+    {
+        throw GiwsException::JniObjectCreationException(curEnv, this->className());
+    }
+
+
+    constructObject = curEnv->GetMethodID( this->instanceClass, construct.c_str() , param.c_str() ) ;
+    if (constructObject == NULL)
+    {
+        throw GiwsException::JniObjectCreationException(curEnv, this->className());
+    }
+
+    localInstance = curEnv->NewObject( this->instanceClass, constructObject ) ;
+    if (localInstance == NULL)
+    {
+        throw GiwsException::JniObjectCreationException(curEnv, this->className());
+    }
+
+    this->instance = curEnv->NewGlobalRef(localInstance) ;
+    if (this->instance == NULL)
+    {
+        throw GiwsException::JniObjectCreationException(curEnv, this->className());
+    }
+    /* localInstance not needed anymore */
+    curEnv->DeleteLocalRef(localInstance);
+
+    /* Methods ID set to NULL */
+    jintcreateJarArchivejstringjava_lang_StringjobjectArray_java_lang_Stringjava_lang_Stringjstringjava_lang_Stringjstringjava_lang_StringjbooleanbooleanID = NULL;
+
+
+}
+
+ScilabJarCreator::ScilabJarCreator(JavaVM * jvm_, jobject JObj)
+{
+    jvm = jvm_;
+
+    JNIEnv * curEnv = getCurrentEnv();
+
+    jclass localClass = curEnv->GetObjectClass(JObj);
+    this->instanceClass = static_cast<jclass>(curEnv->NewGlobalRef(localClass));
+    curEnv->DeleteLocalRef(localClass);
+
+    if (this->instanceClass == NULL)
+    {
+        throw GiwsException::JniObjectCreationException(curEnv, this->className());
+    }
+
+    this->instance = curEnv->NewGlobalRef(JObj) ;
+    if (this->instance == NULL)
+    {
+        throw GiwsException::JniObjectCreationException(curEnv, this->className());
+    }
+    /* Methods ID set to NULL */
+    jintcreateJarArchivejstringjava_lang_StringjobjectArray_java_lang_Stringjava_lang_Stringjstringjava_lang_Stringjstringjava_lang_StringjbooleanbooleanID = NULL;
+
+
+}
+
+// Generic methods
+
+void ScilabJarCreator::synchronize()
+{
+    if (getCurrentEnv()->MonitorEnter(instance) != JNI_OK)
+    {
+        throw GiwsException::JniMonitorException(getCurrentEnv(), "ScilabJarCreator");
+    }
+}
+
+void ScilabJarCreator::endSynchronize()
+{
+    if ( getCurrentEnv()->MonitorExit(instance) != JNI_OK)
+    {
+        throw GiwsException::JniMonitorException(getCurrentEnv(), "ScilabJarCreator");
+    }
+}
+// Method(s)
+
+int ScilabJarCreator::createJarArchive (JavaVM * jvm_, char const* jarFilePath, char const* const* filePaths, int filePathsSize, char const* filesRootPath, char const* manifestFilePath, bool keepAbsolutePaths)
+{
+
+    JNIEnv * curEnv = NULL;
+    jvm_->AttachCurrentThread(reinterpret_cast<void **>(&curEnv), NULL);
+    jclass cls = curEnv->FindClass( className().c_str() );
+
+    jmethodID jintcreateJarArchivejstringjava_lang_StringjobjectArray_java_lang_Stringjava_lang_Stringjstringjava_lang_Stringjstringjava_lang_StringjbooleanbooleanID = curEnv->GetStaticMethodID(cls, "createJarArchive", "(Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)I" ) ;
+    if (jintcreateJarArchivejstringjava_lang_StringjobjectArray_java_lang_Stringjava_lang_Stringjstringjava_lang_Stringjstringjava_lang_StringjbooleanbooleanID == NULL)
+    {
+        throw GiwsException::JniMethodNotFoundException(curEnv, "createJarArchive");
+    }
+
+    jstring jarFilePath_ = curEnv->NewStringUTF( jarFilePath );
+    if (jarFilePath != NULL && jarFilePath_ == NULL)
+    {
+        throw GiwsException::JniBadAllocException(curEnv);
+    }
+
+    jclass stringArrayClass = curEnv->FindClass("java/lang/String");
+
+    // create java array of strings.
+    jobjectArray filePaths_ = curEnv->NewObjectArray( filePathsSize, stringArrayClass, NULL);
+    if (filePaths_ == NULL)
+    {
+        throw GiwsException::JniBadAllocException(curEnv);
+    }
+
+    // convert each char * to java strings and fill the java array.
+    for ( int i = 0; i < filePathsSize; i++)
+    {
+        jstring TempString = curEnv->NewStringUTF( filePaths[i] );
+        if (TempString == NULL)
+        {
+            throw GiwsException::JniBadAllocException(curEnv);
+        }
+
+        curEnv->SetObjectArrayElement( filePaths_, i, TempString);
+
+        // avoid keeping reference on to many strings
+        curEnv->DeleteLocalRef(TempString);
+    }
+    jstring filesRootPath_ = curEnv->NewStringUTF( filesRootPath );
+    if (filesRootPath != NULL && filesRootPath_ == NULL)
+    {
+        throw GiwsException::JniBadAllocException(curEnv);
+    }
+
+
+    jstring manifestFilePath_ = curEnv->NewStringUTF( manifestFilePath );
+    if (manifestFilePath != NULL && manifestFilePath_ == NULL)
+    {
+        throw GiwsException::JniBadAllocException(curEnv);
+    }
+
+
+    jboolean keepAbsolutePaths_ = (static_cast<bool>(keepAbsolutePaths) ? JNI_TRUE : JNI_FALSE);
+
+    jint res =  static_cast<jint>( curEnv->CallStaticIntMethod(cls, jintcreateJarArchivejstringjava_lang_StringjobjectArray_java_lang_Stringjava_lang_Stringjstringjava_lang_Stringjstringjava_lang_StringjbooleanbooleanID , jarFilePath_, filePaths_, filesRootPath_, manifestFilePath_, keepAbsolutePaths_));
+    curEnv->DeleteLocalRef(stringArrayClass);
+    curEnv->DeleteLocalRef(jarFilePath_);
+    curEnv->DeleteLocalRef(filePaths_);
+    curEnv->DeleteLocalRef(filesRootPath_);
+    curEnv->DeleteLocalRef(manifestFilePath_);
+    curEnv->DeleteLocalRef(cls);
+    if (curEnv->ExceptionCheck())
+    {
+        throw GiwsException::JniCallMethodException(curEnv);
+    }
+    return res;
+
+}
+
+}
diff --git a/scilab/modules/external_objects_java/src/jni/ScilabJarCreator.hxx b/scilab/modules/external_objects_java/src/jni/ScilabJarCreator.hxx
new file mode 100644 (file)
index 0000000..013348b
--- /dev/null
@@ -0,0 +1,159 @@
+/* Generated by GIWS (version 2.0.1) with command:
+giws -e -f ScilabObjects.giws.xml
+*/
+/*
+
+This is generated code.
+
+This software is a computer program whose purpose is to hide the complexity
+of accessing Java objects/methods from C++ code.
+
+This software is governed by the CeCILL-B license under French law and
+abiding by the rules of distribution of free software.  You can  use,
+modify and/ or redistribute the software under the terms of the CeCILL-B
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info".
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability.
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or
+data to be ensured and,  more generally, to use and operate it in the
+same conditions as regards security.
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL-B license and that you accept its terms.
+*/
+
+
+#ifndef __ORG_SCILAB_MODULES_EXTERNAL_OBJECTS_JAVA_SCILABJARCREATOR__
+#define __ORG_SCILAB_MODULES_EXTERNAL_OBJECTS_JAVA_SCILABJARCREATOR__
+#include <iostream>
+#include <string>
+#include <string.h>
+#include <stdlib.h>
+#include <jni.h>
+
+#include "GiwsException.hxx"
+
+#if defined(_MSC_VER) /* Defined anyway with Visual */
+#include <Windows.h>
+#else
+typedef signed char byte;
+#endif
+
+
+#ifndef GIWSEXPORT
+# if defined(_MSC_VER) || defined(__WIN32__) || defined(__CYGWIN__)
+#   if defined(STATIC_LINKED)
+#     define GIWSEXPORT
+#   else
+#     define GIWSEXPORT __declspec(dllexport)
+#   endif
+# else
+#   if __GNUC__ >= 4
+#     define GIWSEXPORT __attribute__ ((visibility ("default")))
+#   else
+#     define GIWSEXPORT
+#   endif
+# endif
+#endif
+
+namespace org_scilab_modules_external_objects_java
+{
+class GIWSEXPORT ScilabJarCreator
+{
+
+private:
+    JavaVM * jvm;
+
+protected:
+    jmethodID jintcreateJarArchivejstringjava_lang_StringjobjectArray_java_lang_Stringjava_lang_Stringjstringjava_lang_Stringjstringjava_lang_StringjbooleanbooleanID; // cache method id
+    jclass stringArrayClass;
+
+
+
+    jobject instance;
+    jclass instanceClass; // cache class
+
+
+    // Caching (if any)
+
+
+    /**
+    * Get the environment matching to the current thread.
+    */
+    virtual JNIEnv * getCurrentEnv();
+
+public:
+    // Constructor
+    /**
+    * Create a wrapping of the object from a JNIEnv.
+    * It will call the default constructor
+    * @param JEnv_ the Java Env
+    */
+    ScilabJarCreator(JavaVM * jvm_);
+
+    /**
+    * Create a wrapping of an already existing object from a JNIEnv.
+    * The object must have already been instantiated
+    * @param JEnv_ the Java Env
+    * @param JObj the object
+    */
+    ScilabJarCreator(JavaVM * jvm_, jobject JObj);
+
+
+    /**
+    * This is a fake constructor to avoid the constructor
+    * chaining when dealing with extended giws classes
+    */
+#ifdef FAKEGIWSDATATYPE
+    ScilabJarCreator(fakeGiwsDataType::fakeGiwsDataType /* unused */) {}
+#endif
+
+    // Destructor
+    ~ScilabJarCreator();
+
+    // Generic method
+    // Synchronization methods
+    /**
+    * Enter monitor associated with the object.
+    * Equivalent of creating a "synchronized(obj)" scope in Java.
+    */
+    void synchronize();
+
+    /**
+    * Exit monitor associated with the object.
+    * Equivalent of ending a "synchronized(obj)" scope.
+    */
+    void endSynchronize();
+
+    // Methods
+    static int createJarArchive(JavaVM * jvm_, char const* jarFilePath, char const* const* filePaths, int filePathsSize, char const* filesRootPath, char const* manifestFilePath, bool keepAbsolutePaths);
+
+
+    /**
+    * Get class name to use for static methods
+    * @return class name to use for static methods
+    */
+
+    static const std::string className()
+    {
+        return "org/scilab/modules/external_objects_java/ScilabJarCreator";
+    }
+
+};
+
+
+}
+#endif
index fb227f3..06f8774 100644 (file)
             <param type="int" name="idB" />
         </method>
     </object>
+    
+    <object name="ScilabJarCreator">
+        <method name="createJarArchive" returnType="int" modifier="static">
+            <param type="String" name="jarFilePath" />
+            <param type="String[]" name="filePaths" />
+        </method>
+    </object>
 </package>
diff --git a/scilab/modules/external_objects_java/tests/unit_tests/jcreatejar.dia.ref b/scilab/modules/external_objects_java/tests/unit_tests/jcreatejar.dia.ref
new file mode 100644 (file)
index 0000000..1d9bd46
--- /dev/null
@@ -0,0 +1,183 @@
+// =============================================================================
+// 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.
+// =============================================================================
+jimport java.io.FileInputStream;
+jimport java.util.zip.ZipInputStream;
+jimport java.util.zip.ZipEntry;
+testRootDir = fullfile(TMPDIR, "jcreatejar");
+mkdir(testRootDir);
+function path = createSubDir(parentDir, subDir, removeExistingDir)
+    path = fullfile(parentDir, subDir);
+    if isdir(path) & removeExistingDir then
+        removedir(path);
+    end
+    mkdir(path);
+endfunction
+function [filePath, fileContent] = addFileToPackage(fileName, package, packageDir, fileContent)
+    destDir = packageDir;
+    if ~isempty(package) then
+        fileDirs = strsplit(package, '.'),
+        for i = 1:size(fileDirs, '*')
+            destDir = createSubDir(destDir, fileDirs(i), %F);
+        end
+    end
+    filePath = fullfile(destDir, fileName);
+    fd = mopen(filePath, 'wt');
+    if ~isempty(fileContent)
+      mputl(fileContent, fd);
+    else
+      mputl(fileName, fd);
+    end
+    mclose(fd);
+endfunction
+function fileContent = extractFileContent(zipInputStream)
+    BUFFER_SIZE = 1000;
+    buffer = jarray("byte", BUFFER_SIZE);
+    n = zipInputStream.read(buffer, 0, BUFFER_SIZE);
+    if n > 0 then
+        fileContent = junwrap(buffer);
+        fileContent = fileContent(find(fileContent <> 0));
+        fileContent = char(fileContent);
+    else
+        fileContent = [];
+    end
+    jremove(buffer);
+endfunction
+function [filePaths, fileContents] = extractJarContent(zipFilePath)
+    filePaths = [];
+    fileContents = [];
+    fileInputStream = FileInputStream.new(zipFilePath);
+    zipInputStream = ZipInputStream.new(fileInputStream);
+    zipEntry = jinvoke(zipInputStream, "getNextEntry");
+    while ~isempty(zipEntry)
+        isDirectory = jinvoke(zipEntry, "isDirectory");
+        if ~isDirectory then
+            zipEntryName = jinvoke(zipEntry, "getName");
+            filePaths = [filePaths; zipEntryName];
+            fileContent = extractFileContent(zipInputStream);
+            fileContents = [fileContents; fileContent];
+        end
+        jinvoke(zipInputStream, "closeEntry");
+        zipEntry = jinvoke(zipInputStream, "getNextEntry");
+    end
+    zipEntry = jinvoke(zipInputStream, "close");
+endfunction
+function checkJar(jarFilePath, expectedJarFilePaths, expectedJarFileContents)
+    assert_checktrue(isfile(jarFilePath));
+    [jarFilePaths, jarFileContents] = extractJarContent(jarFilePath);
+    jarFilePaths = gsort(jarFilePaths);
+    expectedJarFilePaths = gsort(expectedJarFilePaths);
+    assert_checkequal(jarFilePaths, expectedJarFilePaths);
+    if ~isempty(expectedJarFileContents) then
+        assert_checkequal(jarFileContents, expectedJarFileContents);
+    end
+endfunction
+// TEST JAR STRUCTURE
+// Test create jar with one file, by Arg the dir path
+packageName = 'packageOneClassArgDirPath';
+jarSrcPath = createSubDir(testRootDir, packageName, %T);
+jarDestPath = fullfile(testRootDir, packageName + '.jar');
+addFileToPackage('FooDir', '', jarSrcPath, '');
+jcreatejar(jarDestPath, jarSrcPath);
+checkJar(jarDestPath, ['META-INF/MANIFEST.MF'; 'FooDir'], []);
+// Test create jar with one file, by Arg the file path
+packageName = 'packageOneClassArgFilePath';
+jarSrcPath = createSubDir(testRootDir, packageName, %T);
+jarDestPath = fullfile(testRootDir, packageName + '.jar');
+filePath = addFileToPackage('FooFile', '', jarSrcPath, '');
+jcreatejar(jarDestPath, filePath);
+checkJar(jarDestPath, ['META-INF/MANIFEST.MF'; 'FooFile'], []);
+// Test create jar with two files, by Arg the dir path
+packageName = 'packageTwoClassesArgDirPath';
+jarSrcPath = createSubDir(testRootDir, packageName, %T);
+jarDestPath = fullfile(testRootDir, packageName + '.jar');
+addFileToPackage('FooDir1', '', jarSrcPath, '');
+addFileToPackage('FooDir2', '', jarSrcPath, '');
+jcreatejar(jarDestPath, jarSrcPath);
+checkJar(jarDestPath, ['META-INF/MANIFEST.MF'; 'FooDir1'; 'FooDir2'], []);
+// Test create jar with two files, by Arg the file paths
+packageName = 'packageTwoClassesArgFilePaths';
+jarSrcPath = createSubDir(testRootDir, packageName, %T);
+jarDestPath = fullfile(testRootDir, packageName + '.jar');
+filePath1 = addFileToPackage('FooFile1', '', jarSrcPath, '');
+filePath2 = addFileToPackage('FooFile2', '', jarSrcPath, '');
+jcreatejar(jarDestPath, [filePath1, filePath2]);
+checkJar(jarDestPath, ['META-INF/MANIFEST.MF'; 'FooFile1'; 'FooFile2'], []);
+// Test create jar with two files and one folder, by Arg the dir path
+packageName = 'packageOneFolderArgDirPath';
+jarSrcPath = createSubDir(testRootDir, packageName, %T);
+jarDestPath = fullfile(testRootDir, packageName + '.jar');
+addFileToPackage('FooRoot', '', jarSrcPath, '');
+addFileToPackage('FooFolder', 'folder', jarSrcPath, '');
+jcreatejar(jarDestPath, jarSrcPath);
+checkJar(jarDestPath, ['META-INF/MANIFEST.MF'; 'folder/FooFolder'; 'FooRoot'], []);
+// Test create a standard package 'org.scilab.test.package'
+packageName = 'org.scilab.test.mypackage';
+jarSrcPath = createSubDir(testRootDir, packageName, %T);
+jarDestPath = fullfile(testRootDir, packageName + '.jar');
+addFileToPackage('FooPackage1', packageName, jarSrcPath, '');
+addFileToPackage('FooPackage2', packageName, jarSrcPath, '');
+jcreatejar(jarDestPath, jarSrcPath);
+checkJar(jarDestPath, ..
+    ['META-INF/MANIFEST.MF'; ..
+     'org/scilab/test/mypackage/FooPackage1'; ..
+     'org/scilab/test/mypackage/FooPackage2'], ..
+     []);
+// Test argument files root path
+packageName = 'packageFilesRootPath';
+jarSrcPath = createSubDir(testRootDir, packageName, %T);
+jarDestPath = fullfile(testRootDir, packageName + '.jar');
+addFileToPackage('image1', 'images', jarSrcPath, '');
+addFileToPackage('image2', 'images', jarSrcPath, '');
+addFileToPackage('icon1', 'images/icon', jarSrcPath, '');
+jcreatejar(jarDestPath, jarSrcPath, jarSrcPath);
+checkJar(jarDestPath, ..
+    ['META-INF/MANIFEST.MF'; ..
+     'images/icon/icon1'; ..
+     'images/image1'; ..
+     'images/image2'] ..
+     , []);
+// TESTS JAR MANIFEST
+// Manifest data
+// Manifest need version, otherwise the created manifest may be empty
+manifestData = msprintf('Manifest-Version: 1.0\nName: testManifest');
+CRLF = ascii([13 10]);
+expectedManifestData = 'Manifest-Version: 1.0' + CRLF + ..
+    'Name: testManifest' + CRLF + CRLF;
+// Test META-INF\MANIFEST.MF manifest file is loaded
+packageName = 'packageManifest';
+jarSrcPath = createSubDir(testRootDir, packageName, %T);
+jarDestPath = fullfile(testRootDir, packageName + '.jar');
+addFileToPackage('MANIFEST.MF', 'META-INF', jarSrcPath, manifestData);
+jcreatejar(jarDestPath, jarSrcPath);
+checkJar(jarDestPath, ['META-INF/MANIFEST.MF'], [expectedManifestData]);
+// Test argument manifest file path
+packageName = 'packageManifest';
+jarSrcPath = createSubDir(testRootDir, packageName, %T);
+jarDestPath = fullfile(testRootDir, packageName + '.jar');
+// Create a manifest file somewhere
+manifestFilePath = fullfile(testRootDir, 'MANIFEST_TEST.MF')
+ manifestFilePath  =
+ TMPDIR\jcreatejar\MANIFEST 
+      _TEST.MF                                                          
+fd = mopen(manifestFilePath, 'wt');
+mputl(manifestData, fd);
+mclose(fd);
+jcreatejar(jarDestPath, jarSrcPath, '', manifestFilePath);
+checkJar(jarDestPath, ['META-INF/MANIFEST.MF'], [expectedManifestData]);
+// OTHER TESTS
+// Test JAR overwirting
+packageName = 'packageOverwriting';
+jarSrcPath = createSubDir(testRootDir, packageName, %T);
+jarDestPath = fullfile(testRootDir, packageName + '.jar');
+addFileToPackage('Foo', '', jarSrcPath, '');
+jcreatejar(jarDestPath, jarSrcPath);
+checkJar(jarDestPath, ['META-INF/MANIFEST.MF'; 'Foo'], []);
+// overwrite package
+addFileToPackage('Foo2', '', jarSrcPath, '');
+jcreatejar(jarDestPath, jarSrcPath);
+checkJar(jarDestPath, ['META-INF/MANIFEST.MF'; 'Foo'; 'Foo2'], []);
diff --git a/scilab/modules/external_objects_java/tests/unit_tests/jcreatejar.tst b/scilab/modules/external_objects_java/tests/unit_tests/jcreatejar.tst
new file mode 100644 (file)
index 0000000..dfad932
--- /dev/null
@@ -0,0 +1,205 @@
+// =============================================================================
+// 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.
+// =============================================================================
+
+jimport java.io.FileInputStream;
+jimport java.util.zip.ZipInputStream;
+jimport java.util.zip.ZipEntry;
+
+testRootDir = fullfile(TMPDIR, "jcreatejar");
+mkdir(testRootDir);
+
+function path = createSubDir(parentDir, subDir, removeExistingDir)
+    path = fullfile(parentDir, subDir);
+    if isdir(path) & removeExistingDir then
+        removedir(path);
+    end
+    mkdir(path);
+endfunction
+
+function [filePath, fileContent] = addFileToPackage(fileName, package, packageDir, fileContent)
+    destDir = packageDir;
+    if ~isempty(package) then
+        fileDirs = strsplit(package, '.'),
+        for i = 1:size(fileDirs, '*')
+            destDir = createSubDir(destDir, fileDirs(i), %F);
+        end
+    end
+    filePath = fullfile(destDir, fileName);
+
+    fd = mopen(filePath, 'wt');
+    if ~isempty(fileContent)
+      mputl(fileContent, fd);
+    else
+      mputl(fileName, fd);
+    end
+    mclose(fd);
+endfunction
+
+function fileContent = extractFileContent(zipInputStream)
+    BUFFER_SIZE = 1000;
+    buffer = jarray("byte", BUFFER_SIZE);
+    n = zipInputStream.read(buffer, 0, BUFFER_SIZE);
+    if n > 0 then
+        fileContent = junwrap(buffer);
+        fileContent = fileContent(find(fileContent <> 0));
+        fileContent = char(fileContent);
+    else
+        fileContent = [];
+    end
+    jremove(buffer);
+endfunction
+
+function [filePaths, fileContents] = extractJarContent(zipFilePath)
+    filePaths = [];
+    fileContents = [];
+
+    fileInputStream = FileInputStream.new(zipFilePath);
+    zipInputStream = ZipInputStream.new(fileInputStream);
+
+    zipEntry = jinvoke(zipInputStream, "getNextEntry");
+
+    while ~isempty(zipEntry)
+        isDirectory = jinvoke(zipEntry, "isDirectory");
+        if ~isDirectory then
+            zipEntryName = jinvoke(zipEntry, "getName");
+            filePaths = [filePaths; zipEntryName];
+            fileContent = extractFileContent(zipInputStream);
+            fileContents = [fileContents; fileContent];
+        end
+        jinvoke(zipInputStream, "closeEntry");
+        zipEntry = jinvoke(zipInputStream, "getNextEntry");
+    end
+    zipEntry = jinvoke(zipInputStream, "close");
+endfunction
+
+function checkJar(jarFilePath, expectedJarFilePaths, expectedJarFileContents)
+    assert_checktrue(isfile(jarFilePath));
+    [jarFilePaths, jarFileContents] = extractJarContent(jarFilePath);
+    jarFilePaths = gsort(jarFilePaths);
+    expectedJarFilePaths = gsort(expectedJarFilePaths);
+    assert_checkequal(jarFilePaths, expectedJarFilePaths);
+    if ~isempty(expectedJarFileContents) then
+        assert_checkequal(jarFileContents, expectedJarFileContents);
+    end
+endfunction
+
+// TEST JAR STRUCTURE
+
+// Test create jar with one file, by Arg the dir path
+packageName = 'packageOneClassArgDirPath';
+jarSrcPath = createSubDir(testRootDir, packageName, %T);
+jarDestPath = fullfile(testRootDir, packageName + '.jar');
+addFileToPackage('FooDir', '', jarSrcPath, '');
+jcreatejar(jarDestPath, jarSrcPath);
+checkJar(jarDestPath, ['META-INF/MANIFEST.MF'; 'FooDir'], []);
+
+// Test create jar with one file, by Arg the file path
+packageName = 'packageOneClassArgFilePath';
+jarSrcPath = createSubDir(testRootDir, packageName, %T);
+jarDestPath = fullfile(testRootDir, packageName + '.jar');
+filePath = addFileToPackage('FooFile', '', jarSrcPath, '');
+jcreatejar(jarDestPath, filePath);
+checkJar(jarDestPath, ['META-INF/MANIFEST.MF'; 'FooFile'], []);
+
+// Test create jar with two files, by Arg the dir path
+packageName = 'packageTwoClassesArgDirPath';
+jarSrcPath = createSubDir(testRootDir, packageName, %T);
+jarDestPath = fullfile(testRootDir, packageName + '.jar');
+addFileToPackage('FooDir1', '', jarSrcPath, '');
+addFileToPackage('FooDir2', '', jarSrcPath, '');
+jcreatejar(jarDestPath, jarSrcPath);
+checkJar(jarDestPath, ['META-INF/MANIFEST.MF'; 'FooDir1'; 'FooDir2'], []);
+
+// Test create jar with two files, by Arg the file paths
+packageName = 'packageTwoClassesArgFilePaths';
+jarSrcPath = createSubDir(testRootDir, packageName, %T);
+jarDestPath = fullfile(testRootDir, packageName + '.jar');
+filePath1 = addFileToPackage('FooFile1', '', jarSrcPath, '');
+filePath2 = addFileToPackage('FooFile2', '', jarSrcPath, '');
+jcreatejar(jarDestPath, [filePath1, filePath2]);
+checkJar(jarDestPath, ['META-INF/MANIFEST.MF'; 'FooFile1'; 'FooFile2'], []);
+
+// Test create jar with two files and one folder, by Arg the dir path
+packageName = 'packageOneFolderArgDirPath';
+jarSrcPath = createSubDir(testRootDir, packageName, %T);
+jarDestPath = fullfile(testRootDir, packageName + '.jar');
+addFileToPackage('FooRoot', '', jarSrcPath, '');
+addFileToPackage('FooFolder', 'folder', jarSrcPath, '');
+jcreatejar(jarDestPath, jarSrcPath);
+checkJar(jarDestPath, ['META-INF/MANIFEST.MF'; 'folder/FooFolder'; 'FooRoot'], []);
+
+// Test create a standard package 'org.scilab.test.package'
+packageName = 'org.scilab.test.mypackage';
+jarSrcPath = createSubDir(testRootDir, packageName, %T);
+jarDestPath = fullfile(testRootDir, packageName + '.jar');
+addFileToPackage('FooPackage1', packageName, jarSrcPath, '');
+addFileToPackage('FooPackage2', packageName, jarSrcPath, '');
+jcreatejar(jarDestPath, jarSrcPath);
+checkJar(jarDestPath, ..
+    ['META-INF/MANIFEST.MF'; ..
+     'org/scilab/test/mypackage/FooPackage1'; ..
+     'org/scilab/test/mypackage/FooPackage2'], ..
+     []);
+
+// Test argument files root path
+packageName = 'packageFilesRootPath';
+jarSrcPath = createSubDir(testRootDir, packageName, %T);
+jarDestPath = fullfile(testRootDir, packageName + '.jar');
+addFileToPackage('image1', 'images', jarSrcPath, '');
+addFileToPackage('image2', 'images', jarSrcPath, '');
+addFileToPackage('icon1', 'images/icon', jarSrcPath, '');
+jcreatejar(jarDestPath, jarSrcPath, jarSrcPath);
+checkJar(jarDestPath, ..
+    ['META-INF/MANIFEST.MF'; ..
+     'images/icon/icon1'; ..
+     'images/image1'; ..
+     'images/image2'] ..
+     , []);
+
+// TESTS JAR MANIFEST
+
+// Manifest data
+// Manifest need version, otherwise the created manifest may be empty
+manifestData = msprintf('Manifest-Version: 1.0\nName: testManifest');
+CRLF = ascii([13 10]);
+expectedManifestData = 'Manifest-Version: 1.0' + CRLF + ..
+    'Name: testManifest' + CRLF + CRLF;
+
+// Test META-INF\MANIFEST.MF manifest file is loaded
+packageName = 'packageManifest';
+jarSrcPath = createSubDir(testRootDir, packageName, %T);
+jarDestPath = fullfile(testRootDir, packageName + '.jar');
+addFileToPackage('MANIFEST.MF', 'META-INF', jarSrcPath, manifestData);
+jcreatejar(jarDestPath, jarSrcPath);
+checkJar(jarDestPath, ['META-INF/MANIFEST.MF'], [expectedManifestData]);
+
+// Test argument manifest file path
+packageName = 'packageManifest';
+jarSrcPath = createSubDir(testRootDir, packageName, %T);
+jarDestPath = fullfile(testRootDir, packageName + '.jar');
+// Create a manifest file somewhere
+manifestFilePath = fullfile(testRootDir, 'MANIFEST_TEST.MF')
+fd = mopen(manifestFilePath, 'wt');
+mputl(manifestData, fd);
+mclose(fd);
+jcreatejar(jarDestPath, jarSrcPath, '', manifestFilePath);
+checkJar(jarDestPath, ['META-INF/MANIFEST.MF'], [expectedManifestData]);
+
+// OTHER TESTS
+
+// Test JAR overwirting
+packageName = 'packageOverwriting';
+jarSrcPath = createSubDir(testRootDir, packageName, %T);
+jarDestPath = fullfile(testRootDir, packageName + '.jar');
+addFileToPackage('Foo', '', jarSrcPath, '');
+jcreatejar(jarDestPath, jarSrcPath);
+checkJar(jarDestPath, ['META-INF/MANIFEST.MF'; 'Foo'], []);
+// overwrite package
+addFileToPackage('Foo2', '', jarSrcPath, '');
+jcreatejar(jarDestPath, jarSrcPath);
+checkJar(jarDestPath, ['META-INF/MANIFEST.MF'; 'Foo'; 'Foo2'], []);
+