Skip to content

Commit

Permalink
Merge pull request #566 from eclipse/custom-write
Browse files Browse the repository at this point in the history
Enhance ValueUtil
  • Loading branch information
otaviojava authored Dec 15, 2024
2 parents dac8165 + 00b95f6 commit 0605fb6
Show file tree
Hide file tree
Showing 6 changed files with 246 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,74 +35,105 @@ public final class ValueUtil {
@SuppressWarnings("rawtypes")
private static final Function CONVERT = o -> {
if (o instanceof Value) {
return convert(Value.class.cast(o));
return convert((Value) o);
}
return getObject(o);
return getObject(o, VALUE_WRITER);
};

private ValueUtil() {
}

/**
* converter a {@link Value} to Object
* Converts a {@link Value} to Object
*
* @param value the value
* @return a object converted
* @return an object converted
*/
public static Object convert(Value value) {
return convert(value, VALUE_WRITER);
}

/**
* Converts a {@link Value} using a custom {@link ValueWriter}.
*
* @param value the value to be converted
* @param valueWriter the custom ValueWriter to use for conversion
* @return the converted object
*/
public static Object convert(Value value, ValueWriter<?, ?> valueWriter) {
Objects.requireNonNull(value, "value is required");
Objects.requireNonNull(valueWriter, "valueWriter is required");
Object val = value.get();
if (val instanceof Iterable) {
return getObjects(val);
return getObjects(val, valueWriter);
}
return getObject(val);
return getObject(val, valueWriter);
}


/**
* Converts the {@link Value} to {@link List}
* Converts a {@link Value} to {@link List}
*
* @param value the value
* @return a list object
*/
@SuppressWarnings("unchecked")
public static List<Object> convertToList(Value value) {
return convertToList(value, VALUE_WRITER);
}

/**
* Converts a {@link Value} to {@link List} using a custom {@link ValueWriter}.
*
* @param value the value
* @param valueWriter the custom ValueWriter to use for conversion
* @return a list object
*/
@SuppressWarnings("unchecked")
public static List<Object> convertToList(Value value, ValueWriter<?, ?> valueWriter) {
Objects.requireNonNull(value, "value is required");
Objects.requireNonNull(valueWriter, "valueWriter is required");
Object val = value.get();
if (val instanceof Iterable) {
List<Object> items = new ArrayList<>();
Iterable.class.cast(val).forEach(items::add);
if (items.size() == 1) {
Object item = items.get(0);
//check if it is dynamic params
// check if it is dynamic params
if (PARAM_CLASS_NAME.equals(item.getClass().getName())) {
Object params = Value.class.cast(item).get();
if (params instanceof Iterable) {
return getObjects(Iterable.class.cast(params));
return getObjects(Iterable.class.cast(params), valueWriter);
} else {
return Collections.singletonList(getObject(params));
return Collections.singletonList(getObject(params, valueWriter));
}
}
}
return (List<Object>) items.stream().map(CONVERT).collect(toList());

return (List<Object>) items.stream().map(o -> getObject(o, valueWriter)).collect(toList());
}
return Collections.singletonList(getObject(val));
return Collections.singletonList(getObject(val, valueWriter));
}

@SuppressWarnings("unchecked")
private static List<Object> getObjects(Object val) {
return (List<Object>) StreamSupport.stream(Iterable.class.cast(val).spliterator(), false)
.map(CONVERT).collect(toList());
@SuppressWarnings({"unchecked", "rawtypes"})
private static List<Object> getObjects(Object val, ValueWriter<?, ?> valueWriter) {
return (List<Object>) StreamSupport.stream(((Iterable) val).spliterator(), false)
.map(o -> {
if (o instanceof Value) {
return convert((Value) o, valueWriter);
}
return getObject(o, valueWriter);
})
.collect(toList());
}

@SuppressWarnings("unchecked")
private static Object getObject(Object val) {
@SuppressWarnings({"unchecked", "rawtypes"})
private static Object getObject(Object val, ValueWriter valueWriter) {
if (val == null) {
return null;
} else if (VALUE_WRITER.test(val.getClass())) {
return VALUE_WRITER.write(val);
} else if (val instanceof Value) {
return convert(Value.class.cast(val), valueWriter);
} else if (valueWriter.test(val.getClass())) {
return valueWriter.write(val);
}
return val;
}
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
*
* Copyright (c) 2024 Contributors to the Eclipse Foundation
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Apache License v2.0 which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Apache License v2.0 is available at http://www.opensource.org/licenses/apache2.0.php.
*
* You may elect to redistribute this code under either of these licenses.
*
* Contributors:
*
* Otavio Santana
*
*/
package org.eclipse.jnosql.communication.reader;

import org.eclipse.jnosql.communication.CommunicationException;
import org.eclipse.jnosql.communication.ValueReader;

import java.util.UUID;

public class UUIDValueReader implements ValueReader {

@SuppressWarnings("unchecked")
@Override
public <T> T read(Class<T> type, Object value) {
if (value instanceof UUID) {
return (T) value;
}
if (value instanceof CharSequence) {
return (T) getUuid(value);
}
return null;
}

private static UUID getUuid(Object value) {
try {
return UUID.fromString(value.toString());
} catch (IllegalArgumentException exp) {
throw new CommunicationException("There is an error to convert to UUID, because the value is not UUID format: " + value, exp);
}
}

@Override
public boolean test(Class<?> type) {
return UUID.class.equals(type);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ org.eclipse.jnosql.communication.reader.YearReader
org.eclipse.jnosql.communication.reader.ZonedDateTimeReader
org.eclipse.jnosql.communication.reader.LocalTimeReader
org.eclipse.jnosql.communication.reader.OffsetDateTimeReader
org.eclipse.jnosql.communication.reader.OffsetTimeReader
org.eclipse.jnosql.communication.reader.OffsetTimeReader
org.eclipse.jnosql.communication.reader.UUIDValueReader
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,76 @@ void shouldReturnNullWhenValueUtilHasNullValue() {
Object result = ValueUtil.convert(Value.ofNull());
Assertions.assertNull(result);
}
}

@Test
void shouldConvertWithCustomWriter() {
ValueWriter<Integer, String> customWriter = new ValueWriter<>() {
@Override
public String write(Integer object) {
return "Custom-" + object;
}

@Override
public boolean test(Class<?> aClass) {
return Integer.class.equals(aClass);
}
};

Value value = Value.of(42);
assertEquals("Custom-42", ValueUtil.convert(value, customWriter));
}

@Test
void shouldConvertListWithCustomWriter() {
ValueWriter<Integer, String> customWriter = new ValueWriter<>() {
@Override
public String write(Integer object) {
return "Custom-" + object;
}

@Override
public boolean test(Class<?> aClass) {
return Integer.class.equals(aClass);
}
};

Value value = Value.of(Arrays.asList(10, 20));
assertEquals(Arrays.asList("Custom-10", "Custom-20"), ValueUtil.convertToList(value, customWriter));
}

@Test
void shouldConvertNestedValueWithCustomWriter() {
ValueWriter<Integer, String> customWriter = new ValueWriter<>() {
@Override
public String write(Integer object) {
return "Custom-" + object;
}

@Override
public boolean test(Class<?> aClass) {
return Integer.class.equals(aClass);
}
};

Value value = Value.of(Arrays.asList(Value.of(10), Value.of(20)));
assertEquals(Arrays.asList("Custom-10", "Custom-20"), ValueUtil.convert(value, customWriter));
}

@Test
void shouldConvertNestedListWithCustomWriter() {
ValueWriter<Integer, String> customWriter = new ValueWriter<>() {
@Override
public String write(Integer object) {
return "Custom-" + object;
}

@Override
public boolean test(Class<?> aClass) {
return Integer.class.equals(aClass);
}
};

Value value = Value.of(Arrays.asList(Value.of(10), Value.of(20)));
assertEquals(Arrays.asList("Custom-10", "Custom-20"), ValueUtil.convertToList(value, customWriter));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
*
* Copyright (c) 2024 Contributors to the Eclipse Foundation
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Apache License v2.0 which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Apache License v2.0 is available at http://www.opensource.org/licenses/apache2.0.php.
*
* You may elect to redistribute this code under either of these licenses.
*
* Contributors:
*
* Otavio Santana
*
*/
package org.eclipse.jnosql.communication.reader;

import org.eclipse.jnosql.communication.CommunicationException;
import org.junit.jupiter.api.Test;

import java.util.UUID;

import static org.junit.jupiter.api.Assertions.*;

class UUIDValueReaderTest {
private final UUIDValueReader valueReader = new UUIDValueReader();

@Test
void shouldReadUUIDFromUUIDInstance() {
UUID uuid = UUID.randomUUID();
UUID result = valueReader.read(UUID.class, uuid);
assertEquals(uuid, result);
}

@Test
void shouldReadUUIDFromString() {
UUID uuid = UUID.randomUUID();
UUID result = valueReader.read(UUID.class, uuid.toString());
assertEquals(uuid, result);
}

@Test
void shouldReturnNullForInvalidString() {
String invalidUUID = "invalid-uuid";
assertThrows(CommunicationException.class, () -> valueReader.read(UUID.class, invalidUUID));
}

@Test
void shouldReturnNullForUnsupportedType() {
Integer unsupportedValue = 42;
UUID result = valueReader.read(UUID.class, unsupportedValue);
assertNull(result);
}

@Test
void shouldTestUUIDType() {
assertTrue(valueReader.test(UUID.class));
}

@Test
void shouldNotTestNonUUIDType() {
assertFalse(valueReader.test(String.class));
}
}
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -551,7 +551,7 @@
<version>${apache.pdm.plugin.version}</version>
<configuration>
<rulesets>
<ruleset>pmd/pmd-rules.xml</ruleset>
<ruleset>https://raw.githubusercontent.com/eclipse/jnosql/refs/heads/main/pmd/pmd-rules.xml</ruleset>
</rulesets>
<excludes>
<exclude>**/org/eclipse/jnosql/query/**/*.java</exclude>
Expand Down

0 comments on commit 0605fb6

Please sign in to comment.