Skip to content

Commit 787b334

Browse files
committed
Add Op dependency information to OpInfo
And implement Op dependency parsing for OpClassInfo.
1 parent b7fdd06 commit 787b334

File tree

8 files changed

+261
-2
lines changed

8 files changed

+261
-2
lines changed
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*
2+
* #%L
3+
* ImageJ software for multidimensional image processing and analysis.
4+
* %%
5+
* Copyright (C) 2014 - 2016 Board of Regents of the University of
6+
* Wisconsin-Madison and University of Konstanz.
7+
* %%
8+
* Redistribution and use in source and binary forms, with or without
9+
* modification, are permitted provided that the following conditions are met:
10+
*
11+
* 1. Redistributions of source code must retain the above copyright notice,
12+
* this list of conditions and the following disclaimer.
13+
* 2. Redistributions in binary form must reproduce the above copyright notice,
14+
* this list of conditions and the following disclaimer in the documentation
15+
* and/or other materials provided with the distribution.
16+
*
17+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
21+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27+
* POSSIBILITY OF SUCH DAMAGE.
28+
* #L%
29+
*/
30+
31+
package org.scijava.ops;
32+
33+
import java.lang.reflect.Type;
34+
35+
/**
36+
* @author Marcel Wiedenmann
37+
*/
38+
public abstract class AnnotatedOpDependencyMember<T> implements
39+
OpDependencyMember<T>
40+
{
41+
42+
private String key;
43+
private Type type;
44+
private final OpDependency annotation;
45+
46+
public AnnotatedOpDependencyMember(String key, Type type,
47+
final OpDependency annotation)
48+
{
49+
this.key = key;
50+
this.type = type;
51+
this.annotation = annotation;
52+
}
53+
54+
public OpDependency getAnnotation() {
55+
return annotation;
56+
}
57+
58+
// -- OpDependencyMember methods --
59+
60+
@Override
61+
public String getDependencyName() {
62+
return annotation.name();
63+
}
64+
65+
// -- Member methods --
66+
67+
@Override
68+
public String getKey() {
69+
return key;
70+
}
71+
72+
@Override
73+
public Type getType() {
74+
return type;
75+
}
76+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*
2+
* #%L
3+
* ImageJ software for multidimensional image processing and analysis.
4+
* %%
5+
* Copyright (C) 2014 - 2016 Board of Regents of the University of
6+
* Wisconsin-Madison and University of Konstanz.
7+
* %%
8+
* Redistribution and use in source and binary forms, with or without
9+
* modification, are permitted provided that the following conditions are met:
10+
*
11+
* 1. Redistributions of source code must retain the above copyright notice,
12+
* this list of conditions and the following disclaimer.
13+
* 2. Redistributions in binary form must reproduce the above copyright notice,
14+
* this list of conditions and the following disclaimer in the documentation
15+
* and/or other materials provided with the distribution.
16+
*
17+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
21+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27+
* POSSIBILITY OF SUCH DAMAGE.
28+
* #L%
29+
*/
30+
31+
package org.scijava.ops;
32+
33+
import java.lang.reflect.Field;
34+
35+
import org.scijava.struct.MemberInstance;
36+
import org.scijava.struct.ValueAccessible;
37+
import org.scijava.struct.ValueAccessibleMemberInstance;
38+
import org.scijava.util.Types;
39+
40+
/**
41+
* @author Marcel Wiedenmann
42+
*/
43+
public class FieldOpDependencyMember<T> extends AnnotatedOpDependencyMember<T>
44+
implements ValueAccessible<T>
45+
{
46+
47+
private final Field field;
48+
49+
public FieldOpDependencyMember(final Field field, final Class<?> structType) {
50+
super(field.getName(), Types.fieldType(field, structType), field
51+
.getAnnotation(OpDependency.class));
52+
this.field = field;
53+
}
54+
55+
// -- ValueAccessible methods --
56+
57+
@Override
58+
public T get(Object o) {
59+
field.setAccessible(true);
60+
try {
61+
@SuppressWarnings("unchecked")
62+
final T value = (T) field.get(o);
63+
return value;
64+
}
65+
catch (final IllegalAccessException exc) {
66+
// FIXME
67+
throw new RuntimeException(exc);
68+
}
69+
}
70+
71+
@Override
72+
public void set(T value, Object o) {
73+
field.setAccessible(true);
74+
try {
75+
field.set(o, value);
76+
}
77+
catch (final IllegalAccessException exc) {
78+
// FIXME
79+
throw new RuntimeException(exc);
80+
}
81+
}
82+
83+
// -- Member methods --
84+
85+
@Override
86+
public MemberInstance<T> createInstance(final Object o) {
87+
return new ValueAccessibleMemberInstance<>(this, o);
88+
}
89+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* #%L
3+
* ImageJ software for multidimensional image processing and analysis.
4+
* %%
5+
* Copyright (C) 2014 - 2016 Board of Regents of the University of
6+
* Wisconsin-Madison and University of Konstanz.
7+
* %%
8+
* Redistribution and use in source and binary forms, with or without
9+
* modification, are permitted provided that the following conditions are met:
10+
*
11+
* 1. Redistributions of source code must retain the above copyright notice,
12+
* this list of conditions and the following disclaimer.
13+
* 2. Redistributions in binary form must reproduce the above copyright notice,
14+
* this list of conditions and the following disclaimer in the documentation
15+
* and/or other materials provided with the distribution.
16+
*
17+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
21+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27+
* POSSIBILITY OF SUCH DAMAGE.
28+
* #L%
29+
*/
30+
31+
package org.scijava.ops;
32+
33+
import org.scijava.struct.ItemIO;
34+
import org.scijava.struct.Member;
35+
36+
/**
37+
* @author Marcel Wiedenmann
38+
*/
39+
public interface OpDependencyMember<T> extends Member<T> {
40+
41+
String getDependencyName();
42+
43+
// -- Member methods --
44+
45+
@Override
46+
default ItemIO getIOType() {
47+
return ItemIO.NONE;
48+
}
49+
}

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,13 @@ public static void checkHasSingleOutput(Struct struct) throws ValidityException
173173
}
174174
}
175175

