Compare commits

...

7 Commits

Author SHA1 Message Date
Niclas Thobaben 0ab9980583 FEAT StreamUtils.toInputStream & StreamUtils.toString
NClazz/java-commons/pipeline/head This commit looks good Details
2021-01-25 12:16:03 +01:00
Niclas Thobaben f406b6235d FEAT de.nclazz.commons.util.Canon global canon
NClazz/java-commons/pipeline/head This commit looks good Details
2021-01-20 16:27:03 +01:00
Niclas Thobaben b0c4d3fe9f REFC mv package de.nclazz.commons.env to de.nclazz.commons.util 2021-01-20 16:16:19 +01:00
Niclas Thobaben ba3bb5ce4c FEAT Canon class for canonicalization of objects 2021-01-20 16:10:03 +01:00
Niclas Thobaben bf56816e6c FEAT ReflectionUtils hasAnnotation Predicate
NClazz/java-commons/pipeline/head This commit looks good Details
2020-12-27 22:31:41 +01:00
Niclas Thobaben 5ea5f89d4c FEAT ReflectionUtils fields recursively
NClazz/java-commons/pipeline/head This commit looks good Details
2020-12-27 22:17:08 +01:00
Niclas Thobaben fe1d97c9d9 BLD new staging version 1.1.0
NClazz/java-commons/pipeline/head This commit looks good Details
2020-12-04 20:24:08 +01:00
12 changed files with 238 additions and 17 deletions

View File

@ -6,7 +6,7 @@
<groupId>de.nclazz</groupId>
<artifactId>commons</artifactId>
<version>1.0.0</version>
<version>1.1.0-SNAPSHOT</version>
<parent>
<groupId>de.nclazz</groupId>

View File

