Skip to content

Conversation

@stelfrich
Copy link
Member

For most SingletonServices the instances and instanceMap fields were only set during initialization making them inflexible during runtime. Registering to PluginAddedEvents and PluginRemovedEvents allows for more dynamic behavior, e.g. adding Converters in notebooks.

/cc @ctrueden

For most SingletonServices the instance field was only set during
initialization making them inflexible during runtime. Registering to
PluginAddedEvents and PluginRemovedEvents allows for more dynamic
behavior, e.g. adding Converters in a SJJK-backed notebook.
@SuppressWarnings("unchecked")
final Class<? extends PT> ptClass = (Class<? extends PT>) instance
.getClass();
instanceMap.putIfAbsent(ptClass, instance);
Copy link
Member

@ctrueden ctrueden Jun 16, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If someone tries to add a plugin which already exists, should we overwrite it? Naively, I would vote yes. (Though I suppose you could remove it and readd it, otherwise—but then there are two separate events.) And actually it might cause problems/skew if the PluginIndex was overwritten with a new version of a class, but the SingletonServices ignored that new version and kept the old one, no?

* {@link PluginsAddedEvent}s originating from the {@link PluginService}.
*/
@Test
public void testSingletonServicePluginsAddedHandling() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@SuppressWarnings("rawtypes")
PluginInfo<Converter> converterInfo = new PluginInfo<>(
DummyStringConverter.class, Converter.class);
converterInfo.setPluginClass(DummyStringConverter.class);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it actually necessary to call setPluginClass here? The constructor should do it?

@SuppressWarnings("rawtypes")
PluginInfo<Converter> converterInfo = new PluginInfo<>(
DummyStringConverter.class, Converter.class);
converterInfo.setPluginClass(DummyStringConverter.class);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here: is this call necessary?

pluginService.addPlugin(converterInfo);

// De-register DummyStringConverter
pluginService.removePlugin(converterInfo);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of adding then immediately removing, a cleaner approach might be to simply remove one of the built-in discovered plugins. If you don't like that external dependency for some reason (and I wouldn't blame you), you could create a second static inner class here annotated with @Plugin so that it is automatically discovered and added initially, and then remove it here. The advantage is that we ensure it works to remove plugins where were present when the context was first initialized. I think this is a more robust test—or at least a needed additional test.

pluginService.removePlugin(converterInfo);

assertNull(pluginService.getPlugin(DummyStringConverter.class));
assertFalse(convertService.supports("StringInput", Number.class));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wait... doesn't the convert service support conversion of string to number? Or only if you give an explicit Number subtype otherwise?

I would prefer, instead of String and Number, that you use two new interfaces defined here. That way we can be certain that future converters relating to basic types like strings and numbers do not inadvertently cause this test to fail in the future.

@ctrueden
Copy link
Member

Thank you very much, @stelfrich, this is looking really good. I'm glad it turned out to be straightforward and clean to implement.

I made some comments—could you please address them if you have time? Should be relatively minor and quick I hope.

@stelfrich
Copy link
Member Author

I made some comments—could you please address them if you have time? Should be relatively minor and quick I hope.

I have addressed your comments @ctrueden.

@ctrueden
Copy link
Member

ctrueden commented Oct 3, 2018

Meanwhile, @gab1one did this work again in ecf6cbb. 😓 @gab1one: will you please take a look at this PR and see if it accomplished anything that your changes did not?

@stelfrich I am very sorry that I not only dropped the ball on merging this, but then forgot it even existed. I am now making it a priority to go through the substantial backlog of very worthy PRs across the various SciJava and ImageJ components.

@stelfrich
Copy link
Member Author

I am very sorry that I not only dropped the ball on merging this, but then forgot it even existed.

Don't worry! I know how hard it is to keep track of all the PRs...

@gab1one: will you please take a look at this PR and see if it accomplished anything that your changes did not?

Just go ahead and close this if there's nothing of additional value here (which is likely)..

gab1one added a commit that referenced this pull request Oct 4, 2018
@gab1one
Copy link
Contributor

gab1one commented Oct 4, 2018

I have extracted the tests to a new PR #338, everything else is pretty much identical.

@gab1one gab1one closed this Oct 4, 2018
ctrueden added a commit that referenced this pull request Oct 11, 2018
SingletonServiceTest: extend with tests from #271.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants