Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AddEventSystem #1028

Merged
merged 16 commits into from
May 9, 2016
Merged

AddEventSystem #1028

merged 16 commits into from
May 9, 2016

Conversation

obraliar
Copy link
Contributor

@obraliar obraliar commented Mar 23, 2016

  • Introduce an EventBus object being passed around. This enables better testing.
  • Make DatabaseChangeEvent abstract and add subclasses according to DatbaseChangeEvent
  • Rewrite the currently existing code to use that event bus instead of net.sf.jabref.model.database.BibDatabase.addDatabaseChangeListener(DatabaseChangeListener) and net.sf.jabref.model.database.BibDatabase.removeDatabaseChangeListener(DatabaseChangeListener)
  • Changes described in CHANGELOG.md?
  • Tests created for changes?
  • Tests green?

@obraliar
Copy link
Contributor Author

Issue: #969

@obraliar
Copy link
Contributor Author

This commit should also demonstrate the structure of the new event system.

Discussions are welcome.

@oscargus
Copy link
Contributor

I just want to point out that there is an event system for BibDatabase. Which is not that much used. Maybe it can be used as inspiration/replaced.

@koppor
Copy link
Member

koppor commented Mar 25, 2016

This does demonstrate how the API of Google Guava works, but not how it can really be used at JabRef. Should we use one bus for everything? Should we use one bus per "thing" such as BibDatabase etc. - This is also discussed at the documentation.

Please double check the usage of net.sf.jabref.model.database.DatabaseChangeEvent. I think, the whole code around net.sf.jabref.model.database.DatabaseChangeEvent should be replaced with the Guava thing. Instead of net.sf.jabref.model.database.DatabaseChangeEvent.ChangeType there should be different classes. Then, it is possible to use the power of the EventBus. Important excerpts of the documentation: "which accepts a single argument of the type of event desired; " and "The EventBus instance will determine the type of event and route it to all registered listeners.". This enables to use a single bus with dedicated events such as FieldContentChanged etc.

Thus, please update this PR to

  • Introduce a Global EventBus into net.sf.jabref.Globals Introduce an EventBus object being passed around. This enables better testing.
  • Make DatabaseChangeEvent abstract and add subclasses according to DatbaseChangeEvent
  • Rewrite the currently existing code to use that event bus instead of net.sf.jabref.model.database.BibDatabase.addDatabaseChangeListener(DatabaseChangeListener) and net.sf.jabref.model.database.BibDatabase.removeDatabaseChangeListener(DatabaseChangeListener)

@koppor koppor added stupro type: code-quality Issues related to code or architecture decisions labels Mar 25, 2016
@obraliar
Copy link
Contributor Author

Yes, it actually only demonstrates the base function. I think we should have a separate package for that. So I created a new one and created a interface, which should normalize the usage of Google guava. Now we are going to replace the existing listeners and as @koppor already observed to prepare a global event bus.

@tobiasdiez
Copy link
Member

Mhh...I'm not sure that a global event bus is the right way to go. It adds another global object, makes debugging harder, everyone gets informed about everything (it is hard to listen only to changes to a certain database) etc. But of course it also has its advantages. What is the opinion of the other @JabRef/developers here?

@obraliar
Copy link
Contributor Author

I think its OK to use one. Therefore we use different Event objects, which should prevent the chaos.

@koppor
Copy link
Member

koppor commented Mar 25, 2016

On the one hand, I don't like to pass around the EventBus object everywhere. It is a global thing and used everywhere. Maybe we should place it in net.sf.jabref.gui.GUIGlobals.

On the other hand, I agree that a global object makes testing difficult.

Let's hear about design ideas by the others. This, however, doesn't stop @obraliar replacing the old event system. The "location" of the EventBus object can be changed later on.

* to pass objects on event occurrence.
*/

