Merge remote-tracking branch 'origin/6.1'
[scilab.git] / scilab / modules / dynamic_link / macros / ilib_build_jar.sci
1 // ====================================================================
2 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 // Copyright (C) 2013 - Scilab Enterprises
4 //
5 // Copyright (C) 2012 - 2016 - Scilab Enterprises
6 //
7 // This file is hereby licensed under the terms of the GNU GPL v2.0,
8 // pursuant to article 5.3.4 of the CeCILL v.2.1.
9 // This file was originally licensed under the terms of the CeCILL v2.1,
10 // and continues to be available under such terms.
11 // For more information, see the COPYING file which you should have received
12 // along with this program.
13 // =====================================================================
14
15 // Builds a Java package (JAR) from a set of Java sources (see SEP #116)
16 // - jarFilePath: is the JAR target file path
17 // - packageNames: names of packages to archive in the JAR
18 // - sourcePaths: paths to directories containing Java sources
19 // - classPaths (optional): paths to dependencies (JARs or directories)
20 // - manifestFilePath (optional) : file path to manifest
21 function ilib_build_jar(jarFilePath, packageNames, sourcePaths, classPaths, manifestFilePath)
22
23     // Returns all the java source files contained in a path tree
24     function javaFilePaths = findJavaFiles(path, javaFilePaths)
25         fileNames = listfiles(path)';
26         if (isempty(fileNames)) then
27             return;
28         end
29         filePaths = fullfile(path, fileNames);
30
31         // First, explore sub directories
32         dirPaths = filePaths(find(isdir(filePaths)));
33         for i = 1:size(dirPaths, "*")
34             javaFilePaths = [javaFilePaths; findJavaFiles(dirPaths(i), [])];
35         end
36
37         // Then add Java files of that directory
38         dirJavaFilePaths = filePaths(find(fileext(filePaths) == ".java"));
39         javaFilePaths = [javaFilePaths; dirJavaFilePaths'];
40     endfunction
41
42     // Returns the JIMS build root path
43     // It is the JIMS/bin folder in TMPDIR
44     function jimsBuildPath = getJimsBuildPath()
45         jimsBuildPath = fullfile(TMPDIR, "JIMS/bin");
46     endfunction
47
48     // Returns the package compilation path
49     // It is the 'deepest' directory containing the built classes
50     // if package is 'com.foo.package' the returned path will be:
51     //   TMPDIR/JIMS/bin/com/foo/package
52     function packageCompilePath = getPackageCompilePath(packageName)
53         packageSubPath = strsubst(packageName, ".", filesep());
54         packageCompilePath = fullfile(getJimsBuildPath(), packageSubPath);
55     endfunction
56
57     // Returns the jar root input path
58     // It is the directory that will be jar-ed
59     // if jar is 'com.foo.package' the returned path will be:
60     //   TMPDIR/JIMS/bin/com.foo.package
61     function jarInputRootPath = getJarInputRootPath(jarName)
62         jarInputRootPath = fullfile(getJimsBuildPath(), "_jar_" + jarName);
63         if isdir(jarInputRootPath) then
64             removedir(jarInputRootPath);
65         end
66         mkdir(jarInputRootPath);
67     endfunction
68
69     // Returns the package path in the jar input path
70     // It is the directory where the classes will be copied
71     // if package is 'com.foo.package' the returned path will be:
72     //   TMPDIR/JIMS/com.foo.package/bin/com/foo/package
73     function jarInputPackagePath = getJarPackagePath(jarInputRootPath, packageName)
74         if ~isempty(packageName) then
75             packagePath = strsubst(packageName, ".", filesep());
76             jarInputPackagePath = fullfile(jarInputRootPath, packagePath);
77             mkdir(jarInputPackagePath);
78         else
79             jarInputPackagePath = jarInputRootPath;
80         end
81     endfunction
82
83     // Add header instructions for loader and cleaner script (license info, change dir, etc..)
84     function addHeaderToScript(scriptName, fd)
85         mputl("// This file is released under the 3-clause BSD license. See COPYING-BSD.", fd);
86         mputl("// Generated by builder.sce: Please, do not edit this file.", fd);
87         mputl("// ------------------------------------------------------", fd);
88         mputl("curdir = pwd();", fd);
89         mputl(msprintf("scriptdir = get_file_path(''%s'');", scriptName), fd);
90         mputl(msprintf("chdir(scriptdir);"), fd);
91         mputl("// ------------------------------------------------------", fd);
92     endfunction
93
94     // Add footer instructions for loader and cleaner script (restore dir, etc..)
95     function addFooterToScript(fd)
96         mputl("// ------------------------------------------------------", fd);
97         mputl("chdir(curdir);", fd);
98         mputl("clear curdir;", fd);
99     endfunction
100
101     // Creates a loader script (loader.sce)
102     // Does the javaclasspath on the created jar file
103     function createLoaderScript(loaderScriptName, jarFilePath)
104         fd = mopen(loaderScriptName, "wt");
105         addHeaderToScript(loaderScriptName, fd);
106         mputl(msprintf("jarFilePath = fullfile(scriptdir, ''%s'');", jarFilePath), fd);
107         mputl("javaclasspath(fullpath(jarFilePath));", fd);
108         addFooterToScript(fd);
109         mclose(fd);
110     endfunction
111
112     // Creates a cleaner script (cleaner.sce)
113     // Deletes the loader script and jar file
114     function createCleanerScript(cleanerScriptName, loaderScriptName, jarFilePath)
115         fd = mopen(cleanerScriptName, "wt");
116         addHeaderToScript(cleanerScriptName, fd);
117         mputl(msprintf("if fileinfo(''%s'') <> [] then", loaderScriptName), fd');
118         mputl(msprintf("    mdelete(''%s'');", loaderScriptName), fd);
119         mputl("end", fd);
120         mputl("// ------------------------------------------------------", fd);
121         mputl(msprintf("jarFilePath = fullfile(scriptdir, ''%s'');", jarFilePath), fd);
122         mputl("if fileinfo(jarFilePath) <> [] then", fd);
123         mputl("    mdelete(jarFilePath);", fd);
124         mputl("end", fd);
125         addFooterToScript(fd);
126         mclose(fd);
127     endfunction
128
129
130     // ilib_build_jar body
131
132     // ilib_build_jar needs Java, it is not usable in NWNI mode
133     if (getscilabmode() == "NWNI")
134         error(msprintf(_("%s: function not available in NWNI mode.\n"), "ilib_build_jar"));
135         return;
136     end
137
138     // Check input arguments
139     [lhs, rhs] = argn(0);
140     if rhs < 3 then
141         error(msprintf(_("%s: Wrong number of input argument(s): 3 to 5 expected.\n"), "ilib_build_jar"));
142         return;
143     end
144
145     // Input argument 1: jar file path
146     if type(jarFilePath) <> 10 then
147         error(msprintf(_("%s: Wrong type for input argument #%d: string expected.\n"), "ilib_build_jar", 1));
148     end
149     if size(jarFilePath, "*") <> 1 then
150         error(msprintf(_("%s: Wrong size for input argument #%d: string expected.\n"), "ilib_build_jar", 1));
151         return;
152     end
153
154     // Input argument 2: package names
155     if rhs > 2 then
156         if type(packageNames) <> 10 then
157             error(msprintf(_("%s: Wrong type for input argument #%d: A matrix of strings expected.\n"), "ilib_build_jar", 2));
158             return;
159         end
160     end
161
162     // Input argument 3: source paths
163     if type(sourcePaths) <> 10 then
164         error(msprintf(_("%s: Wrong type for input argument #%d: A matrix of strings expected.\n"), "ilib_build_jar", 3));
165         return;
166     end
167
168     // Input argument 4 (optional): class paths
169     if rhs > 3 then
170         if type(classPaths) <> 10 then
171             error(msprintf(_("%s: Wrong type for input argument #%d: A matrix of strings expected.\n"), "ilib_build_jar", 4));
172             return;
173         end
174     else
175         classPaths = "";
176     end
177
178     // Input argument 5 (optional): manifest file path
179     if rhs > 4 then
180         if type(manifestFilePath) <> 10 then
181             error(msprintf(_("%s: Wrong type for input argument #%d: A matrix of strings expected.\n"), "ilib_build_jar", 5));
182             return;
183         end
184     else
185         manifestFilePath = "";
186     end
187
188     [jarDir, jarName] = fileparts(jarFilePath);
189
190     if (ilib_verbose() <> 0) then
191         mprintf(_("   Building JAR library %s\n"), jarName + ".jar");
192     end
193
194     // Create a directory for jar creation
195     jarInputRootPath = getJarInputRootPath(jarName);
196     if ~isdir(jarInputRootPath) then
197         error(msprintf(_("Cannot create jar build dir %s"), jarInputRootPath));
198         return;
199     end
200
201     // Dependencies
202     if ~isempty(classPaths) then
203         if (ilib_verbose() == 2) then
204             mprintf(_("   Add dependency class paths:\n%s\n"), classPaths);
205         end
206         javaclasspath(classPaths);
207     end
208
209     nbPackages = size(packageNames, "*");
210     for i = 1:nbPackages
211         packageName = packageNames(i);
212         if (ilib_verbose() == 2) then
213             mprintf(_("   Build package %s\n"), packageName);
214         end
215
216         // Delete each package compilation directory if exists
217         packageCompilePath = getPackageCompilePath(packageName);
218         if isdir(packageCompilePath) then
219             removedir(packageCompilePath);
220         end
221
222         // Find all Java sources for that package and compile
223         sourcePath = sourcePaths(i);
224         javaFilePaths = findJavaFiles(sourcePath, []);
225         if javaFilePaths <> [] then
226             if (ilib_verbose() == 2) then
227                 mprintf(_("   Compiling source files:\n"));
228                 disp(javaFilePaths);
229             elseif (ilib_verbose() == 1) then
230                 mprintf(_("   Compiling Java sources in %s\n"), sourcePath);
231             end
232             jcompile(javaFilePaths);
233         else
234             if (ilib_verbose() <> 0) then
235                 warning(msprintf(_("No Java sources in %s to compile for package %s"), sourcePath, packageName));
236             end
237         end
238
239         // Copy package compiled classes ...
240         packageCompilePath = getPackageCompilePath(packageName);
241         if isdir(packageCompilePath) then
242             // ... to its location in JAR
243             jarInputPackagePath = getJarPackagePath(jarInputRootPath, packageName);
244             if ~isdir(jarInputPackagePath) then
245                 error(msprintf(_("Cannot create jar package directory %s"), jarInputRootPath));
246             end
247
248             if (ilib_verbose() == 2) then
249                 mprintf(_("   Copying compiled package from %s to %s\n"), packageCompilePath, jarInputPackagePath);
250             end
251             copyfile(packageCompilePath, jarInputPackagePath);
252         else
253             if (ilib_verbose() <> 0) then
254                 warning(msprintf(_("Cannot find compilation directory %s for package %s"), packageCompilePath, packageName));
255             end
256         end
257     end
258
259     // Delete target jar if already exists
260     if isfile(jarFilePath) then
261         deletefile(jarFilePath);
262     end
263
264     // Create jar
265     if (ilib_verbose() <> 0) then
266         mprintf(_("   Creating JAR archive %s\n"), jarFilePath);
267     end
268     jcreatejar(jarFilePath, jarInputRootPath, "", manifestFilePath);
269     if ~isfile(jarFilePath) then
270         error(msprintf(_("Cannot create JAR file %s"), jarFilePath));
271     end
272
273     // Creates script
274     jarFileRelativePath = getrelativefilename(pwd(), jarFilePath);
275     if (ilib_verbose() == 2) then
276         mprintf(_("   Creating scripts for JAR relative path %s\n"), jarFileRelativePath);
277     end
278
279     // Creates loader script
280     loaderScriptName = "loader.sce";
281     if (ilib_verbose() <> 0) then
282         mprintf(_("   Create loader script for Java %s\n"), loaderScriptName);
283     end
284     createLoaderScript(loaderScriptName, jarFileRelativePath);
285
286     // Creates cleaner script
287     cleanerScriptName = "cleaner.sce";
288     if (ilib_verbose() <> 0) then
289         mprintf(_("   Create cleaner script for Java %s\n"), cleanerScriptName);
290     end
291     createCleanerScript(cleanerScriptName, loaderScriptName, jarFileRelativePath);
292 endfunction