176+
public static List<OpDependencyMember<?>> dependencies(Struct struct) {
177+
return struct.members().stream() //
178+
.filter(member -> member instanceof OpDependencyMember) //
179+
.map(member -> (OpDependencyMember<?>) member) //
180+
.collect(Collectors.toList());
181+
}
182+
176183
public static Type[] types(OpCandidate candidate) {
177184
return getTypes(candidate.struct().members());
178185
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import java.lang.reflect.Type;
55
import java.util.List;
66

7+
import org.scijava.ops.OpDependencyMember;
78
import org.scijava.ops.OpUtils;
89
import org.scijava.param.ValidityException;
910
import org.scijava.struct.Member;
@@ -34,6 +35,11 @@ default Member<?> output() {
3435
return OpUtils.outputs(struct()).get(0);
3536
}
3637

38+
/** Gets the op's dependencies on other ops. */
39+
default List<OpDependencyMember<?>> dependencies() {
40+
return OpUtils.dependencies(struct());
41+
}
42+
3743
/** The op's priority. */
3844
double priority();
3945

src/main/java/org/scijava/ops/util/Inject.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import java.util.stream.Collectors;
77

88
import org.scijava.command.Command;
9+
import org.scijava.ops.OpDependencyMember;
910
import org.scijava.param.ParameterStructs;
1011
import org.scijava.param.ValidityException;
1112
import org.scijava.struct.ItemIO;
@@ -23,7 +24,10 @@ private Structs() {
2324
}
2425

2526
public static boolean isInjectable(final StructInstance<?> instance) {
26-
return !getAccessibles(instance).isEmpty();
27+
// HACK: Exclude Op dependencies since they were already injected when
28+
// constructing the instance.
29+
return !filterAccessibles(getAccessibles(instance), mi -> !(mi
30+
.member() instanceof OpDependencyMember)).isEmpty();
2731
}
2832

2933
public static void inputs(StructInstance<?> instance, Object... objs) {

src/main/java/org/scijava/param/ParameterStructs.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
import java.util.Set;
1818
import java.util.stream.Collectors;
1919

20+
import org.scijava.ops.FieldOpDependencyMember;
21+
import org.scijava.ops.OpDependency;
22+
import org.scijava.ops.OpDependencyMember;
2023
import org.scijava.struct.ItemIO;
2124
import org.scijava.struct.Member;
2225
import org.scijava.struct.Struct;
@@ -73,6 +76,9 @@ public static List<Member<?>> parse(final Class<?> type)
7376
// Parse field level @Parameter annotations.
7477
parseFieldParameters(items, names, problems, type);
7578

79+
// Parse field level @OpDependency annotations.
80+
parseFieldOpDependencies(items, problems, type);
81+
7682
// Fail if there were any problems.
7783
if (!problems.isEmpty()) throw new ValidityException(problems);
7884

@@ -200,6 +206,28 @@ private static void parseFunctionalParameters(final ArrayList<Member<?>> items,
200206
}
201207
}
202208

209+
private static void parseFieldOpDependencies(final List<Member<?>> items,
210+
final List<ValidityProblem> problems, Class<?> annotatedClass)
211+
{
212+
final List<Field> fields = ClassUtils.getAnnotatedFields(annotatedClass,
213+
OpDependency.class);
214+
for (final Field f : fields) {
215+
f.setAccessible(true);
216+
final boolean isFinal = Modifier.isFinal(f.getModifiers());
217+
if (isFinal) {
218+
final String name = f.getName();
219+
// Final fields are bad because they cannot be modified.
220+
final String error = "Invalid final Op dependency field: " + name;
221+
problems.add(new ValidityProblem(error));
222+
// Skip invalid Op dependencies.
223+
continue;
224+
}
225+
final OpDependencyMember<?> item = new FieldOpDependencyMember<>(f,
226+
annotatedClass);
227+
items.add(item);
228+
}
229+
}
230+
203231
private static boolean isImmutable(final Class<?> type) {
204232
// NB: All eight primitive types, as well as the boxed primitive
205233
// wrapper classes, as well as strings, are immutable objects.

src/main/java/org/scijava/struct/ItemIO.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,5 +47,5 @@
4747
* @author Curtis Rueden
4848
*/
4949
public enum ItemIO {
50-
INPUT, OUTPUT, BOTH, AUTO
50+
INPUT, OUTPUT, BOTH, AUTO, NONE
5151
}

0 commit comments

Comments
 (0)