public class Event {
Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh, I didn't know that there is a existing class for this purpose :)

Copy link
Member

Choose a reason for hiding this comment

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

I see no reason for using java-util. We are implementing something contrary when using Guava. The only argument I see is that we can trace which events are existing. For that thing, I would agree to define an abstract class JabRefEvent.

Copy link
Member

Choose a reason for hiding this comment

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

I agree with @koppor From the api doc the EventObject looks like that is's main purpose is to be used in GUI swing/awt events.

@koppor
Copy link
Member

koppor commented Mar 25, 2016

@obraliar Please do not take further action until @JabRef/developers decided which way to go.

@obraliar
Copy link
Contributor Author

No opinions? If not, we would begin to discuss the details internally within the stupro group.

@lenhard
Copy link
Member

lenhard commented Mar 29, 2016

Sorry, but (in contrast to other developers) I do not see why we need an event system. Everything we need should be doable with the plain old observer pattern and the benefit of an event bus is not clear to me.

This will be discussed in a devcall, which may or may not take place soon.

@obraliar obraliar force-pushed the AddEventSystem branch 5 times, most recently from 8ce8ea5 to 8e34f7d Compare April 24, 2016 14:08
@obraliar
Copy link
Contributor Author

Now all entry events only base upon Google's Guava Bus System.
The integrated event system (listener registration, event posts & receivements, etc.) works.

Here are some new findings:

  • We have to use one EventBus for each BibDatabase, cause there may be more than one opened. A main event such as AddEntryEvent should not affect all opened databases.
  • For all other events that do not affect BibDatabase we could introduce one general EventBus. This part of introduction is very easy, but I see no need for that yet.

@@ -189,6 +167,20 @@ public void setType(EntryType type) {
}

/**
* Sets this entry's ID, provided the database containing it
Copy link
Member

Choose a reason for hiding this comment

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

Why is the code moved in this class? Could you keep the old position? I think, the move was on purpose. See #1309

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. Moved to old position.

return fieldName;
}

public String getValue() {
Copy link
Member

Choose a reason for hiding this comment

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

getNewValue and rename private variable.

if (entry.isPresent() && (entry.get() != newEntry)) {
entry.ifPresent(e -> e.unregisterListener(this.currentChangeFieldUpdateEvent));
this.currentChangeFieldUpdateEvent = new ChangeFieldUpdateEvent();
newEntry.registerListener(this.currentChangeFieldUpdateEvent);
Copy link
Member

Choose a reason for hiding this comment

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

I think, the registerListener should be moved after the if statement.

Copy link
Member

Choose a reason for hiding this comment

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

With a check if newEntry is not null.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

obraliar added 2 commits May 8, 2016 02:29
and use ChangeFieldEvent instead.
Remove private listener classes.
Small refactorings.
import net.sf.jabref.model.entry.BibEntry;

/**
* <code>ChangedFieldEvent</code> is fired when a field of <code>BibEntry</code> has been modified.
Copy link
Member

Choose a reason for hiding this comment

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

Or removed. Or added. See eventBus.post(new ChangedFieldEvent(this, fieldName, null));. Please add this as comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

@koppor
Copy link
Member

koppor commented May 9, 2016

LGTM

@koppor koppor merged commit a851faf into JabRef:master May 9, 2016
@koppor koppor changed the title [WIP] AddEventSystem AddEventSystem May 9, 2016
@koppor koppor removed status: devcall status: ready-for-review Pull Requests that are ready to be reviewed by the maintainers labels May 9, 2016
newEntry.addPropertyChangeListener(this);

if (entry.isPresent() && (entry.get() != newEntry)) {
entry.ifPresent(e -> e.unregisterListener(this));
}
Copy link
Contributor

Choose a reason for hiding this comment

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

could be written simpler: entry.filter(e -> e != newEntry).ifPresent(e -> e.unregisterListener(this));

@tobiasdiez
Copy link
Member

@JabRef/stupro could you please add some short notes to the wiki on how to push and subscribe to events (using the eventbus). Thanks!

@obraliar
Copy link
Contributor Author

obraliar commented Jul 8, 2016

Done. See https://github.com/JabRef/jabref/wiki/Code-Howtos#using-the-eventsystem

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: code-quality Issues related to code or architecture decisions
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants