[BAEL-5041] Validate String as file name in Java
This commit is contained in:
parent
bc575d1917
commit
c99989e599
|
@ -0,0 +1,61 @@
|
||||||
|
package com.baeldung.stringfilenamevalidaiton;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
public class StringFilenameValidationUtils {
|
||||||
|
|
||||||
|
public static final Character[] INVALID_WINDOWS_SPECIFIC_CHARS = {'"', '*', ':', '<', '>', '?', '\\', '|', 0x7F};
|
||||||
|
public static final Character[] INVALID_UNIX_SPECIFIC_CHARS = {'\000'};
|
||||||
|
|
||||||
|
public static final String REGEX_PATTERN = "^[A-za-z0-9.]{1,255}$";
|
||||||
|
|
||||||
|
private StringFilenameValidationUtils() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean validateStringFilenameUsingIO(String filename) throws IOException {
|
||||||
|
File file = new File(filename);
|
||||||
|
boolean created = false;
|
||||||
|
try {
|
||||||
|
created = file.createNewFile();
|
||||||
|
return created;
|
||||||
|
} finally {
|
||||||
|
if (created) {
|
||||||
|
file.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean validateStringFilenameUsingNIO2(String filename) {
|
||||||
|
Paths.get(filename);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean validateStringFilenameUsingContains(String filename) {
|
||||||
|
if (filename == null || filename.isEmpty() || filename.length() > 255) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return Arrays.stream(getInvalidCharsByOS())
|
||||||
|
.noneMatch(ch -> filename.contains(ch.toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean validateStringFilenameUsingRegex(String filename) {
|
||||||
|
if (filename == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return filename.matches(REGEX_PATTERN);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Character[] getInvalidCharsByOS() {
|
||||||
|
String os = System.getProperty("os.name").toLowerCase();
|
||||||
|
if (os.contains("win")) {
|
||||||
|
return INVALID_WINDOWS_SPECIFIC_CHARS;
|
||||||
|
} else if (os.contains("nix") || os.contains("nux") || os.contains("mac")) {
|
||||||
|
return INVALID_UNIX_SPECIFIC_CHARS;
|
||||||
|
} else {
|
||||||
|
return new Character[]{};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,130 @@
|
||||||
|
package com.baeldung.stringfilenamevalidaiton;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.RandomStringUtils;
|
||||||
|
import org.apache.commons.lang3.RandomUtils;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.condition.EnabledOnOs;
|
||||||
|
import org.junit.jupiter.api.condition.OS;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.EmptySource;
|
||||||
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
import org.junit.jupiter.params.provider.NullSource;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.InvalidPathException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static com.baeldung.stringfilenamevalidaiton.StringFilenameValidationUtils.validateStringFilenameUsingContains;
|
||||||
|
import static com.baeldung.stringfilenamevalidaiton.StringFilenameValidationUtils.validateStringFilenameUsingIO;
|
||||||
|
import static com.baeldung.stringfilenamevalidaiton.StringFilenameValidationUtils.validateStringFilenameUsingNIO2;
|
||||||
|
import static com.baeldung.stringfilenamevalidaiton.StringFilenameValidationUtils.validateStringFilenameUsingRegex;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||||
|
|
||||||
|
public class StringFilenameValidationUnitTest {
|
||||||
|
|
||||||
|
private static final String CORRECT_FILENAME_PATTERN = "baeldung.txt";
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@MethodSource("correctAlphanumericFilenamesProvider")
|
||||||
|
public void givenCorrectAlphanumericRandomFilenameString_whenValidateUsingIO_thenReturnTrue(String filename) throws IOException {
|
||||||
|
assertThat(validateStringFilenameUsingIO(filename)).isTrue();
|
||||||
|
assertThat(validateStringFilenameUsingNIO2(filename)).isTrue();
|
||||||
|
assertThat(validateStringFilenameUsingContains(filename)).isTrue();
|
||||||
|
assertThat(validateStringFilenameUsingRegex(filename)).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenTooLongFileNameString_whenValidate_thenIOAndCustomFailsNIO2Succeed() {
|
||||||
|
String filename = RandomStringUtils.randomAlphabetic(500);
|
||||||
|
assertThatThrownBy(() -> validateStringFilenameUsingIO(filename))
|
||||||
|
.isInstanceOf(IOException.class)
|
||||||
|
.hasMessageContaining("File name too long");
|
||||||
|
assertThat(validateStringFilenameUsingNIO2(filename)).isTrue();
|
||||||
|
assertThat(validateStringFilenameUsingContains(filename)).isFalse();
|
||||||
|
assertThat(validateStringFilenameUsingRegex(filename)).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@NullSource
|
||||||
|
public void givenNullString_whenValidate_thenFails(String filename) {
|
||||||
|
assertThatThrownBy(() -> validateStringFilenameUsingIO(filename))
|
||||||
|
.isInstanceOf(NullPointerException.class);
|
||||||
|
assertThatThrownBy(() -> validateStringFilenameUsingNIO2(filename))
|
||||||
|
.isInstanceOf(NullPointerException.class);
|
||||||
|
assertThat(validateStringFilenameUsingContains(filename)).isFalse();
|
||||||
|
assertThat(validateStringFilenameUsingRegex(filename)).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@EmptySource
|
||||||
|
public void givenEmptyString_whenValidate_thenIOAndCustomFailsNIO2Succeed(String filename) {
|
||||||
|
assertThatThrownBy(() -> validateStringFilenameUsingIO(filename))
|
||||||
|
.isInstanceOf(IOException.class);
|
||||||
|
assertThat(validateStringFilenameUsingNIO2(filename)).isTrue();
|
||||||
|
assertThat(validateStringFilenameUsingContains(filename)).isFalse();
|
||||||
|
assertThat(validateStringFilenameUsingRegex(filename)).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@EnabledOnOs({OS.LINUX, OS.MAC})
|
||||||
|
@MethodSource("filenamesWithInvalidWindowsChars")
|
||||||
|
public void givenFilenameStringWithInvalidWindowsCharAndIsUnix_whenValidateUsingIO_thenReturnTrue(String filename) throws IOException {
|
||||||
|
assertThat(validateStringFilenameUsingIO(filename)).isTrue();
|
||||||
|
assertThat(validateStringFilenameUsingNIO2(filename)).isTrue();
|
||||||
|
assertThat(validateStringFilenameUsingContains(filename)).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@EnabledOnOs(OS.WINDOWS)
|
||||||
|
@MethodSource("filenamesWithInvalidWindowsChars")
|
||||||
|
public void givenFilenameStringWithInvalidWindowsCharAndIsWindows_whenValidateUsingIO_thenRaiseException(String filename) {
|
||||||
|
assertThatThrownBy(() -> validateStringFilenameUsingIO(filename))
|
||||||
|
.isInstanceOf(IOException.class)
|
||||||
|
.hasMessageContaining("Invalid file path");
|
||||||
|
|
||||||
|
assertThatThrownBy(() -> validateStringFilenameUsingNIO2(filename))
|
||||||
|
.isInstanceOf(InvalidPathException.class)
|
||||||
|
.hasMessage("character not allowed");
|
||||||
|
|
||||||
|
assertThat(validateStringFilenameUsingContains(filename)).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@EnabledOnOs({OS.LINUX, OS.MAC})
|
||||||
|
@MethodSource("filenamesWithInvalidUnixChars")
|
||||||
|
public void givenFilenameStringWithInvalidUnixCharAndIsUnix_whenValidate_thenRaiseException(String filename) {
|
||||||
|
assertThatThrownBy(() -> validateStringFilenameUsingIO(filename))
|
||||||
|
.isInstanceOf(IOException.class)
|
||||||
|
.hasMessageContaining("Invalid file path");
|
||||||
|
|
||||||
|
assertThatThrownBy(() -> validateStringFilenameUsingNIO2(filename))
|
||||||
|
.isInstanceOf(InvalidPathException.class)
|
||||||
|
.hasMessageContaining("character not allowed");
|
||||||
|
|
||||||
|
assertThat(validateStringFilenameUsingContains(filename)).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static Stream<String> correctAlphanumericFilenamesProvider() {
|
||||||
|
return Stream.generate(() -> RandomStringUtils.randomAlphanumeric(1, 10) + "." + RandomStringUtils.randomAlphabetic(3, 5)).limit(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Stream<String> filenamesWithInvalidWindowsChars() {
|
||||||
|
return Arrays.stream(StringFilenameValidationUtils.INVALID_WINDOWS_SPECIFIC_CHARS)
|
||||||
|
.map(character -> {
|
||||||
|
int idx = RandomUtils.nextInt(0, CORRECT_FILENAME_PATTERN.length());
|
||||||
|
return CORRECT_FILENAME_PATTERN.substring(0, idx) + character + CORRECT_FILENAME_PATTERN.substring(idx);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Stream<String> filenamesWithInvalidUnixChars() {
|
||||||
|
return Arrays.stream(StringFilenameValidationUtils.INVALID_UNIX_SPECIFIC_CHARS)
|
||||||
|
.map(character -> {
|
||||||
|
int idx = RandomUtils.nextInt(0, CORRECT_FILENAME_PATTERN.length());
|
||||||
|
return CORRECT_FILENAME_PATTERN.substring(0, idx) + character + CORRECT_FILENAME_PATTERN.substring(idx);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue