Skip to content

Commit ce12f88

Browse files
Treiblesschorlegselzer
authored andcommitted
Refactoring, renaming, make more dry, and javadoc
1 parent 29782cf commit ce12f88

14 files changed

Lines changed: 344 additions & 179 deletions

src/main/java/org/scijava/ops/OpService.java

Lines changed: 5 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,7 @@
5151
import org.scijava.ops.matcher.OpMatchingException;
5252
import org.scijava.ops.matcher.OpRef;
5353
import org.scijava.ops.matcher.OpTypeMatchingService;
54-
import org.scijava.ops.transform.OpTransformation;
55-
import org.scijava.ops.transform.OpTransformationInfo;
54+
import org.scijava.ops.transform.OpTransformationCandidate;
5655
import org.scijava.ops.transform.OpTransformerService;
5756
import org.scijava.plugin.Parameter;
5857
import org.scijava.plugin.Plugin;
@@ -169,44 +168,15 @@ public <T> T findOpInstance(final String opName, final Nil<T> specialType, final
169168
return (T) match.createOp(secondaryArgs);
170169
} catch (OpMatchingException e) {
171170
// If we can't find an op matching the original request, we try to find a transformation
172-
OpTransformation transfrom = findTransfromation(ref);
171+
OpTransformationCandidate transformation = transformer.findTransfromation(ref);
173172
// If we found one, try to do transformation and return transformed op
174-
if (transfrom != null) {
175-
return (T) transfrom.exceute(this, secondaryArgs);
173+
if (transformation != null) {
174+
return (T) transformation.exceute(this, secondaryArgs);
176175
}
177-
throw new RuntimeException(e);
176+
throw new IllegalArgumentException(e);
178177
}
179178
}
180179

