Skip to content

Commit 273d4be

Browse files
gselzerctrueden
authored andcommitted
More signature->InfoChain work
The most important change here is the change to the javassist portion of OpMethodInfo. The current framework cannot cache the Op returned if called via signature, as we do not have enough to cache a MatchingConditions, but this commit avoids the matching if we have alreaady created the class. This commit should be viewed with scrutiny.
1 parent 1c2bfe9 commit 273d4be

5 files changed

Lines changed: 53 additions & 24 deletions

File tree

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,11 @@ private Object generateOp() {
8282
private synchronized void generateSignature() {
8383
if (id != null) return;
8484
String s = info().id();
85-
s = s.concat(InfoChainGenerator.DEP_START_DELIM);
85+
s = s.concat(String.valueOf(InfoChainGenerator.DEP_START_DELIM));
8686
for (InfoChain dependency : dependencies()) {
8787
s = s.concat(dependency.signature());
8888
}
89-
id = s.concat(InfoChainGenerator.DEP_END_DELIM);
89+
id = s.concat(String.valueOf(InfoChainGenerator.DEP_END_DELIM));
9090
}
9191

9292
}

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

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

1010
public interface InfoChainGenerator extends SciJavaPlugin {
1111

12-
public static final String DEP_END_DELIM = "[";
13-
public static final String DEP_START_DELIM = "]";
12+
public static final Character DEP_START_DELIM = '{';
13+
public static final Character DEP_END_DELIM = '}';
1414

1515
/**
1616
* Generates an {@link InfoChain}. This {@link InfoChainGenerator} is only

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ private List<String> getDependencies(String signature) {
4646

4747
for (int i = 0; i < signature.length(); i++) {
4848
char ch = signature.charAt(i);
49-
if (ch == '[') parenDepth++;
50-
else if (ch == ']') {
49+
if (ch == DEP_START_DELIM) parenDepth++;
50+
else if (ch == DEP_END_DELIM) {
5151
parenDepth--;
5252
if (parenDepth == 0) {
5353
splits.add(signature.substring(start, i + 1));

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

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -209,32 +209,39 @@ private Object javassistOp(Method m, List<? extends Object> dependencies)
209209

210210
// Create wrapper class
211211
String className = formClassName(m);
212-
CtClass cc = pool.makeClass(className);
212+
List<OpDependencyMember<?>> depMembers = OpUtils.dependencies(struct());
213+
Class<?> c;
214+
try {
215+
CtClass cc = pool.makeClass(className);
213216

214-
// Add implemented interface
215-
CtClass jasOpType = pool.get(Types.raw(opType).getName());
216-
cc.addInterface(jasOpType);
217+
// Add implemented interface
218+
CtClass jasOpType = pool.get(Types.raw(opType).getName());
219+
cc.addInterface(jasOpType);
217220

218-
// Add OpDependency fields
219-
List<OpDependencyMember<?>> depMembers = OpUtils.dependencies(struct());
220-
for (int i = 0; i < depMembers.size(); i++) {
221-
CtField f = createDependencyField(pool, cc, depMembers.get(i), i);
222-
cc.addField(f);
223-
}
221+
// Add OpDependency fields
222+
for (int i = 0; i < depMembers.size(); i++) {
223+
CtField f = createDependencyField(pool, cc, depMembers.get(i), i);
224+
cc.addField(f);
225+
}
224226

225-
// Add constructor
226-
CtConstructor constructor = CtNewConstructor.make(createConstructor(
227-
depMembers, cc), cc);
228-
cc.addConstructor(constructor);
227+
// Add constructor
228+
CtConstructor constructor = CtNewConstructor.make(createConstructor(
229+
depMembers, cc), cc);
230+
cc.addConstructor(constructor);
229231

230-
// add functional interface method
231-
CtMethod functionalMethod = CtNewMethod.make(createFunctionalMethod(m), cc);
232-
cc.addMethod(functionalMethod);
232+
// add functional interface method
233+
CtMethod functionalMethod = CtNewMethod.make(createFunctionalMethod(m),
234+
cc);
235+
cc.addMethod(functionalMethod);
236+
c = cc.toClass(MethodHandles.lookup());
237+
}
238+
catch (Exception e) {
239+
c = this.getClass().getClassLoader().loadClass(className);
240+
}
233241

234242
// Return Op instance
235243
Class<?>[] depClasses = depMembers.stream().map(dep -> dep.getRawType())
236244
.toArray(Class[]::new);
237-
Class<?> c = cc.toClass(MethodHandles.lookup());
238245
return c.getDeclaredConstructor(depClasses).newInstance(dependencies
239246
.toArray());
240247
}

scijava/scijava-ops-engine/src/test/java/org/scijava/ops/engine/impl/ProvenanceTest.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import java.util.ArrayList;
44
import java.util.Arrays;
5+
import java.util.Collections;
56
import java.util.Iterator;
67
import java.util.List;
78
import java.util.function.Function;
@@ -176,4 +177,25 @@ public void testDependencylessOpRecoveryFromString() {
176177
Function<Double, Thing> actual = ops.env().opFromID(signature, special, new Nil[] {inType}, outType);
177178
}
178179

180+
@Test
181+
public void testOpWithDependencyRecoveryFromString() {
182+
OpInfo info = singularInfoOfName("test.provenanceMapper");
183+
OpInfo dependency = singularInfoOfName("test.provenanceMapped");
184+
InfoChain depChain = new InfoChain(dependency);
185+
InfoChain chain = new InfoChain(info, Collections.singletonList(depChain));
186+
String signature = chain.signature();
187+
Nil<Function<Double[], Thing>> special = new Nil<>() {};
188+
Nil<Double[]> inType = Nil.of(Double[].class);
189+
Nil<Thing> outType = Nil.of(Thing.class);
190+
Function<Double[], Thing> actual = ops.env().opFromID(signature, special, new Nil[] {inType}, outType);
191+
}
192+
193+
private OpInfo singularInfoOfName(String name) {
194+
Iterator<OpInfo> infos = ops.env().infos(name).iterator();
195+
Assert.assertTrue(infos.hasNext());
196+
OpInfo info = infos.next();
197+
Assert.assertFalse(infos.hasNext());
198+
return info;
199+
}
200+
179201
}

0 commit comments

Comments
 (0)