Skip to content

Commit bff97b7

Browse files
authored
Merge pull request #46 from tensorics/gson-prep
preparation for gson adaptation
2 parents c392b53 + 4f3f7c7 commit bff97b7

File tree

5 files changed

+100
-20
lines changed

5 files changed

+100
-20
lines changed

src/java/org/tensorics/core/lang/Tensorics.java

+12-1
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,10 @@ public static <T> TensorBuilder<T> builder(Class<?>... dimensions) {
124124
return ImmutableTensor.builder(dimensions);
125125
}
126126

127+
public static <T> TensorbackedScalarBuilder<T, TensorbackedScalar<T>> builderBacked() {
128+
return DimtypedTensorbackedBuilderImpl.from(ImmutableTensor.builder(), TensorbackedScalarBuilder.class, TensorbackedScalar.class);
129+
}
130+
127131
public static <C1, T> Tensorbacked1dBuilder<C1, T, Tensorbacked1d<C1, T>> builderBacked(Class<C1> dimension1) {
128132
return DimtypedTensorbackedBuilderImpl.from(ImmutableTensor.builder(dimension1), Tensorbacked1dBuilder.class, Tensorbacked1d.class);
129133
}
@@ -198,6 +202,13 @@ public static <V, TB extends Tensorbacked<V>> SimpleTensorbackedBuilder<V, TB> b
198202
return Tensorbackeds.builderFor(tensorbackedClass);
199203
}
200204

205+
/**
206+
* @see Tensorbackeds#builderForScalar(Class)
207+
*/
208+
public static <V, TB extends TensorbackedScalar< V>> TensorbackedScalarBuilder<V, TB> builderForScalar(Class<TB> tensorbackedClass) {
209+
return Tensorbackeds.builderForScalar(tensorbackedClass);
210+
}
211+
201212
/**
202213
* @see Tensorbackeds#builderFor1D(Class)
203214
*/
@@ -450,7 +461,7 @@ public static <S> void forEach(Tensor<S> tensor, BiConsumer<Position, S> consume
450461
}
451462

452463
public static Scalar<QuantifiedValue<Double>> zeroDimensionalOf(double value,
453-
javax.measure.unit.Unit<?> unit) {
464+
javax.measure.unit.Unit<?> unit) {
454465
QuantifiedValue<Double> quantity = quantityOf(value, unit);
455466
return scalarOf(quantity);
456467
}

src/java/org/tensorics/core/tensorbacked/TensorbackedInternals.java

+22-2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
import java.util.Optional;
3232
import java.util.Set;
3333

34+
import com.google.common.collect.ImmutableList;
35+
import com.google.common.reflect.TypeToken;
3436
import org.tensorics.core.lang.Tensorics;
3537
import org.tensorics.core.tensor.Positions;
3638
import org.tensorics.core.tensor.Shape;
@@ -63,23 +65,28 @@ private TensorbackedInternals() {
6365
* class.
6466
*/
6567
public static <T extends Tensorbacked<?>> Set<Class<?>> dimensionsOf(Class<T> tensorBackedClass) {
68+
return ImmutableSet.copyOf(dimensionListFrom(tensorBackedClass));
69+
}
70+
71+
public static <T extends Tensorbacked<?>> List<Class<?>> dimensionListFrom(Class<T> tensorBackedClass) {
6672
if (DimtypedTensorbacked.class.isAssignableFrom(tensorBackedClass)) {
6773
if (tensorBackedClass.isAnnotationPresent(Dimensions.class)) {
6874
throw new IllegalArgumentException("No annotation of type '" + Dimensions.class + "' must be present in case " +
6975
DimtypedTensorbacked.class + " is implemented. This rule is violated for class " + tensorBackedClass + ".");
7076
}
71-
return DimtypedTypes.dimensionsFrom((Class<? extends DimtypedTensorbacked>) tensorBackedClass);
77+
return DimtypedTypes.dimensionListFrom((Class<? extends DimtypedTensorbacked>) tensorBackedClass);
7278
} else {
7379
Dimensions dimensionAnnotation = tensorBackedClass.getAnnotation(Dimensions.class);
7480
if (dimensionAnnotation == null) {
7581
throw new IllegalArgumentException(
7682
"Neither an annotation of type '" + Dimensions.class + "' is present on the class '" + tensorBackedClass
7783
+ "', nor does it inherit from " + DimtypedTensorbacked.class + ". Therefore, the dimensions of this tensorbacked type cannot be determined.");
7884
}
79-
return ImmutableSet.copyOf(dimensionAnnotation.value());
85+
return ImmutableList.copyOf(dimensionAnnotation.value());
8086
}
8187
}
8288

89+
8390
/**
8491
* Creates an instance of a class backed by a tensor.
8592
*
@@ -154,4 +161,17 @@ private static <E> Tensor<E> copyWithDimensions(Tensor<E> tensor, Set<Class<?>>
154161
builder.context(tensor.context());
155162
return builder.build();
156163
}
164+
165+
/**
166+
* Determines the type of the value of the given tensorbacked class.
167+
*
168+
* @param tensorBackedClass the class from which to determine the value type
169+
* @param <T> the type of the tensorbacked
170+
* @return the type of the value
171+
*/
172+
public static <V, T extends Tensorbacked<V>> Class<V> valueTypeFrom(Class<T> tensorBackedClass) {
173+
TypeToken<T> tbToken = TypeToken.of(tensorBackedClass);
174+
TypeToken<?> valueToken = tbToken.resolveType(Tensorbacked.class.getTypeParameters()[0]);
175+
return (Class<V>) valueToken.getRawType();
176+
}
157177
}

