Merge branch 'master' into feature/io/BOMInputStream
NClazz/java-commons/pipeline/pr-master There was a failure building this commit
Details
NClazz/java-commons/pipeline/pr-master There was a failure building this commit
Details
commit
4b0014554d
|
@ -24,4 +24,6 @@ pipeline {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# java-commons
|
||||
[![Build Status](https://jenkins.niclas-thobaben.de/buildStatus/icon?job=de.nclazz%2Fjava-commons%2Fmaster)](https://jenkins.niclas-thobaben.de/job/de.nclazz/job/java-commons/job/master/)
|
||||
[![Build Status](https://jenkins.niclas-thobaben.de/buildStatus/icon?job=NClazz%2Fjava-commons%2Fmaster)](https://jenkins.niclas-thobaben.de/job/NClazz/job/java-commons/job/master/)
|
||||
|
||||
|
||||
Common and reusable java utilities and functionalities.
|
||||
|
|
10
pom.xml
10
pom.xml
|
@ -14,8 +14,16 @@
|
|||
<version>1.0.0</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<properties>
|
||||
<commons.io.version>2.6</commons.io.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>${commons.io.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
package de.nclazz.commons;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
|
||||
public abstract class StringUtils {
|
||||
|
||||
private StringUtils() { /* no-op */ }
|
||||
|
@ -75,4 +80,45 @@ public abstract class StringUtils {
|
|||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a hex-{@code String} from given byte array,
|
||||
* @param bytes array
|
||||
* @return new {@code String}
|
||||
* @throws NullPointerException if bytes are {@code null}
|
||||
*/
|
||||
public static String toHex(@NonNull byte[] bytes) {
|
||||
StringBuilder sb = new StringBuilder(bytes.length*2);
|
||||
|
||||
for (int v : bytes) {
|
||||
sb.append(Character.forDigit((v >> 4) & 0xF, 16))
|
||||
.append(Character.forDigit((v & 0xF), 16));
|
||||
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Hashes given String with given hash algorithm
|
||||
*
|
||||
* @param input to hash
|
||||
* @param md hash algorithm
|
||||
* @return hash (hex-)String
|
||||
*/
|
||||
@SneakyThrows
|
||||
public static String digestString(@NonNull String input, MessageDigest md) {
|
||||
md.update(input.getBytes());
|
||||
String hash = toHex(md.digest());
|
||||
return hash;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static String toSHA1(String input) {
|
||||
return digestString(input, MessageDigest.getInstance("SHA-1"));
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static String toMD(String input) {
|
||||
return digestString(input, MessageDigest.getInstance("MD5"));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
package de.nclazz.commons.io;
|
||||
|
||||
import de.nclazz.commons.StringUtils;
|
||||
import lombok.NonNull;
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileWriter;
|
||||
import java.io.Writer;
|
||||
import java.io.*;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.security.MessageDigest;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public abstract class FileUtils {
|
||||
|
@ -95,7 +94,7 @@ public abstract class FileUtils {
|
|||
|
||||
if(!file.exists()) file.createNewFile();
|
||||
|
||||
try(FileWriter writer = new FileWriter(file);) {
|
||||
try(FileWriter writer = new FileWriter(file)) {
|
||||
writerConsumer.accept(writer);
|
||||
}catch(Exception e) {
|
||||
throw e;
|
||||
|
@ -104,4 +103,29 @@ public abstract class FileUtils {
|
|||
return file;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a hash from the file content of given file with given{@link MessageDigest}
|
||||
* @param file to hash
|
||||
* @param md hash algorithm
|
||||
* @return hex {@code String} hash
|
||||
*/
|
||||
public static String digestFileContent(@NonNull File file, @NonNull MessageDigest md) {
|
||||
try(FileInputStream stream = new FileInputStream(file)) {
|
||||
return StreamUtils.digestStream(stream, md);
|
||||
}catch(Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static String generateSHA1FromFile(File file) {
|
||||
return digestFileContent(file, MessageDigest.getInstance("SHA-1"));
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static String generateMD5FromFile(File file) {
|
||||
return digestFileContent(file, MessageDigest.getInstance("MD5"));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
package de.nclazz.commons.io;
|
||||
|
||||
import lombok.NonNull;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Simple implementation of a MimeType.
|
||||
*/
|
||||
public class MimeType {
|
||||
|
||||
public static final String MEDIA_APPLICATION = "application";
|
||||
public static final String MEDIA_AUDIO = "audio";
|
||||
public static final String MEDIA_EXAMPLE = "example";
|
||||
public static final String MEDIA_IMAGE = "image";
|
||||
public static final String MEDIA_MESSAGE = "message";
|
||||
public static final String MEDIA_MODEL = "model";
|
||||
public static final String MEDIA_MULTIPART = "multipart";
|
||||
public static final String MEDIA_TEXT = "text";
|
||||
public static final String MEDIA_VIDEO = "video";
|
||||
|
||||
public static final MimeType JAVA_ARCHIVE = new MimeType("application", "java-archive");
|
||||
public static final MimeType JAVASCRIPT = new MimeType("application", "javascript");
|
||||
public static final MimeType JSON = new MimeType("application", "json");
|
||||
public static final MimeType OCTET_STREAM = new MimeType("application", "octet-stream");
|
||||
public static final MimeType PDF = new MimeType("application", "pdf");
|
||||
public static final MimeType RTF = new MimeType("application", "rtf");
|
||||
public static final MimeType XHTML = new MimeType("application", "xhtml+xml");
|
||||
public static final MimeType XML = new MimeType("application", "xml");
|
||||
public static final MimeType ZIP = new MimeType("application", "zip");
|
||||
public static final MimeType AAC = new MimeType("audio", "aac");
|
||||
public static final MimeType MIDI = new MimeType("audio", "midi");
|
||||
public static final MimeType OGG_AUDIO = new MimeType("audio", "ogg");
|
||||
public static final MimeType WAV = new MimeType("audio", "x-wav");
|
||||
public static final MimeType TTF = new MimeType("font", "ttf");
|
||||
public static final MimeType WOFF = new MimeType("font", "woff");
|
||||
public static final MimeType GIF = new MimeType("image", "gif");
|
||||
public static final MimeType JPEG = new MimeType("image", "jpeg");
|
||||
public static final MimeType SVG = new MimeType("image", "svg+xml");
|
||||
public static final MimeType TIFF = new MimeType("image", "tiff");
|
||||
public static final MimeType ICON = new MimeType("image", "x-icon");
|
||||
public static final MimeType ICALENDAR = new MimeType("text", "calendar");
|
||||
public static final MimeType CSS = new MimeType("text", "css");
|
||||
public static final MimeType CSV = new MimeType("text", "csv");
|
||||
public static final MimeType HTML = new MimeType("text", "html");
|
||||
public static final MimeType MPEG_VIDEO = new MimeType("video", "mpeg");
|
||||
public static final MimeType OGG_VIDEO = new MimeType("video", "ogg");
|
||||
|
||||
private static final Pattern MIME_REGEX = Pattern.compile("^(?<media>\\p{Alnum}+)/(?<sub>\\p{Alnum}+)$");
|
||||
|
||||
private final String mediaType;
|
||||
private final String subType;
|
||||
|
||||
public MimeType(String mediaType, String subType) {
|
||||
this.mediaType = mediaType;
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
public String getMediaType() {
|
||||
return mediaType;
|
||||
}
|
||||
|
||||
public String getSubType() {
|
||||
return subType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s/%s", this.mediaType, this.subType);
|
||||
}
|
||||
|
||||
public static MimeType parse(@NonNull String mime) {
|
||||
Matcher matcher = MIME_REGEX.matcher(mime);
|
||||
if(!matcher.matches()) {
|
||||
throw new IllegalArgumentException(String.format("Invalid MimeType '%s'!", mime));
|
||||
}
|
||||
return new MimeType(matcher.group("media"), matcher.group("sub"));
|
||||
}
|
||||
|
||||
}
|
|
@ -1,9 +1,10 @@
|
|||
package de.nclazz.commons.io;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import de.nclazz.commons.StringUtils;
|
||||
import lombok.NonNull;
|
||||
|
||||
import java.io.*;
|
||||
import java.security.MessageDigest;
|
||||
|
||||
public abstract class StreamUtils {
|
||||
|
||||
|
@ -15,7 +16,7 @@ public abstract class StreamUtils {
|
|||
*
|
||||
* @param streamIn InputStream
|
||||
* @param streamOut OutputStream
|
||||
* @throws IOException
|
||||
* @throws IOException on Error
|
||||
*/
|
||||
public static void pipeStream(InputStream streamIn, OutputStream streamOut) throws IOException {
|
||||
byte[] bytes = new byte[4096]; //TODO make configurable? maybe as a sys property?
|
||||
|
@ -41,6 +42,26 @@ public abstract class StreamUtils {
|
|||
return bos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Digest an InputStream with given MessageDigest.
|
||||
* The stream will not be closed after processing!
|
||||
* @param stream to hash
|
||||
* @param md hash algorithm
|
||||
* @return new String hash
|
||||
*/
|
||||
public static String digestStream(@NonNull InputStream stream, @NonNull MessageDigest md) {
|
||||
try {
|
||||
byte[] buffer = new byte[2048];
|
||||
int len;
|
||||
while((len = stream.read(buffer)) != -1) {
|
||||
md.update(buffer, 0, len);
|
||||
}
|
||||
byte[] digest = md.digest();
|
||||
return StringUtils.toHex(digest);
|
||||
}catch(Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import org.junit.jupiter.api.Test;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.security.MessageDigest;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
|
@ -22,15 +23,19 @@ public class FileUtilsTests {
|
|||
assertThrows(IllegalArgumentException.class, () -> FileUtils.deleteDirectoryRecursively(readmeFile));
|
||||
assertDoesNotThrow(() -> FileUtils.deleteDirectoryRecursively(dir));
|
||||
|
||||
assertTrue(!dir.exists());
|
||||
assertFalse(dir.exists());
|
||||
}
|
||||
|
||||
File createDirectory() throws IOException {
|
||||
File dir = new File("target/tmp/subdirs/secondlevel");
|
||||
dir.mkdirs();
|
||||
if(!dir.mkdirs())
|
||||
throw new RuntimeException("Could not create directories!");
|
||||
|
||||
for(int i = 0; i < 64; i++) {
|
||||
new File(dir, "test_"+i+".txt").createNewFile();
|
||||
String filename = "test_" + i + ".txt";
|
||||
if(!new File(dir, filename).createNewFile()) {
|
||||
throw new RuntimeException("Could not create File +'" + filename + "'!");
|
||||
}
|
||||
}
|
||||
|
||||
return dir;
|
||||
|
@ -66,4 +71,13 @@ public class FileUtilsTests {
|
|||
assertFalse(tempFile.exists());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDigestFileContent() {
|
||||
File file = new File("src/test/resources/test-files/alphabet-utf8.txt");
|
||||
String sha1 = "db16441c4b330570a9ac83b0e0b006fcd74cc32b";
|
||||
String md5 = "2ad372c377013baa4ee32ab6649d2449";
|
||||
|
||||
assertEquals(sha1, FileUtils.generateSHA1FromFile(file));
|
||||
assertEquals(md5, FileUtils.generateMD5FromFile(file));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
package de.nclazz.commons.io;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class MimeTypeTest {
|
||||
|
||||
@Test
|
||||
void MimeTypeParsedFromString() {
|
||||
|
||||
MimeType type = MimeType.parse("application/json");
|
||||
assertEquals("application", type.getMediaType());
|
||||
assertEquals("json", type.getSubType());
|
||||
|
||||
type = MimeType.parse("image/jpeg");
|
||||
assertEquals("image", type.getMediaType());
|
||||
assertEquals("jpeg", type.getSubType());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void MimeTypeParsedThrowsExceptionOnInvalidInput() {
|
||||
assertThrows(IllegalArgumentException.class, () -> MimeType.parse("application/"));
|
||||
assertThrows(IllegalArgumentException.class, () -> MimeType.parse("/json"));
|
||||
assertThrows(IllegalArgumentException.class, () -> MimeType.parse("/"));
|
||||
assertThrows(IllegalArgumentException.class, () -> MimeType.parse("application"));
|
||||
assertThrows(NullPointerException.class, () -> MimeType.parse(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void MimeTypeToStringEqualsOriginalString() {
|
||||
|
||||
String mimeStr = "application/json";
|
||||
MimeType type = MimeType.parse(mimeStr);
|
||||
assertEquals("application", type.getMediaType());
|
||||
assertEquals("json", type.getSubType());
|
||||
assertEquals(mimeStr, type.toString());
|
||||
|
||||
mimeStr = "image/jpeg";
|
||||
type = MimeType.parse(mimeStr);
|
||||
assertEquals("image", type.getMediaType());
|
||||
assertEquals("jpeg", type.getSubType());
|
||||
assertEquals(mimeStr, type.toString());
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue