Skip to content

Commit f7ca044

Browse files
committed
latestofexpression. Better error message when a node is not resolved. Placeholder of classes
1 parent d0cbdaf commit f7ca044

File tree

5 files changed

+129
-5
lines changed

5 files changed

+129
-5
lines changed
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/**
2+
* Copyright (c) 2017 European Organisation for Nuclear Research (CERN), All Rights Reserved.
3+
*/
4+
5+
package org.tensorics.core.expressions;
6+
7+
import java.util.List;
8+
9+
import org.tensorics.core.tree.domain.Expression;
10+
11+
import com.google.common.collect.Iterables;
12+
13+
/**
14+
* Expression that given an {@link Expression} of {@link List} of T, it gets the latest. Especially usefull for buffers.
15+
*
16+
* @param <T>
17+
*/
18+
public class LatestOfExpression<T> extends ConversionOperationExpression<Iterable<T>, T> {
19+
20+
private static final long serialVersionUID = 6562010523280754793L;
21+
22+
private final Expression<Iterable<T>> bufferExpression;
23+
24+
private LatestOfExpression(Expression<Iterable<T>> source) {
25+
super(Iterables::getLast, source);
26+
bufferExpression = source;
27+
}
28+
29+
public static <T> LatestOfExpression<T> latestOf(Expression<Iterable<T>> source) {
30+
return new LatestOfExpression<>(source);
31+
}
32+
33+
@Override
34+
public int hashCode() {
35+
final int prime = 31;
36+
int result = super.hashCode();
37+
result = prime * result + ((bufferExpression == null) ? 0 : bufferExpression.hashCode());
38+
return result;
39+
}
40+
41+
@Override
42+
public boolean equals(Object obj) {
43+
if (this == obj)
44+
return true;
45+
if (!super.equals(obj))
46+
return false;
47+
if (getClass() != obj.getClass())
48+
return false;
49+
LatestOfExpression<?> other = (LatestOfExpression<?>) obj;
50+
if (bufferExpression == null) {
51+
if (other.bufferExpression != null)
52+
return false;
53+
} else if (!bufferExpression.equals(other.bufferExpression))
54+
return false;
55+
return true;
56+
}
57+
58+
@Override
59+
public String toString() {
60+
return "LatestOfExpression [bufferExpression=" + bufferExpression + "]";
61+
}
62+
63+
}