src/java/org/tensorics/core/tensorbacked/Tensorbackeds.java

+5-11
Original file line numberDiff line numberDiff line change
@@ -32,17 +32,7 @@
3232
import org.tensorics.core.tensor.lang.QuantityTensors;
3333
import org.tensorics.core.tensor.lang.TensorStructurals;
3434
import org.tensorics.core.tensorbacked.annotation.Dimensions;
35-
import org.tensorics.core.tensorbacked.dimtyped.DimtypedTensorbackedBuilderImpl;
36-
import org.tensorics.core.tensorbacked.dimtyped.Tensorbacked1d;
37-
import org.tensorics.core.tensorbacked.dimtyped.Tensorbacked1dBuilder;
38-
import org.tensorics.core.tensorbacked.dimtyped.Tensorbacked2d;
39-
import org.tensorics.core.tensorbacked.dimtyped.Tensorbacked2dBuilder;
40-
import org.tensorics.core.tensorbacked.dimtyped.Tensorbacked3d;
41-
import org.tensorics.core.tensorbacked.dimtyped.Tensorbacked3dBuilder;
42-
import org.tensorics.core.tensorbacked.dimtyped.Tensorbacked4d;
43-
import org.tensorics.core.tensorbacked.dimtyped.Tensorbacked4dBuilder;
44-
import org.tensorics.core.tensorbacked.dimtyped.Tensorbacked5d;
45-
import org.tensorics.core.tensorbacked.dimtyped.Tensorbacked5dBuilder;
35+
import org.tensorics.core.tensorbacked.dimtyped.*;
4636
import org.tensorics.core.tensorbacked.lang.OngoingTensorbackedConstruction;
4737
import org.tensorics.core.tensorbacked.lang.OngoingTensorbackedFiltering;
4838
import org.tensorics.core.units.Unit;
@@ -75,6 +65,10 @@ public static <V, TB extends Tensorbacked<V>> SimpleTensorbackedBuilder<V, TB> b
7565
return new SimpleTensorbackedBuilder<>(tensorbackedClass);
7666
}
7767

68+
public static <V, TB extends TensorbackedScalar< V>> TensorbackedScalarBuilder<V, TB> builderForScalar(Class<TB> tensorbackedClass) {
69+
return DimtypedTensorbackedBuilderImpl.immutableBuilderFrom(tensorbackedClass, TensorbackedScalarBuilder.class);
70+
}
71+
7872
public static <C1, V, TB extends Tensorbacked1d<C1, V>> Tensorbacked1dBuilder<C1, V, TB> builderFor1D(Class<TB> tensorbackedClass) {
7973
return DimtypedTensorbackedBuilderImpl.immutableBuilderFrom(tensorbackedClass, Tensorbacked1dBuilder.class);
8074
}

src/java/org/tensorics/core/tensorbacked/dimtyped/DimtypedTypes.java

+23-6
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
package org.tensorics.core.tensorbacked.dimtyped;
22

3+
import com.google.common.collect.ImmutableList;
34
import com.google.common.collect.ImmutableMap;
45
import com.google.common.collect.ImmutableSet;
56
import com.google.common.collect.Iterables;
67
import com.google.common.reflect.TypeToken;
78

9+
import java.util.Collection;
10+
import java.util.List;
811
import java.util.NoSuchElementException;
912
import java.util.Set;
1013
import java.util.stream.Collectors;
1114
import java.util.stream.IntStream;
1215

16+
import static com.google.common.collect.ImmutableList.toImmutableList;
1317
import static java.util.stream.Collectors.toSet;
1418

1519
public final class DimtypedTypes {
@@ -63,29 +67,42 @@ public static Class<? extends DimtypedTensorbacked> coordinateParametrizedSubtyp
6367
return Iterables.getOnlyElement(found);
6468
}
6569