181-
private OpTransformation findTransfromation(OpRef ref) {
182-
List<OpTransformationInfo> ts = transformer.getTansformationsTo(ref);
183-
for (OpTransformationInfo t : ts) {
184-
OpTransformation match = findTransfromation(t, 0);
185-
if (match != null) {
186-
return match;
187-
}
188-
}
189-
return null;
190-
}
191-
192-
private OpTransformation findTransfromation(OpTransformationInfo candidate, int depth) {
193-
if (candidate == null || depth > 1) {
194-
return null;
195-
} else {
196-
OpRef fromRef = candidate.getFrom();
197-
try {
198-
OpCandidate match = findTypeMatch(fromRef);
199-
return new OpTransformation(match, candidate);
200-
} catch (OpMatchingException e) {
201-
List<OpTransformationInfo> ts = transformer.getTansformationsTo(fromRef);
202-
for (OpTransformationInfo t : ts) {
203-
return findTransfromation(candidate.chain(t), depth + 1);
204-
}
205-
}
206-
}
207-
return null;
208-
}
209-
210180
public <T> T findOp(final Nil<T> specialType, final Nil<?>[] inTypes, final Nil<?>[] outTypes,
211181
final Object... secondaryArgs) {
212182
return findOpInstance(null, specialType, inTypes, outTypes, secondaryArgs);

src/main/java/org/scijava/ops/matcher/OpCandidate.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ public String toString() {
200200
public StructInstance<?> createOpInstance(Object... secondaryArgs) throws OpMatchingException {
201201
if (!getStatusCode().equals(StatusCode.MATCH)) {
202202
throw new OpMatchingException(
203-
"Status of candidate to create op " + "from indicates a problem: " + getStatus());
203+
"Status of candidate to create op from indicates a problem: " + getStatus());
204204
}
205205

206206
StructInstance<?> inst = opInfo().createOpInstance();

src/main/java/org/scijava/ops/transform/DefaultOpTransformerService.java

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,26 +35,76 @@
3535
import java.util.ArrayList;
3636
import java.util.List;
3737

38+
import org.scijava.ops.OpService;
39+
import org.scijava.ops.matcher.OpCandidate;
40+
import org.scijava.ops.matcher.OpMatchingException;
3841
import org.scijava.ops.matcher.OpRef;
3942
import org.scijava.plugin.AbstractSingletonService;
4043
import org.scijava.plugin.Plugin;
4144
import org.scijava.service.Service;
4245

46+
/**
47+
* Default service to find Op transformations. This default service will chain two transformations
48+
* at maximum.
49+
*
50+
* @author David Kolb
51+
*/
4352
@Plugin(type = Service.class)
4453
public final class DefaultOpTransformerService extends AbstractSingletonService<OpTransformer>
4554
implements OpTransformerService {
4655

56+
//TODO why does this not work?
57+
// @Parameter
58+
private OpService opService;
59+
4760
@Override
48-
public List<OpTransformationInfo> getTansformationsTo(OpRef toRef) {
49-
List<OpTransformationInfo> transforms = new ArrayList<>();
61+
public List<OpTransformation> getTansformationsTo(OpRef toRef) {
62+
init();
63+
List<OpTransformation> transforms = new ArrayList<>();
5064

5165
for (OpTransformer ot: getInstances()) {
52-
OpRef fromRef = ot.getFromTransformTo(toRef);
66+
OpRef fromRef = ot.getRefTransformingTo(toRef);
5367
if (fromRef != null) {
54-
transforms.add(new OpTransformationInfo(fromRef, toRef, ot));
68+
transforms.add(new OpTransformation(fromRef, toRef, ot));
5569
}
5670
}
5771
return transforms;
5872
}
59-
73+
74+
@Override
75+
public OpTransformationCandidate findTransfromation(OpRef ref) {
76+
init();
77+
List<OpTransformation> ts = getTansformationsTo(ref);
78+
for (OpTransformation t : ts) {
79+
OpTransformationCandidate match = findTransfromation(opService, t, 0);
80+
if (match != null) {
81+
return match;
82+
}
83+
}
84+
return null;
85+
}
86+
87+
private OpTransformationCandidate findTransfromation(OpService opService, OpTransformation candidate, int depth) {
88+
if (candidate == null || depth > 1) {
89+
return null;
90+
} else {
91+
OpRef fromRef = candidate.getSource();
92+
try {
93+
OpCandidate match = opService.findTypeMatch(fromRef);
94+
return new OpTransformationCandidate(match, candidate);
95+
} catch (OpMatchingException e) {
96+
List<OpTransformation> ts = getTansformationsTo(fromRef);
97+
for (OpTransformation t : ts) {
98+
return findTransfromation(opService, t.chain(candidate), depth + 1);
99+
}
100+
}
101+
}
102+
return null;
103+
}
104+
105+
private void init() {
106+
if (opService == null) {
107+
opService = context().getService(OpService.class);
108+
}
109+
}
60110
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* #%L
3+
* ImageJ software for multidimensional image processing and analysis.
4+
* %%
5+
* Copyright (C) 2014 - 2018 ImageJ developers.
6+
* %%
7+
* Redistribution and use in source and binary forms, with or without
8+
* modification, are permitted provided that the following conditions are met:
9+
*
10+
* 1. Redistributions of source code must retain the above copyright notice,
11+
* this list of conditions and the following disclaimer.
12+
* 2. Redistributions in binary form must reproduce the above copyright notice,
13+
* this list of conditions and the following disclaimer in the documentation
14+
* and/or other materials provided with the distribution.
15+
*
16+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
20+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26+
* POSSIBILITY OF SUCH DAMAGE.
27+
* #L%
28+
*/
29+
30+
package org.scijava.ops.transform;
31+
32+
import java.lang.reflect.Type;
33+
34+
import org.scijava.ops.matcher.OpRef;
35+
36+
/**
37+
* Utility class to do transformations on {@link OpRef}s.
38+
*
39+
* @author David Kolb
40+
*/
41+
public final class OpRefTransformUtils {
42+
43+
private OpRefTransformUtils() {
44+
// NB: prevent instantiation of utility class.
45+
}
46+
47+
// -- Utility methods --
48+
49+
/**
50+
* Attempts to perform "unlift" transformation of the specified
51+
* {@link OpRef} if it matches the specified classes. Otherwise, null is
52+
* returned, indicating that transformation is not possible.
53+
*
54+
* @param toRef the ref to transform
55+
* @param rawSearchClass the functional raw type to look for
56+
* @param unliftRawClass the raw type of types to unlift
57+
* @return
58+
*/
59+
public static OpRef unliftTransform(OpRef toRef, Class<?> rawSearchClass, Class<?> unliftRawClass) {
60+
Type[] refTypes = toRef.getTypes();
61+
boolean typesChanged = TypeModUtils.unliftParameterizedTypes(refTypes, rawSearchClass, unliftRawClass);
62+
// TODO We assume here that the functional input is the first Type in
63+
// this list and all others are secondary args if there are any (we do
64+
// not want to touch them as they are not part of op transformations).
65+
// Should always be the case as during structification of the ops,
66+
// the functional args are always checked first. Hence, they always
67+
// need to be requested first and are thus at the beginning of the list.
68+
// From the functional type we know how many there must be.
69+
Type[] args = toRef.getArgs();
70+
boolean argsChanged = TypeModUtils.unliftTypes(args, unliftRawClass);
71+
Type[] outs = toRef.getOutTypes();
72+
boolean outsChanged = TypeModUtils.unliftTypes(outs, unliftRawClass);
73+
74+
if (typesChanged && argsChanged && outsChanged) {
75+
return OpRef.fromTypes(toRef.getName(), refTypes, outs, args);
76+
}
77+
return null;
78+
}
79+
}
Lines changed: 104 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,115 @@
11
package org.scijava.ops.transform;
22

3+
import java.util.Arrays;
4+
35
import org.scijava.ops.OpService;
4-
import org.scijava.ops.matcher.OpCandidate;
5-
import org.scijava.ops.matcher.OpMatchingException;
6+
import org.scijava.ops.matcher.OpRef;
67

8+
/**
9+
* Class used to describe an Op transformation possibly chained with other transformations.
10+
*
11+
* @author David Kolb
12+
*/
713
public class OpTransformation {
814

9-
OpTransformationInfo transformation;
10-
OpCandidate srcOp;
15+
private OpRef srcRef;
16+
private OpRef targetRef;
17+
private OpTransformer transformation;
18+
19+
private OpTransformation child;
20+
21+
public OpTransformation(OpRef from, OpRef to, OpTransformer transformer) {
22+
this.srcRef = from;
23+
this.targetRef = to;
24+
this.transformation = transformer;
25+
}
26+
27+
/**
28+
* Returns the source ref of this transformation.
29+
*
30+
* @return
31+
*/
32+
public OpRef getSource() {
33+
return srcRef;
34+
}
35+
36+
/**
37+
* Returns the target ref of this transformation.
38+
*
39+
* @return
40+
*/
41+
public OpRef getTarget() {
42+
return targetRef;
43+
}
44+
45+
/**
46+
* Returns the transformer.
47+
*
48+
* @return
49+
*/
50+
public OpTransformer getTransformer() {
51+
return transformation;
52+
}
53+
54+
/**
55+
* Get the child transformation if this transformation is part of a chain.
56+
*
57+
* @return
58+
*/
59+
public OpTransformation getChild() {
60+
return this.child;
61+
}
1162

12-
public OpTransformation(OpCandidate scrOp, OpTransformationInfo transformation) {
13-
this.srcOp = scrOp;
14-
this.transformation = transformation;
63+
/**
64+
* Executes this transformation on the specified object.
65+
* If this transformation describes a chain, the whole chain will
66+
* be executed.
67+
*
68+
* @param obj
69+
* @param opService
70+
* @return
71+
*/
72+
public Object execute(Object obj, OpService opService) {
73+
Object candidate = obj;
74+
OpTransformation c = this;
75+
do {
76+
candidate = c.getTransformer().transform(opService, c.targetRef, candidate);
77+
c = c.getChild();
78+
} while (c != null);
79+
80+
return candidate;
81+
}
82+
83+
/**
84+
* Chains the specified with this transformation. If this transformation is executed,
85+
* the chained transformation will be executed after this one.
86+
*
87+
* @param transformation
88+
* @return
89+
*/
90+
public OpTransformation chain(OpTransformation transformation) {
91+
child = transformation;
92+
return this;
1593
}
1694

17-
public Object exceute(OpService opService, Object... secondaryArgs) {
18-
try {
19-
Object op = srcOp.createOp(secondaryArgs);
20-
return transformation.execute(op, opService);
21-
} catch (OpMatchingException e) {
22-
return null;
23-
}
95+
@Override
96+
public String toString() {
97+
StringBuilder s = new StringBuilder();
98+
int i = 0;
99+
OpTransformation c = this;
100+
do {
101+
s.append(i + ")\n");
102+
s.append("\tFrom:\t");
103+
s.append(Arrays.deepToString(c.getSource().getTypes()));
104+
s.append("\n\tTo:\t\t");
105+
s.append(Arrays.deepToString(c.getTarget().getTypes()));
106+
s.append("\n\tWith:\t");
107+
s.append(c.getTransformer().getClass().getName());
108+
s.append("\n\n");
109+
c = c.getChild();
110+
i++;
111+
} while (c != null);
112+
113+
return s.toString();
24114
}
25115
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package org.scijava.ops.transform;
2+
3+
import org.scijava.ops.OpService;
4+
import org.scijava.ops.matcher.OpCandidate;
5+
import org.scijava.ops.matcher.OpMatchingException;
6+
7+
/**
8+
* Wrapper class to match a {@link OpTransformation} with a matching {@link OpCandidate}.
9+
*
10+
* @author David Kolb
11+
*/
12+
public class OpTransformationCandidate {
13+
14+
OpTransformation transformation;
15+
OpCandidate srcOp;
16+
17+
public OpTransformationCandidate(OpCandidate scrOp, OpTransformation transformation) {
18+
this.srcOp = scrOp;
19+
this.transformation = transformation;
20+
}
21+
22+
public Object exceute(OpService opService, Object... secondaryArgs) {
23+
try {
24+
Object op = srcOp.createOp(secondaryArgs);
25+
return transformation.execute(op, opService);
26+
} catch (OpMatchingException e) {
27+
return null;
28+
}
29+
}
30+
}

0 commit comments

Comments
 (0)