src/java/org/tensorics/core/expressions/Placeholder.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ public class Placeholder<R> extends AbstractDeferredExpression<R> {
2222
public static <R> Placeholder<R> ofName(String name) {
2323
return new Placeholder<>(name);
2424
}
25+
26+
public static <R> Placeholder<R> ofClass(Class<R> clazz) {
27+
return new Placeholder<>(clazz.getName());
28+
}
2529

2630
private Placeholder(String name) {
2731
this.name = requireNonNull(name, "name must not be null.");

src/java/org/tensorics/core/resolve/engine/BiggestSubTreeDispatcher.java

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import org.tensorics.core.resolve.options.ResolvingOption;
3434
import org.tensorics.core.resolve.resolvers.Resolver;
3535
import org.tensorics.core.resolve.resolvers.ResolverRepository;
36+
import org.tensorics.core.resolve.resolvers.Resolvers;
3637
import org.tensorics.core.tree.domain.Contexts;
3738
import org.tensorics.core.tree.domain.EditableResolvingContext;
3839
import org.tensorics.core.tree.domain.Expression;
@@ -84,7 +85,7 @@ public ResolvingContext processTree(Node rootNode, ResolvingContext oldContext,
8485
*/
8586
private ResolverCandidateRepository findResolverCandidates(Node startingNode, final ResolvingContext oldContext) {
8687

87-
final ResolverCandidateRepository directlyExecutableNodes = new ResolverCandidateRepository(oldContext);
88+
final ResolverCandidateRepository repository = new ResolverCandidateRepository(oldContext);
8889

8990
Trees.walkParentAfterChildren(startingNode, new SkipNodeAndSubTreesCallback() {
9091

@@ -105,15 +106,20 @@ private <R> boolean process(Expression<R> expression) {
105106

106107
for (Resolver<R, Expression<R>> resolver : resolvers) {
107108
if (resolver.canResolve(expression, oldContext)) {
108-
directlyExecutableNodes.put(expression, resolver);
109+
repository.put(expression, resolver);
109110
}
110111
}
111112

112-
return directlyExecutableNodes.containsKey(expression);
113+
if (repository.resolversFor(expression).isEmpty() && Resolvers.contextResolvesAllNodes(expression.getChildren(), oldContext)) {
114+
throw new IllegalStateException("No resolvers could be found for node " + expression
115+
+ ", while all children are already resolved.");
116+
}
117+
118+
return repository.containsKey(expression);
113119
}
114120

115121
});
116-
return directlyExecutableNodes;
122+
return repository;
117123
}
118124

119125
static class ResolverCandidateRepository {
@@ -152,7 +158,8 @@ private boolean containsKey(Expression<?> expression) {
152158

153159
private <R, E extends Expression<R>> void resolveNode(E expression, EditableResolvingContext context,
154160
ResolverSelectionStrategy resolverSelection) {
155-
Resolver<R, E> resolver = resolverSelection.selectResolver(resolversFor(expression));
161+
List<Resolver<R, E>> resolverCandidates = resolversFor(expression);
162+
Resolver<R, E> resolver = resolverSelection.selectResolver(resolverCandidates);
156163
context.put(expression, resolver.resolve(expression, oldContext));
157164
}
158165

src/java/org/tensorics/core/resolve/resolvers/Resolvers.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import java.util.List;
2828

2929
import org.tensorics.core.tree.domain.Expression;
30+
import org.tensorics.core.tree.domain.Node;
3031
import org.tensorics.core.tree.domain.ResolvingContext;
3132

3233
/**
@@ -76,4 +77,10 @@ public static final boolean contextResolvesAll(List<? extends Expression<?>> exp
7677
ResolvingContext context) {
7778
return expressions.stream().allMatch(context::resolves);
7879
}
80+
81+
public static final boolean contextResolvesAllNodes(List<? extends Node> expressions,
82+
ResolvingContext context) {
83+
/*XXX ugly cast */
84+
return expressions.stream().map(n -> (Expression<?>) n).allMatch(context::resolves);
85+
}
7986
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/**
2+
* Copyright (c) 2017 European Organisation for Nuclear Research (CERN), All Rights Reserved.
3+
*/
4+
5+
package org.tensorics.core.expressions;
6+
7+
import static java.util.Arrays.asList;
8+
import static org.assertj.core.api.Assertions.assertThat;
9+
import static org.tensorics.core.expressions.LatestOfExpression.latestOf;
10+
import static org.tensorics.core.tree.domain.ResolvedExpression.of;
11+
12+
import java.util.Arrays;
13+
14+
import org.junit.Before;
15+
import org.junit.Test;
16+
import org.tensorics.core.resolve.engine.ResolvingEngine;
17+
import org.tensorics.core.resolve.engine.ResolvingEngines;
18+
import org.tensorics.core.tree.domain.Expression;
19+
import org.tensorics.core.tree.domain.ResolvedExpression;
20+
21+
public class LatestOfExpressionTest {
22+
23+
private ResolvingEngine engine;
24+
25+
@Before
26+
public void setUp() {
27+
engine = ResolvingEngines.defaultEngine();
28+
}
29+
30+
@Test
31+
public void testLatestValue() {
32+
Expression<Iterable<Integer>> buffer = ResolvedExpression.of(Arrays.asList(1, 2, 3, 4));
33+
Expression<Integer> latestFromBuffer = latestOf(buffer);
34+
35+
assertThat(engine.resolve(latestFromBuffer)).isEqualTo(4);
36+
}
37+
38+
@Test
39+
public void equality() {
40+
assertThat(latestOf(of(asList(new Integer(300))))).isEqualTo(latestOf(of(asList(300))));
41+
}
42+
43+
}

0 commit comments

Comments
 (0)