Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,10 @@ documentation/rebuildpdf.bat
.envrc
.env
*.versionsBackup

# ai-commons knowledge base (managed by ai-commons/setup.sh)
.ai-commons/
.ai-commons/sessions/
.ai-commons/skills/manage-zephyr-test-cases/references/.env
.claude/CLAUDE.md
.github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,32 @@
* @return parameters for the validation.
*/
String[] parameters() default { "." };

/**
* Controls how each suggestion option is rendered in the UI.
* Use {@link LabelDisplayMode#LABEL_ID} when option labels may not be unique,
* so that the identifier is shown alongside the label to allow unambiguous selection.
* Defaults to {@link LabelDisplayMode#LABEL} — preserves full backward compatibility.
*
* @return the display mode for suggestion options.
*/
LabelDisplayMode labelDisplayMode() default LabelDisplayMode.LABEL;

/**
* Defines how suggestion options are displayed in the UI.
*/
enum LabelDisplayMode {

/**
* Display the option label only.
* Default behaviour — use this when labels are unique.
*/
LABEL,

/**
* Display both the label and the identifier, e.g. {@code Paris (fr-paris-01)}.
* Use this when labels may not be unique so that the user can make an unambiguous choice.
*/
LABEL_ID
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,11 @@ public class Defaults {
.invokeWithArguments(args);
} else { // j > 8 - can need some --add-opens, we will add a module-info later to be clean when dropping j8
final Method privateLookup = findPrivateLookup();
HANDLER = (clazz, method, proxy, args) -> ((MethodHandles.Lookup) privateLookup.invoke(null, clazz, constructor.newInstance(clazz)))
.unreflectSpecial(method, clazz)
.bindTo(proxy)
.invokeWithArguments(args);
HANDLER = (clazz, method, proxy,
args) -> ((MethodHandles.Lookup) privateLookup.invoke(null, clazz, constructor.newInstance(clazz)))
.unreflectSpecial(method, clazz)
.bindTo(proxy)
.invokeWithArguments(args);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ private Jsonb getJsonb(Jsonb jsonb) {
// create a Jsonb instance which is PojoJsonbProvider as in component-runtime-manager
return (Jsonb) Proxy
.newProxyInstance(Thread.currentThread().getContextClassLoader(),
new Class<?>[]{Jsonb.class, PojoJsonbProvider.class}, (proxy, method, args) -> {
new Class<?>[] { Jsonb.class, PojoJsonbProvider.class }, (proxy, method, args) -> {
if (method.getDeclaringClass() == Supplier.class) {
return jsonb;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1924,7 +1924,8 @@ public void onPartitionMapper(final Class<?> type, final PartitionMapper partiti
() -> {
final List<ParameterMeta> params = parameterModelService
.buildParameterMetas(constructor, getPackage(type),
new BaseParameterEnricher.Context((LocalConfiguration) services.getServices().get(LocalConfiguration.class)));
new BaseParameterEnricher.Context((LocalConfiguration) services.getServices()
.get(LocalConfiguration.class)));
if (infinite) {
if (partitionMapper.stoppable()) {
addInfiniteMapperBuiltInParameters(type, params);
Expand Down Expand Up @@ -1977,7 +1978,8 @@ public void onEmitter(final Class<?> type, final Emitter emitter) {
final Supplier<List<ParameterMeta>> parameterMetas = lazy(() -> executeInContainer(plugin,
() -> parameterModelService
.buildParameterMetas(constructor, getPackage(type),
new BaseParameterEnricher.Context((LocalConfiguration) services.getServices().get(LocalConfiguration.class)))));
new BaseParameterEnricher.Context((LocalConfiguration) services.getServices()
.get(LocalConfiguration.class)))));
final Function<Map<String, String>, Object[]> parameterFactory =
createParametersFactory(plugin, constructor, services.getServices(), parameterMetas);
final String name = of(emitter.name()).filter(n -> !n.isEmpty()).orElseGet(type::getName);
Expand Down Expand Up @@ -2161,7 +2163,8 @@ public void onDriverRunner(final Class<?> type, final DriverRunner processor) {
final Supplier<List<ParameterMeta>> parameterMetas = lazy(() -> executeInContainer(plugin,
() -> parameterModelService
.buildParameterMetas(constructor, getPackage(type),
new BaseParameterEnricher.Context((LocalConfiguration) services.getServices().get(LocalConfiguration.class)))));
new BaseParameterEnricher.Context((LocalConfiguration) services.getServices()
.get(LocalConfiguration.class)))));
final Function<Map<String, String>, Object[]> parameterFactory =
createParametersFactory(plugin, constructor, services.getServices(), parameterMetas);
final String name = of(processor.name()).filter(n -> !n.isEmpty()).orElseGet(type::getName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -254,10 +254,10 @@ private Stream<Annotation> getReflectionAnnotations(final Type genericType, fina
.concat(Stream.of(annotations),
// if a class concat its annotations
genericType instanceof Class
? getClassAnnotations(genericType, annotations)
: (hasAClassFirstParameter(genericType) ? getClassAnnotations(
((ParameterizedType) genericType).getActualTypeArguments()[0],
annotations) : Stream.empty()));
? getClassAnnotations(genericType, annotations)
: (hasAClassFirstParameter(genericType) ? getClassAnnotations(
((ParameterizedType) genericType).getActualTypeArguments()[0],
annotations) : Stream.empty()));
}

private boolean hasAClassFirstParameter(final Type genericType) {
Expand Down Expand Up @@ -297,7 +297,7 @@ private List<ParameterMeta> buildParametersMetas(final String name, final String
}
return Stream
.concat(buildParametersMetas(name + ".key[${index}]", prefix + "key[${index}].",
(Class) pt.getActualTypeArguments()[0], annotations, i18nPackages, ignoreI18n,
(Class) pt.getActualTypeArguments()[0], annotations, i18nPackages, ignoreI18n,
context).stream(),
buildParametersMetas(name + ".value[${index}]", prefix + "value[${index}].",
(Class) pt.getActualTypeArguments()[1], annotations, i18nPackages,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -524,10 +524,11 @@ private Object createObject(final ClassLoader loader, final Function<Supplier<Ob
if (arrayClass.isArray()) {
// we could use Array.newInstance but for now use the list, shouldn't impact
// much the perf
final Collection<?> list = (Collection) createList(loader, contextualSupplier, prefix + enclosingName, List.class,
arrayClass.getComponentType(), toList(), createObjectFactory(loader,
contextualSupplier, arrayClass.getComponentType(), metas, precomputed),
new HashMap<>(listEntries), metas, precomputed);
final Collection<?> list =
(Collection) createList(loader, contextualSupplier, prefix + enclosingName, List.class,
arrayClass.getComponentType(), toList(), createObjectFactory(loader,
contextualSupplier, arrayClass.getComponentType(), metas, precomputed),
new HashMap<>(listEntries), metas, precomputed);

// we need that conversion to ensure the type matches
final Object array = Array.newInstance(arrayClass.getComponentType(), list.size());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,8 @@ private <T> void doInject(final Class<?> type, final T instance) {
})
.forEach(field -> {
try {
final Class<?> configClass = (Class) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0];
final Class<?> configClass =
(Class) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0];
final ClassLoader loader = Thread.currentThread().getContextClassLoader();
final Supplier<?> supplier = () -> {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -611,7 +611,8 @@ void testLocalConfigurationFromEnvironment(@TempDir final File temporaryFolder)
manager.addPlugin(plugin.getAbsolutePath());
final Container container = manager.getContainer().findAll().stream().findFirst().orElse(null);
assertNotNull(container);
final LocalConfiguration envConf = (LocalConfiguration) container.get(AllServices.class).getServices().get(LocalConfiguration.class);
final LocalConfiguration envConf =
(LocalConfiguration) container.get(AllServices.class).getServices().get(LocalConfiguration.class);
// check translated env vars
assertEquals("/home/user", envConf.get("USER_PATH"));
assertEquals("/home/user", envConf.get("USER.PATH"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,26 +42,30 @@ void run(@TempDir final Path temporaryFolder) throws Exception {
"META-INF/test/dependencies", "org.talend.test:type=plugin,value=%s")) {
manager.addPlugin(jar.getAbsolutePath());
{
final Object nested = ((ProcessorImpl) manager.findProcessor("chain", "configured1", 0, new HashMap<String, String>() {
final Object nested = ((ProcessorImpl) manager
.findProcessor("chain", "configured1", 0, new HashMap<String, String>() {

{
put("config.__version", "-1");
}
}).orElseThrow(IllegalStateException::new))
{
put("config.__version", "-1");
}
})
.orElseThrow(IllegalStateException::new))
.getDelegate();

final Object config = get(nested, "getConfig");
assertNotNull(config);
assertEquals("ok", get(config, "getName"));
}
{
final Object nested = ((ProcessorImpl) manager.findProcessor("chain", "configured2", 0, new HashMap<String, String>() {
final Object nested = ((ProcessorImpl) manager
.findProcessor("chain", "configured2", 0, new HashMap<String, String>() {

{
put("config.__version", "0");
put("value.__version", "-1");
}
}).orElseThrow(IllegalStateException::new))
{
put("config.__version", "0");
put("value.__version", "-1");
}
})
.orElseThrow(IllegalStateException::new))
.getDelegate();
assertEquals("set", get(nested, "getValue"));

Expand All @@ -70,13 +74,15 @@ void run(@TempDir final Path temporaryFolder) throws Exception {
assertEquals("ok", get(config, "getName"));
}
{
final Object nested = ((ProcessorImpl) manager.findProcessor("chain", "migrationtest", -1, new HashMap<String, String>() {
final Object nested = ((ProcessorImpl) manager
.findProcessor("chain", "migrationtest", -1, new HashMap<String, String>() {

{
put("config.__version", "1");
put("config.datastore.__version", "1");
}
}).orElseThrow(IllegalStateException::new))
{
put("config.__version", "1");
put("config.datastore.__version", "1");
}
})
.orElseThrow(IllegalStateException::new))
.getDelegate();

final Object config = get(nested, "getConfig");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -450,8 +450,10 @@ void copiable() throws NoSuchMethodException {
new HttpClientFactoryImpl("test", reflectionService, JsonbBuilder.create(), emptyMap())
.create(UserHttpClient.class, "http://foo"));
final Method httpMtd = TableOwner.class.getMethod("http", UserHttpClient.class);
final HttpClient client1 = (HttpClient) reflectionService.parameterFactory(httpMtd, precomputed, null).apply(emptyMap())[0];
final HttpClient client2 = (HttpClient) reflectionService.parameterFactory(httpMtd, precomputed, null).apply(emptyMap())[0];
final HttpClient client1 =
(HttpClient) reflectionService.parameterFactory(httpMtd, precomputed, null).apply(emptyMap())[0];
final HttpClient client2 =
(HttpClient) reflectionService.parameterFactory(httpMtd, precomputed, null).apply(emptyMap())[0];
assertNotSame(client1, client2);
final InvocationHandler handler1 = Proxy.getInvocationHandler(client1);
final InvocationHandler handler2 = Proxy.getInvocationHandler(client2);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ void suggestion() {
{
put("tcomp::action::suggestions", "test");
put("tcomp::action::suggestions::parameters", ".,foo,/bar/dummy");
put("tcomp::action::suggestions::labelDisplayMode", "LABEL");
}
}, new ActionParameterEnricher().onParameterAnnotation("testParam", String.class, new Suggestable() {

Expand All @@ -172,6 +173,44 @@ public String[] parameters() {
return new String[] { ".", "foo", "/bar/dummy" };
}

@Override
public LabelDisplayMode labelDisplayMode() {
return LabelDisplayMode.LABEL;
}

@Override
public Class<? extends Annotation> annotationType() {
return Suggestable.class;
}
}));
}

@Test
void suggestionWithLabelId() {
assertEquals(new HashMap<String, String>() {

{
put("tcomp::action::suggestions", "test");
put("tcomp::action::suggestions::parameters", ".");
put("tcomp::action::suggestions::labelDisplayMode", "LABEL_ID");
}
}, new ActionParameterEnricher().onParameterAnnotation("testParam", String.class, new Suggestable() {

@Override
public String value() {
return "test";
}

@Override
public String[] parameters() {
return new String[] { "." };
}

@Override
public LabelDisplayMode labelDisplayMode() {
return LabelDisplayMode.LABEL_ID;
}

@Override
public Class<? extends Annotation> annotationType() {
return Suggestable.class;
Expand Down
Loading
Loading