66-
public static Set<Class<?>> dimensionsFrom(Class<? extends DimtypedTensorbacked> tensorbackedClass) {
70+
public static List<Class<?>> dimensionListFrom(Class<? extends DimtypedTensorbacked> tensorbackedClass) {
6771
Class<? extends DimtypedTensorbacked> coordinateParametrized = coordinateParametrizedSubtypeOf(tensorbackedClass);
6872
int dimensionality = DIMENSION_PARAMETRIZED_TYPES.get(coordinateParametrized);
6973

7074
TypeToken<?> tt = TypeToken.of(tensorbackedClass);
71-
Set<Class<?>> dimensions = IntStream.range(0, dimensionality)
75+
List<Class<?>> dimensions = IntStream.range(0, dimensionality)
7276
.mapToObj(i -> tt.resolveType(coordinateParametrized.getTypeParameters()[i]))
7377
.map(typeToken -> typeToken.getRawType())
74-
.collect(toSet());
78+
.collect(toImmutableList());
79+
80+
assertNoObjectDimension(tensorbackedClass, dimensions);
81+
assertDistinctDimensionality(coordinateParametrized, dimensions);
82+
return dimensions;
83+
}
7584

85+
private static void assertNoObjectDimension(Class<? extends DimtypedTensorbacked> tensorbackedClass, Collection<Class<?>> dimensions) {
7686
if (dimensions.contains(Object.class)) {
7787
/* If type parameters are not explicitely defined in a subtype, then they seem to be resolved to Object.class.
7888
However, this is not what we want for dimensions... */
7989
throw new IllegalArgumentException("At least one of the extracted dimensions is '" + Object.class + "'. This is most probably a conceptual error.\n" +
8090
"Most probably, the passed in class (" + tensorbackedClass + ") is not a valid subtype with resolvable type parameters.");
8191
}
82-
if (dimensions.size() != dimensionality) {
83-
throw new IllegalArgumentException("The size of the set of the retrieved dimensions (size=" + dimensions.size() + ", dimensions=" + dimensions + "), " +
92+
}
93+
94+
private static void assertDistinctDimensionality(Class<? extends DimtypedTensorbacked> coordinateParametrized, Collection<Class<?>> dimensions) {
95+
int dimensionality = DIMENSION_PARAMETRIZED_TYPES.get(coordinateParametrized);
96+
Collection<Class<?>> distinctDimensions = ImmutableSet.copyOf(dimensions);
97+
if (distinctDimensions.size() != dimensionality) {
98+
throw new IllegalArgumentException("The size of the set of the retrieved distinct dimensions (size=" + distinctDimensions.size() + ", dimensions=" + distinctDimensions + "), " +
8499
"is not equal to the required number of dimensions (" + dimensionality + ") for the parametrized class " + coordinateParametrized + ".\n"
85100
+ "Probably two dimensions are of the same type?");
86101
}
87-
return dimensions;
102+
}
88103

104+
public static Set<Class<?>> dimensionsFrom(Class<? extends DimtypedTensorbacked> tensorbackedClass) {
105+
return ImmutableSet.copyOf(dimensionListFrom(tensorbackedClass));
89106
}
90107

91108
private static ImmutableSet<Class<? extends DimtypedTensorbacked>> allowedTypes() {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package org.tensorics.core.tensorbacked;
2+
3+
import org.junit.Test;
4+
import org.tensorics.core.tensor.Tensor;
5+
import org.tensorics.core.tensorbacked.AbstractTensorbacked;
6+
import org.tensorics.core.tensorbacked.TensorbackedInternals;
7+
import org.tensorics.core.tensorbacked.annotation.Dimensions;
8+
import org.tensorics.core.tensorbacked.dimtyped.Tensorbacked1d;
9+
10+
import static org.assertj.core.api.Assertions.assertThat;
11+
12+
public class ValueTypeDeterminationTest {
13+
14+
@Test
15+
public void valueTypeWorksForInherited() {
16+
Class<?> valueType = TensorbackedInternals.valueTypeFrom(AnInheritedTensorbacked.class);
17+
assertThat(valueType).isEqualTo(Double.class);
18+
}
19+
20+
@Test
21+
public void valueTypeWorksForInterface() {
22+
Class<?> valueType = TensorbackedInternals.valueTypeFrom(AnInterfaceDerivedTensorbacked.class);
23+
assertThat(valueType).isEqualTo(Double.class);
24+
}
25+
26+
@Dimensions({String.class, Integer.class})
27+
public static class AnInheritedTensorbacked extends AbstractTensorbacked<Double> {
28+
29+
public AnInheritedTensorbacked(Tensor<Double> tensor) {
30+
super(tensor);
31+
}
32+
33+
}
34+
35+
public interface AnInterfaceDerivedTensorbacked extends Tensorbacked1d<String, Double> {
36+
37+
}
38+
}

0 commit comments

Comments
 (0)