Skip to content

Commit b4bdc97

Browse files
gselzerctrueden
authored andcommitted
Improve OpAdaptationInfo constructor
1 parent 273d4be commit b4bdc97

4 files changed

Lines changed: 59 additions & 19 deletions

File tree

scijava/scijava-ops-api/src/main/java/org/scijava/ops/api/InfoChain.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ public OpInstance<?> op(Type opType) {
7171
return OpInstance.of(generateOp(), this, opType);
7272
}
7373

74-
private Object generateOp() {
74+
protected Object generateOp() {
7575
List<Object> dependencyInstances = dependencies().stream() //
7676
.map(d -> d.op().op()) //
7777
.collect(Collectors.toList());

scijava/scijava-ops-engine/src/main/java/org/scijava/ops/engine/impl/DefaultOpEnvironment.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -652,11 +652,7 @@ private OpCandidate adaptOp(OpRef ref, Hints hints) {
652652
// resolve adaptor dependencies
653653
final List<RichOp<?>> dependencies = resolveOpDependencies(adaptor,
654654
map, hints);
655-
656-
@SuppressWarnings("unchecked")
657-
Function<Object, Object> adaptorOp = //
658-
(Function<Object, Object>) adaptor.createOpInstance(dependencies) //
659-
.object(); //
655+
InfoChain adaptorChain = new DependencyInstantiatedInfoChain(adaptor, dependencies);
660656

661657
// grab the first type parameter from the OpInfo and search for
662658
// an Op that will then be adapted (this will be the only input of the
@@ -669,7 +665,7 @@ private OpCandidate adaptOp(OpRef ref, Hints hints) {
669665
Type adapterOpType = Types.substituteTypeVariables(adaptor.output()
670666
.getType(), map);
671667
OpAdaptationInfo adaptedInfo = new OpAdaptationInfo(srcCandidate
672-
.opInfo(), adapterOpType, adaptor, adaptorOp);
668+
.opInfo(), adapterOpType, adaptorChain);
673669
OpCandidate adaptedCandidate = new OpCandidate(this, ref, adaptedInfo, map);
674670
adaptedCandidate.setStatus(StatusCode.MATCH);
675671
return adaptedCandidate;
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package org.scijava.ops.engine.impl;
2+
3+
import java.util.List;
4+
import java.util.stream.Collectors;
5+
6+
import org.scijava.ops.api.InfoChain;
7+
import org.scijava.ops.api.OpInfo;
8+
import org.scijava.ops.api.RichOp;
9+
10+
/**
11+
* An {@link InfoChain} specialization for instances when the dependencies are
12+
* already instantiated. With a normal {@link InfoChain}, we'd have to get the
13+
* {@link InfoChain}s of all dependencies, then reinstantiate them.
14+
*
15+
* @author Gabe Selzer
16+
*/
17+
public class DependencyInstantiatedInfoChain extends InfoChain {
18+
19+
private final List<RichOp<?>> dependencies;
20+
21+
public DependencyInstantiatedInfoChain(OpInfo info, List<RichOp<?>> dependencies) {
22+
super(info, chainsFrom(dependencies));
23+
this.dependencies = dependencies;
24+
}
25+
26+
@Override
27+
protected Object generateOp() {
28+
List<Object> dependencyInstances = dependencies.stream() //
29+
.map(d -> d.op()) //
30+
.collect(Collectors.toList());
31+
return info().createOpInstance(dependencyInstances).object();
32+
}
33+
34+
public static List<InfoChain> chainsFrom(List<RichOp<?>> dependencies) {
35+
return dependencies.stream().map(op -> op.infoChain()).collect(Collectors.toList());
36+
}
37+
38+
}

scijava/scijava-ops-engine/src/main/java/org/scijava/ops/engine/matcher/impl/OpAdaptationInfo.java

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@
99

1010
import org.scijava.ValidityProblem;
1111
import org.scijava.ops.api.Hints;
12+
import org.scijava.ops.api.InfoChain;
1213
import org.scijava.ops.api.OpDependencyMember;
1314
import org.scijava.ops.api.OpInfo;
15+
import org.scijava.ops.api.OpInstance;
1416
import org.scijava.ops.api.OpUtils;
1517
import org.scijava.ops.api.features.BaseOpHints.Adaptation;
1618
import org.scijava.ops.engine.struct.FunctionalParameters;
@@ -21,6 +23,7 @@
2123
import org.scijava.struct.StructInstance;
2224
import org.scijava.struct.Structs;
2325
import org.scijava.struct.ValidityException;
26+
import org.scijava.types.Nil;
2427

2528
/**
2629
* {@link OpInfo} for ops that have been adapted to some other Op type.
@@ -33,21 +36,19 @@ public class OpAdaptationInfo implements OpInfo {
3336
private static final String IMPL_DELIMITER = "|Adaptation|";
3437

3538
private final OpInfo srcInfo;
36-
private final OpInfo adaptorInfo;
39+
private final InfoChain adaptorChain;
3740
private final Type type;
38-
private final Function<Object, Object> adaptor;
3941
private final Hints hints;
4042

4143
private Struct struct;
4244
private ValidityException validityException;
4345

4446
public OpAdaptationInfo(OpInfo srcInfo, Type type,
45-
OpInfo adaptorInfo, Function<Object, Object> adaptor)
47+
InfoChain adaptorChain)
4648
{
4749
this.srcInfo = srcInfo;
48-
this.adaptorInfo = adaptorInfo;
50+
this.adaptorChain = adaptorChain;
4951
this.type = type;
50-
this.adaptor = adaptor;
5152

5253
// NOTE: since the source Op has already been shown to be valid, there is
5354
// not
@@ -102,16 +103,21 @@ public double priority() {
102103

103104
@Override
104105
public String implementationName() {
105-
return srcInfo.implementationName() + IMPL_DELIMITER + adaptorInfo.implementationName();
106+
return srcInfo.implementationName() + IMPL_DELIMITER + adaptorChain.signature();
106107
}
107108

108109
/**
109110
* @param dependencies - the list of depencies <b>for the source Op</b>
110111
*/
111112
@Override
112113
public StructInstance<?> createOpInstance(List<?> dependencies) {
114+
@SuppressWarnings("unchecked")
115+
OpInstance<Function<Object, Object>> adaptorInstance =
116+
(OpInstance<Function<Object, Object>>) adaptorChain.op(
117+
new Nil<Function<Object, Object>>()
118+
{}.getType());
113119
final Object op = srcInfo.createOpInstance(dependencies).object();
114-
final Object adaptedOp = adaptor.apply(op);
120+
final Object adaptedOp = adaptorInstance.op().apply(op);
115121
return struct().createInstance(adaptedOp);
116122
}
117123

@@ -139,28 +145,28 @@ public AnnotatedElement getAnnotationBearer() {
139145
*/
140146
@Override
141147
public String version() {
142-
return adaptorInfo.version();
148+
return adaptorChain.info().version();
143149
}
144150

145151
/**
146152
* For an adapted Op, we define the implementation name as the concatenation
147153
* of:
148154
* <ol>
149-
* <li>The implementation name of the <b>original info</b>
155+
* <li>The signature of the <b>adaptor</b> {@link InfoChain}
150156
* <li>The adaptation delimiter
151-
* <li>The implementation name of the <b>adaptor</b>
157+
* <li>The implementation name of the <b>original info</b>
152158
* </ol>
153159
* <p>
154160
* For example, for a source {@code com.example.foo.Bar@1.0.0} with adaptor
155161
* {@code com.example.foo.BazAdaptor@1.0.0} with delimiter
156162
* {@code |Adaptation|}, you might have
157163
* <p>
158-
* {@code com.example.foo.Bar@1.0.0|Adaptation|com.example.foo.BazAdaptor@1.0.0}
164+
* {@code com.example.foo.BazAdaptor@1.0.0{}|Adaptation|com.example.foo.Bar@1.0.0}
159165
* <p>
160166
*/
161167
@Override
162168
public String id() {
163-
return srcInfo.id() + IMPL_DELIMITER + adaptorInfo.id();
169+
return adaptorChain.signature() + IMPL_DELIMITER + srcInfo.id();
164170
}
165171

166172
}

0 commit comments

Comments
 (0)