Skip to content

Commit 5ad6c6a

Browse files
committed
Merge branch 'main' of github.com:FormikoLudo/Utils
2 parents ac557cc + dbc8262 commit 5ad6c6a

File tree

4 files changed

+197
-33
lines changed

4 files changed

+197
-33
lines changed

src/main/java/fr/formiko/utils/FLUFiles.java

+79-22
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
public class FLUFiles {
2929
private static FLUFilesInternal internal = new FLUFilesInternal();
3030
private static FLUProgression progression;
31+
private static final String FILE_SEPARATOR = "/";
3132

3233
private FLUFiles() {} // hide constructor
3334

@@ -71,10 +72,12 @@ public static boolean unzip(String source, String destination, String directoryI
7172
public static boolean unzip(String source, String destination) { return unzip(source, destination, ""); }
7273

7374
public static boolean download(String url, String destination) { return internal.download(url, destination); }
74-
public static boolean downloadAndUnzip(String url, String destination, String directoryInsideZipToGet) { return false; }
75+
public static boolean downloadAndUnzip(String url, String destination, String directoryInsideZipToGet) {
76+
return internal.downloadAndUnzip(url, destination, directoryInsideZipToGet);
77+
}
7578
public static boolean downloadAndUnzip(String url, String destination) { return downloadAndUnzip(url, destination, ""); }
76-
public static String downloadAndRead(String url) { return null; }
77-
public static int countEntryOfZipFile(String url) { return -1; }
79+
public static String downloadAndRead(String url) { return readFileFromWeb(url); }
80+
public static int countEntryOfZipFile(String url) { return internal.countEntryOfZipFile(url); }
7881
public static long getSize(String path) { return -1; }
7982

8083
public static boolean setMaxPermission(String path, boolean recursive) { return false; }
@@ -125,7 +128,7 @@ private boolean delete(String path) {
125128
File f = new File(path);
126129
if (f.isDirectory()) {
127130
for (String subPath : f.list()) {
128-
delete(path + File.separator + subPath);
131+
delete(path + FILE_SEPARATOR + subPath);
129132
}
130133
}
131134
return f.delete();
@@ -147,7 +150,7 @@ private boolean copy(String source, String destination) {
147150
if (sourceFile.isDirectory()) {
148151
destinationFile.mkdirs();
149152
for (String subPath : sourceFile.list()) {
150-
copy(source + File.separator + subPath, destination + File.separator + subPath);
153+
copy(source + FILE_SEPARATOR + subPath, destination + FILE_SEPARATOR + subPath);
151154
}
152155
return true;
153156
}
@@ -297,7 +300,7 @@ private boolean zip(String source, String destination) {
297300
}
298301
private void zipFile(File fileToZip, String fileName, String destination, ZipOutputStream zos) throws IOException {
299302
if (fileToZip.isDirectory()) {
300-
fileName = FLUStrings.addAtTheEndIfNeeded(fileName, File.separator);
303+
fileName = FLUStrings.addAtTheEndIfNeeded(fileName, FILE_SEPARATOR);
301304
zos.putNextEntry(new ZipEntry(fileName));
302305
zos.closeEntry();
303306
for (File file : fileToZip.listFiles()) {
@@ -317,15 +320,30 @@ private void createParents(File file) {
317320
}
318321

319322
private boolean unzip(String source, String destination, String directoryInsideZipToGet) {
320-
if (isAValidePath(source) && isAValidePath(destination)) {
323+
if (isAValidePath(source)) {
321324
source = FLUStrings.addAtTheEndIfNeeded(source, ".zip");
325+
try {
326+
return unzip(Files.newInputStream(Paths.get(source)), destination, directoryInsideZipToGet);
327+
} catch (IOException e) {
328+
return false;
329+
}
330+
} else {
331+
return false;
332+
}
333+
}
334+
335+
private boolean unzip(InputStream source, String destination, String directoryInsideZipToGet) {
336+
if (isAValidePath(destination)) {
322337
File destinationFile = new File(destination);
323338
createParents(destinationFile);
324-
try (ZipInputStream zis = new ZipInputStream(Files.newInputStream(Paths.get(source)))) {
339+
try (ZipInputStream zis = new ZipInputStream(source)) {
340+
boolean allOk = true;
325341
for (ZipEntry entry = zis.getNextEntry(); entry != null; entry = zis.getNextEntry()) {
326-
createZipEntry(destination, directoryInsideZipToGet, zis, entry);
342+
if (!createZipEntry(destination, directoryInsideZipToGet, zis, entry)) {
343+
allOk = false;
344+
}
327345
}
328-
return true;
346+
return allOk;
329347
} catch (Exception e) {
330348
System.out.println(e);
331349
e.printStackTrace();
@@ -335,26 +353,35 @@ private boolean unzip(String source, String destination, String directoryInsideZ
335353
return false;
336354
}
337355
}
338-
private void createZipEntry(String destination, String directoryInsideZipToGet, ZipInputStream zis, ZipEntry entry)
356+
private boolean createZipEntry(String destination, String directoryInsideZipToGet, ZipInputStream zis, ZipEntry entry)
339357
throws IOException {
358+
directoryInsideZipToGet = FLUStrings.removeAtTheEndIfNeeded(directoryInsideZipToGet.replace('\\', '/'), FILE_SEPARATOR);
340359
File destinationFile = new File(destination);
341-
String absoluteDestinationPath = FLUStrings.addAtTheEndIfNeeded(destinationFile.getAbsolutePath(), File.separator);
342-
// System.out.println("absoluteDestinationPath: " + absoluteDestinationPath);
343-
String entryName = entry.getName();
344-
// System.out.println("entryName before: " + entryName);
345-
if (entryName.startsWith(directoryInsideZipToGet)) {
346-
entryName = entryName.substring(Math.max(0, directoryInsideZipToGet.length() - 1));
360+
String absoluteDestinationPath = FLUStrings.addAtTheEndIfNeeded(destinationFile.getAbsolutePath().replace('\\', '/'),
361+
FILE_SEPARATOR);
362+
String entryName = entry.getName().replace('\\', '/');
363+
if (directoryInsideZipToGet.isEmpty() || directoryInsideZipToGet.equals(".") || entryName.startsWith(directoryInsideZipToGet)) {
364+
// Remove part of the path that we don't want
365+
int charToCut = directoryInsideZipToGet.lastIndexOf('/');
366+
entryName = FLUStrings.removeAtTheBeginningIfNeeded(entryName.substring(Math.max(0, charToCut)), FILE_SEPARATOR);
367+
368+
if (entryName.isEmpty()) {
369+
return true;
370+
}
347371
File fileToCreate = new File(destination, entryName);
348-
if (fileToCreate.getAbsolutePath().startsWith(absoluteDestinationPath)) {
349-
// System.out.println("entryName: " + entryName);
372+
if (fileToCreate.getAbsolutePath().replace('\\', '/').startsWith(absoluteDestinationPath)) {
350373
if (entry.isDirectory()) {
351-
createDirectory(absoluteDestinationPath + entryName);
374+
if (!createDirectory(absoluteDestinationPath + entryName)) {
375+
return false;
376+
}
377+
return true;
352378
} else {
353379
createParents(absoluteDestinationPath + entryName);
354-
Files.copy(zis, Paths.get(absoluteDestinationPath + entryName));
380+
return Files.copy(zis, Paths.get(absoluteDestinationPath + entryName)) >= 0L;
355381
}
356382
}
357383
}
384+
return true;
358385
}
359386

360387
private boolean download(String url, String destination) {
@@ -373,6 +400,37 @@ private boolean download(String url, String destination) {
373400
return false;
374401
}
375402
}
403+
404+
private boolean downloadAndUnzip(String url, String destination, String directoryInsideZipToGet) {
405+
if (isAValidePath(url)) {
406+
url = FLUStrings.addAtTheEndIfNeeded(url, ".zip");
407+
try {
408+
return unzip(URI.create(url).toURL().openStream(), destination, directoryInsideZipToGet);
409+
} catch (IOException e) {
410+
return false;
411+
}
412+
} else {
413+
return false;
414+
}
415+
}
416+
417+
private int countEntryOfZipFile(String url) {
418+
if (isAValidePath(url)) {
419+
try (ZipInputStream zis = new ZipInputStream(URI.create(url).toURL().openStream())) {
420+
int count = 0;
421+
while (zis.getNextEntry() != null) {
422+
count++;
423+
}
424+
return count;
425+
} catch (IOException e) {
426+
return -1;
427+
}
428+
} else {
429+
return -1;
430+
}
431+
}
432+
433+
376434
class FLUProgressionThread extends Thread {
377435
private File fileOut;
378436
private long fileToDowloadSize;
@@ -432,5 +490,4 @@ public void run() {
432490
}
433491
}
434492
}
435-
436493
}

src/main/java/fr/formiko/utils/FLUStrings.java

+30
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,34 @@ public static String addAtTheEndIfNeeded(String string, String toAdd) {
1111
}
1212
return string.endsWith(toAdd) ? string : string + toAdd;
1313
}
14+
15+
public static String removeAtTheEndIfNeeded(String string, String toRemove) {
16+
if (string == null) {
17+
string = "";
18+
}
19+
if (toRemove == null) {
20+
toRemove = "";
21+
}
22+
return string.endsWith(toRemove) ? string.substring(0, string.length() - toRemove.length()) : string;
23+
}
24+
25+
public static String addAtTheBeginningIfNeeded(String string, String toAdd) {
26+
if (string == null) {
27+
string = "";
28+
}
29+
if (toAdd == null) {
30+
toAdd = "";
31+
}
32+
return string.startsWith(toAdd) ? string : toAdd + string;
33+
}
34+
35+
public static String removeAtTheBeginningIfNeeded(String string, String toRemove) {
36+
if (string == null) {
37+
string = "";
38+
}
39+
if (toRemove == null) {
40+
toRemove = "";
41+
}
42+
return string.startsWith(toRemove) ? string.substring(toRemove.length()) : string;
43+
}
1444
}

src/test/java/fr/formiko/utils/FLUFilesTest.java

+53-9
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package fr.formiko.utils;
22

3-
import fr.formiko.utils.progressions.FLUProgressionCLI;
43
import static org.junit.jupiter.api.Assertions.assertEquals;
54
import static org.junit.jupiter.api.Assertions.assertNull;
65
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -17,12 +16,10 @@ public class FLUFilesTest {
1716
private static String TEST_PATH = "src/test/resources/";
1817
private static String TEST_PATH_TEMPORARY = TEST_PATH + "tmp/";
1918

20-
2119
@AfterAll
2220
@BeforeAll
2321
static void clean() { FLUFiles.delete(TEST_PATH_TEMPORARY); }
2422

25-
2623
@ParameterizedTest
2724
@MethodSource("testIsAValidePathSource")
2825
void testIsAValidePath(String path, boolean isValide) { assertEquals(isValide, FLUFiles.isAValidePath(path)); }
@@ -40,6 +37,7 @@ void testCreateFiles(String path, boolean shouldWork) {
4037
assertEquals(true, FLUFiles.delete(path));
4138
}
4239
}
40+
4341
private static Stream<Arguments> testCreateFilesSource() {
4442
return Stream.of(Arguments.of(TEST_PATH_TEMPORARY + "testCreateFiles1.txt", true),
4543
Arguments.of(TEST_PATH_TEMPORARY + "testCreateFiles2.png", true), Arguments.of(TEST_PATH_TEMPORARY + "éà@--", true),
@@ -55,6 +53,7 @@ void testCreateDirectory(String path, boolean shouldWork) {
5553
assertEquals(true, FLUFiles.delete(path));
5654
}
5755
}
56+
5857
private static Stream<Arguments> testCreateDirectorySource() {
5958
return Stream.of(Arguments.of(TEST_PATH_TEMPORARY + "testCreateDirectory1", true),
6059
Arguments.of(TEST_PATH_TEMPORARY + "testCreateDirectory2", true), Arguments.of(TEST_PATH_TEMPORARY + "éàOP%u%", true),
@@ -157,9 +156,8 @@ private static Stream<Arguments> testReadFileSource() {
157156
return Stream.of(Arguments.of(TEST_PATH + "existingFile.x", true, "Some content."),
158157
Arguments.of(TEST_PATH + "unexistingFile.x", false, null), Arguments.of(null, false, null),
159158
Arguments.of(TEST_PATH + "existingDir/subDir/", false, null),
160-
Arguments.of(TEST_PATH + "existingDir/subDir/existingFile.txt", true, "ipnzéfl\n" + //
161-
"zgrebinoa\n" + //
162-
"rez bzn,\n"));
159+
Arguments.of(TEST_PATH + "existingDir/subDir/existingFile.txt", true,
160+
"ipnzéfl" + System.lineSeparator() + "zgrebinoa" + System.lineSeparator() + "rez bzn," + System.lineSeparator()));
163161
}
164162

165163
@ParameterizedTest
@@ -251,7 +249,7 @@ void testAppendToExistingFile(String path, boolean shouldWork, String contentToW
251249
private static Stream<Arguments> testAppendToExistingFileFileSource() {
252250
return Stream.of(
253251
Arguments.of(TEST_PATH + "existingFile3", true, "Some content", "ABCSome content", TEST_PATH_TEMPORARY + "existingFile3"),
254-
Arguments.of(TEST_PATH + "existingFile4", true, "Some content", "ABC\nSome content",
252+
Arguments.of(TEST_PATH + "existingFile4", true, "Some content", "ABC" + System.lineSeparator() + "Some content",
255253
TEST_PATH_TEMPORARY + "existingFile4"));
256254
}
257255

@@ -334,8 +332,54 @@ private static Stream<Arguments> testDownloadSource() {
334332
Arguments.of("https://unexisting.url", false, TEST_PATH_TEMPORARY + "unexisting.url", null));
335333
}
336334

335+
@ParameterizedTest
336+
@MethodSource("testDownloadAndUnzipSource")
337+
void testDownloadAndUnzip(String url, boolean shouldWork, String destination, String fileToCheck, String directoryInsideZipToGet) {
338+
assertEquals(shouldWork, FLUFiles.downloadAndUnzip(url, destination, directoryInsideZipToGet));
339+
if (shouldWork) {
340+
assertTrue(new File(fileToCheck).exists());
341+
assertEquals(true, FLUFiles.delete(destination));
342+
}
343+
}
344+
345+
private static Stream<Arguments> testDownloadAndUnzipSource() {
346+
return Stream.of(
347+
Arguments.of("https://github.com/HydrolienF/Kokcinelo/releases/download/3.0.20/KokcineloLauncher.zip", true,
348+
TEST_PATH_TEMPORARY + "kl1/", TEST_PATH_TEMPORARY + "kl1/" + "Kokcinelo3.0.20/", "Kokcinelo3.0.20/"),
349+
Arguments.of("https://github.com/HydrolienF/Kokcinelo/releases/download/3.0.20/KokcineloLauncher.zip", true,
350+
TEST_PATH_TEMPORARY + "kl2/", TEST_PATH_TEMPORARY + "kl2/" + "", "Kokcinelo3.0.20/"),
351+
Arguments.of("https://github.com/HydrolienF/Kokcinelo/releases/download/3.0.20/KokcineloLauncher.zip", true,
352+
TEST_PATH_TEMPORARY + "kl3/", TEST_PATH_TEMPORARY + "kl3/" + "Kokcinelo3.0.20", "Kokcinelo3.0.20/"),
353+
Arguments.of("https://github.com/HydrolienF/Kokcinelo/releases/download/3.0.20/KokcineloLauncher.zip", true,
354+
TEST_PATH_TEMPORARY + "kl4/", TEST_PATH_TEMPORARY + "kl4/" + "icon.png", "Kokcinelo3.0.20/icon.png"),
355+
Arguments.of("https://github.com/HydrolienF/Kokcinelo/releases/download/3.0.20/KokcineloLauncher.zip", true,
356+
TEST_PATH_TEMPORARY + "kl5/", TEST_PATH_TEMPORARY + "kl5/" + "icon.ico", "Kokcinelo3.0.20/icon.ico"),
357+
Arguments.of("https://github.com/HydrolienF/Formiko/releases/download/2.29.23/Formiko2.29.23Linux.zip", true,
358+
TEST_PATH_TEMPORARY + "kl6/", TEST_PATH_TEMPORARY + "kl6/" + "java/", "Formiko2.29.23Linux/java/"),
359+
Arguments.of("https://github.com/HydrolienF/Formiko/releases/download/2.29.23/Formiko2.29.23Linux.zip", true,
360+
TEST_PATH_TEMPORARY + "kl6/", TEST_PATH_TEMPORARY + "kl6/" + "java", "Formiko2.29.23Linux/java"),
361+
Arguments.of("https://unexisting.url", false, TEST_PATH_TEMPORARY + "unexisting.url", null, ""));
362+
}
363+
364+
@ParameterizedTest
365+
@MethodSource("testCountEntryOfZipFileSource")
366+
void testCountEntryOfZipFile(String url, int expectedCount) { assertEquals(expectedCount, FLUFiles.countEntryOfZipFile(url)); }
367+
368+
private static Stream<Arguments> testCountEntryOfZipFileSource() {
369+
return Stream.of(Arguments.of("https://github.com/HydrolienF/Kokcinelo/releases/download/3.0.20/KokcineloLauncher.zip", 9),
370+
Arguments.of("https://github.com/HydrolienF/Formiko/releases/download/2.29.23/Formiko2.29.23Linux.zip", 9),
371+
Arguments.of("https://unexisting.url", -1));
372+
}
373+
374+
337375
public static void main(String[] args) {
338-
FLUFiles.setProgression(new FLUProgressionCLI());
339-
FLUFiles.createFile(TEST_PATH_TEMPORARY + "/testCreateFiles1.txt");
376+
// FLUFiles.setProgression(new FLUProgressionCLI());
377+
// FLUFiles.createFile(TEST_PATH_TEMPORARY + "/testCreateFiles1.txt");
378+
// Arguments.of("https://github.com/HydrolienF/Kokcinelo/releases/download/3.0.20/KokcineloLauncher.zip", true,
379+
// TEST_PATH_TEMPORARY + "kl1/", TEST_PATH_TEMPORARY + "kl1/" + "KokcineloLauncher/", "")
380+
clean();
381+
System.out
382+
.println(FLUFiles.downloadAndUnzip("https://github.com/HydrolienF/Kokcinelo/releases/download/3.0.20/KokcineloLauncher.zip",
383+
TEST_PATH_TEMPORARY, "Kokcinelo3.0.20/icon.png"));
340384
}
341385
}

src/test/java/fr/formiko/utils/FLUStringsTest.java

+35-2
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,48 @@
66
import org.junit.jupiter.params.provider.Arguments;
77
import org.junit.jupiter.params.provider.MethodSource;
88

9-
public class FLUStringsTest {
9+
class FLUStringsTest {
1010
@ParameterizedTest
1111
@MethodSource("testAddAtTheEndIfNeededSource")
12-
public void testAddAtTheEndIfNeeded(String string, String toAdd, String expected) {
12+
void testAddAtTheEndIfNeeded(String string, String toAdd, String expected) {
1313
assertEquals(expected, FLUStrings.addAtTheEndIfNeeded(string, toAdd));
1414
}
1515

1616
private static Stream<Arguments> testAddAtTheEndIfNeededSource() {
1717
return Stream.of(Arguments.of("test", "test", "test"), Arguments.of("test1", "test", "test1test"),
1818
Arguments.of("OPJ", ".txt", "OPJ.txt"), Arguments.of(null, ".txt", ".txt"), Arguments.of("A", null, "A"));
1919
}
20+
21+
@ParameterizedTest
22+
@MethodSource("testRemoveAtTheEndIfNeededSource")
23+
void testRemoveAtTheEndIfNeeded(String string, String toRemove, String expected) {
24+
assertEquals(expected, FLUStrings.removeAtTheEndIfNeeded(string, toRemove));
25+
}
26+
27+
private static Stream<Arguments> testRemoveAtTheEndIfNeededSource() {
28+
return Stream.of(Arguments.of("test", "test", ""), Arguments.of("test1", "test", "test1"), Arguments.of("OPJ.txt", ".txt", "OPJ"),
29+
Arguments.of(null, ".txt", ""), Arguments.of("A", null, "A"));
30+
}
31+
32+
@ParameterizedTest
33+
@MethodSource("testAddAtTheBeginningIfNeededSource")
34+
void testAddAtTheBeginningIfNeeded(String string, String toAdd, String expected) {
35+
assertEquals(expected, FLUStrings.addAtTheBeginningIfNeeded(string, toAdd));
36+
}
37+
38+
private static Stream<Arguments> testAddAtTheBeginningIfNeededSource() {
39+
return Stream.of(Arguments.of("test", "test", "test"), Arguments.of("1test", "test", "test1test"),
40+
Arguments.of("OPJ", "C:", "C:OPJ"), Arguments.of(null, "C:", "C:"), Arguments.of("A", null, "A"));
41+
}
42+
43+
@ParameterizedTest
44+
@MethodSource("testRemoveAtTheBeginningIfNeededSource")
45+
void testRemoveAtTheBeginningIfNeeded(String string, String toRemove, String expected) {
46+
assertEquals(expected, FLUStrings.removeAtTheBeginningIfNeeded(string, toRemove));
47+
}
48+
49+
private static Stream<Arguments> testRemoveAtTheBeginningIfNeededSource() {
50+
return Stream.of(Arguments.of("test", "test", ""), Arguments.of("test1", "test", "1"), Arguments.of("C:OPJ", "C:", "OPJ"),
51+
Arguments.of(null, "C:", ""), Arguments.of("A", null, "A"));
52+
}
2053
}

0 commit comments

Comments
 (0)