Skip to content

Commit 942da8a

Browse files
committed
2025.12.0
1 parent 21b340d commit 942da8a

File tree

8 files changed

+207
-9
lines changed

8 files changed

+207
-9
lines changed

capability-tests/capability-tests.log

Lines changed: 144 additions & 0 deletions
Large diffs are not rendered by default.

capability/src/main/java/org/nasdanika/capability/emf/BinaryResourceFactoryCapabilityFactory.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import org.eclipse.emf.ecore.resource.Resource.Factory;
66
import org.eclipse.emf.ecore.resource.ResourceSet;
77
import org.eclipse.emf.ecore.resource.impl.BinaryResourceImpl;
8-
import org.nasdanika.capability.CapabilityFactory.Loader;
98
import org.nasdanika.common.ProgressMonitor;
109

1110
public class BinaryResourceFactoryCapabilityFactory extends ResourceFactoryCapabilityFactory {

capability/src/main/java/org/nasdanika/capability/factories/URIInvocableCapabilityFactory.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.io.ByteArrayInputStream;
44
import java.io.IOException;
55
import java.io.InputStream;
6+
import java.lang.reflect.AccessibleObject;
67
import java.lang.reflect.InvocationTargetException;
78
import java.lang.reflect.Modifier;
89
import java.net.URLDecoder;
@@ -21,6 +22,7 @@
2122
import java.util.TreeMap;
2223
import java.util.concurrent.CompletableFuture;
2324
import java.util.concurrent.CompletionStage;
25+
import java.util.function.Predicate;
2426
import java.util.regex.Pattern;
2527
import java.util.stream.Stream;
2628

@@ -244,7 +246,13 @@ protected CompletionStage<Iterable<CapabilityProvider<Invocable>>> handleSpec(
244246
return wrapError(new IllegalArgumentException("Diagram and script are mutually exclusive"));
245247
}
246248

247-
CompletionStage<DiagramRequirement> diagramRequirementCS = classLoaderCS.thenApply(classLoader -> createDiagramRequirement(requirement, invocableRequirement, classLoader, loader, progressMonitor));
249+
CompletionStage<DiagramRequirement> diagramRequirementCS = classLoaderCS.thenApply(classLoader -> createDiagramRequirement(
250+
requirement,
251+
invocableRequirement,
252+
classLoader,
253+
loader,
254+
ao -> true, // To support scripting reflection. TODO - implement as invocable attribute/component
255+
progressMonitor));
248256
CompletionStage<Object> diagramCS = diagramRequirementCS.thenCompose(diagramRequirement -> loader.loadOne(diagramRequirement, progressMonitor));
249257
return wrapCompletionStage(diagramCS.thenApply(Invocable::ofValue));
250258
}
@@ -368,6 +376,7 @@ protected DiagramRequirement createDiagramRequirement(
368376
InvocableRequirement spec,
369377
ClassLoader classLoader,
370378
Loader loader,
379+
Predicate<AccessibleObject> makeAccessiblePredicate,
371380
ProgressMonitor progressMonitor) {
372381
String[] diagramInterfaces = spec.diagram().interfaces();
373382
Class<?>[] interfaces;
@@ -409,6 +418,7 @@ protected DiagramRequirement createDiagramRequirement(
409418
spec.diagram().processor(),
410419
spec.diagram().bind(),
411420
classLoader,
421+
makeAccessiblePredicate,
412422
interfaces);
413423

414424
return diagramRequirement;

capability/src/main/java/org/nasdanika/capability/requirements/DiagramRequirement.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package org.nasdanika.capability.requirements;
22

33
import java.io.InputStream;
4+
import java.lang.reflect.AccessibleObject;
45
import java.util.function.Function;
6+
import java.util.function.Predicate;
57

68
import org.eclipse.emf.common.util.URI;
79

@@ -36,6 +38,8 @@ public record DiagramRequirement(
3638

3739
// Function<ProcessorInfo<Invocable>,Invocable> processorFilter, Not supported yet
3840

41+
Predicate<AccessibleObject> makeAccessiblePredicate,
42+
3943
/**
4044
* Interfaces to be implemented by a proxy.
4145
* If not provided, no proxy is created and a map of elements to processor info (registry) is used as a result.

common/src/main/java/org/nasdanika/common/DefaultConverter.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import java.io.StringReader;
1313
import java.io.StringWriter;
1414
import java.io.Writer;
15+
import java.net.URISyntaxException;
1516
import java.net.URL;
1617
import java.nio.charset.StandardCharsets;
1718
import java.time.Duration;
@@ -286,18 +287,22 @@ public URI toURI(String str) {
286287

287288
// URI
288289

289-
public InputStream toInputStream(URI uri, ClassLoader classLoader) throws IOException {
290+
public InputStream toInputStream(URI uri, ClassLoader classLoader) throws IOException, URISyntaxException {
290291
if (Util.CLASSPATH_SCHEME.equals(uri.scheme())) {
291292
String resource = uri.toString().substring(Util.CLASSPATH_URL_PREFIX.length());
292293
return Objects.requireNonNull(classLoader.getResourceAsStream(resource), "ClassLoader resource not found: " + resource);
293294
}
294-
return toInputStream(new URL(uri.toString()));
295+
return toInputStream(new java.net.URI(uri.toString()).toURL());
295296
}
296297

297298
@ConverterMethod
298299
public InputStream toInputStream(URI uri) throws IOException {
299300
ClassLoader cl = Thread.currentThread().getContextClassLoader();
300-
return toInputStream(uri, cl);
301+
try {
302+
return toInputStream(uri, cl);
303+
} catch (URISyntaxException e) {
304+
throw new IOException(e);
305+
}
301306
}
302307

303308
/**

common/src/main/java/org/nasdanika/common/Reflector.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import java.lang.annotation.Target;
1212
import java.lang.invoke.MethodHandles;
1313
import java.lang.invoke.MethodType;
14+
import java.lang.reflect.AccessibleObject;
1415
import java.lang.reflect.AnnotatedElement;
1516
import java.lang.reflect.Field;
1617
import java.lang.reflect.InvocationHandler;
@@ -169,7 +170,9 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl
169170
if (method.getDeclaringClass().isInterface()) {
170171
return invokeMethod(target, (Method) annotatedElement, args);
171172
}
172-
173+
if (!method.canAccess(this) && isMakeAccessible(method)) {
174+
method.setAccessible(true);
175+
}
173176
return method.invoke(this, args); // equals, hashCode, ...
174177
}
175178
};
@@ -413,6 +416,9 @@ protected void onEvaluationException(Object obj, String expr, Map<String,Object>
413416
*/
414417
protected Object getFieldValue(Object target, Field field) {
415418
try {
419+
if (!field.canAccess(target) && isMakeAccessible(field)) {
420+
field.setAccessible(true);
421+
}
416422
return field.get(target);
417423
} catch (IllegalAccessException e) {
418424
throw new NasdanikaException("Cannot access field " + field + " of " + target + ": " + e, e);
@@ -432,12 +438,19 @@ protected void setFieldValue(Object target, Field field, Object value) {
432438
if (value instanceof Invocable && !field.getType().isInstance(value) && field.getType().isInterface()) {
433439
value = ((Invocable) value).createProxy(field.getType());
434440
}
441+
if (!field.canAccess(target) && isMakeAccessible(field)) {
442+
field.setAccessible(true);
443+
}
435444
field.set(target, value);
436445
} catch (IllegalAccessException e) {
437446
throw new NasdanikaException("Cannot access field " + field + " of " + target + ": " + e, e);
438447
}
439448
}
440449

450+
protected boolean isMakeAccessible(AccessibleObject accessibleObject) {
451+
return false;
452+
}
453+
441454
/**
442455
* Invokes method. May need to be overridden if the target class is not exported by its module.
443456
* @param target
@@ -456,7 +469,9 @@ protected Object invokeMethod(Object target, Method method, Object... args) {
456469
args[i] = ((Invocable) arg).createProxy(parameterType);
457470
}
458471
}
459-
472+
if (!method.canAccess(target) && isMakeAccessible(method)) {
473+
method.setAccessible(true);
474+
}
460475
return method.invoke(target, args);
461476
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
462477
throw new NasdanikaException("Error invoking " + method + " of " + target + ": " + e, e);

drawio/src/main/java/org/nasdanika/drawio/processor/DiagramCapabilityFactory.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import java.io.IOException;
44
import java.io.InputStream;
5+
import java.lang.reflect.AccessibleObject;
56
import java.net.URISyntaxException;
67
import java.util.Map;
78
import java.util.concurrent.CompletionStage;
@@ -68,7 +69,15 @@ public String getProperty(String name) {
6869
return wrap(document);
6970
}
7071

71-
ElementInvocableFactory<Object,Object,Object> elementInvocableFactory = new ElementInvocableFactory<>(requirement.selector() == null ? document : (org.nasdanika.drawio.Element<?>) requirement.selector().apply(document), requirement.processor());
72+
ElementInvocableFactory<Object,Object,Object> elementInvocableFactory = new ElementInvocableFactory<>(requirement.selector() == null ? document : (org.nasdanika.drawio.Element<?>) requirement.selector().apply(document), requirement.processor()) {
73+
74+
@Override
75+
protected boolean isMakeAccessible(AccessibleObject accessibleObject) {
76+
return requirement.makeAccessiblePredicate() != null && requirement.makeAccessiblePredicate().test(accessibleObject);
77+
}
78+
79+
};
80+
7281
if (requirement.bind() == null) {
7382
// Processors
7483
Map<Element, ProcessorInfo<Object,Object,Object,Object>> processors = elementInvocableFactory.createProcessors(null, false, progressMonitor);

graph/src/main/java/org/nasdanika/graph/processor/ReflectiveWiringProcessorFactory.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.nasdanika.graph.processor;
22

3+
import java.lang.reflect.AccessibleObject;
34
import java.util.concurrent.CompletionStage;
45
import java.util.function.BiConsumer;
56
import java.util.function.Consumer;
@@ -13,7 +14,18 @@
1314
*/
1415
public abstract class ReflectiveWiringProcessorFactory<H,E,K,P> extends ProcessorFactory<H,E,K,P> {
1516

16-
ReflectiveProcessorWirer<H,E,K,P> wirerer = new ReflectiveProcessorWirer<>();
17+
ReflectiveProcessorWirer<H,E,K,P> wirerer = new ReflectiveProcessorWirer<>() {
18+
19+
@Override
20+
protected boolean isMakeAccessible(AccessibleObject accessibleObject) {
21+
return ReflectiveWiringProcessorFactory.this.isMakeAccessible(accessibleObject);
22+
}
23+
24+
};
25+
26+
protected boolean isMakeAccessible(AccessibleObject accessibleObject) {
27+
return false;
28+
}
1729

1830
@Override
1931
protected ProcessorInfo<H,E,K,P> createProcessor(

0 commit comments

Comments
 (0)