Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance ValueUtil #566

Merged
merged 13 commits into from
Dec 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading