Skip to content

Package: DatatypeTransformer

DatatypeTransformer

nameinstructionbranchcomplexitylinemethod
DatatypeTransformer()
M: 6 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
initTransformers()
M: 0 C: 213
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 25
100%
M: 0 C: 1
100%
lambda$initTransformers$0(Object)
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
lambda$initTransformers$1(Object)
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
lambda$initTransformers$10(Object)
M: 0 C: 5
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
lambda$initTransformers$11(Object)
M: 0 C: 5
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
lambda$initTransformers$12(Object)
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
lambda$initTransformers$13(Object)
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
lambda$initTransformers$14(Object)
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
lambda$initTransformers$15(Object)
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
lambda$initTransformers$16(Object)
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
lambda$initTransformers$17(Object)
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
lambda$initTransformers$18(Object)
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
lambda$initTransformers$19(Object)
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
lambda$initTransformers$2(Object)
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
lambda$initTransformers$20(Object)
M: 11 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 3 C: 0
0%
M: 1 C: 0
0%
lambda$initTransformers$21(Object)
M: 0 C: 5
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
lambda$initTransformers$22(Object)
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
lambda$initTransformers$3(Object)
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
lambda$initTransformers$4(Object)
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
lambda$initTransformers$5(Object)
M: 0 C: 5
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
lambda$initTransformers$6(Object)
M: 0 C: 5
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
lambda$initTransformers$7(Object)
M: 0 C: 5
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
lambda$initTransformers$8(Object)
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
lambda$initTransformers$9(Object)
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
lambda$transform$23(Object, Class)
M: 0 C: 21
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
static {...}
M: 0 C: 3
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
transform(Object, Class)
M: 0 C: 63
100%
M: 0 C: 10
100%
M: 0 C: 6
100%
M: 0 C: 13
100%
M: 0 C: 1
100%
tryConversionUsingConstructor(Object, Class)
M: 7 C: 46
87%
M: 0 C: 6
100%
M: 0 C: 4
100%
M: 2 C: 7
78%
M: 0 C: 1
100%

Coverage

1: /*
2: * JOPA
3: * Copyright (C) 2024 Czech Technical University in Prague
4: *
5: * This library is free software; you can redistribute it and/or
6: * modify it under the terms of the GNU Lesser General Public
7: * License as published by the Free Software Foundation; either
8: * version 3.0 of the License, or (at your option) any later version.
9: *
10: * This library is distributed in the hope that it will be useful,
11: * but WITHOUT ANY WARRANTY; without even the implied warranty of
12: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13: * Lesser General Public License for more details.
14: *
15: * You should have received a copy of the GNU Lesser General Public
16: * License along with this library.
17: */
18: package cz.cvut.kbss.jopa.datatype;
19:
20: import cz.cvut.kbss.jopa.datatype.exception.DatatypeMappingException;
21: import cz.cvut.kbss.jopa.datatype.exception.UnsupportedTypeTransformationException;
22: import cz.cvut.kbss.jopa.datatype.util.Pair;
23: import cz.cvut.kbss.ontodriver.model.LangString;
24:
25: import java.lang.reflect.Constructor;
26: import java.lang.reflect.InvocationTargetException;
27: import java.math.BigInteger;
28: import java.net.MalformedURLException;
29: import java.net.URI;
30: import java.net.URL;
31: import java.util.HashMap;
32: import java.util.Map;
33: import java.util.Objects;
34: import java.util.Optional;
35: import java.util.function.Function;
36:
37: /**
38: * Utility containing transformation rules for selected basic types.
39: */
40: public class DatatypeTransformer {
41:
42: private static final Map<Pair, Function<Object, ?>> TRANSFORMERS = initTransformers();
43:
44: private DatatypeTransformer() {
45: throw new AssertionError();
46: }
47:
48: private static Map<Pair, Function<Object, ?>> initTransformers() {
49: final Map<Pair, Function<Object, ?>> map = new HashMap<>();
50: map.put(new Pair(Short.class, Integer.class), value -> ((Short) value).intValue());
51: map.put(new Pair(Short.class, Long.class), value -> ((Short) value).longValue());
52: map.put(new Pair(Short.class, Float.class), value -> ((Short) value).floatValue());
53: map.put(new Pair(Short.class, Double.class), value -> ((Short) value).doubleValue());
54: map.put(new Pair(Integer.class, Short.class), value -> ((Integer) value).shortValue());
55: map.put(new Pair(Integer.class, Long.class), value -> ((Integer) value).longValue());
56: map.put(new Pair(Integer.class, Float.class), value -> ((Integer) value).floatValue());
57: map.put(new Pair(Integer.class, Double.class), value -> ((Integer) value).doubleValue());
58: map.put(new Pair(Long.class, Integer.class), value -> ((Long) value).intValue());
59: map.put(new Pair(Long.class, Short.class), value -> ((Long) value).shortValue());
60: map.put(new Pair(Long.class, Float.class), value -> ((Long) value).floatValue());
61: map.put(new Pair(Long.class, Double.class), value -> ((Long) value).doubleValue());
62: map.put(new Pair(Float.class, Short.class), value -> ((Float) value).shortValue());
63: map.put(new Pair(Float.class, Integer.class), value -> ((Float) value).intValue());
64: map.put(new Pair(Float.class, Long.class), value -> ((Float) value).longValue());
65: map.put(new Pair(Float.class, Double.class), value -> ((Float) value).doubleValue());
66: map.put(new Pair(Double.class, Short.class), value -> ((Double) value).shortValue());
67: map.put(new Pair(Double.class, Integer.class), value -> ((Double) value).intValue());
68: map.put(new Pair(Double.class, Long.class), value -> ((Double) value).longValue());
69: map.put(new Pair(Double.class, Float.class), value -> ((Double) value).floatValue());
70: map.put(new Pair(URI.class, URL.class), value -> {
71: try {
72: return ((URI) value).toURL();
73: } catch (MalformedURLException e) {
74: throw new DatatypeMappingException("Unable to transform URI to URL.", e);
75: }
76: });
77: map.put(new Pair(BigInteger.class, Integer.class), value -> ((BigInteger) value).intValueExact());
78: map.put(new Pair(BigInteger.class, Long.class), value -> ((BigInteger) value).longValueExact());
79: return map;
80: }
81:
82: /**
83: * Maps the specified value to the target type (if possible).
84: *
85: * @param value The value to convert
86: * @param targetType The type to which the specified value should be converted
87: * @param <T> Target type
88: * @return Value as the target type
89: * @throws UnsupportedTypeTransformationException If the specified value cannot be transformed to the specified target type
90: */
91: public static <T> T transform(Object value, Class<T> targetType) {
92: Objects.requireNonNull(targetType);
93:• if (value == null) {
94: return null;
95: }
96:• if (targetType.equals(String.class)) {
97:• return targetType.cast(value instanceof LangString ? ((LangString) value).getValue() : value.toString());
98: }
99: final Class<?> sourceType = value.getClass();
100:• if (targetType.isAssignableFrom(sourceType)) {
101: return targetType.cast(value);
102: }
103: final Pair p = new Pair(sourceType, targetType);
104:• if (TRANSFORMERS.containsKey(p)) {
105: return targetType.cast(TRANSFORMERS.get(p).apply(value));
106: }
107: final Optional<T> result = tryConversionUsingConstructor(value, targetType);
108: return result.orElseThrow(() -> new UnsupportedTypeTransformationException(
109: String.format("Cannot transform value %s of type %s to target type %s.", value, value.getClass(),
110: targetType)));
111: }
112:
113: private static <T> Optional<T> tryConversionUsingConstructor(Object value, Class<T> targetType) {
114: try {
115: final Constructor<?>[] ctors = targetType.getDeclaredConstructors();
116:• for (Constructor<?> c : ctors) {
117:• if (c.getParameterCount() != 1) {
118: continue;
119: }
120:• if (c.getParameterTypes()[0].isAssignableFrom(value.getClass())) {
121: return Optional.of(targetType.cast(c.newInstance(value)));
122: }
123: }
124: return Optional.empty();
125: } catch (IllegalAccessException | InstantiationException | InvocationTargetException e) {
126: throw new DatatypeMappingException("Unable to transform value using target type constructor.", e);
127: }
128: }
129:
130: }