@ -1,6 +1,5 @@
package de.nclazz.commons.io;
import de.nclazz.commons.StringUtils;
import lombok.NonNull;
import lombok.SneakyThrows;
@ -8,6 +7,7 @@ import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.MessageDigest;
import java.util.Objects;
import java.util.function.Consumer;
public abstract class FileUtils {
@ -26,7 +26,7 @@ public abstract class FileUtils {
throw new IllegalArgumentException(String.format("File '%s' is not a directory!", dir.getAbsolutePath()));
}
for(File file : dir.listFiles()) {
for(File file : Objects.requireNonNull(dir.listFiles())) {
if(file.isDirectory()) {
deleteDirectoryRecursively(file);
}else {
@ -97,7 +97,7 @@ public abstract class FileUtils {
try(FileWriter writer = new FileWriter(file)) {
writerConsumer.accept(writer);
}catch(Exception e) {
throw e;
throw new RuntimeException(e);
}
return file;

View File

@ -1,9 +1,11 @@
package de.nclazz.commons.io;
import de.nclazz.commons.StringUtils;
import de.nclazz.commons.util.StringUtils;
import lombok.NonNull;
import lombok.SneakyThrows;
import java.io.*;
import java.nio.charset.Charset;
import java.security.MessageDigest;
public abstract class StreamUtils {
@ -63,5 +65,47 @@ public abstract class StreamUtils {
}
}
/**
* Converts given string to an InputStream.
* @param string to convert
* @return new InputStream
*/
public static InputStream toInputStream(@NonNull String string, Charset charset) {
charset = charset != null ? charset : Charset.defaultCharset();
byte[] bytes = string.getBytes(charset);
return new ByteArrayInputStream(bytes);
}
/**
* @see #toInputStream(String, Charset)
* @param string to read
* @return new InputStream
*/
public static InputStream toInputStream(@NonNull String string) {
return toInputStream(string, Charset.defaultCharset());
}
/**
* Reads the given InputStream and converts it to a String.
* The stream does not close after this operation.
* @param stream to read
* @param charset of the String
* @return new String
*/
@SneakyThrows
public static String toString(@NonNull InputStream stream, Charset charset) {
charset = charset != null ? charset : Charset.defaultCharset();
byte[] bytes = inputStreamToByteArray(stream);
return new String(bytes, charset);
}
/**
* @see #toString(InputStream, Charset)
* @param stream to read
* @return new String
*/
public static String toString(@NonNull InputStream stream) {
return toString(stream, Charset.defaultCharset());
}
}

View File

@ -0,0 +1,37 @@
package de.nclazz.commons.reflection;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Predicate;
public final class ReflectionUtils {
private ReflectionUtils() { /* no-op */ }
public static Predicate<Field> hasAnnotation(Class<? extends Annotation> annotation) {
return field -> field.isAnnotationPresent(annotation);
}
public static Set<Field> getDeclaredFieldRecursively(Class<?> clazz, Predicate<Field> predicate) {
Class<?> currentClass = clazz;
Set<Field> fields = new HashSet<>();
while(currentClass != Object.class && !currentClass.isInterface()) {
for(Field field : currentClass.getDeclaredFields()) {
if(predicate.test(field)) {
fields.add(field);
}
}
currentClass = currentClass.getSuperclass();
}
return fields;
}
public static Set<Field> getDeclaredFieldRecursively(Class<?> clazz) {
return getDeclaredFieldRecursively(clazz, f -> true);
}
}

View File

@ -0,0 +1,43 @@
package de.nclazz.commons.util;
import lombok.NonNull;
import java.util.WeakHashMap;
public class Canon<T> {
private static final WeakHashMap<Class<?>, Canon<?>> globalCanon = new WeakHashMap<>();
private final WeakHashMap<T,T> canon;
public Canon(int initialCapacity) {
this.canon = new WeakHashMap<>(initialCapacity);
}
public Canon() {
this(32);
}
public T getCanonical(T object) {
synchronized (this.canon) {
T canonical = this.canon.get(object);
if(canonical == null) {
this.canon.put(object, object);
canonical = object;
}
return canonical;
}
}
@SuppressWarnings("unchecked") //Type is directly fetched from instance
public static <T> T canonical(@NonNull T object) {
Class<? extends T> clazz = (Class<? extends T>) object.getClass();
Canon<T> canon = (Canon<T>) globalCanon.get(clazz);
if(canon == null) {
canon = new Canon<>();
globalCanon.put(clazz, canon);
}
return canon.getCanonical(object);
}
}

View File

@ -1,4 +1,4 @@
package de.nclazz.commons.env;
package de.nclazz.commons.util;
import lombok.SneakyThrows;
@ -55,7 +55,7 @@ public class PropertyProvider {
/**
* Loads the properties from given {@code stream}.
* The stream remains open after loading.
* @param stream
* @param stream InputStream to load
*/
@SneakyThrows
public void load(InputStream stream) {

View File

@ -1,8 +1,9 @@
package de.nclazz.commons;
package de.nclazz.commons.util;
import lombok.NonNull;
import lombok.SneakyThrows;
import java.io.InputStream;
import java.security.MessageDigest;
public abstract class StringUtils {
@ -107,8 +108,7 @@ public abstract class StringUtils {
@SneakyThrows
public static String digestString(@NonNull String input, MessageDigest md) {
md.update(input.getBytes());
String hash = toHex(md.digest());
return hash;
return toHex(md.digest());
}
@SneakyThrows

View File

@ -8,6 +8,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class StreamUtilsTests {
@ -37,4 +38,16 @@ public class StreamUtilsTests {
assertTrue(Arrays.equals(alphabetBytes, bytes));
}
@Test
void stringToInputStreamRoundTrip() throws IOException {
String testString = "Hello World!";
InputStream stream = StreamUtils.toInputStream(testString);
String backString = StreamUtils.toString(stream);
stream.close();
assertEquals(testString, backString);
}
}

View File

@ -0,0 +1,34 @@
package de.nclazz.commons.reflection;
import org.junit.jupiter.api.Test;
import java.lang.reflect.Field;
import java.util.Set;
import static org.junit.jupiter.api.Assertions.*;
class ReflectionUtilsTest {
static class BaseClass {
private int baseFieldInt;
private float baseFieldFloat;
private String baseField;
}
static class InheritedClass extends BaseClass {
private String inheritField;
}
@Test
void findDeclaredFieldsRecursively() {
Set<Field> fields = ReflectionUtils.getDeclaredFieldRecursively(InheritedClass.class);
assertEquals(4, fields.size());
}
@Test
void testDeclaredFieldsPredicate() {
Set<Field> fields = ReflectionUtils.getDeclaredFieldRecursively(InheritedClass.class, field -> field.getType() == String.class);
assertEquals(2, fields.size());
}
}

View File

@ -0,0 +1,52 @@
package de.nclazz.commons.util;
import lombok.EqualsAndHashCode;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class CanonTest {
@EqualsAndHashCode
public static class ImmutableClass {
final String str;
final int integer;
public ImmutableClass(String str, int integer) {
this.str = str;
this.integer = integer;
}
}
@Test
void equalityTest() {
Canon<ImmutableClass> canon = new Canon<>();
ImmutableClass objectA = canon.getCanonical(new ImmutableClass("myString", 12));
for(int i = 0; i < 24; i++) {
ImmutableClass objectCanon = canon.getCanonical(new ImmutableClass("myString", 12));
assertEquals(objectA, objectCanon);
assertSame(objectA, objectCanon, () -> String.format("a: %s == %s", objectA, objectCanon));
}
}
@Test
void equalityTestGlobal() {
ImmutableClass objectA = Canon.canonical(new ImmutableClass("myString", 12));
for(int i = 0; i < 24; i++) {
ImmutableClass objectCanon = Canon.canonical(new ImmutableClass("myString", 12));
assertEquals(objectA, objectCanon);
assertSame(objectA, objectCanon, () -> String.format("a: %s == %s", objectA, objectCanon));
}
}
}

View File

@ -1,10 +1,8 @@
package de.nclazz.commons.env;
package de.nclazz.commons.util;
import de.nclazz.commons.io.FileUtils;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
@ -13,7 +11,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
public class PropertyProviderTests {
@Test
void testPropertyProviderBasic() throws Exception {
void testPropertyProviderBasic() {
PropertyProvider provider = new PropertyProvider();
try(InputStream stream = PropertyProviderTests.class.getResourceAsStream("/test-files/env.properties")) {
@ -27,7 +25,7 @@ public class PropertyProviderTests {
.map(Float::parseFloat)
.orElse(0f));
}catch(Exception e) {
throw e;
throw new RuntimeException(e);
}
}

View File

@ -1,6 +1,6 @@
package de.nclazz.commons;
package de.nclazz.commons.util;
import org.junit.jupiter.api.Assertions;
import de.nclazz.commons.util.StringUtils;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;